From 36e628339927bd06e7d5e834c4d5d4886ce7e42f Mon Sep 17 00:00:00 2001 From: Alfa Team Date: Fri, 26 Jun 2026 10:57:38 -0400 Subject: [PATCH 1/9] Lock ProjectInstructions single source --- docs_build/dev/BUILD_PR.md | 66 +- docs_build/dev/PLAN_PR.md | 34 +- docs_build/dev/PROJECT_INSTRUCTIONS.md | 14 +- .../PROJECT_INSTRUCTIONS.md | 12 +- docs_build/dev/ProjectInstructions/README.txt | 23 +- .../TEAM_START_COMMANDS.md | 31 + .../addendums/assistant_execution_modes.md | 120 ++ .../addendums/branch_lock_governance.md | 34 + .../canonical_repository_structure.md | 39 + .../codex_artifact_and_reporting_standard.md | 66 + .../codex_project_instructions_startup.md | 65 + .../addendums/legacy_migration_policy.md | 33 + .../addendums/pr_workflow.md | 37 + ...ect_instructions_single_source_eod_lock.md | 61 + .../test_structure_standardization.md | 33 + .../team_assignments/TEAM_ASSIGNMENTS.md | 41 + ...ect-instructions-single-source-eod-lock.md | 25 + ...ingle-source-eod-lock_branch-validation.md | 7 + ...source-eod-lock_manual-validation-notes.md | 8 + ...e-source-eod-lock_requirement-checklist.md | 16 + ...-single-source-eod-lock_validation-lane.md | 17 + .../dev/reports/codex_changed_files.txt | 40 +- docs_build/dev/reports/codex_review.diff | 1601 ++++++++++++----- project-instructions/README.md | 11 + .../addendums/assistant-execution-modes.md | 2 + .../canonical-repository-structure.md | 2 + .../codex-artifact-and-reporting-standard.md | 2 + .../codex-project-instructions-startup.md | 2 + .../addendums/legacy-migration-policy.md | 2 + .../test-structure-standardization.md | 2 + 30 files changed, 1913 insertions(+), 533 deletions(-) create mode 100644 docs_build/dev/ProjectInstructions/addendums/assistant_execution_modes.md create mode 100644 docs_build/dev/ProjectInstructions/addendums/canonical_repository_structure.md create mode 100644 docs_build/dev/ProjectInstructions/addendums/codex_artifact_and_reporting_standard.md create mode 100644 docs_build/dev/ProjectInstructions/addendums/codex_project_instructions_startup.md create mode 100644 docs_build/dev/ProjectInstructions/addendums/legacy_migration_policy.md create mode 100644 docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md create mode 100644 docs_build/dev/ProjectInstructions/addendums/test_structure_standardization.md create mode 100644 docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock.md create mode 100644 docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_branch-validation.md create mode 100644 docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_manual-validation-notes.md create mode 100644 docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_requirement-checklist.md create mode 100644 docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_validation-lane.md create mode 100644 project-instructions/README.md diff --git a/docs_build/dev/BUILD_PR.md b/docs_build/dev/BUILD_PR.md index 30700e9cd..50b1b27fa 100644 --- a/docs_build/dev/BUILD_PR.md +++ b/docs_build/dev/BUILD_PR.md @@ -1,66 +1,52 @@ -# PR_26177_006-shared-time-foundation +# PR_26177_OWNER_007-project-instructions-single-source-eod-lock ## Purpose -Add a small shared time foundation. +Make `docs_build/dev/ProjectInstructions/` the only active Project Instructions source and add EOD main lock plus next-day reset governance. ## Source Of Truth -This `BUILD_PR.md`, `PLAN_PR.md`, and the user request are the source of truth for `PR_26177_006-shared-time-foundation`. - -## Stack - -- Base branch: `PR_26177_005-shared-text-foundation` +This `BUILD_PR.md`, `PLAN_PR.md`, and the user request are the source of truth for `PR_26177_OWNER_007-project-instructions-single-source-eod-lock`. ## Exact Scope -- Add `src/shared/time/` foundation. -- Include duration formatting, timestamp helpers, debounce/throttle/sleep helpers where safe for shared runtime. -- Add targeted tests for the shared time area. -- No scheduler/runtime behavior changes. -- Create required Codex reports under `docs_build/dev/reports/`. -- Create repo-structured delta ZIP under `tmp/`. +- Audit repo for ProjectInstructions / project instructions duplicates. +- Establish `docs_build/dev/ProjectInstructions/` as the only active source. +- Mark all other ProjectInstructions-style sources changed by this PR as deprecated references. +- Update active team start/governance docs to reference only `docs_build/dev/ProjectInstructions/`. +- Add EOD main lock and next-day reset governance. +- Add required reports under `docs_build/dev/reports/`. ## Exact Targets - `docs_build/dev/PLAN_PR.md` - `docs_build/dev/BUILD_PR.md` -- `src/shared/time/time.js` -- `tests/shared/TimeFoundation.test.mjs` -- `docs_build/dev/reports/PR_26177_006-shared-time-foundation.md` -- `docs_build/dev/reports/PR_26177_006-shared-time-foundation_branch-validation.md` -- `docs_build/dev/reports/PR_26177_006-shared-time-foundation_requirement-checklist.md` -- `docs_build/dev/reports/PR_26177_006-shared-time-foundation_validation-lane.md` -- `docs_build/dev/reports/PR_26177_006-shared-time-foundation_manual-validation-notes.md` +- `docs_build/dev/PROJECT_INSTRUCTIONS.md` +- `docs_build/dev/ProjectInstructions/README.txt` +- `docs_build/dev/ProjectInstructions/PROJECT_INSTRUCTIONS.md` +- `docs_build/dev/ProjectInstructions/TEAM_START_COMMANDS.md` +- `docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md` +- `docs_build/dev/ProjectInstructions/addendums/*.md` +- `project-instructions/README.md` +- `project-instructions/addendums/*.md` +- `docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock*.md` - `docs_build/dev/reports/codex_review.diff` - `docs_build/dev/reports/codex_changed_files.txt` ## Out Of Scope -- No scheduler/runtime behavior changes. -- No browser-owned product data. -- No runtime UI changes. -- No browser storage changes. -- No API/database changes. -- No `start_of_day` folder changes. -- No unrelated cleanup. -- No full samples smoke by default. +- No product/runtime changes. +- No feature work. +- No `start_of_day` changes. +- No legacy SQLite file changes. ## Validation -Run exactly: +Run: ```powershell -node ./scripts/run-node-test-files.mjs tests/shared/TimeFoundation.test.mjs -node --check src/shared/time/time.js -node --check tests/shared/TimeFoundation.test.mjs +rg -n 'project-instructions/addendums|docs_build/dev/PROJECT_INSTRUCTIONS.md.*source of truth|Codex must always read `docs_build/dev/PROJECT_INSTRUCTIONS.md`|Read `docs_build/dev/PROJECT_INSTRUCTIONS.md`' docs_build/dev/ProjectInstructions docs_build/dev/PROJECT_INSTRUCTIONS.md project-instructions +rg -n "End of Day:|Next Day Start:|HEAD.*published EOD SHA|only active Project Instructions source" docs_build/dev/ProjectInstructions +git diff --name-only -- src assets toolbox games api serverside package.json package-lock.json docs_build/dev/start_of_day git diff --check ``` - -## Artifact - -Create repo-structured delta ZIP: - -```text -tmp/PR_26177_006-shared-time-foundation_delta.zip -``` diff --git a/docs_build/dev/PLAN_PR.md b/docs_build/dev/PLAN_PR.md index 907936aee..39fa03385 100644 --- a/docs_build/dev/PLAN_PR.md +++ b/docs_build/dev/PLAN_PR.md @@ -1,22 +1,28 @@ -# PLAN_PR: PR_26177_006-shared-time-foundation +# PLAN_PR: PR_26177_OWNER_007-project-instructions-single-source-eod-lock ## Purpose -Add a small shared time foundation. +Make `docs_build/dev/ProjectInstructions/` the only active Project Instructions source and add EOD main lock plus next-day reset governance. ## Scope -- Add `src/shared/time/` foundation. -- Include duration formatting, timestamp helpers, sleep, debounce, and throttle helpers. -- Add targeted tests. -- No scheduler/runtime behavior changes. -- No browser-owned product data. -- No runtime UI changes. -- No unrelated cleanup. +- Audit ProjectInstructions and project instructions duplicates. +- Mark legacy ProjectInstructions-style sources as deprecated reference material. +- Move active legacy addendums into `docs_build/dev/ProjectInstructions/addendums/`. +- Update active team start and governance docs to reference only `docs_build/dev/ProjectInstructions/`. +- Add EOD main lock, next-day reset, and team PR branch creation gate. +- Add required Codex reports under `docs_build/dev/reports/`. -## Implementation Plan +## Out Of Scope -1. Add `src/shared/time/time.js`. -2. Add `tests/shared/TimeFoundation.test.mjs`. -3. Validate duration, timestamp, sleep, debounce, and throttle helpers. -4. Produce required Codex reports and repo-structured ZIP. +- No product/runtime changes. +- No feature work. +- No `start_of_day` changes. +- No legacy SQLite file changes. + +## Validation Plan + +1. Run targeted grep/search proving no active duplicate ProjectInstructions source remains. +2. Confirm EOD/Next Day rule appears in active governance docs. +3. Confirm no product/runtime files changed. +4. Run `git diff --check`. diff --git a/docs_build/dev/PROJECT_INSTRUCTIONS.md b/docs_build/dev/PROJECT_INSTRUCTIONS.md index af9e9e2db..c1136fdbe 100644 --- a/docs_build/dev/PROJECT_INSTRUCTIONS.md +++ b/docs_build/dev/PROJECT_INSTRUCTIONS.md @@ -1,5 +1,7 @@ # PROJECT INSTRUCTIONS +> Deprecated active-source notice: this file is preserved as historical reference only. The only active Project Instructions source is `docs_build/dev/ProjectInstructions/`. If this file conflicts with `docs_build/dev/ProjectInstructions/`, the active folder wins unless OWNER explicitly approves a newer governance change. + You are working in a docs-first repo workflow. Workflow: @@ -864,7 +866,7 @@ Controls must remain copy-friendly and human-readable. ### ChatGPT Workflow Governance Consistency -ChatGPT repo workflow responses are governed by `docs_build/dev/PROJECT_INSTRUCTIONS.md` as the source of truth. +Deprecated note: this historical section no longer defines the active source of truth. ChatGPT repo workflow responses are governed by `docs_build/dev/ProjectInstructions/`. ChatGPT must not drift from the required response ordering. @@ -1716,13 +1718,13 @@ Do not compact: Do not change JSON contracts or semantics while applying array formatting. -## PROJECT INSTRUCTIONS LOCATION +## DEPRECATED PROJECT INSTRUCTIONS LOCATION -PROJECT_INSTRUCTIONS.md lives at: +Historical PROJECT_INSTRUCTIONS.md is preserved at: `docs_build/dev/PROJECT_INSTRUCTIONS.md` -Codex must always read `docs_build/dev/PROJECT_INSTRUCTIONS.md` from this path as the source of truth before executing repository workflow instructions. +This file is not the active source of truth. Codex must read `docs_build/dev/ProjectInstructions/README.txt` first and use `docs_build/dev/ProjectInstructions/` as the active Project Instructions source before executing repository workflow instructions. ## CODEX COMMAND FORMATTING RULE @@ -2384,9 +2386,9 @@ Treat these files the same as existing instruction documents for read-set, revie Codex must run this gate before every PR execution and before any file changes. Required instruction reads: -- Read `docs_build/dev/PROJECT_INSTRUCTIONS.md`. +- Read `docs_build/dev/ProjectInstructions/README.txt`. - Read `docs_build/dev/PROJECT_MULTI_PC.txt`. -- Treat the newest applicable section in `PROJECT_INSTRUCTIONS.md` as authoritative when rules overlap. +- Treat the newest applicable section in `docs_build/dev/ProjectInstructions/` as authoritative when rules overlap. - Treat the current team ownership section in `PROJECT_MULTI_PC.txt` as authoritative for TEAM routing. Required pre-change report: diff --git a/docs_build/dev/ProjectInstructions/PROJECT_INSTRUCTIONS.md b/docs_build/dev/ProjectInstructions/PROJECT_INSTRUCTIONS.md index d2a84ecbe..99ddd0f42 100644 --- a/docs_build/dev/ProjectInstructions/PROJECT_INSTRUCTIONS.md +++ b/docs_build/dev/ProjectInstructions/PROJECT_INSTRUCTIONS.md @@ -4,6 +4,12 @@ Read `README.txt` first. This file is the root index for the append-first Project Instructions operating system under `docs_build/dev/ProjectInstructions/`. +## Active Source + +`docs_build/dev/ProjectInstructions/` is the only active Project Instructions source. + +Historical Project Instructions material outside this folder is deprecated reference material only and must not be used as an active source of governance. + ## Purpose The Project Instructions operating system provides additive governance for: @@ -20,7 +26,7 @@ The Project Instructions operating system provides additive governance for: ## Preservation -Existing Project Instructions remain preserved in their current locations. This operating system adds structure without deleting or rewriting existing documentation. +Existing Project Instructions outside `docs_build/dev/ProjectInstructions/` remain preserved only as deprecated reference material. When guidance conflicts, active files under `docs_build/dev/ProjectInstructions/` win unless OWNER explicitly approves a newer governance change. ## Folders @@ -41,6 +47,10 @@ Existing Project Instructions remain preserved in their current locations. This `docs_build/dev/ProjectInstructions/addendums/environment_configuration_standards.md` defines official `.env` file names, environment variable values, host/domain configuration, API URL configuration, R2 prefix configuration, and feature flag governance. +## Single Source and Main Lock Governance + +`docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md` defines the single active Project Instructions source, EOD main lock, next-day reset, and team branch creation gate. + ## Merge Control No PR in this operating system is merged without explicit owner approval. diff --git a/docs_build/dev/ProjectInstructions/README.txt b/docs_build/dev/ProjectInstructions/README.txt index a48becf05..631fd3918 100644 --- a/docs_build/dev/ProjectInstructions/README.txt +++ b/docs_build/dev/ProjectInstructions/README.txt @@ -1,10 +1,10 @@ Read this file first. Folder purpose: -This folder is the append-first Project Instructions operating system for Game Foundry Studio. It organizes active governance, backlog, team assignment, deprecation, and history material without deleting or rewriting the existing Project Instructions files elsewhere in the repository. +This folder is the only active Project Instructions source for Game Foundry Studio. It organizes active governance, backlog, team assignment, deprecation, and history material under `docs_build/dev/ProjectInstructions/`. Preservation rules: -Preserve all existing documentation. Add new files or append explicit references unless the owner explicitly approves deletion or rewrite. When a conflict appears, stop, explain the conflict, and request owner approval before changing existing instruction text. +Preserve historical Project Instructions material as deprecated reference only. Do not treat `docs_build/dev/PROJECT_INSTRUCTIONS.md`, `project-instructions/`, or archived snapshots as active instruction sources. When a conflict appears, `docs_build/dev/ProjectInstructions/` wins unless OWNER explicitly approves a newer governance change. Backlog workflow: Backlog work is tracked under backlog/. BACKLOG_MASTER.md is the planned source for backlog item status, notes, and references. Backlog item text is treated as immutable once created; status and notes may change under the governance addendums. @@ -29,9 +29,9 @@ Do not rewrite history snapshots after creation unless the owner explicitly appr READ THIS FIRST -1. Read Project Instructions before making changes. -2. Project Instructions are append-only. -3. Existing approved guidance may not be removed. +1. Read `docs_build/dev/ProjectInstructions/README.txt` before making changes. +2. Treat `docs_build/dev/ProjectInstructions/` as the only active Project Instructions source. +3. Historical Project Instructions files outside this folder are deprecated references only. 4. Team ownership must be respected. 5. BACKLOG_MASTER.md is the authoritative backlog. 6. Build Path status derives from backlog status. @@ -42,12 +42,13 @@ READ THIS FIRST 11. Batch Governance Mode is the default for governance, documentation, and administrative work. Addendum index: -- Canonical Repository Structure: project-instructions/addendums/canonical-repository-structure.md -- Test Structure Standardization: project-instructions/addendums/test-structure-standardization.md -- Legacy Migration Policy: project-instructions/addendums/legacy-migration-policy.md -- Assistant Execution Modes: project-instructions/addendums/assistant-execution-modes.md -- Codex Artifact and Reporting Standard: project-instructions/addendums/codex-artifact-and-reporting-standard.md -- Codex Project Instructions Startup: project-instructions/addendums/codex-project-instructions-startup.md +- Single Source and EOD Main Lock: docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md +- Canonical Repository Structure: docs_build/dev/ProjectInstructions/addendums/canonical_repository_structure.md +- Test Structure Standardization: docs_build/dev/ProjectInstructions/addendums/test_structure_standardization.md +- Legacy Migration Policy: docs_build/dev/ProjectInstructions/addendums/legacy_migration_policy.md +- Assistant Execution Modes: docs_build/dev/ProjectInstructions/addendums/assistant_execution_modes.md +- Codex Artifact and Reporting Standard: docs_build/dev/ProjectInstructions/addendums/codex_artifact_and_reporting_standard.md +- Codex Project Instructions Startup: docs_build/dev/ProjectInstructions/addendums/codex_project_instructions_startup.md - Project Reference Files Governance: docs_build/dev/ProjectInstructions/addendums/project_reference_files.md - Environment Governance Model: docs_build/dev/ProjectInstructions/addendums/environment_governance_model.md - Environment Configuration Standards: docs_build/dev/ProjectInstructions/addendums/environment_configuration_standards.md diff --git a/docs_build/dev/ProjectInstructions/TEAM_START_COMMANDS.md b/docs_build/dev/ProjectInstructions/TEAM_START_COMMANDS.md index d0118f63a..c446a4b33 100644 --- a/docs_build/dev/ProjectInstructions/TEAM_START_COMMANDS.md +++ b/docs_build/dev/ProjectInstructions/TEAM_START_COMMANDS.md @@ -1,5 +1,16 @@ # TEAM_START_COMMANDS +## Required Main Reset Gate For Every Team + +No team creates a PR branch until all checks pass: + +- Current branch: `main` +- Worktree: clean +- `main...origin/main`: `0 0` +- `HEAD` SHA matches the published EOD SHA + +Use `docs_build/dev/ProjectInstructions/` as the only active Project Instructions source. + ## Start Team Alfa Ready-to-copy command: @@ -123,4 +134,24 @@ Merge to main is EOD-only and owner-approved, unless the owner explicitly says: "Merge this PR now." Do not treat sequential PR completion as merge approval. + +End of Day: +git checkout main +git fetch origin +git pull --ff-only origin main +git status +git rev-list --left-right --count main...origin/main + +Required: +On branch main +nothing to commit, working tree clean +0 0 + +Next Day Start: +git checkout main +git fetch origin +git pull --ff-only origin main +git status +git rev-list --left-right --count main...origin/main +git rev-parse HEAD ``` diff --git a/docs_build/dev/ProjectInstructions/addendums/assistant_execution_modes.md b/docs_build/dev/ProjectInstructions/addendums/assistant_execution_modes.md new file mode 100644 index 000000000..6d7928669 --- /dev/null +++ b/docs_build/dev/ProjectInstructions/addendums/assistant_execution_modes.md @@ -0,0 +1,120 @@ +# Assistant Execution Modes + +## Purpose + +Standardize request interpretation and expected outputs for Review, Owner, Build PR, Continue, Challenge, and Stop Gate workflows. + +## Command Modes + +### Review + +Expected Output: +- Findings +- Risks +- Recommendations + +Do Not Output: +- PRs +- Implementation plans + +### Owner + +Expected Output: +- Decisions +- Governance direction +- Standards + +Do Not Output: +- Detailed implementation + +### Build PR + +Expected Output: +- Single Codex work order +- May contain multiple sequential PRs belonging to the same workstream +- Copy/paste ready for execution + +Should Include: +- Start gates +- Changes +- Validation +- Commit names +- Stop point + +Do Not Output: +- Design discussion +- Alternatives +- Rationale +- Architecture brainstorming + +### Continue + +Expected Output: +- Next sequential executable PR +- Next sequential work order + +Do Not Output: +- New ideas +- Re-analysis +- Additional brainstorming + +### Challenge + +Expected Output: +- Risks +- Contradictions +- Better alternatives + +Do Not Output: +- Immediate implementation + +### Stop Gate + +Expected Output: +- Why work should stop +- Required corrections + +Allowed Reasons: +- Governance conflict +- Architecture conflict +- Security risk +- Data loss risk +- Major technical debt increase + +## Additional Definitions + +### Follow Project Instructions + +Meaning: +- Use existing governance +- Do not redesign process + +### Build the PR + +Meaning: +- Produce Codex executable work order immediately + +### Continue + +Meaning: +- Produce next sequential work item + +### No zip file + +Meaning: +- Generate instructions only +- Do not expect artifact review + +### You are owner + +Meaning: +- Make decisions +- Do not ask for direction unless blocked + +### Done for the day + +Meaning: +- Finish commits +- Merge +- Push +- Create next-day start document diff --git a/docs_build/dev/ProjectInstructions/addendums/branch_lock_governance.md b/docs_build/dev/ProjectInstructions/addendums/branch_lock_governance.md index 518f8c943..d6c8e4cf7 100644 --- a/docs_build/dev/ProjectInstructions/addendums/branch_lock_governance.md +++ b/docs_build/dev/ProjectInstructions/addendums/branch_lock_governance.md @@ -23,6 +23,7 @@ Keep active work attached to the correct assigned team, branch, and OWNER decisi - Start from current `main`. - Pull latest `origin/main` before creating a work branch. +- Do not create a PR branch unless current branch is `main`, worktree is clean, `main...origin/main` is `0 0`, and `HEAD` SHA matches the published EOD SHA. - Keep work on the active branch until the PR is merged, the branch is retired, or OWNER says to return to `main`. - Do not commit directly to `main` unless OWNER explicitly approves. - Do not merge stale historical branches directly unless they are current, clean, still needed, and OWNER-approved. @@ -54,3 +55,36 @@ Protected guidance includes: - Governance Phase 1 completion guidance If protected guidance must change, OWNER approval is required. + +## End Of Day Main Lock + +End of Day: + +```text +git checkout main +git fetch origin +git pull --ff-only origin main +git status +git rev-list --left-right --count main...origin/main +``` + +Required: + +```text +On branch main +nothing to commit, working tree clean +0 0 +``` + +Next Day Start: + +```text +git checkout main +git fetch origin +git pull --ff-only origin main +git status +git rev-list --left-right --count main...origin/main +git rev-parse HEAD +``` + +The next-day `HEAD` SHA must match the published EOD SHA before any team creates a PR branch. diff --git a/docs_build/dev/ProjectInstructions/addendums/canonical_repository_structure.md b/docs_build/dev/ProjectInstructions/addendums/canonical_repository_structure.md new file mode 100644 index 000000000..e26939469 --- /dev/null +++ b/docs_build/dev/ProjectInstructions/addendums/canonical_repository_structure.md @@ -0,0 +1,39 @@ +# Canonical Repository Structure + +## Purpose + +Establish the canonical repository structure for future development and reduce technical debt. + +## Canonical Structure + +Tools: +- toolbox/{tool-name}/index.html + +Tool assets: +- assets/toolbox/{tool-name}/js/index.js +- assets/toolbox/{tool-name}/css/index.css + +Themes: +- assets/theme-v1/ +- assets/theme-v2/ + +Shared JavaScript: +- assets/js/shared/ + +Engine: +- src/engine/{feature-name}/ + +API: +- api/{feature-name}/ + +Serverside: +- serverside/{feature-name}/ + +## Rules + +- Theme first. +- Tool CSS second. +- Shared functionality belongs in assets/js/shared/. +- No new scattered JS folders. +- No new scattered CSS folders. +- New development follows the canonical structure. diff --git a/docs_build/dev/ProjectInstructions/addendums/codex_artifact_and_reporting_standard.md b/docs_build/dev/ProjectInstructions/addendums/codex_artifact_and_reporting_standard.md new file mode 100644 index 000000000..498e3895e --- /dev/null +++ b/docs_build/dev/ProjectInstructions/addendums/codex_artifact_and_reporting_standard.md @@ -0,0 +1,66 @@ +# Codex Artifact and Reporting Standard + +## Purpose + +Standardize Codex deliverables, completion reporting, and artifact generation. + +## ZIP Artifact Requirement + +Every Codex task must produce a ZIP artifact. + +Applies to: +- Success +- Failure +- Stop Gate +- Partial Completion +- Review Deliverables +- Governance Deliverables + +Minimum ZIP contents: +- summary.md + +Optional: +- changed-files.txt +- findings.md +- validation.txt +- generated artifacts + +## Completion Reporting + +Codex responses must include: +- ZIP filename +- ZIP location +- PR number(s) +- Merge commit(s) +- Validation results + +## Code Change Reporting + +When a ZIP is uploaded, report executable code changes only. + +Report format: + +```text +{relative path} - {added|updated|deleted} +``` + +Examples: + +```text +toolbox/text-to-speech/index.html - updated +assets/toolbox/text-to-speech/js/index.js - added +tests/toolbox/text-to-speech/functional.spec.mjs - updated +``` + +Do not report: +- markdown +- documentation +- reports +- notes +- README updates + +unless explicitly requested. + +## No ZIP Means Incomplete + +A task is not considered complete until the ZIP artifact is generated and reported. diff --git a/docs_build/dev/ProjectInstructions/addendums/codex_project_instructions_startup.md b/docs_build/dev/ProjectInstructions/addendums/codex_project_instructions_startup.md new file mode 100644 index 000000000..e0abb9db0 --- /dev/null +++ b/docs_build/dev/ProjectInstructions/addendums/codex_project_instructions_startup.md @@ -0,0 +1,65 @@ +# Codex Project Instructions Startup + +## Purpose + +Ensure Codex uses the current approved governance before making repository changes. + +## Startup Requirement + +Before performing work, Codex must review and use: + +```text +docs_build/dev/ProjectInstructions/ +``` + +Codex must use this as the only active source of truth for: +- Governance rules +- Repository standards +- Ownership rules +- Workflow rules +- Addendums +- Execution modes +- Artifact requirements + +Deprecated Project Instructions material outside `docs_build/dev/ProjectInstructions/` is reference-only and must not override active governance. + +## Project Reference File Review + +When present in `ProjectInstructions.zip`, the active project instruction directory, or `docs_build/dev/admin-notes/`, Codex must include these recognized project instruction/reference files in the Project Instructions read set: + +- `Installs required.txt` +- `Table layout.txt` + +Chat instructions may supplement Project Instructions but must not override approved governance without explicit OWNER approval. + +## Conflict Handling + +If a chat instruction conflicts with Project Instructions: +- Stop +- Do not continue the PR +- Produce the required ZIP artifact +- Document the conflict in summary.md +- Ask for OWNER direction + +## Execution Mode Validation + +When a request contains: +- Build PR +- Continue +- Follow Project Instructions +- Next PR + +Codex must treat the request as Execution Mode. + +Execution Mode means: +- Execute the requested work order +- Do not redesign the process +- Do not provide alternatives unless a Stop Gate condition exists + +## Validation + +Before completing the PR: +- Verify this addendum appears in the Project Instructions index +- Verify markdown is valid +- Verify all indexed addendums exist +- Verify the required ZIP artifact is produced diff --git a/docs_build/dev/ProjectInstructions/addendums/legacy_migration_policy.md b/docs_build/dev/ProjectInstructions/addendums/legacy_migration_policy.md new file mode 100644 index 000000000..5e43679f4 --- /dev/null +++ b/docs_build/dev/ProjectInstructions/addendums/legacy_migration_policy.md @@ -0,0 +1,33 @@ +# Legacy Migration Policy + +## Purpose + +Reduce technical debt incrementally during normal development. + +## Migration Trigger + +Migration review is required when any of these actions touch legacy files: + +- File modified +- File renamed +- Bug fix +- Enhancement +- Test modification + +## Migration Process + +1. Review JS location. +2. Review CSS location. +3. Review test location. +4. Move touched files into canonical structure. +5. Update imports. +6. Update tests. +7. Remove legacy references. + +## Rules + +- Legacy files may only be deleted when no active references remain. +- Temporary bridge code must contain `TEMPORARY_MIGRATION` and a removal plan. +- No new scattered JS locations. +- No new scattered CSS locations. +- No new scattered test locations. diff --git a/docs_build/dev/ProjectInstructions/addendums/pr_workflow.md b/docs_build/dev/ProjectInstructions/addendums/pr_workflow.md index f8a4acb6e..7c1cd8275 100644 --- a/docs_build/dev/ProjectInstructions/addendums/pr_workflow.md +++ b/docs_build/dev/ProjectInstructions/addendums/pr_workflow.md @@ -129,3 +129,40 @@ Stop only for: - Merge conflict - Validation failure - OWNER decision + +## EOD Main Lock + +End of Day: + +```text +git checkout main +git fetch origin +git pull --ff-only origin main +git status +git rev-list --left-right --count main...origin/main +``` + +Required: + +```text +On branch main +nothing to commit, working tree clean +0 0 +``` + +## Next Day Start + +```text +git checkout main +git fetch origin +git pull --ff-only origin main +git status +git rev-list --left-right --count main...origin/main +git rev-parse HEAD +``` + +No team creates a PR branch until: +- Current branch: `main` +- Worktree: clean +- `main...origin/main`: `0 0` +- `HEAD` SHA matches published EOD SHA diff --git a/docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md b/docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md new file mode 100644 index 000000000..9ea3824e0 --- /dev/null +++ b/docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md @@ -0,0 +1,61 @@ +# Project Instructions Single Source And EOD Main Lock + +Status: Approved +Owner: OWNER + +## Active Source + +`docs_build/dev/ProjectInstructions/` is the only active Project Instructions source for Game Foundry Studio. + +Deprecated reference locations must not be used as active instruction sources: +- `docs_build/dev/PROJECT_INSTRUCTIONS.md` +- `project-instructions/` +- archived Project Instructions snapshots +- generated PR reports + +If deprecated reference material conflicts with `docs_build/dev/ProjectInstructions/`, the active folder wins unless OWNER explicitly approves a newer governance change. + +## End Of Day + +```text +git checkout main +git fetch origin +git pull --ff-only origin main +git status +git rev-list --left-right --count main...origin/main +``` + +Required: + +```text +On branch main +nothing to commit, working tree clean +0 0 +``` + +The EOD report must record the final `HEAD` SHA as the published EOD SHA. + +## Next Day Start + +```text +git checkout main +git fetch origin +git pull --ff-only origin main +git status +git rev-list --left-right --count main...origin/main +git rev-parse HEAD +``` + +## Team Branch Creation Gate + +No team creates a PR branch until: +- Current branch: `main` +- Worktree: clean +- `main...origin/main`: `0 0` +- `HEAD` SHA matches published EOD SHA + +If any check fails, stop before branch creation and restore main to the published EOD state or request OWNER direction. + +## Start Of Day Boundary + +`docs_build/dev/start_of_day/` may point to `docs_build/dev/ProjectInstructions/`, but it must not become a second active Project Instructions source. diff --git a/docs_build/dev/ProjectInstructions/addendums/test_structure_standardization.md b/docs_build/dev/ProjectInstructions/addendums/test_structure_standardization.md new file mode 100644 index 000000000..997b16730 --- /dev/null +++ b/docs_build/dev/ProjectInstructions/addendums/test_structure_standardization.md @@ -0,0 +1,33 @@ +# Test Structure Standardization + +## Purpose + +Standardize testing locations and ensure independent tool validation. + +## Canonical Test Structure + +Tool tests: +- tests/toolbox/{tool-name}/ + +Engine tests: +- tests/engine/{feature-name}/ + +API tests: +- tests/api/{feature-name}/ + +Server tests: +- tests/server/{feature-name}/ + +Shared JavaScript tests: +- tests/js/shared/ + +Regression tests: +- tests/regression/ + +## Rules + +- Every tool must be independently testable. +- Regression tests do not replace tool tests. +- Tool tests validate tool functionality. +- Regression tests validate platform behavior. +- New tests follow the canonical structure. diff --git a/docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md b/docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md index 9735b4bd4..9a104b4f9 100644 --- a/docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md +++ b/docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md @@ -211,3 +211,44 @@ Commit/push during the day is allowed only on assigned team/OWNER/PR branches. Merge to main is EOD-only and owner-approved, unless the owner explicitly says: "Merge this PR now." + +## EOD Main Lock And Next Day Reset + +End of Day: + +```text +git checkout main +git fetch origin +git pull --ff-only origin main +git status +git rev-list --left-right --count main...origin/main +``` + +Required: + +```text +On branch main +nothing to commit, working tree clean +0 0 +``` + +Next Day Start: + +```text +git checkout main +git fetch origin +git pull --ff-only origin main +git status +git rev-list --left-right --count main...origin/main +git rev-parse HEAD +``` + +Team rule: +No team creates a PR branch until: +- Current branch: `main` +- Worktree: clean +- `main...origin/main`: `0 0` +- `HEAD` SHA matches published EOD SHA + +Active source rule: +Teams must use only `docs_build/dev/ProjectInstructions/` as the active Project Instructions source. diff --git a/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock.md b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock.md new file mode 100644 index 000000000..5c7927f17 --- /dev/null +++ b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock.md @@ -0,0 +1,25 @@ +# PR_26177_OWNER_007-project-instructions-single-source-eod-lock + +Date: 2026-06-26 +Scope: Project Instructions single-source and EOD main lock governance +Status: PASS + +## Summary + +- Established `docs_build/dev/ProjectInstructions/` as the only active Project Instructions source. +- Migrated legacy root `project-instructions/addendums/` content into active `docs_build/dev/ProjectInstructions/addendums/` files. +- Marked legacy `docs_build/dev/PROJECT_INSTRUCTIONS.md` and `project-instructions/` material as deprecated reference only. +- Added EOD main lock, next-day reset, and team branch creation gate governance. +- Updated active team start and governance docs to reference only `docs_build/dev/ProjectInstructions/`. +- No product/runtime, `start_of_day`, feature, or legacy SQLite file changes were made. + +## Validation + +- PASS: targeted grep found no active duplicate ProjectInstructions source-of-truth claim outside the active source. +- PASS: targeted grep confirmed EOD/Next Day governance appears in active governance docs. +- PASS: product/runtime and `start_of_day` changed-file check returned no files. +- PASS: `git diff --check`. + +## Artifact + +- `tmp/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_delta.zip` diff --git a/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_branch-validation.md b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_branch-validation.md new file mode 100644 index 000000000..17e0bfc39 --- /dev/null +++ b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_branch-validation.md @@ -0,0 +1,7 @@ +# PR_26177_OWNER_007-project-instructions-single-source-eod-lock Branch Validation + +- PASS: Started from `main`. +- PASS: Start gate confirmed worktree clean before branch creation. +- PASS: Start gate confirmed `main...origin/main` was `0 0` before branch creation. +- PASS: Current branch is `PR_26177_OWNER_007-project-instructions-single-source-eod-lock`. +- PASS: No `.vscode/settings.json` change is staged or included. diff --git a/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_manual-validation-notes.md b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_manual-validation-notes.md new file mode 100644 index 000000000..10cbb4170 --- /dev/null +++ b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_manual-validation-notes.md @@ -0,0 +1,8 @@ +# PR_26177_OWNER_007-project-instructions-single-source-eod-lock Manual Validation Notes + +- Reviewed ProjectInstructions path and text references. +- Confirmed active source declarations live under `docs_build/dev/ProjectInstructions/`. +- Confirmed legacy locations are preserved as deprecated reference material rather than active sources. +- Confirmed `docs_build/dev/start_of_day/` was not modified. +- Confirmed no product/runtime files were modified. +- Confirmed ZIP artifact path: `tmp/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_delta.zip`. diff --git a/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_requirement-checklist.md b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_requirement-checklist.md new file mode 100644 index 000000000..99ab45345 --- /dev/null +++ b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_requirement-checklist.md @@ -0,0 +1,16 @@ +# PR_26177_OWNER_007-project-instructions-single-source-eod-lock Requirement Checklist + +- PASS: Audited repo for ProjectInstructions / project instructions duplicates. +- PASS: Active source is `docs_build/dev/ProjectInstructions/`. +- PASS: Legacy `docs_build/dev/PROJECT_INSTRUCTIONS.md` is marked deprecated. +- PASS: Legacy root `project-instructions/` folder is marked deprecated. +- PASS: Legacy root addendums are migrated into the active addendum tree. +- PASS: Active team start/governance docs reference only `docs_build/dev/ProjectInstructions/`. +- PASS: Added EOD command sequence. +- PASS: Added required EOD output: `On branch main`, clean worktree, `0 0`. +- PASS: Added Next Day Start command sequence. +- PASS: Added team branch creation rule requiring main, clean worktree, `0 0`, and matching published EOD SHA. +- PASS: Did not modify `start_of_day` folders. +- PASS: Did not modify product/runtime files. +- PASS: Did not remove, move, or overwrite legacy SQLite files. +- PASS: Did not start feature work. diff --git a/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_validation-lane.md b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_validation-lane.md new file mode 100644 index 000000000..8a1b82360 --- /dev/null +++ b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_validation-lane.md @@ -0,0 +1,17 @@ +# PR_26177_OWNER_007-project-instructions-single-source-eod-lock Validation Lane + +- PASS: duplicate-source grep returned no matches for old active source claims. +- PASS: EOD/Next Day governance grep returned active governance matches. +- PASS: product/runtime/start_of_day changed-file check returned no files. +- PASS: git diff --check. + +Commands used: + +~~~text +rg -n 'project-instructions/addendums|docs_build/dev/PROJECT_INSTRUCTIONS.md.*source of truth|Codex must always read `docs_build/dev/PROJECT_INSTRUCTIONS.md`|Read `docs_build/dev/PROJECT_INSTRUCTIONS.md`' docs_build/dev/ProjectInstructions docs_build/dev/PROJECT_INSTRUCTIONS.md project-instructions +rg -n "End of Day:|Next Day Start:|HEAD.*published EOD SHA|only active Project Instructions source" docs_build/dev/ProjectInstructions +git diff --name-only -- src assets toolbox games api serverside package.json package-lock.json docs_build/dev/start_of_day +git diff --check +~~~ + +Full product/runtime tests were not run because this PR changes governance documentation only. diff --git a/docs_build/dev/reports/codex_changed_files.txt b/docs_build/dev/reports/codex_changed_files.txt index 8e34972a1..85beb7824 100644 --- a/docs_build/dev/reports/codex_changed_files.txt +++ b/docs_build/dev/reports/codex_changed_files.txt @@ -1,14 +1,30 @@ -docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_branch-validation.md -docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_manual-validation-notes.md -docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_report.md -docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_requirement-checklist.md -docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_validation-lane.md +docs_build/dev/BUILD_PR.md +docs_build/dev/PLAN_PR.md +docs_build/dev/PROJECT_INSTRUCTIONS.md +docs_build/dev/ProjectInstructions/PROJECT_INSTRUCTIONS.md +docs_build/dev/ProjectInstructions/README.txt +docs_build/dev/ProjectInstructions/TEAM_START_COMMANDS.md +docs_build/dev/ProjectInstructions/addendums/assistant_execution_modes.md +docs_build/dev/ProjectInstructions/addendums/branch_lock_governance.md +docs_build/dev/ProjectInstructions/addendums/canonical_repository_structure.md +docs_build/dev/ProjectInstructions/addendums/codex_artifact_and_reporting_standard.md +docs_build/dev/ProjectInstructions/addendums/codex_project_instructions_startup.md +docs_build/dev/ProjectInstructions/addendums/legacy_migration_policy.md +docs_build/dev/ProjectInstructions/addendums/pr_workflow.md +docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md +docs_build/dev/ProjectInstructions/addendums/test_structure_standardization.md +docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md +docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock.md +docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_branch-validation.md +docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_manual-validation-notes.md +docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_requirement-checklist.md +docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_validation-lane.md docs_build/dev/reports/codex_changed_files.txt docs_build/dev/reports/codex_review.diff -src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs -src/dev-runtime/persistence/tool-repositories/game-journey-mock-repository.js -src/dev-runtime/server/local-api-router.mjs -tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs -tests/helpers/playwrightRepoServer.mjs -tests/playwright/tools/GameJourneyTool.spec.mjs -tests/playwright/tools/IdeaBoardTableNotes.spec.mjs +project-instructions/README.md +project-instructions/addendums/assistant-execution-modes.md +project-instructions/addendums/canonical-repository-structure.md +project-instructions/addendums/codex-artifact-and-reporting-standard.md +project-instructions/addendums/codex-project-instructions-startup.md +project-instructions/addendums/legacy-migration-policy.md +project-instructions/addendums/test-structure-standardization.md diff --git a/docs_build/dev/reports/codex_review.diff b/docs_build/dev/reports/codex_review.diff index f88731273..53132b823 100644 --- a/docs_build/dev/reports/codex_review.diff +++ b/docs_build/dev/reports/codex_review.diff @@ -1,465 +1,1168 @@ -diff --git a/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_branch-validation.md b/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_branch-validation.md -index c5ced6d1b..53bc243c2 100644 ---- a/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_branch-validation.md -+++ b/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_branch-validation.md -@@ -17,3 +17,4 @@ Status: PASS - - PASS: Tests are limited to targeted Game Journey completion metrics regression coverage. - - PASS: Did not delete, move, overwrite, export, or migrate `tmp/local-api/game-journey-completion-metrics.sqlite`. - - PASS: Did not start Alfa Tags PRs. -+- PASS: Final audit removed active runtime JS/MJS SQLite and `tmp/local-api` references outside the migration-only utility. -diff --git a/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_manual-validation-notes.md b/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_manual-validation-notes.md -index 9a952fb7b..6dad6bb08 100644 ---- a/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_manual-validation-notes.md -+++ b/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_manual-validation-notes.md -@@ -5,9 +5,10 @@ Status: PASS - ## Notes - - - Confirmed the repo-local `tmp/local-api/game-journey-completion-metrics.sqlite` file exists before validation. --- Confirmed active `createGameJourneyCompletionMetricsStore({ postgresClient })` no longer resolves that retired path by default. --- Confirmed active metrics load 14 Postgres-backed completion buckets while the retired file remains untouched. --- Confirmed explicit `legacyDbPath` protection remains covered by the existing migration/regression test file. -+- Confirmed active `createGameJourneyCompletionMetricsStore({ postgresClient })` exposes no `legacyDbPath`. -+- Confirmed active metrics snapshots expose no `legacySqlitePath`. -+- Confirmed active metrics load 14 DB-backed completion buckets while the retired file remains untouched. -+- Confirmed active runtime JS/MJS has no SQLite or `tmp/local-api` metrics references outside the migration-only utility. - - Confirmed the toolbox page renders neutral Creator-facing outage wording when active metrics are unavailable. - - Confirmed the toolbox page does not render the forbidden warning string, SQLite wording, `tmp/local-api`, or Postgres internals in the simulated outage lane. - - Confirmed no Alfa Tags PR work was started. -diff --git a/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_report.md b/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_report.md -index 1940890cf..777642b00 100644 ---- a/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_report.md -+++ b/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_report.md -@@ -11,9 +11,10 @@ Recover the Game Journey completion metrics path so active Alfa and Owner work n - ## Implementation Summary - - - Removed active runtime defaulting to `tmp/local-api/game-journey-completion-metrics.sqlite` in `createGameJourneyCompletionMetricsStore`. --- Kept the explicit `legacyDbPath` guard intact for recovery/migration callers so legacy data is still protected from silent overwrite or deletion. -+- Removed active runtime `legacyDbPath` guard plumbing from the Game Journey metrics store, repository, Local API router, and Playwright test server helper. - - Updated `toolbox/tools-page-accordions.js` to render neutral Creator-safe progress outage wording instead of backend diagnostics. --- Added a store-level regression test proving a retired default SQLite-shaped file does not block active Postgres-backed metrics. -+- Added a store-level regression test proving a retired default SQLite-shaped file does not block or get touched by active DB-backed metrics. -+- Added a targeted guardrail test proving active runtime JS/MJS under `src`, `assets`, and `toolbox` has no SQLite or `tmp/local-api` metrics references, excluding the migration-only utility. - - Added a focused Playwright test proving the toolbox page does not render the forbidden warning, SQLite wording, local filesystem path, or Postgres internals when metrics are unavailable. - - ## Reference Comparison -@@ -28,16 +29,20 @@ Recover the Game Journey completion metrics path so active Alfa and Owner work n - - PASS: `node --check` on modified source and test files. - - PASS: `node ./scripts/run-node-test-files.mjs tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs tests/dev-runtime/GameJourneyCompletionMetricsMigration.test.mjs`. - - PASS: `npx playwright test tests/playwright/tools/GameJourneyTool.spec.mjs --project=playwright --workers=1 --reporter=line -g "Game Journey Local API persists completion metrics to Postgres|Toolbox renders Creator-safe Game Journey progress outage copy"`. --- PASS: Direct proof against the actual existing `tmp/local-api/game-journey-completion-metrics.sqlite` file confirmed active Postgres metrics load 14 buckets and do not resolve a legacy path. --- PASS: Runtime source search found no `Game Journey completion metrics unavailable` string. --- PASS: Runtime source search found no active metrics-store default reference to `game-journey-completion-metrics.sqlite`, `GAMEFOUNDRY_GAME_JOURNEY_METRICS_DB_PATH`, or `defaultLegacySqlitePath`. -+- PASS: Direct proof against the actual existing `tmp/local-api/game-journey-completion-metrics.sqlite` file confirmed active DB metrics load 14 buckets, expose no legacy path fields, and do not touch the retired file. -+- PASS: Active runtime JS/MJS search found no SQLite, `.sqlite`, `better-sqlite`, `game-journey-completion-metrics.sqlite`, or `tmp/local-api` references outside the migration-only utility. -+- PASS: Runtime source search found no `Game Journey completion metrics unavailable` Creator-facing string. - - PASS: `git diff --check` reported no whitespace errors. Git emitted line-ending warnings only. - - ## Files - - - `src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs` -+- `src/dev-runtime/persistence/tool-repositories/game-journey-mock-repository.js` -+- `src/dev-runtime/server/local-api-router.mjs` - - `tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs` -+- `tests/helpers/playwrightRepoServer.mjs` - - `tests/playwright/tools/GameJourneyTool.spec.mjs` -+- `tests/playwright/tools/IdeaBoardTableNotes.spec.mjs` - - `toolbox/tools-page-accordions.js` - - ## Artifact -diff --git a/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_requirement-checklist.md b/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_requirement-checklist.md -index 544b7057f..65a654b6d 100644 ---- a/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_requirement-checklist.md -+++ b/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_requirement-checklist.md -@@ -11,12 +11,14 @@ Status: PASS - - PASS: Fixed only the Game Journey completion metrics regression. - - PASS: Did not delete, move, overwrite, export, or migrate `tmp/local-api/game-journey-completion-metrics.sqlite`. - - PASS: Stopped active runtime from defaulting to `tmp/local-api/game-journey-completion-metrics.sqlite`. -+- PASS: Removed active runtime `legacyDbPath` SQLite guard plumbing. - - PASS: Preserved Postgres-backed Game Journey completion metrics as the active path. - - PASS: Ensured `toolbox/tools-page-accordions.js` cannot render `Game Journey completion metrics unavailable:`. - - PASS: Creator-facing UI does not expose SQLite, local filesystem paths, migration/export language, or Postgres internals. - - PASS: Did not introduce silent fallback behavior; metrics outage remains visible with neutral wording. - - PASS: Added targeted regression tests. - - PASS: Proved the existing legacy SQLite file does not block active metrics. -+- PASS: Proved active runtime JS/MJS has no SQLite or `tmp/local-api` metrics references outside the migration-only utility. - - PASS: Proved the forbidden warning string is not rendered. - - PASS: Proved Game Journey metrics still load through the active DB/API path. - - PASS: Used targeted validation only. -diff --git a/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_validation-lane.md b/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_validation-lane.md -index fe5ba4768..47530c453 100644 ---- a/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_validation-lane.md -+++ b/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_validation-lane.md -@@ -6,9 +6,13 @@ Status: PASS +diff --git a/docs_build/dev/BUILD_PR.md b/docs_build/dev/BUILD_PR.md +index 30700e9cd..50b1b27fa 100644 +--- a/docs_build/dev/BUILD_PR.md ++++ b/docs_build/dev/BUILD_PR.md +@@ -1,66 +1,52 @@ +-# PR_26177_006-shared-time-foundation ++# PR_26177_OWNER_007-project-instructions-single-source-eod-lock - ```powershell - node --check src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs -+node --check src/dev-runtime/persistence/tool-repositories/game-journey-mock-repository.js -+node --check src/dev-runtime/server/local-api-router.mjs - node --check toolbox/tools-page-accordions.js - node --check tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs -+node --check tests/helpers/playwrightRepoServer.mjs - node --check tests/playwright/tools/GameJourneyTool.spec.mjs -+node --check tests/playwright/tools/IdeaBoardTableNotes.spec.mjs - ``` + ## Purpose - Result: PASS -@@ -17,7 +21,7 @@ Result: PASS - node ./scripts/run-node-test-files.mjs tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs tests/dev-runtime/GameJourneyCompletionMetricsMigration.test.mjs - ``` +-Add a small shared time foundation. ++Make `docs_build/dev/ProjectInstructions/` the only active Project Instructions source and add EOD main lock plus next-day reset governance. --Result: PASS, 2 targeted node test files passed -+Result: PASS, 2 targeted node test files passed. Includes active runtime JS/MJS SQLite reference guardrail. + ## Source Of Truth - ```powershell - npx playwright test tests/playwright/tools/GameJourneyTool.spec.mjs --project=playwright --workers=1 --reporter=line -g "Game Journey Local API persists completion metrics to Postgres|Toolbox renders Creator-safe Game Journey progress outage copy" -@@ -26,14 +30,14 @@ npx playwright test tests/playwright/tools/GameJourneyTool.spec.mjs --project=pl - Result: PASS, 2 passed +-This `BUILD_PR.md`, `PLAN_PR.md`, and the user request are the source of truth for `PR_26177_006-shared-time-foundation`. +- +-## Stack +- +-- Base branch: `PR_26177_005-shared-text-foundation` ++This `BUILD_PR.md`, `PLAN_PR.md`, and the user request are the source of truth for `PR_26177_OWNER_007-project-instructions-single-source-eod-lock`. + + ## Exact Scope + +-- Add `src/shared/time/` foundation. +-- Include duration formatting, timestamp helpers, debounce/throttle/sleep helpers where safe for shared runtime. +-- Add targeted tests for the shared time area. +-- No scheduler/runtime behavior changes. +-- Create required Codex reports under `docs_build/dev/reports/`. +-- Create repo-structured delta ZIP under `tmp/`. ++- Audit repo for ProjectInstructions / project instructions duplicates. ++- Establish `docs_build/dev/ProjectInstructions/` as the only active source. ++- Mark all other ProjectInstructions-style sources changed by this PR as deprecated references. ++- Update active team start/governance docs to reference only `docs_build/dev/ProjectInstructions/`. ++- Add EOD main lock and next-day reset governance. ++- Add required reports under `docs_build/dev/reports/`. + + ## Exact Targets + + - `docs_build/dev/PLAN_PR.md` + - `docs_build/dev/BUILD_PR.md` +-- `src/shared/time/time.js` +-- `tests/shared/TimeFoundation.test.mjs` +-- `docs_build/dev/reports/PR_26177_006-shared-time-foundation.md` +-- `docs_build/dev/reports/PR_26177_006-shared-time-foundation_branch-validation.md` +-- `docs_build/dev/reports/PR_26177_006-shared-time-foundation_requirement-checklist.md` +-- `docs_build/dev/reports/PR_26177_006-shared-time-foundation_validation-lane.md` +-- `docs_build/dev/reports/PR_26177_006-shared-time-foundation_manual-validation-notes.md` ++- `docs_build/dev/PROJECT_INSTRUCTIONS.md` ++- `docs_build/dev/ProjectInstructions/README.txt` ++- `docs_build/dev/ProjectInstructions/PROJECT_INSTRUCTIONS.md` ++- `docs_build/dev/ProjectInstructions/TEAM_START_COMMANDS.md` ++- `docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md` ++- `docs_build/dev/ProjectInstructions/addendums/*.md` ++- `project-instructions/README.md` ++- `project-instructions/addendums/*.md` ++- `docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock*.md` + - `docs_build/dev/reports/codex_review.diff` + - `docs_build/dev/reports/codex_changed_files.txt` + + ## Out Of Scope + +-- No scheduler/runtime behavior changes. +-- No browser-owned product data. +-- No runtime UI changes. +-- No browser storage changes. +-- No API/database changes. +-- No `start_of_day` folder changes. +-- No unrelated cleanup. +-- No full samples smoke by default. ++- No product/runtime changes. ++- No feature work. ++- No `start_of_day` changes. ++- No legacy SQLite file changes. + + ## Validation + +-Run exactly: ++Run: ```powershell --node -e "import('node:fs').then(async fs=>{const [{createGameJourneyCompletionMetricsStore}, {createGameJourneyCompletionMetricsPostgresClientStub}] = await Promise.all([import('./src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs'), import('./tests/helpers/gameJourneyCompletionMetricsPostgresClientStub.mjs')]); const legacy='tmp/local-api/game-journey-completion-metrics.sqlite'; if(!fs.existsSync(legacy)) throw new Error('Expected existing legacy SQLite file for regression proof'); const store=createGameJourneyCompletionMetricsStore({postgresClient:createGameJourneyCompletionMetricsPostgresClientStub()}); const metrics=await store.listMetrics(); if(store.legacyDbPath) throw new Error('Active store resolved a legacy path'); if(metrics.length!==14) throw new Error('Expected 14 active metrics'); console.log('PASS active Postgres metrics ignore existing retired legacy SQLite file');})" -+node -e "import('node:fs').then(async fs=>{const [{createGameJourneyCompletionMetricsStore}, {createGameJourneyCompletionMetricsPostgresClientStub}] = await Promise.all([import('./src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs'), import('./tests/helpers/gameJourneyCompletionMetricsPostgresClientStub.mjs')]); const legacy='tmp/local-api/game-journey-completion-metrics.sqlite'; if(!fs.existsSync(legacy)) throw new Error('Expected existing retired local file for regression proof'); const before=fs.statSync(legacy).mtimeMs; const store=createGameJourneyCompletionMetricsStore({postgresClient:createGameJourneyCompletionMetricsPostgresClientStub()}); const metrics=await store.listMetrics(); const snapshot=await store.snapshot(); const after=fs.statSync(legacy).mtimeMs; if(Object.hasOwn(store, 'legacyDbPath')) throw new Error('Store exposes legacyDbPath'); if(Object.hasOwn(snapshot, 'legacySqlitePath')) throw new Error('Snapshot exposes legacySqlitePath'); if(metrics.length!==14) throw new Error('Expected 14 active metrics'); if(before!==after) throw new Error('Retired local file was touched'); console.log('PASS active DB metrics ignore and do not inspect retired local file');})" +-node ./scripts/run-node-test-files.mjs tests/shared/TimeFoundation.test.mjs +-node --check src/shared/time/time.js +-node --check tests/shared/TimeFoundation.test.mjs ++rg -n 'project-instructions/addendums|docs_build/dev/PROJECT_INSTRUCTIONS.md.*source of truth|Codex must always read `docs_build/dev/PROJECT_INSTRUCTIONS.md`|Read `docs_build/dev/PROJECT_INSTRUCTIONS.md`' docs_build/dev/ProjectInstructions docs_build/dev/PROJECT_INSTRUCTIONS.md project-instructions ++rg -n "End of Day:|Next Day Start:|HEAD.*published EOD SHA|only active Project Instructions source" docs_build/dev/ProjectInstructions ++git diff --name-only -- src assets toolbox games api serverside package.json package-lock.json docs_build/dev/start_of_day + git diff --check ``` +- +-## Artifact +- +-Create repo-structured delta ZIP: +- +-```text +-tmp/PR_26177_006-shared-time-foundation_delta.zip +-``` +diff --git a/docs_build/dev/PLAN_PR.md b/docs_build/dev/PLAN_PR.md +index 907936aee..39fa03385 100644 +--- a/docs_build/dev/PLAN_PR.md ++++ b/docs_build/dev/PLAN_PR.md +@@ -1,22 +1,28 @@ +-# PLAN_PR: PR_26177_006-shared-time-foundation ++# PLAN_PR: PR_26177_OWNER_007-project-instructions-single-source-eod-lock - Result: PASS + ## Purpose - ```powershell -+rg -n -i "sqlite|better-sqlite|game-journey-completion-metrics\.sqlite|tmp/local-api" src assets toolbox -g "*.js" -g "*.mjs" --glob "!src/dev-runtime/persistence/game-journey-completion-metrics-migration.mjs" - rg -n "Game Journey completion metrics unavailable" src assets toolbox --glob "!**/*.map" --rg -n "game-journey-completion-metrics\.sqlite|GAMEFOUNDRY_GAME_JOURNEY_METRICS_DB_PATH|defaultLegacySqlitePath" src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs toolbox/tools-page-accordions.js assets/toolbox/game-journey/js/index.js +-Add a small shared time foundation. ++Make `docs_build/dev/ProjectInstructions/` the only active Project Instructions source and add EOD main lock plus next-day reset governance. + + ## Scope + +-- Add `src/shared/time/` foundation. +-- Include duration formatting, timestamp helpers, sleep, debounce, and throttle helpers. +-- Add targeted tests. +-- No scheduler/runtime behavior changes. +-- No browser-owned product data. +-- No runtime UI changes. +-- No unrelated cleanup. ++- Audit ProjectInstructions and project instructions duplicates. ++- Mark legacy ProjectInstructions-style sources as deprecated reference material. ++- Move active legacy addendums into `docs_build/dev/ProjectInstructions/addendums/`. ++- Update active team start and governance docs to reference only `docs_build/dev/ProjectInstructions/`. ++- Add EOD main lock, next-day reset, and team PR branch creation gate. ++- Add required Codex reports under `docs_build/dev/reports/`. + +-## Implementation Plan ++## Out Of Scope + +-1. Add `src/shared/time/time.js`. +-2. Add `tests/shared/TimeFoundation.test.mjs`. +-3. Validate duration, timestamp, sleep, debounce, and throttle helpers. +-4. Produce required Codex reports and repo-structured ZIP. ++- No product/runtime changes. ++- No feature work. ++- No `start_of_day` changes. ++- No legacy SQLite file changes. ++ ++## Validation Plan ++ ++1. Run targeted grep/search proving no active duplicate ProjectInstructions source remains. ++2. Confirm EOD/Next Day rule appears in active governance docs. ++3. Confirm no product/runtime files changed. ++4. Run `git diff --check`. +diff --git a/docs_build/dev/PROJECT_INSTRUCTIONS.md b/docs_build/dev/PROJECT_INSTRUCTIONS.md +index af9e9e2db..c1136fdbe 100644 +--- a/docs_build/dev/PROJECT_INSTRUCTIONS.md ++++ b/docs_build/dev/PROJECT_INSTRUCTIONS.md +@@ -1,5 +1,7 @@ + # PROJECT INSTRUCTIONS + ++> Deprecated active-source notice: this file is preserved as historical reference only. The only active Project Instructions source is `docs_build/dev/ProjectInstructions/`. If this file conflicts with `docs_build/dev/ProjectInstructions/`, the active folder wins unless OWNER explicitly approves a newer governance change. ++ + You are working in a docs-first repo workflow. + + Workflow: +@@ -864,7 +866,7 @@ Controls must remain copy-friendly and human-readable. + + ### ChatGPT Workflow Governance Consistency + +-ChatGPT repo workflow responses are governed by `docs_build/dev/PROJECT_INSTRUCTIONS.md` as the source of truth. ++Deprecated note: this historical section no longer defines the active source of truth. ChatGPT repo workflow responses are governed by `docs_build/dev/ProjectInstructions/`. + + ChatGPT must not drift from the required response ordering. + +@@ -1716,13 +1718,13 @@ Do not compact: + + Do not change JSON contracts or semantics while applying array formatting. + +-## PROJECT INSTRUCTIONS LOCATION ++## DEPRECATED PROJECT INSTRUCTIONS LOCATION + +-PROJECT_INSTRUCTIONS.md lives at: ++Historical PROJECT_INSTRUCTIONS.md is preserved at: + + `docs_build/dev/PROJECT_INSTRUCTIONS.md` + +-Codex must always read `docs_build/dev/PROJECT_INSTRUCTIONS.md` from this path as the source of truth before executing repository workflow instructions. ++This file is not the active source of truth. Codex must read `docs_build/dev/ProjectInstructions/README.txt` first and use `docs_build/dev/ProjectInstructions/` as the active Project Instructions source before executing repository workflow instructions. + + ## CODEX COMMAND FORMATTING RULE + +@@ -2384,9 +2386,9 @@ Treat these files the same as existing instruction documents for read-set, revie + Codex must run this gate before every PR execution and before any file changes. + + Required instruction reads: +-- Read `docs_build/dev/PROJECT_INSTRUCTIONS.md`. ++- Read `docs_build/dev/ProjectInstructions/README.txt`. + - Read `docs_build/dev/PROJECT_MULTI_PC.txt`. +-- Treat the newest applicable section in `PROJECT_INSTRUCTIONS.md` as authoritative when rules overlap. ++- Treat the newest applicable section in `docs_build/dev/ProjectInstructions/` as authoritative when rules overlap. + - Treat the current team ownership section in `PROJECT_MULTI_PC.txt` as authoritative for TEAM routing. + + Required pre-change report: +diff --git a/docs_build/dev/ProjectInstructions/PROJECT_INSTRUCTIONS.md b/docs_build/dev/ProjectInstructions/PROJECT_INSTRUCTIONS.md +index d2a84ecbe..99ddd0f42 100644 +--- a/docs_build/dev/ProjectInstructions/PROJECT_INSTRUCTIONS.md ++++ b/docs_build/dev/ProjectInstructions/PROJECT_INSTRUCTIONS.md +@@ -4,6 +4,12 @@ Read `README.txt` first. + + This file is the root index for the append-first Project Instructions operating system under `docs_build/dev/ProjectInstructions/`. + ++## Active Source ++ ++`docs_build/dev/ProjectInstructions/` is the only active Project Instructions source. ++ ++Historical Project Instructions material outside this folder is deprecated reference material only and must not be used as an active source of governance. ++ + ## Purpose + + The Project Instructions operating system provides additive governance for: +@@ -20,7 +26,7 @@ The Project Instructions operating system provides additive governance for: + + ## Preservation + +-Existing Project Instructions remain preserved in their current locations. This operating system adds structure without deleting or rewriting existing documentation. ++Existing Project Instructions outside `docs_build/dev/ProjectInstructions/` remain preserved only as deprecated reference material. When guidance conflicts, active files under `docs_build/dev/ProjectInstructions/` win unless OWNER explicitly approves a newer governance change. + + ## Folders + +@@ -41,6 +47,10 @@ Existing Project Instructions remain preserved in their current locations. This + + `docs_build/dev/ProjectInstructions/addendums/environment_configuration_standards.md` defines official `.env` file names, environment variable values, host/domain configuration, API URL configuration, R2 prefix configuration, and feature flag governance. + ++## Single Source and Main Lock Governance ++ ++`docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md` defines the single active Project Instructions source, EOD main lock, next-day reset, and team branch creation gate. ++ + ## Merge Control + + No PR in this operating system is merged without explicit owner approval. +diff --git a/docs_build/dev/ProjectInstructions/README.txt b/docs_build/dev/ProjectInstructions/README.txt +index a48becf05..631fd3918 100644 +--- a/docs_build/dev/ProjectInstructions/README.txt ++++ b/docs_build/dev/ProjectInstructions/README.txt +@@ -1,10 +1,10 @@ + Read this file first. + + Folder purpose: +-This folder is the append-first Project Instructions operating system for Game Foundry Studio. It organizes active governance, backlog, team assignment, deprecation, and history material without deleting or rewriting the existing Project Instructions files elsewhere in the repository. ++This folder is the only active Project Instructions source for Game Foundry Studio. It organizes active governance, backlog, team assignment, deprecation, and history material under `docs_build/dev/ProjectInstructions/`. + + Preservation rules: +-Preserve all existing documentation. Add new files or append explicit references unless the owner explicitly approves deletion or rewrite. When a conflict appears, stop, explain the conflict, and request owner approval before changing existing instruction text. ++Preserve historical Project Instructions material as deprecated reference only. Do not treat `docs_build/dev/PROJECT_INSTRUCTIONS.md`, `project-instructions/`, or archived snapshots as active instruction sources. When a conflict appears, `docs_build/dev/ProjectInstructions/` wins unless OWNER explicitly approves a newer governance change. + + Backlog workflow: + Backlog work is tracked under backlog/. BACKLOG_MASTER.md is the planned source for backlog item status, notes, and references. Backlog item text is treated as immutable once created; status and notes may change under the governance addendums. +@@ -29,9 +29,9 @@ Do not rewrite history snapshots after creation unless the owner explicitly appr + + READ THIS FIRST + +-1. Read Project Instructions before making changes. +-2. Project Instructions are append-only. +-3. Existing approved guidance may not be removed. ++1. Read `docs_build/dev/ProjectInstructions/README.txt` before making changes. ++2. Treat `docs_build/dev/ProjectInstructions/` as the only active Project Instructions source. ++3. Historical Project Instructions files outside this folder are deprecated references only. + 4. Team ownership must be respected. + 5. BACKLOG_MASTER.md is the authoritative backlog. + 6. Build Path status derives from backlog status. +@@ -42,12 +42,13 @@ READ THIS FIRST + 11. Batch Governance Mode is the default for governance, documentation, and administrative work. + + Addendum index: +-- Canonical Repository Structure: project-instructions/addendums/canonical-repository-structure.md +-- Test Structure Standardization: project-instructions/addendums/test-structure-standardization.md +-- Legacy Migration Policy: project-instructions/addendums/legacy-migration-policy.md +-- Assistant Execution Modes: project-instructions/addendums/assistant-execution-modes.md +-- Codex Artifact and Reporting Standard: project-instructions/addendums/codex-artifact-and-reporting-standard.md +-- Codex Project Instructions Startup: project-instructions/addendums/codex-project-instructions-startup.md ++- Single Source and EOD Main Lock: docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md ++- Canonical Repository Structure: docs_build/dev/ProjectInstructions/addendums/canonical_repository_structure.md ++- Test Structure Standardization: docs_build/dev/ProjectInstructions/addendums/test_structure_standardization.md ++- Legacy Migration Policy: docs_build/dev/ProjectInstructions/addendums/legacy_migration_policy.md ++- Assistant Execution Modes: docs_build/dev/ProjectInstructions/addendums/assistant_execution_modes.md ++- Codex Artifact and Reporting Standard: docs_build/dev/ProjectInstructions/addendums/codex_artifact_and_reporting_standard.md ++- Codex Project Instructions Startup: docs_build/dev/ProjectInstructions/addendums/codex_project_instructions_startup.md + - Project Reference Files Governance: docs_build/dev/ProjectInstructions/addendums/project_reference_files.md + - Environment Governance Model: docs_build/dev/ProjectInstructions/addendums/environment_governance_model.md + - Environment Configuration Standards: docs_build/dev/ProjectInstructions/addendums/environment_configuration_standards.md +diff --git a/docs_build/dev/ProjectInstructions/TEAM_START_COMMANDS.md b/docs_build/dev/ProjectInstructions/TEAM_START_COMMANDS.md +index d0118f63a..c446a4b33 100644 +--- a/docs_build/dev/ProjectInstructions/TEAM_START_COMMANDS.md ++++ b/docs_build/dev/ProjectInstructions/TEAM_START_COMMANDS.md +@@ -1,5 +1,16 @@ + # TEAM_START_COMMANDS + ++## Required Main Reset Gate For Every Team ++ ++No team creates a PR branch until all checks pass: ++ ++- Current branch: `main` ++- Worktree: clean ++- `main...origin/main`: `0 0` ++- `HEAD` SHA matches the published EOD SHA ++ ++Use `docs_build/dev/ProjectInstructions/` as the only active Project Instructions source. ++ + ## Start Team Alfa + + Ready-to-copy command: +@@ -123,4 +134,24 @@ Merge to main is EOD-only and owner-approved, unless the owner explicitly says: + "Merge this PR now." + + Do not treat sequential PR completion as merge approval. ++ ++End of Day: ++git checkout main ++git fetch origin ++git pull --ff-only origin main ++git status ++git rev-list --left-right --count main...origin/main ++ ++Required: ++On branch main ++nothing to commit, working tree clean ++0 0 ++ ++Next Day Start: ++git checkout main ++git fetch origin ++git pull --ff-only origin main ++git status ++git rev-list --left-right --count main...origin/main ++git rev-parse HEAD ``` +diff --git a/docs_build/dev/ProjectInstructions/addendums/branch_lock_governance.md b/docs_build/dev/ProjectInstructions/addendums/branch_lock_governance.md +index 518f8c943..d6c8e4cf7 100644 +--- a/docs_build/dev/ProjectInstructions/addendums/branch_lock_governance.md ++++ b/docs_build/dev/ProjectInstructions/addendums/branch_lock_governance.md +@@ -23,6 +23,7 @@ Keep active work attached to the correct assigned team, branch, and OWNER decisi - Result: PASS, no matches + - Start from current `main`. + - Pull latest `origin/main` before creating a work branch. ++- Do not create a PR branch unless current branch is `main`, worktree is clean, `main...origin/main` is `0 0`, and `HEAD` SHA matches the published EOD SHA. + - Keep work on the active branch until the PR is merged, the branch is retired, or OWNER says to return to `main`. + - Do not commit directly to `main` unless OWNER explicitly approves. + - Do not merge stale historical branches directly unless they are current, clean, still needed, and OWNER-approved. +@@ -54,3 +55,36 @@ Protected guidance includes: + - Governance Phase 1 completion guidance + + If protected guidance must change, OWNER approval is required. ++ ++## End Of Day Main Lock ++ ++End of Day: ++ ++```text ++git checkout main ++git fetch origin ++git pull --ff-only origin main ++git status ++git rev-list --left-right --count main...origin/main ++``` ++ ++Required: ++ ++```text ++On branch main ++nothing to commit, working tree clean ++0 0 ++``` ++ ++Next Day Start: ++ ++```text ++git checkout main ++git fetch origin ++git pull --ff-only origin main ++git status ++git rev-list --left-right --count main...origin/main ++git rev-parse HEAD ++``` ++ ++The next-day `HEAD` SHA must match the published EOD SHA before any team creates a PR branch. +diff --git a/docs_build/dev/ProjectInstructions/addendums/pr_workflow.md b/docs_build/dev/ProjectInstructions/addendums/pr_workflow.md +index f8a4acb6e..7c1cd8275 100644 +--- a/docs_build/dev/ProjectInstructions/addendums/pr_workflow.md ++++ b/docs_build/dev/ProjectInstructions/addendums/pr_workflow.md +@@ -129,3 +129,40 @@ Stop only for: + - Merge conflict + - Validation failure + - OWNER decision ++ ++## EOD Main Lock ++ ++End of Day: ++ ++```text ++git checkout main ++git fetch origin ++git pull --ff-only origin main ++git status ++git rev-list --left-right --count main...origin/main ++``` ++ ++Required: ++ ++```text ++On branch main ++nothing to commit, working tree clean ++0 0 ++``` ++ ++## Next Day Start ++ ++```text ++git checkout main ++git fetch origin ++git pull --ff-only origin main ++git status ++git rev-list --left-right --count main...origin/main ++git rev-parse HEAD ++``` ++ ++No team creates a PR branch until: ++- Current branch: `main` ++- Worktree: clean ++- `main...origin/main`: `0 0` ++- `HEAD` SHA matches published EOD SHA +diff --git a/docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md b/docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md +index 9735b4bd4..9a104b4f9 100644 +--- a/docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md ++++ b/docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md +@@ -211,3 +211,44 @@ Commit/push during the day is allowed only on assigned team/OWNER/PR branches. + + Merge to main is EOD-only and owner-approved, unless the owner explicitly says: + "Merge this PR now." ++ ++## EOD Main Lock And Next Day Reset ++ ++End of Day: ++ ++```text ++git checkout main ++git fetch origin ++git pull --ff-only origin main ++git status ++git rev-list --left-right --count main...origin/main ++``` ++ ++Required: ++ ++```text ++On branch main ++nothing to commit, working tree clean ++0 0 ++``` ++ ++Next Day Start: ++ ++```text ++git checkout main ++git fetch origin ++git pull --ff-only origin main ++git status ++git rev-list --left-right --count main...origin/main ++git rev-parse HEAD ++``` ++ ++Team rule: ++No team creates a PR branch until: ++- Current branch: `main` ++- Worktree: clean ++- `main...origin/main`: `0 0` ++- `HEAD` SHA matches published EOD SHA ++ ++Active source rule: ++Teams must use only `docs_build/dev/ProjectInstructions/` as the active Project Instructions source. diff --git a/docs_build/dev/reports/codex_changed_files.txt b/docs_build/dev/reports/codex_changed_files.txt -index 585a10850..8e34972a1 100644 +index 8e34972a1..85beb7824 100644 --- a/docs_build/dev/reports/codex_changed_files.txt +++ b/docs_build/dev/reports/codex_changed_files.txt -@@ -6,6 +6,9 @@ docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recove +@@ -1,14 +1,30 @@ +-docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_branch-validation.md +-docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_manual-validation-notes.md +-docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_report.md +-docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_requirement-checklist.md +-docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_validation-lane.md ++docs_build/dev/BUILD_PR.md ++docs_build/dev/PLAN_PR.md ++docs_build/dev/PROJECT_INSTRUCTIONS.md ++docs_build/dev/ProjectInstructions/PROJECT_INSTRUCTIONS.md ++docs_build/dev/ProjectInstructions/README.txt ++docs_build/dev/ProjectInstructions/TEAM_START_COMMANDS.md ++docs_build/dev/ProjectInstructions/addendums/assistant_execution_modes.md ++docs_build/dev/ProjectInstructions/addendums/branch_lock_governance.md ++docs_build/dev/ProjectInstructions/addendums/canonical_repository_structure.md ++docs_build/dev/ProjectInstructions/addendums/codex_artifact_and_reporting_standard.md ++docs_build/dev/ProjectInstructions/addendums/codex_project_instructions_startup.md ++docs_build/dev/ProjectInstructions/addendums/legacy_migration_policy.md ++docs_build/dev/ProjectInstructions/addendums/pr_workflow.md ++docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md ++docs_build/dev/ProjectInstructions/addendums/test_structure_standardization.md ++docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md ++docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock.md ++docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_branch-validation.md ++docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_manual-validation-notes.md ++docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_requirement-checklist.md ++docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_validation-lane.md docs_build/dev/reports/codex_changed_files.txt docs_build/dev/reports/codex_review.diff - src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs -+src/dev-runtime/persistence/tool-repositories/game-journey-mock-repository.js -+src/dev-runtime/server/local-api-router.mjs - tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs -+tests/helpers/playwrightRepoServer.mjs - tests/playwright/tools/GameJourneyTool.spec.mjs --toolbox/tools-page-accordions.js -+tests/playwright/tools/IdeaBoardTableNotes.spec.mjs -diff --git a/src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs b/src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs -index 6c202c8a2..eea6294e7 100644 ---- a/src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs -+++ b/src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs -@@ -1,5 +1,3 @@ --import { existsSync } from "node:fs"; --import path from "node:path"; - import { createPostgresConnectionClient } from "./postgres-connection-client.mjs"; - import { SEED_DB_KEYS, makeSeedUlid } from "../seed/seed-db-keys.mjs"; - -@@ -59,24 +57,6 @@ function clone(value) { - return JSON.parse(JSON.stringify(value)); - } - --function resolveLegacySqlitePath(legacyDbPath) { -- if (legacyDbPath === null || legacyDbPath === undefined) { -- return ""; -- } -- const value = String(legacyDbPath || "").trim(); -- if (!value) { -- return ""; -- } -- return path.resolve(value); --} -- --function assertNoUnmigratedLegacySqlite(legacyDbPath) { -- if (!legacyDbPath || !existsSync(legacyDbPath)) { -- return; -- } -- throw new Error(`Legacy Game Journey completion metrics SQLite data exists at ${legacyDbPath}. No data was removed or overwritten. Export or migrate that data into Postgres, then move the legacy file before using the Postgres metrics store.`); --} -- - function normalizeCount(value, fallback = 0) { - const parsed = Number(value); - if (!Number.isFinite(parsed)) { -@@ -158,7 +138,6 @@ function bucketSeedRow(bucket, now) { - export function createGameJourneyCompletionMetricsStore(options = {}) { - const env = options.env || process.env; - const bucketSeeds = Object.freeze((options.buckets || GAME_JOURNEY_COMPLETION_BUCKETS).map(clone)); -- const legacyDbPath = resolveLegacySqlitePath(options.legacyDbPath); - let postgresClient = options.postgresClient || null; - let readyPromise = null; - -@@ -230,7 +209,6 @@ export function createGameJourneyCompletionMetricsStore(options = {}) { - async function ensureReady() { - if (!readyPromise) { - readyPromise = (async () => { -- assertNoUnmigratedLegacySqlite(legacyDbPath); - await client().query(GAME_JOURNEY_COMPLETION_METRICS_SCHEMA_SQL); - await seedDefaultBuckets(); - })(); -@@ -298,7 +276,6 @@ export function createGameJourneyCompletionMetricsStore(options = {}) { - databaseConfigKey: "GAMEFOUNDRY_DATABASE_URL", - databaseEngine: "Postgres", - databasePath: "GAMEFOUNDRY_DATABASE_URL", -- legacySqlitePath: legacyDbPath, - serviceContract: "Web UI -> Local API/Service Contract -> Postgres", - source: GAME_JOURNEY_COMPLETION_METRICS_TABLE, - tableName: GAME_JOURNEY_COMPLETION_METRICS_TABLE, -@@ -312,7 +289,6 @@ export function createGameJourneyCompletionMetricsStore(options = {}) { - } - - return { -- legacyDbPath, - listMetrics, - snapshot, - updateMetric, -diff --git a/src/dev-runtime/persistence/tool-repositories/game-journey-mock-repository.js b/src/dev-runtime/persistence/tool-repositories/game-journey-mock-repository.js -index 73b409c42..8e0ddc92b 100644 ---- a/src/dev-runtime/persistence/tool-repositories/game-journey-mock-repository.js -+++ b/src/dev-runtime/persistence/tool-repositories/game-journey-mock-repository.js -@@ -627,7 +627,6 @@ export function createGameJourneyMockRepository(options = {}) { - const completionMetricsStore = - options.completionMetricsStore || createGameJourneyCompletionMetricsStore({ - dbPath: options.completionMetricsDbPath, -- legacyDbPath: options.completionMetricsLegacyDbPath, - postgresClient: options.completionMetricsPostgresClient, - }); - const tables = loadMockDbTables(GAME_JOURNEY_DB_OWNER, getSeedTables(), options).tables; -diff --git a/src/dev-runtime/server/local-api-router.mjs b/src/dev-runtime/server/local-api-router.mjs -index f2f927aff..2cb9a66f1 100644 ---- a/src/dev-runtime/server/local-api-router.mjs -+++ b/src/dev-runtime/server/local-api-router.mjs -@@ -3304,14 +3304,12 @@ function productTablesFromSnapshot(snapshot) { - - class ApiRuntimeDataSource { - constructor({ -- gameJourneyCompletionMetricsLegacyDbPath = undefined, - gameJourneyCompletionMetricsPostgresClient = null, - messagesPostgresClient = null, - messagesService = null, - repoRoot = process.cwd(), - } = {}) { - this.messagesService = messagesService || createMessagesPostgresService({ postgresClient: messagesPostgresClient }); -- this.gameJourneyCompletionMetricsLegacyDbPath = gameJourneyCompletionMetricsLegacyDbPath; - this.gameJourneyCompletionMetricsPostgresClient = gameJourneyCompletionMetricsPostgresClient; - this.repositoryCounter = 1; - this.repositoryById = new Map(); -@@ -3556,7 +3554,6 @@ class ApiRuntimeDataSource { - this.standaloneTables.invitations = []; - } - this.sharedOptions = { -- completionMetricsLegacyDbPath: this.gameJourneyCompletionMetricsLegacyDbPath, - completionMetricsPostgresClient: this.gameJourneyCompletionMetricsPostgresClient, - memoryDbTables: this.standaloneTables, - sessionMode: this.sessionModeId, -@@ -6839,14 +6836,12 @@ SELECT pg_database_size(current_database()) AS database_size_bytes, - * The router itself serves the configured server API contract. - */ - export function createLocalApiRouter({ -- gameJourneyCompletionMetricsLegacyDbPath = undefined, - gameJourneyCompletionMetricsPostgresClient = null, - messagesPostgresClient = null, - messagesService = null, - repoRoot = process.cwd(), - } = {}) { - const dataSource = new ApiRuntimeDataSource({ -- gameJourneyCompletionMetricsLegacyDbPath, - gameJourneyCompletionMetricsPostgresClient, - messagesPostgresClient, - messagesService, -diff --git a/tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs b/tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs -index edbc0333e..1ca7de68e 100644 ---- a/tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs -+++ b/tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs -@@ -10,6 +10,34 @@ import { - } from "../../src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs"; - import { createGameJourneyCompletionMetricsPostgresClientStub } from "../helpers/gameJourneyCompletionMetricsPostgresClientStub.mjs"; - -+const ACTIVE_RUNTIME_ROOTS = Object.freeze(["src", "assets", "toolbox"]); -+const ACTIVE_RUNTIME_ALLOWED_FILES = new Set([ -+ path.normalize("src/dev-runtime/persistence/game-journey-completion-metrics-migration.mjs"), -+]); -+const RUNTIME_FORBIDDEN_PATTERNS = Object.freeze([ -+ /sqlite/i, -+ /\.sqlite/i, -+ /better-sqlite/i, -+ /game-journey-completion-metrics\.sqlite/i, -+ /tmp\/local-api/i, -+]); -+ -+async function activeRuntimeJavaScriptFiles(root) { -+ const entries = await fs.readdir(root, { withFileTypes: true }); -+ const files = []; -+ for (const entry of entries) { -+ const child = path.join(root, entry.name); -+ if (entry.isDirectory()) { -+ files.push(...await activeRuntimeJavaScriptFiles(child)); -+ continue; -+ } -+ if (entry.isFile() && /\.(?:mjs|js)$/i.test(entry.name)) { -+ files.push(child); -+ } -+ } -+ return files; -+} -+ - test("active Game Journey metrics ignore the retired default legacy SQLite path", async () => { - const originalCwd = process.cwd(); - const directory = await fs.mkdtemp(path.join(os.tmpdir(), "gfs-game-journey-metrics-store-")); -@@ -24,8 +52,10 @@ test("active Game Journey metrics ignore the retired default legacy SQLite path" - const postgresClient = createGameJourneyCompletionMetricsPostgresClientStub(); - const store = createGameJourneyCompletionMetricsStore({ postgresClient }); - const metrics = await store.listMetrics(); -+ const snapshot = await store.snapshot(); - -- assert.equal(store.legacyDbPath, ""); -+ assert.equal(Object.hasOwn(store, "legacyDbPath"), false); -+ assert.equal(Object.hasOwn(snapshot, "legacySqlitePath"), false); - assert.equal(metrics.length, 14); - assert.equal(postgresClient.dumpTable(GAME_JOURNEY_COMPLETION_METRICS_TABLE).length, 14); - assert.equal(await fs.readFile(retiredLegacyPath, "utf8"), retiredLegacyContents); -@@ -34,3 +64,26 @@ test("active Game Journey metrics ignore the retired default legacy SQLite path" - await fs.rm(directory, { force: true, recursive: true }); - } - }); -+ -+test("active runtime JS and MJS do not contain SQLite or tmp local metrics references", async () => { -+ const files = []; -+ for (const root of ACTIVE_RUNTIME_ROOTS) { -+ files.push(...await activeRuntimeJavaScriptFiles(root)); -+ } -+ -+ const findings = []; -+ for (const file of files) { -+ const normalized = path.normalize(file); -+ if (ACTIVE_RUNTIME_ALLOWED_FILES.has(normalized)) { -+ continue; -+ } -+ const contents = await fs.readFile(file, "utf8"); -+ RUNTIME_FORBIDDEN_PATTERNS.forEach((pattern) => { -+ if (pattern.test(contents)) { -+ findings.push(`${file}: ${pattern}`); -+ } -+ }); -+ } -+ -+ assert.deepEqual(findings, []); -+}); -diff --git a/tests/helpers/playwrightRepoServer.mjs b/tests/helpers/playwrightRepoServer.mjs -index 9bc8e8f07..71c7853aa 100644 ---- a/tests/helpers/playwrightRepoServer.mjs -+++ b/tests/helpers/playwrightRepoServer.mjs -@@ -91,13 +91,11 @@ function resolveBrowserRoutePath(decodedPath) { - } - - export async function startRepoServer({ -- gameJourneyCompletionMetricsLegacyDbPath = undefined, - gameJourneyCompletionMetricsPostgresClient = null, - messagesPostgresClient = null, - } = {}) { - await loadRuntimeEnv(); - const handleLocalApiRequest = createLocalApiRouter({ -- gameJourneyCompletionMetricsLegacyDbPath, - gameJourneyCompletionMetricsPostgresClient, - messagesPostgresClient, - repoRoot, -diff --git a/tests/playwright/tools/GameJourneyTool.spec.mjs b/tests/playwright/tools/GameJourneyTool.spec.mjs -index 75a913d96..cc47265cf 100644 ---- a/tests/playwright/tools/GameJourneyTool.spec.mjs -+++ b/tests/playwright/tools/GameJourneyTool.spec.mjs -@@ -40,7 +40,6 @@ test.afterAll(async () => { - async function openRepoPage(page, pathName, options = {}) { - const gameJourneyCompletionMetricsPostgresClient = createGameJourneyCompletionMetricsPostgresClientStub(); - const server = await startRepoServer({ -- gameJourneyCompletionMetricsLegacyDbPath: null, - gameJourneyCompletionMetricsPostgresClient, - }); - const previousApiUrl = process.env.GAMEFOUNDRY_API_URL; -@@ -238,7 +237,6 @@ test("Game Journey exposes static tool ownership areas without automatic counts" - - const gameJourneyCompletionMetricsPostgresClient = createGameJourneyCompletionMetricsPostgresClientStub(); - const server = await startRepoServer({ -- gameJourneyCompletionMetricsLegacyDbPath: null, - gameJourneyCompletionMetricsPostgresClient, - }); - try { -@@ -262,7 +260,6 @@ test("Game Journey progress dashboard summarizes completion metrics", async ({ p - process.env.GAMEFOUNDRY_LOCAL_DB_PATH = localDbPath; - const gameJourneyCompletionMetricsPostgresClient = createGameJourneyCompletionMetricsPostgresClientStub(); - const server = await startRepoServer({ -- gameJourneyCompletionMetricsLegacyDbPath: null, - gameJourneyCompletionMetricsPostgresClient, - }); - const previousApiUrl = process.env.GAMEFOUNDRY_API_URL; -@@ -1285,7 +1282,6 @@ test("Game Journey displays system template diagnostics", async ({ page }) => { - - test("Game Journey mock data keeps system guidance template-owned", async () => { - const repository = createGameJourneyMockRepository({ -- completionMetricsLegacyDbPath: null, - completionMetricsPostgresClient: createGameJourneyCompletionMetricsPostgresClientStub(), - memoryDbTables: standaloneSeedTables, - persist: false, -@@ -1452,7 +1448,6 @@ test("Game Journey mock data keeps system guidance template-owned", async () => - test("Game Journey Local API persists completion metrics to Postgres", async () => { - const gameJourneyCompletionMetricsPostgresClient = createGameJourneyCompletionMetricsPostgresClientStub(); - const server = await startRepoServer({ -- gameJourneyCompletionMetricsLegacyDbPath: null, - gameJourneyCompletionMetricsPostgresClient, - }); - try { -@@ -1511,29 +1506,11 @@ test("Game Journey Local API persists completion metrics to Postgres", async () - test("Game Journey completion metrics fail visibly when Postgres is not configured", async () => { - const store = createGameJourneyCompletionMetricsStore({ - env: {}, -- legacyDbPath: null, - }); - - await expect(store.listMetrics()).rejects.toThrow(/GAMEFOUNDRY_DATABASE_URL/); - }); - --test("Game Journey completion metrics protect legacy SQLite data from silent drop", async () => { -- const legacyDbPath = path.join(process.cwd(), "tmp", "local-api", `game-journey-legacy-guard-${process.pid}-${Date.now()}.sqlite`); -- await fs.mkdir(path.dirname(legacyDbPath), { recursive: true }); -- await fs.writeFile(legacyDbPath, "legacy metrics placeholder"); -- -- const store = createGameJourneyCompletionMetricsStore({ -- legacyDbPath, -- postgresClient: createGameJourneyCompletionMetricsPostgresClientStub(), -- }); -- -- try { -- await expect(store.listMetrics()).rejects.toThrow(/Legacy Game Journey completion metrics SQLite data exists/); -- } finally { -- await fs.rm(legacyDbPath, { force: true }); -- } --}); -- - test("Game Journey requires an active game before editing", async ({ page }) => { - const failures = await openRepoPage(page, "/toolbox/game-journey/index.html?game=none"); - -diff --git a/tests/playwright/tools/IdeaBoardTableNotes.spec.mjs b/tests/playwright/tools/IdeaBoardTableNotes.spec.mjs -index 6d626f03b..be8c88698 100644 ---- a/tests/playwright/tools/IdeaBoardTableNotes.spec.mjs -+++ b/tests/playwright/tools/IdeaBoardTableNotes.spec.mjs -@@ -115,7 +115,6 @@ async function expectNoNavigationFallbackUi(page) { - - test("Idea Board uses accordion table ideas and notes", async ({ page }) => { - const server = await startRepoServer({ -- gameJourneyCompletionMetricsLegacyDbPath: null, - gameJourneyCompletionMetricsPostgresClient: createGameJourneyCompletionMetricsPostgresClientStub(), - }); - const previousApiUrl = process.env.GAMEFOUNDRY_API_URL; -@@ -478,7 +477,6 @@ test("Idea Board uses accordion table ideas and notes", async ({ page }) => { - - test("Idea Board gates Create Project to Ready ideas and locks converted projects", async ({ page }) => { - const server = await startRepoServer({ -- gameJourneyCompletionMetricsLegacyDbPath: null, - gameJourneyCompletionMetricsPostgresClient: createGameJourneyCompletionMetricsPostgresClientStub(), - }); - const previousApiUrl = process.env.GAMEFOUNDRY_API_URL; -@@ -595,7 +593,6 @@ test("Idea Board gates Create Project to Ready ideas and locks converted project - - test("Idea Board guest write actions redirect to sign in before saving data", async ({ page }) => { - const server = await startRepoServer({ -- gameJourneyCompletionMetricsLegacyDbPath: null, - gameJourneyCompletionMetricsPostgresClient: createGameJourneyCompletionMetricsPostgresClientStub(), - }); - const previousApiUrl = process.env.GAMEFOUNDRY_API_URL; \ No newline at end of file +-src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs +-src/dev-runtime/persistence/tool-repositories/game-journey-mock-repository.js +-src/dev-runtime/server/local-api-router.mjs +-tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs +-tests/helpers/playwrightRepoServer.mjs +-tests/playwright/tools/GameJourneyTool.spec.mjs +-tests/playwright/tools/IdeaBoardTableNotes.spec.mjs ++project-instructions/README.md ++project-instructions/addendums/assistant-execution-modes.md ++project-instructions/addendums/canonical-repository-structure.md ++project-instructions/addendums/codex-artifact-and-reporting-standard.md ++project-instructions/addendums/codex-project-instructions-startup.md ++project-instructions/addendums/legacy-migration-policy.md ++project-instructions/addendums/test-structure-standardization.md +diff --git a/project-instructions/addendums/assistant-execution-modes.md b/project-instructions/addendums/assistant-execution-modes.md +index 6d7928669..4c5637d0d 100644 +--- a/project-instructions/addendums/assistant-execution-modes.md ++++ b/project-instructions/addendums/assistant-execution-modes.md +@@ -1,5 +1,7 @@ + # Assistant Execution Modes + ++> Deprecated reference notice: this file is preserved for history only. The active copy is `docs_build/dev/ProjectInstructions/addendums/assistant_execution_modes.md`. ++ + ## Purpose + + Standardize request interpretation and expected outputs for Review, Owner, Build PR, Continue, Challenge, and Stop Gate workflows. +diff --git a/project-instructions/addendums/canonical-repository-structure.md b/project-instructions/addendums/canonical-repository-structure.md +index e26939469..6b9dcb242 100644 +--- a/project-instructions/addendums/canonical-repository-structure.md ++++ b/project-instructions/addendums/canonical-repository-structure.md +@@ -1,5 +1,7 @@ + # Canonical Repository Structure + ++> Deprecated reference notice: this file is preserved for history only. The active copy is `docs_build/dev/ProjectInstructions/addendums/canonical_repository_structure.md`. ++ + ## Purpose + + Establish the canonical repository structure for future development and reduce technical debt. +diff --git a/project-instructions/addendums/codex-artifact-and-reporting-standard.md b/project-instructions/addendums/codex-artifact-and-reporting-standard.md +index 3f16a3641..8d1327886 100644 +--- a/project-instructions/addendums/codex-artifact-and-reporting-standard.md ++++ b/project-instructions/addendums/codex-artifact-and-reporting-standard.md +@@ -1,5 +1,7 @@ + # Codex Artifact and Reporting Standard + ++> Deprecated reference notice: this file is preserved for history only. The active copy is `docs_build/dev/ProjectInstructions/addendums/codex_artifact_and_reporting_standard.md`. ++ + ## Purpose + + Standardize Codex deliverables, completion reporting, and artifact generation. +diff --git a/project-instructions/addendums/codex-project-instructions-startup.md b/project-instructions/addendums/codex-project-instructions-startup.md +index 94744f06e..135498b42 100644 +--- a/project-instructions/addendums/codex-project-instructions-startup.md ++++ b/project-instructions/addendums/codex-project-instructions-startup.md +@@ -1,5 +1,7 @@ + # Codex Project Instructions Startup + ++> Deprecated reference notice: this file is preserved for history only. The active copy is `docs_build/dev/ProjectInstructions/addendums/codex_project_instructions_startup.md`. ++ + ## Purpose + + Ensure Codex uses the current approved governance before making repository changes. +diff --git a/project-instructions/addendums/legacy-migration-policy.md b/project-instructions/addendums/legacy-migration-policy.md +index 5e43679f4..5515a1728 100644 +--- a/project-instructions/addendums/legacy-migration-policy.md ++++ b/project-instructions/addendums/legacy-migration-policy.md +@@ -1,5 +1,7 @@ + # Legacy Migration Policy + ++> Deprecated reference notice: this file is preserved for history only. The active copy is `docs_build/dev/ProjectInstructions/addendums/legacy_migration_policy.md`. ++ + ## Purpose + + Reduce technical debt incrementally during normal development. +diff --git a/project-instructions/addendums/test-structure-standardization.md b/project-instructions/addendums/test-structure-standardization.md +index 997b16730..eeb62d561 100644 +--- a/project-instructions/addendums/test-structure-standardization.md ++++ b/project-instructions/addendums/test-structure-standardization.md +@@ -1,5 +1,7 @@ + # Test Structure Standardization + ++> Deprecated reference notice: this file is preserved for history only. The active copy is `docs_build/dev/ProjectInstructions/addendums/test_structure_standardization.md`. ++ + ## Purpose + + Standardize testing locations and ensure independent tool validation. +diff --git a/docs_build/dev/ProjectInstructions/addendums/assistant_execution_modes.md b/docs_build/dev/ProjectInstructions/addendums/assistant_execution_modes.md +new file mode 100644 +index 000000000..6d7928669 +--- /dev/null ++++ b/docs_build/dev/ProjectInstructions/addendums/assistant_execution_modes.md +@@ -0,0 +1,120 @@ ++# Assistant Execution Modes ++ ++## Purpose ++ ++Standardize request interpretation and expected outputs for Review, Owner, Build PR, Continue, Challenge, and Stop Gate workflows. ++ ++## Command Modes ++ ++### Review ++ ++Expected Output: ++- Findings ++- Risks ++- Recommendations ++ ++Do Not Output: ++- PRs ++- Implementation plans ++ ++### Owner ++ ++Expected Output: ++- Decisions ++- Governance direction ++- Standards ++ ++Do Not Output: ++- Detailed implementation ++ ++### Build PR ++ ++Expected Output: ++- Single Codex work order ++- May contain multiple sequential PRs belonging to the same workstream ++- Copy/paste ready for execution ++ ++Should Include: ++- Start gates ++- Changes ++- Validation ++- Commit names ++- Stop point ++ ++Do Not Output: ++- Design discussion ++- Alternatives ++- Rationale ++- Architecture brainstorming ++ ++### Continue ++ ++Expected Output: ++- Next sequential executable PR ++- Next sequential work order ++ ++Do Not Output: ++- New ideas ++- Re-analysis ++- Additional brainstorming ++ ++### Challenge ++ ++Expected Output: ++- Risks ++- Contradictions ++- Better alternatives ++ ++Do Not Output: ++- Immediate implementation ++ ++### Stop Gate ++ ++Expected Output: ++- Why work should stop ++- Required corrections ++ ++Allowed Reasons: ++- Governance conflict ++- Architecture conflict ++- Security risk ++- Data loss risk ++- Major technical debt increase ++ ++## Additional Definitions ++ ++### Follow Project Instructions ++ ++Meaning: ++- Use existing governance ++- Do not redesign process ++ ++### Build the PR ++ ++Meaning: ++- Produce Codex executable work order immediately ++ ++### Continue ++ ++Meaning: ++- Produce next sequential work item ++ ++### No zip file ++ ++Meaning: ++- Generate instructions only ++- Do not expect artifact review ++ ++### You are owner ++ ++Meaning: ++- Make decisions ++- Do not ask for direction unless blocked ++ ++### Done for the day ++ ++Meaning: ++- Finish commits ++- Merge ++- Push ++- Create next-day start document +diff --git a/docs_build/dev/ProjectInstructions/addendums/canonical_repository_structure.md b/docs_build/dev/ProjectInstructions/addendums/canonical_repository_structure.md +new file mode 100644 +index 000000000..e26939469 +--- /dev/null ++++ b/docs_build/dev/ProjectInstructions/addendums/canonical_repository_structure.md +@@ -0,0 +1,39 @@ ++# Canonical Repository Structure ++ ++## Purpose ++ ++Establish the canonical repository structure for future development and reduce technical debt. ++ ++## Canonical Structure ++ ++Tools: ++- toolbox/{tool-name}/index.html ++ ++Tool assets: ++- assets/toolbox/{tool-name}/js/index.js ++- assets/toolbox/{tool-name}/css/index.css ++ ++Themes: ++- assets/theme-v1/ ++- assets/theme-v2/ ++ ++Shared JavaScript: ++- assets/js/shared/ ++ ++Engine: ++- src/engine/{feature-name}/ ++ ++API: ++- api/{feature-name}/ ++ ++Serverside: ++- serverside/{feature-name}/ ++ ++## Rules ++ ++- Theme first. ++- Tool CSS second. ++- Shared functionality belongs in assets/js/shared/. ++- No new scattered JS folders. ++- No new scattered CSS folders. ++- New development follows the canonical structure. +diff --git a/docs_build/dev/ProjectInstructions/addendums/codex_artifact_and_reporting_standard.md b/docs_build/dev/ProjectInstructions/addendums/codex_artifact_and_reporting_standard.md +new file mode 100644 +index 000000000..498e3895e +--- /dev/null ++++ b/docs_build/dev/ProjectInstructions/addendums/codex_artifact_and_reporting_standard.md +@@ -0,0 +1,66 @@ ++# Codex Artifact and Reporting Standard ++ ++## Purpose ++ ++Standardize Codex deliverables, completion reporting, and artifact generation. ++ ++## ZIP Artifact Requirement ++ ++Every Codex task must produce a ZIP artifact. ++ ++Applies to: ++- Success ++- Failure ++- Stop Gate ++- Partial Completion ++- Review Deliverables ++- Governance Deliverables ++ ++Minimum ZIP contents: ++- summary.md ++ ++Optional: ++- changed-files.txt ++- findings.md ++- validation.txt ++- generated artifacts ++ ++## Completion Reporting ++ ++Codex responses must include: ++- ZIP filename ++- ZIP location ++- PR number(s) ++- Merge commit(s) ++- Validation results ++ ++## Code Change Reporting ++ ++When a ZIP is uploaded, report executable code changes only. ++ ++Report format: ++ ++```text ++{relative path} - {added|updated|deleted} ++``` ++ ++Examples: ++ ++```text ++toolbox/text-to-speech/index.html - updated ++assets/toolbox/text-to-speech/js/index.js - added ++tests/toolbox/text-to-speech/functional.spec.mjs - updated ++``` ++ ++Do not report: ++- markdown ++- documentation ++- reports ++- notes ++- README updates ++ ++unless explicitly requested. ++ ++## No ZIP Means Incomplete ++ ++A task is not considered complete until the ZIP artifact is generated and reported. +diff --git a/docs_build/dev/ProjectInstructions/addendums/codex_project_instructions_startup.md b/docs_build/dev/ProjectInstructions/addendums/codex_project_instructions_startup.md +new file mode 100644 +index 000000000..e0abb9db0 +--- /dev/null ++++ b/docs_build/dev/ProjectInstructions/addendums/codex_project_instructions_startup.md +@@ -0,0 +1,65 @@ ++# Codex Project Instructions Startup ++ ++## Purpose ++ ++Ensure Codex uses the current approved governance before making repository changes. ++ ++## Startup Requirement ++ ++Before performing work, Codex must review and use: ++ ++```text ++docs_build/dev/ProjectInstructions/ ++``` ++ ++Codex must use this as the only active source of truth for: ++- Governance rules ++- Repository standards ++- Ownership rules ++- Workflow rules ++- Addendums ++- Execution modes ++- Artifact requirements ++ ++Deprecated Project Instructions material outside `docs_build/dev/ProjectInstructions/` is reference-only and must not override active governance. ++ ++## Project Reference File Review ++ ++When present in `ProjectInstructions.zip`, the active project instruction directory, or `docs_build/dev/admin-notes/`, Codex must include these recognized project instruction/reference files in the Project Instructions read set: ++ ++- `Installs required.txt` ++- `Table layout.txt` ++ ++Chat instructions may supplement Project Instructions but must not override approved governance without explicit OWNER approval. ++ ++## Conflict Handling ++ ++If a chat instruction conflicts with Project Instructions: ++- Stop ++- Do not continue the PR ++- Produce the required ZIP artifact ++- Document the conflict in summary.md ++- Ask for OWNER direction ++ ++## Execution Mode Validation ++ ++When a request contains: ++- Build PR ++- Continue ++- Follow Project Instructions ++- Next PR ++ ++Codex must treat the request as Execution Mode. ++ ++Execution Mode means: ++- Execute the requested work order ++- Do not redesign the process ++- Do not provide alternatives unless a Stop Gate condition exists ++ ++## Validation ++ ++Before completing the PR: ++- Verify this addendum appears in the Project Instructions index ++- Verify markdown is valid ++- Verify all indexed addendums exist ++- Verify the required ZIP artifact is produced +diff --git a/docs_build/dev/ProjectInstructions/addendums/legacy_migration_policy.md b/docs_build/dev/ProjectInstructions/addendums/legacy_migration_policy.md +new file mode 100644 +index 000000000..5e43679f4 +--- /dev/null ++++ b/docs_build/dev/ProjectInstructions/addendums/legacy_migration_policy.md +@@ -0,0 +1,33 @@ ++# Legacy Migration Policy ++ ++## Purpose ++ ++Reduce technical debt incrementally during normal development. ++ ++## Migration Trigger ++ ++Migration review is required when any of these actions touch legacy files: ++ ++- File modified ++- File renamed ++- Bug fix ++- Enhancement ++- Test modification ++ ++## Migration Process ++ ++1. Review JS location. ++2. Review CSS location. ++3. Review test location. ++4. Move touched files into canonical structure. ++5. Update imports. ++6. Update tests. ++7. Remove legacy references. ++ ++## Rules ++ ++- Legacy files may only be deleted when no active references remain. ++- Temporary bridge code must contain `TEMPORARY_MIGRATION` and a removal plan. ++- No new scattered JS locations. ++- No new scattered CSS locations. ++- No new scattered test locations. +diff --git a/docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md b/docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md +new file mode 100644 +index 000000000..9ea3824e0 +--- /dev/null ++++ b/docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md +@@ -0,0 +1,61 @@ ++# Project Instructions Single Source And EOD Main Lock ++ ++Status: Approved ++Owner: OWNER ++ ++## Active Source ++ ++`docs_build/dev/ProjectInstructions/` is the only active Project Instructions source for Game Foundry Studio. ++ ++Deprecated reference locations must not be used as active instruction sources: ++- `docs_build/dev/PROJECT_INSTRUCTIONS.md` ++- `project-instructions/` ++- archived Project Instructions snapshots ++- generated PR reports ++ ++If deprecated reference material conflicts with `docs_build/dev/ProjectInstructions/`, the active folder wins unless OWNER explicitly approves a newer governance change. ++ ++## End Of Day ++ ++```text ++git checkout main ++git fetch origin ++git pull --ff-only origin main ++git status ++git rev-list --left-right --count main...origin/main ++``` ++ ++Required: ++ ++```text ++On branch main ++nothing to commit, working tree clean ++0 0 ++``` ++ ++The EOD report must record the final `HEAD` SHA as the published EOD SHA. ++ ++## Next Day Start ++ ++```text ++git checkout main ++git fetch origin ++git pull --ff-only origin main ++git status ++git rev-list --left-right --count main...origin/main ++git rev-parse HEAD ++``` ++ ++## Team Branch Creation Gate ++ ++No team creates a PR branch until: ++- Current branch: `main` ++- Worktree: clean ++- `main...origin/main`: `0 0` ++- `HEAD` SHA matches published EOD SHA ++ ++If any check fails, stop before branch creation and restore main to the published EOD state or request OWNER direction. ++ ++## Start Of Day Boundary ++ ++`docs_build/dev/start_of_day/` may point to `docs_build/dev/ProjectInstructions/`, but it must not become a second active Project Instructions source. +diff --git a/docs_build/dev/ProjectInstructions/addendums/test_structure_standardization.md b/docs_build/dev/ProjectInstructions/addendums/test_structure_standardization.md +new file mode 100644 +index 000000000..997b16730 +--- /dev/null ++++ b/docs_build/dev/ProjectInstructions/addendums/test_structure_standardization.md +@@ -0,0 +1,33 @@ ++# Test Structure Standardization ++ ++## Purpose ++ ++Standardize testing locations and ensure independent tool validation. ++ ++## Canonical Test Structure ++ ++Tool tests: ++- tests/toolbox/{tool-name}/ ++ ++Engine tests: ++- tests/engine/{feature-name}/ ++ ++API tests: ++- tests/api/{feature-name}/ ++ ++Server tests: ++- tests/server/{feature-name}/ ++ ++Shared JavaScript tests: ++- tests/js/shared/ ++ ++Regression tests: ++- tests/regression/ ++ ++## Rules ++ ++- Every tool must be independently testable. ++- Regression tests do not replace tool tests. ++- Tool tests validate tool functionality. ++- Regression tests validate platform behavior. ++- New tests follow the canonical structure. +diff --git a/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock.md b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock.md +new file mode 100644 +index 000000000..5c7927f17 +--- /dev/null ++++ b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock.md +@@ -0,0 +1,25 @@ ++# PR_26177_OWNER_007-project-instructions-single-source-eod-lock ++ ++Date: 2026-06-26 ++Scope: Project Instructions single-source and EOD main lock governance ++Status: PASS ++ ++## Summary ++ ++- Established `docs_build/dev/ProjectInstructions/` as the only active Project Instructions source. ++- Migrated legacy root `project-instructions/addendums/` content into active `docs_build/dev/ProjectInstructions/addendums/` files. ++- Marked legacy `docs_build/dev/PROJECT_INSTRUCTIONS.md` and `project-instructions/` material as deprecated reference only. ++- Added EOD main lock, next-day reset, and team branch creation gate governance. ++- Updated active team start and governance docs to reference only `docs_build/dev/ProjectInstructions/`. ++- No product/runtime, `start_of_day`, feature, or legacy SQLite file changes were made. ++ ++## Validation ++ ++- PASS: targeted grep found no active duplicate ProjectInstructions source-of-truth claim outside the active source. ++- PASS: targeted grep confirmed EOD/Next Day governance appears in active governance docs. ++- PASS: product/runtime and `start_of_day` changed-file check returned no files. ++- PASS: `git diff --check`. ++ ++## Artifact ++ ++- `tmp/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_delta.zip` +diff --git a/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_branch-validation.md b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_branch-validation.md +new file mode 100644 +index 000000000..17e0bfc39 +--- /dev/null ++++ b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_branch-validation.md +@@ -0,0 +1,7 @@ ++# PR_26177_OWNER_007-project-instructions-single-source-eod-lock Branch Validation ++ ++- PASS: Started from `main`. ++- PASS: Start gate confirmed worktree clean before branch creation. ++- PASS: Start gate confirmed `main...origin/main` was `0 0` before branch creation. ++- PASS: Current branch is `PR_26177_OWNER_007-project-instructions-single-source-eod-lock`. ++- PASS: No `.vscode/settings.json` change is staged or included. +diff --git a/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_manual-validation-notes.md b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_manual-validation-notes.md +new file mode 100644 +index 000000000..10cbb4170 +--- /dev/null ++++ b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_manual-validation-notes.md +@@ -0,0 +1,8 @@ ++# PR_26177_OWNER_007-project-instructions-single-source-eod-lock Manual Validation Notes ++ ++- Reviewed ProjectInstructions path and text references. ++- Confirmed active source declarations live under `docs_build/dev/ProjectInstructions/`. ++- Confirmed legacy locations are preserved as deprecated reference material rather than active sources. ++- Confirmed `docs_build/dev/start_of_day/` was not modified. ++- Confirmed no product/runtime files were modified. ++- Confirmed ZIP artifact path: `tmp/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_delta.zip`. +diff --git a/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_requirement-checklist.md b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_requirement-checklist.md +new file mode 100644 +index 000000000..99ab45345 +--- /dev/null ++++ b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_requirement-checklist.md +@@ -0,0 +1,16 @@ ++# PR_26177_OWNER_007-project-instructions-single-source-eod-lock Requirement Checklist ++ ++- PASS: Audited repo for ProjectInstructions / project instructions duplicates. ++- PASS: Active source is `docs_build/dev/ProjectInstructions/`. ++- PASS: Legacy `docs_build/dev/PROJECT_INSTRUCTIONS.md` is marked deprecated. ++- PASS: Legacy root `project-instructions/` folder is marked deprecated. ++- PASS: Legacy root addendums are migrated into the active addendum tree. ++- PASS: Active team start/governance docs reference only `docs_build/dev/ProjectInstructions/`. ++- PASS: Added EOD command sequence. ++- PASS: Added required EOD output: `On branch main`, clean worktree, `0 0`. ++- PASS: Added Next Day Start command sequence. ++- PASS: Added team branch creation rule requiring main, clean worktree, `0 0`, and matching published EOD SHA. ++- PASS: Did not modify `start_of_day` folders. ++- PASS: Did not modify product/runtime files. ++- PASS: Did not remove, move, or overwrite legacy SQLite files. ++- PASS: Did not start feature work. +diff --git a/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_validation-lane.md b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_validation-lane.md +new file mode 100644 +index 000000000..8a1b82360 +--- /dev/null ++++ b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_validation-lane.md +@@ -0,0 +1,17 @@ ++# PR_26177_OWNER_007-project-instructions-single-source-eod-lock Validation Lane ++ ++- PASS: duplicate-source grep returned no matches for old active source claims. ++- PASS: EOD/Next Day governance grep returned active governance matches. ++- PASS: product/runtime/start_of_day changed-file check returned no files. ++- PASS: git diff --check. ++ ++Commands used: ++ ++~~~text ++rg -n 'project-instructions/addendums|docs_build/dev/PROJECT_INSTRUCTIONS.md.*source of truth|Codex must always read `docs_build/dev/PROJECT_INSTRUCTIONS.md`|Read `docs_build/dev/PROJECT_INSTRUCTIONS.md`' docs_build/dev/ProjectInstructions docs_build/dev/PROJECT_INSTRUCTIONS.md project-instructions ++rg -n "End of Day:|Next Day Start:|HEAD.*published EOD SHA|only active Project Instructions source" docs_build/dev/ProjectInstructions ++git diff --name-only -- src assets toolbox games api serverside package.json package-lock.json docs_build/dev/start_of_day ++git diff --check ++~~~ ++ ++Full product/runtime tests were not run because this PR changes governance documentation only. +diff --git a/project-instructions/README.md b/project-instructions/README.md +new file mode 100644 +index 000000000..af401852e +--- /dev/null ++++ b/project-instructions/README.md +@@ -0,0 +1,11 @@ ++# Deprecated Project Instructions Reference ++ ++This folder is preserved as historical reference only. ++ ++The only active Project Instructions source is: ++ ++```text ++docs_build/dev/ProjectInstructions/ ++``` ++ ++Do not use files under `project-instructions/` as active governance. If a file here conflicts with `docs_build/dev/ProjectInstructions/`, the active folder wins unless OWNER explicitly approves a newer governance change. diff --git a/project-instructions/README.md b/project-instructions/README.md new file mode 100644 index 000000000..af401852e --- /dev/null +++ b/project-instructions/README.md @@ -0,0 +1,11 @@ +# Deprecated Project Instructions Reference + +This folder is preserved as historical reference only. + +The only active Project Instructions source is: + +```text +docs_build/dev/ProjectInstructions/ +``` + +Do not use files under `project-instructions/` as active governance. If a file here conflicts with `docs_build/dev/ProjectInstructions/`, the active folder wins unless OWNER explicitly approves a newer governance change. diff --git a/project-instructions/addendums/assistant-execution-modes.md b/project-instructions/addendums/assistant-execution-modes.md index 6d7928669..4c5637d0d 100644 --- a/project-instructions/addendums/assistant-execution-modes.md +++ b/project-instructions/addendums/assistant-execution-modes.md @@ -1,5 +1,7 @@ # Assistant Execution Modes +> Deprecated reference notice: this file is preserved for history only. The active copy is `docs_build/dev/ProjectInstructions/addendums/assistant_execution_modes.md`. + ## Purpose Standardize request interpretation and expected outputs for Review, Owner, Build PR, Continue, Challenge, and Stop Gate workflows. diff --git a/project-instructions/addendums/canonical-repository-structure.md b/project-instructions/addendums/canonical-repository-structure.md index e26939469..6b9dcb242 100644 --- a/project-instructions/addendums/canonical-repository-structure.md +++ b/project-instructions/addendums/canonical-repository-structure.md @@ -1,5 +1,7 @@ # Canonical Repository Structure +> Deprecated reference notice: this file is preserved for history only. The active copy is `docs_build/dev/ProjectInstructions/addendums/canonical_repository_structure.md`. + ## Purpose Establish the canonical repository structure for future development and reduce technical debt. diff --git a/project-instructions/addendums/codex-artifact-and-reporting-standard.md b/project-instructions/addendums/codex-artifact-and-reporting-standard.md index 3f16a3641..8d1327886 100644 --- a/project-instructions/addendums/codex-artifact-and-reporting-standard.md +++ b/project-instructions/addendums/codex-artifact-and-reporting-standard.md @@ -1,5 +1,7 @@ # Codex Artifact and Reporting Standard +> Deprecated reference notice: this file is preserved for history only. The active copy is `docs_build/dev/ProjectInstructions/addendums/codex_artifact_and_reporting_standard.md`. + ## Purpose Standardize Codex deliverables, completion reporting, and artifact generation. diff --git a/project-instructions/addendums/codex-project-instructions-startup.md b/project-instructions/addendums/codex-project-instructions-startup.md index 94744f06e..135498b42 100644 --- a/project-instructions/addendums/codex-project-instructions-startup.md +++ b/project-instructions/addendums/codex-project-instructions-startup.md @@ -1,5 +1,7 @@ # Codex Project Instructions Startup +> Deprecated reference notice: this file is preserved for history only. The active copy is `docs_build/dev/ProjectInstructions/addendums/codex_project_instructions_startup.md`. + ## Purpose Ensure Codex uses the current approved governance before making repository changes. diff --git a/project-instructions/addendums/legacy-migration-policy.md b/project-instructions/addendums/legacy-migration-policy.md index 5e43679f4..5515a1728 100644 --- a/project-instructions/addendums/legacy-migration-policy.md +++ b/project-instructions/addendums/legacy-migration-policy.md @@ -1,5 +1,7 @@ # Legacy Migration Policy +> Deprecated reference notice: this file is preserved for history only. The active copy is `docs_build/dev/ProjectInstructions/addendums/legacy_migration_policy.md`. + ## Purpose Reduce technical debt incrementally during normal development. diff --git a/project-instructions/addendums/test-structure-standardization.md b/project-instructions/addendums/test-structure-standardization.md index 997b16730..eeb62d561 100644 --- a/project-instructions/addendums/test-structure-standardization.md +++ b/project-instructions/addendums/test-structure-standardization.md @@ -1,5 +1,7 @@ # Test Structure Standardization +> Deprecated reference notice: this file is preserved for history only. The active copy is `docs_build/dev/ProjectInstructions/addendums/test_structure_standardization.md`. + ## Purpose Standardize testing locations and ensure independent tool validation. From edca0a297a0e411b32828afb12d8253358926044 Mon Sep 17 00:00:00 2001 From: Alfa Team Date: Fri, 26 Jun 2026 11:18:03 -0400 Subject: [PATCH 2/9] Add ProjectInstructions branch lifecycle governance --- docs_build/dev/BUILD_PR.md | 4 +- docs_build/dev/PLAN_PR.md | 4 +- .../TEAM_START_COMMANDS.md | 26 + .../addendums/branch_lock_governance.md | 35 +- .../codex_project_instructions_startup.md | 28 + .../addendums/pr_workflow.md | 31 + ...ect_instructions_single_source_eod_lock.md | 31 + .../team_assignments/TEAM_ASSIGNMENTS.md | 28 + ...ect-instructions-single-source-eod-lock.md | 20 +- ...ingle-source-eod-lock_branch-validation.md | 9 +- ...source-eod-lock_manual-validation-notes.md | 11 +- ...e-source-eod-lock_requirement-checklist.md | 18 +- ...-single-source-eod-lock_validation-lane.md | 2 + docs_build/dev/reports/codex_review.diff | 2454 ++++++++++++++--- 14 files changed, 2354 insertions(+), 347 deletions(-) diff --git a/docs_build/dev/BUILD_PR.md b/docs_build/dev/BUILD_PR.md index 50b1b27fa..fbff4d261 100644 --- a/docs_build/dev/BUILD_PR.md +++ b/docs_build/dev/BUILD_PR.md @@ -14,7 +14,7 @@ This `BUILD_PR.md`, `PLAN_PR.md`, and the user request are the source of truth f - Establish `docs_build/dev/ProjectInstructions/` as the only active source. - Mark all other ProjectInstructions-style sources changed by this PR as deprecated references. - Update active team start/governance docs to reference only `docs_build/dev/ProjectInstructions/`. -- Add EOD main lock and next-day reset governance. +- Add EOD main lock, next-day reset governance, and explicit START / WORK / END branch lifecycle rules. - Add required reports under `docs_build/dev/reports/`. ## Exact Targets @@ -46,7 +46,7 @@ Run: ```powershell rg -n 'project-instructions/addendums|docs_build/dev/PROJECT_INSTRUCTIONS.md.*source of truth|Codex must always read `docs_build/dev/PROJECT_INSTRUCTIONS.md`|Read `docs_build/dev/PROJECT_INSTRUCTIONS.md`' docs_build/dev/ProjectInstructions docs_build/dev/PROJECT_INSTRUCTIONS.md project-instructions -rg -n "End of Day:|Next Day Start:|HEAD.*published EOD SHA|only active Project Instructions source" docs_build/dev/ProjectInstructions +rg -n "START RULE|WORK RULE|END RULE|HARD STOP before committing|Codex commits only to the PR branch|HEAD SHA recorded as new EOD baseline|End of Day:|Next Day Start:|HEAD.*published EOD SHA|only active Project Instructions source" docs_build/dev/ProjectInstructions git diff --name-only -- src assets toolbox games api serverside package.json package-lock.json docs_build/dev/start_of_day git diff --check ``` diff --git a/docs_build/dev/PLAN_PR.md b/docs_build/dev/PLAN_PR.md index 39fa03385..505e274bd 100644 --- a/docs_build/dev/PLAN_PR.md +++ b/docs_build/dev/PLAN_PR.md @@ -10,7 +10,7 @@ Make `docs_build/dev/ProjectInstructions/` the only active Project Instructions - Mark legacy ProjectInstructions-style sources as deprecated reference material. - Move active legacy addendums into `docs_build/dev/ProjectInstructions/addendums/`. - Update active team start and governance docs to reference only `docs_build/dev/ProjectInstructions/`. -- Add EOD main lock, next-day reset, and team PR branch creation gate. +- Add EOD main lock, next-day reset, team PR branch creation gate, and explicit START / WORK / END branch lifecycle rules. - Add required Codex reports under `docs_build/dev/reports/`. ## Out Of Scope @@ -23,6 +23,6 @@ Make `docs_build/dev/ProjectInstructions/` the only active Project Instructions ## Validation Plan 1. Run targeted grep/search proving no active duplicate ProjectInstructions source remains. -2. Confirm EOD/Next Day rule appears in active governance docs. +2. Confirm EOD/Next Day and START / WORK / END branch lifecycle rules appear in active governance docs. 3. Confirm no product/runtime files changed. 4. Run `git diff --check`. diff --git a/docs_build/dev/ProjectInstructions/TEAM_START_COMMANDS.md b/docs_build/dev/ProjectInstructions/TEAM_START_COMMANDS.md index c446a4b33..192278a34 100644 --- a/docs_build/dev/ProjectInstructions/TEAM_START_COMMANDS.md +++ b/docs_build/dev/ProjectInstructions/TEAM_START_COMMANDS.md @@ -11,6 +11,32 @@ No team creates a PR branch until all checks pass: Use `docs_build/dev/ProjectInstructions/` as the only active Project Instructions source. +START RULE: +- Every team starts on `main`. +- `main` must be clean. +- `main...origin/main` must be `0 0`. +- `HEAD` SHA must match published EOD SHA. +- Only then create or switch to the PR branch. +- No commits are allowed on `main`. + +WORK RULE: +- Codex must remain on the PR branch during implementation. +- Codex commits only to the PR branch. +- Codex pushes only the PR branch. +- HARD STOP if branch changes unexpectedly. +- HARD STOP before committing if current branch is `main`. + +END RULE: +- After PR validation, push the PR branch. +- Merge PR into `main` only when approved. +- Checkout `main`. +- Run `git fetch origin`. +- Run `git pull --ff-only origin main`. +- Confirm current branch is `main`. +- Confirm worktree is clean. +- Confirm `main...origin/main` is `0 0`. +- Record `HEAD` SHA as new EOD baseline. + ## Start Team Alfa Ready-to-copy command: diff --git a/docs_build/dev/ProjectInstructions/addendums/branch_lock_governance.md b/docs_build/dev/ProjectInstructions/addendums/branch_lock_governance.md index d6c8e4cf7..e6ab30ae8 100644 --- a/docs_build/dev/ProjectInstructions/addendums/branch_lock_governance.md +++ b/docs_build/dev/ProjectInstructions/addendums/branch_lock_governance.md @@ -25,11 +25,44 @@ Keep active work attached to the correct assigned team, branch, and OWNER decisi - Pull latest `origin/main` before creating a work branch. - Do not create a PR branch unless current branch is `main`, worktree is clean, `main...origin/main` is `0 0`, and `HEAD` SHA matches the published EOD SHA. - Keep work on the active branch until the PR is merged, the branch is retired, or OWNER says to return to `main`. -- Do not commit directly to `main` unless OWNER explicitly approves. +- Do not commit directly to `main`. +- HARD STOP before committing if current branch is `main`. +- HARD STOP if the branch changes unexpectedly during implementation. +- Commit only to the PR branch. +- Push only the PR branch. - Do not merge stale historical branches directly unless they are current, clean, still needed, and OWNER-approved. - Retain source branches by default after merge and closeout. - Record branch disposition before Closed as `retained`. +## START RULE + +- Every team starts on `main`. +- `main` must be clean. +- `main...origin/main` must be `0 0`. +- `HEAD` SHA must match published EOD SHA. +- Only then create or switch to the PR branch. +- No commits are allowed on `main`. + +## WORK RULE + +- Codex must remain on the PR branch during implementation. +- Codex commits only to the PR branch. +- Codex pushes only the PR branch. +- HARD STOP if branch changes unexpectedly. +- HARD STOP before committing if current branch is `main`. + +## END RULE + +- After PR validation, push the PR branch. +- Merge PR into `main` only when approved. +- Checkout `main`. +- Run `git fetch origin`. +- Run `git pull --ff-only origin main`. +- Confirm current branch is `main`. +- Confirm worktree is clean. +- Confirm `main...origin/main` is `0 0`. +- Record `HEAD` SHA as new EOD baseline. + ## OWNER Override OWNER may override a branch lock or team assignment. diff --git a/docs_build/dev/ProjectInstructions/addendums/codex_project_instructions_startup.md b/docs_build/dev/ProjectInstructions/addendums/codex_project_instructions_startup.md index e0abb9db0..dba8f8d93 100644 --- a/docs_build/dev/ProjectInstructions/addendums/codex_project_instructions_startup.md +++ b/docs_build/dev/ProjectInstructions/addendums/codex_project_instructions_startup.md @@ -21,6 +21,34 @@ Codex must use this as the only active source of truth for: - Execution modes - Artifact requirements +## Branch Lifecycle Start Gate + +START RULE: +- Every team starts on `main`. +- `main` must be clean. +- `main...origin/main` must be `0 0`. +- `HEAD` SHA must match published EOD SHA. +- Only then create or switch to the PR branch. +- No commits are allowed on `main`. + +WORK RULE: +- Codex must remain on the PR branch during implementation. +- Codex commits only to the PR branch. +- Codex pushes only the PR branch. +- HARD STOP if branch changes unexpectedly. +- HARD STOP before committing if current branch is `main`. + +END RULE: +- After PR validation, push the PR branch. +- Merge PR into `main` only when approved. +- Checkout `main`. +- Run `git fetch origin`. +- Run `git pull --ff-only origin main`. +- Confirm current branch is `main`. +- Confirm worktree is clean. +- Confirm `main...origin/main` is `0 0`. +- Record `HEAD` SHA as new EOD baseline. + Deprecated Project Instructions material outside `docs_build/dev/ProjectInstructions/` is reference-only and must not override active governance. ## Project Reference File Review diff --git a/docs_build/dev/ProjectInstructions/addendums/pr_workflow.md b/docs_build/dev/ProjectInstructions/addendums/pr_workflow.md index 7c1cd8275..abad0b789 100644 --- a/docs_build/dev/ProjectInstructions/addendums/pr_workflow.md +++ b/docs_build/dev/ProjectInstructions/addendums/pr_workflow.md @@ -26,6 +26,37 @@ Define the standard pull request workflow for Game Foundry Studio. 15. Pull latest main before starting the next PR. 16. Verify Main Verified and Closed gates. +## Branch Lifecycle Governance + +### START RULE + +- Every team starts on `main`. +- `main` must be clean. +- `main...origin/main` must be `0 0`. +- `HEAD` SHA must match published EOD SHA. +- Only then create or switch to the PR branch. +- No commits are allowed on `main`. + +### WORK RULE + +- Codex must remain on the PR branch during implementation. +- Codex commits only to the PR branch. +- Codex pushes only the PR branch. +- HARD STOP if branch changes unexpectedly. +- HARD STOP before committing if current branch is `main`. + +### END RULE + +- After PR validation, push the PR branch. +- Merge PR into `main` only when approved. +- Checkout `main`. +- Run `git fetch origin`. +- Run `git pull --ff-only origin main`. +- Confirm current branch is `main`. +- Confirm worktree is clean. +- Confirm `main...origin/main` is `0 0`. +- Record `HEAD` SHA as new EOD baseline. + ## PR Lifecycle States Required state order: diff --git a/docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md b/docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md index 9ea3824e0..c41dc503d 100644 --- a/docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md +++ b/docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md @@ -56,6 +56,37 @@ No team creates a PR branch until: If any check fails, stop before branch creation and restore main to the published EOD state or request OWNER direction. +## Branch Lifecycle Governance + +### START RULE + +- Every team starts on `main`. +- `main` must be clean. +- `main...origin/main` must be `0 0`. +- `HEAD` SHA must match published EOD SHA. +- Only then create or switch to the PR branch. +- No commits are allowed on `main`. + +### WORK RULE + +- Codex must remain on the PR branch during implementation. +- Codex commits only to the PR branch. +- Codex pushes only the PR branch. +- HARD STOP if branch changes unexpectedly. +- HARD STOP before committing if current branch is `main`. + +### END RULE + +- After PR validation, push the PR branch. +- Merge PR into `main` only when approved. +- Checkout `main`. +- Run `git fetch origin`. +- Run `git pull --ff-only origin main`. +- Confirm current branch is `main`. +- Confirm worktree is clean. +- Confirm `main...origin/main` is `0 0`. +- Record `HEAD` SHA as new EOD baseline. + ## Start Of Day Boundary `docs_build/dev/start_of_day/` may point to `docs_build/dev/ProjectInstructions/`, but it must not become a second active Project Instructions source. diff --git a/docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md b/docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md index 9a104b4f9..f70440ad2 100644 --- a/docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md +++ b/docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md @@ -252,3 +252,31 @@ No team creates a PR branch until: Active source rule: Teams must use only `docs_build/dev/ProjectInstructions/` as the active Project Instructions source. + +## Explicit Branch Lifecycle Governance + +START RULE: +- Every team starts on `main`. +- `main` must be clean. +- `main...origin/main` must be `0 0`. +- `HEAD` SHA must match published EOD SHA. +- Only then create or switch to the PR branch. +- No commits are allowed on `main`. + +WORK RULE: +- Codex must remain on the PR branch during implementation. +- Codex commits only to the PR branch. +- Codex pushes only the PR branch. +- HARD STOP if branch changes unexpectedly. +- HARD STOP before committing if current branch is `main`. + +END RULE: +- After PR validation, push the PR branch. +- Merge PR into `main` only when approved. +- Checkout `main`. +- Run `git fetch origin`. +- Run `git pull --ff-only origin main`. +- Confirm current branch is `main`. +- Confirm worktree is clean. +- Confirm `main...origin/main` is `0 0`. +- Record `HEAD` SHA as new EOD baseline. diff --git a/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock.md b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock.md index 5c7927f17..ed2f3e94a 100644 --- a/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock.md +++ b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock.md @@ -1,25 +1,27 @@ # PR_26177_OWNER_007-project-instructions-single-source-eod-lock Date: 2026-06-26 -Scope: Project Instructions single-source and EOD main lock governance +Scope: Project Instructions single-source, EOD main lock, and branch lifecycle governance Status: PASS ## Summary -- Established `docs_build/dev/ProjectInstructions/` as the only active Project Instructions source. -- Migrated legacy root `project-instructions/addendums/` content into active `docs_build/dev/ProjectInstructions/addendums/` files. -- Marked legacy `docs_build/dev/PROJECT_INSTRUCTIONS.md` and `project-instructions/` material as deprecated reference only. +- Established docs_build/dev/ProjectInstructions/ as the only active Project Instructions source. +- Migrated legacy root project-instructions/addendums/ content into active docs_build/dev/ProjectInstructions/addendums/ files. +- Marked legacy docs_build/dev/PROJECT_INSTRUCTIONS.md and project-instructions/ material as deprecated reference only. - Added EOD main lock, next-day reset, and team branch creation gate governance. -- Updated active team start and governance docs to reference only `docs_build/dev/ProjectInstructions/`. -- No product/runtime, `start_of_day`, feature, or legacy SQLite file changes were made. +- Added explicit START RULE, WORK RULE, and END RULE branch lifecycle governance. +- Updated active team start and Codex workflow docs under docs_build/dev/ProjectInstructions/. +- No product/runtime, start_of_day, feature, or legacy SQLite file changes were made. ## Validation - PASS: targeted grep found no active duplicate ProjectInstructions source-of-truth claim outside the active source. - PASS: targeted grep confirmed EOD/Next Day governance appears in active governance docs. -- PASS: product/runtime and `start_of_day` changed-file check returned no files. -- PASS: `git diff --check`. +- PASS: targeted grep confirmed START / WORK / END branch lifecycle governance appears in active governance docs. +- PASS: product/runtime and start_of_day changed-file check returned no files. +- PASS: git diff --check. ## Artifact -- `tmp/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_delta.zip` +- tmp/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_delta.zip diff --git a/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_branch-validation.md b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_branch-validation.md index 17e0bfc39..b54d77ced 100644 --- a/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_branch-validation.md +++ b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_branch-validation.md @@ -1,7 +1,6 @@ # PR_26177_OWNER_007-project-instructions-single-source-eod-lock Branch Validation -- PASS: Started from `main`. -- PASS: Start gate confirmed worktree clean before branch creation. -- PASS: Start gate confirmed `main...origin/main` was `0 0` before branch creation. -- PASS: Current branch is `PR_26177_OWNER_007-project-instructions-single-source-eod-lock`. -- PASS: No `.vscode/settings.json` change is staged or included. +- PASS: Current branch is PR_26177_OWNER_007-project-instructions-single-source-eod-lock. +- PASS: Work remained on the PR branch during implementation. +- PASS: No commit was made on main. +- PASS: No .vscode/settings.json change is staged or included. diff --git a/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_manual-validation-notes.md b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_manual-validation-notes.md index 10cbb4170..5d9f186fa 100644 --- a/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_manual-validation-notes.md +++ b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_manual-validation-notes.md @@ -1,8 +1,9 @@ # PR_26177_OWNER_007-project-instructions-single-source-eod-lock Manual Validation Notes -- Reviewed ProjectInstructions path and text references. -- Confirmed active source declarations live under `docs_build/dev/ProjectInstructions/`. -- Confirmed legacy locations are preserved as deprecated reference material rather than active sources. -- Confirmed `docs_build/dev/start_of_day/` was not modified. +- Reviewed active ProjectInstructions branch lifecycle wording. +- Confirmed START RULE, WORK RULE, and END RULE are documented in active governance docs. +- Confirmed active source declarations live under docs_build/dev/ProjectInstructions/. +- Confirmed legacy locations remain deprecated reference material rather than active sources. +- Confirmed docs_build/dev/start_of_day/ was not modified. - Confirmed no product/runtime files were modified. -- Confirmed ZIP artifact path: `tmp/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_delta.zip`. +- Confirmed ZIP artifact path: tmp/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_delta.zip. diff --git a/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_requirement-checklist.md b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_requirement-checklist.md index 99ab45345..c3c7e7c53 100644 --- a/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_requirement-checklist.md +++ b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_requirement-checklist.md @@ -1,16 +1,20 @@ # PR_26177_OWNER_007-project-instructions-single-source-eod-lock Requirement Checklist - PASS: Audited repo for ProjectInstructions / project instructions duplicates. -- PASS: Active source is `docs_build/dev/ProjectInstructions/`. -- PASS: Legacy `docs_build/dev/PROJECT_INSTRUCTIONS.md` is marked deprecated. -- PASS: Legacy root `project-instructions/` folder is marked deprecated. +- PASS: Active source is docs_build/dev/ProjectInstructions/. +- PASS: Legacy docs_build/dev/PROJECT_INSTRUCTIONS.md is marked deprecated. +- PASS: Legacy root project-instructions/ folder is marked deprecated. - PASS: Legacy root addendums are migrated into the active addendum tree. -- PASS: Active team start/governance docs reference only `docs_build/dev/ProjectInstructions/`. +- PASS: Active team start/governance docs reference only docs_build/dev/ProjectInstructions/. - PASS: Added EOD command sequence. -- PASS: Added required EOD output: `On branch main`, clean worktree, `0 0`. +- PASS: Added required EOD output: On branch main, clean worktree, 0 0. - PASS: Added Next Day Start command sequence. -- PASS: Added team branch creation rule requiring main, clean worktree, `0 0`, and matching published EOD SHA. -- PASS: Did not modify `start_of_day` folders. +- PASS: Added team branch creation rule requiring main, clean worktree, 0 0, and matching published EOD SHA. +- PASS: Added START RULE with main clean/synced/EOD SHA gate and no commits on main. +- PASS: Added WORK RULE requiring Codex to remain, commit, and push only on the PR branch. +- PASS: Added hard stops for unexpected branch changes and current branch main before commit. +- PASS: Added END RULE requiring PR branch push, merge to main, main checkout/fetch/pull, clean 0 0 confirmation, and EOD SHA recording. +- PASS: Did not modify start_of_day folders. - PASS: Did not modify product/runtime files. - PASS: Did not remove, move, or overwrite legacy SQLite files. - PASS: Did not start feature work. diff --git a/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_validation-lane.md b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_validation-lane.md index 8a1b82360..6e30ad6f6 100644 --- a/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_validation-lane.md +++ b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_validation-lane.md @@ -2,6 +2,7 @@ - PASS: duplicate-source grep returned no matches for old active source claims. - PASS: EOD/Next Day governance grep returned active governance matches. +- PASS: branch lifecycle grep returned active START / WORK / END governance matches. - PASS: product/runtime/start_of_day changed-file check returned no files. - PASS: git diff --check. @@ -9,6 +10,7 @@ Commands used: ~~~text rg -n 'project-instructions/addendums|docs_build/dev/PROJECT_INSTRUCTIONS.md.*source of truth|Codex must always read `docs_build/dev/PROJECT_INSTRUCTIONS.md`|Read `docs_build/dev/PROJECT_INSTRUCTIONS.md`' docs_build/dev/ProjectInstructions docs_build/dev/PROJECT_INSTRUCTIONS.md project-instructions +rg -n 'START RULE|WORK RULE|END RULE|HARD STOP before committing|Codex commits only to the PR branch|Codex pushes only the PR branch|HEAD SHA recorded as new EOD baseline|No commits are allowed on `main`' docs_build/dev/ProjectInstructions rg -n "End of Day:|Next Day Start:|HEAD.*published EOD SHA|only active Project Instructions source" docs_build/dev/ProjectInstructions git diff --name-only -- src assets toolbox games api serverside package.json package-lock.json docs_build/dev/start_of_day git diff --check diff --git a/docs_build/dev/reports/codex_review.diff b/docs_build/dev/reports/codex_review.diff index 53132b823..ca20f9cf5 100644 --- a/docs_build/dev/reports/codex_review.diff +++ b/docs_build/dev/reports/codex_review.diff @@ -1,5 +1,5 @@ diff --git a/docs_build/dev/BUILD_PR.md b/docs_build/dev/BUILD_PR.md -index 30700e9cd..50b1b27fa 100644 +index 30700e9cd..fbff4d261 100644 --- a/docs_build/dev/BUILD_PR.md +++ b/docs_build/dev/BUILD_PR.md @@ -1,66 +1,52 @@ @@ -32,7 +32,7 @@ index 30700e9cd..50b1b27fa 100644 +- Establish `docs_build/dev/ProjectInstructions/` as the only active source. +- Mark all other ProjectInstructions-style sources changed by this PR as deprecated references. +- Update active team start/governance docs to reference only `docs_build/dev/ProjectInstructions/`. -+- Add EOD main lock and next-day reset governance. ++- Add EOD main lock, next-day reset governance, and explicit START / WORK / END branch lifecycle rules. +- Add required reports under `docs_build/dev/reports/`. ## Exact Targets @@ -83,7 +83,7 @@ index 30700e9cd..50b1b27fa 100644 -node --check src/shared/time/time.js -node --check tests/shared/TimeFoundation.test.mjs +rg -n 'project-instructions/addendums|docs_build/dev/PROJECT_INSTRUCTIONS.md.*source of truth|Codex must always read `docs_build/dev/PROJECT_INSTRUCTIONS.md`|Read `docs_build/dev/PROJECT_INSTRUCTIONS.md`' docs_build/dev/ProjectInstructions docs_build/dev/PROJECT_INSTRUCTIONS.md project-instructions -+rg -n "End of Day:|Next Day Start:|HEAD.*published EOD SHA|only active Project Instructions source" docs_build/dev/ProjectInstructions ++rg -n "START RULE|WORK RULE|END RULE|HARD STOP before committing|Codex commits only to the PR branch|HEAD SHA recorded as new EOD baseline|End of Day:|Next Day Start:|HEAD.*published EOD SHA|only active Project Instructions source" docs_build/dev/ProjectInstructions +git diff --name-only -- src assets toolbox games api serverside package.json package-lock.json docs_build/dev/start_of_day git diff --check ``` @@ -96,7 +96,7 @@ index 30700e9cd..50b1b27fa 100644 -tmp/PR_26177_006-shared-time-foundation_delta.zip -``` diff --git a/docs_build/dev/PLAN_PR.md b/docs_build/dev/PLAN_PR.md -index 907936aee..39fa03385 100644 +index 907936aee..505e274bd 100644 --- a/docs_build/dev/PLAN_PR.md +++ b/docs_build/dev/PLAN_PR.md @@ -1,22 +1,28 @@ @@ -121,7 +121,7 @@ index 907936aee..39fa03385 100644 +- Mark legacy ProjectInstructions-style sources as deprecated reference material. +- Move active legacy addendums into `docs_build/dev/ProjectInstructions/addendums/`. +- Update active team start and governance docs to reference only `docs_build/dev/ProjectInstructions/`. -+- Add EOD main lock, next-day reset, and team PR branch creation gate. ++- Add EOD main lock, next-day reset, team PR branch creation gate, and explicit START / WORK / END branch lifecycle rules. +- Add required Codex reports under `docs_build/dev/reports/`. -## Implementation Plan @@ -139,7 +139,7 @@ index 907936aee..39fa03385 100644 +## Validation Plan + +1. Run targeted grep/search proving no active duplicate ProjectInstructions source remains. -+2. Confirm EOD/Next Day rule appears in active governance docs. ++2. Confirm EOD/Next Day and START / WORK / END branch lifecycle rules appear in active governance docs. +3. Confirm no product/runtime files changed. +4. Run `git diff --check`. diff --git a/docs_build/dev/PROJECT_INSTRUCTIONS.md b/docs_build/dev/PROJECT_INSTRUCTIONS.md @@ -280,10 +280,10 @@ index a48becf05..631fd3918 100644 - Environment Governance Model: docs_build/dev/ProjectInstructions/addendums/environment_governance_model.md - Environment Configuration Standards: docs_build/dev/ProjectInstructions/addendums/environment_configuration_standards.md diff --git a/docs_build/dev/ProjectInstructions/TEAM_START_COMMANDS.md b/docs_build/dev/ProjectInstructions/TEAM_START_COMMANDS.md -index d0118f63a..c446a4b33 100644 +index d0118f63a..192278a34 100644 --- a/docs_build/dev/ProjectInstructions/TEAM_START_COMMANDS.md +++ b/docs_build/dev/ProjectInstructions/TEAM_START_COMMANDS.md -@@ -1,5 +1,16 @@ +@@ -1,5 +1,42 @@ # TEAM_START_COMMANDS +## Required Main Reset Gate For Every Team @@ -296,11 +296,37 @@ index d0118f63a..c446a4b33 100644 +- `HEAD` SHA matches the published EOD SHA + +Use `docs_build/dev/ProjectInstructions/` as the only active Project Instructions source. ++ ++START RULE: ++- Every team starts on `main`. ++- `main` must be clean. ++- `main...origin/main` must be `0 0`. ++- `HEAD` SHA must match published EOD SHA. ++- Only then create or switch to the PR branch. ++- No commits are allowed on `main`. ++ ++WORK RULE: ++- Codex must remain on the PR branch during implementation. ++- Codex commits only to the PR branch. ++- Codex pushes only the PR branch. ++- HARD STOP if branch changes unexpectedly. ++- HARD STOP before committing if current branch is `main`. ++ ++END RULE: ++- After PR validation, push the PR branch. ++- Merge PR into `main` only when approved. ++- Checkout `main`. ++- Run `git fetch origin`. ++- Run `git pull --ff-only origin main`. ++- Confirm current branch is `main`. ++- Confirm worktree is clean. ++- Confirm `main...origin/main` is `0 0`. ++- Record `HEAD` SHA as new EOD baseline. + ## Start Team Alfa Ready-to-copy command: -@@ -123,4 +134,24 @@ Merge to main is EOD-only and owner-approved, unless the owner explicitly says: +@@ -123,4 +160,24 @@ Merge to main is EOD-only and owner-approved, unless the owner explicitly says: "Merge this PR now." Do not treat sequential PR completion as merge approval. @@ -325,268 +351,6 @@ index d0118f63a..c446a4b33 100644 +git rev-list --left-right --count main...origin/main +git rev-parse HEAD ``` -diff --git a/docs_build/dev/ProjectInstructions/addendums/branch_lock_governance.md b/docs_build/dev/ProjectInstructions/addendums/branch_lock_governance.md -index 518f8c943..d6c8e4cf7 100644 ---- a/docs_build/dev/ProjectInstructions/addendums/branch_lock_governance.md -+++ b/docs_build/dev/ProjectInstructions/addendums/branch_lock_governance.md -@@ -23,6 +23,7 @@ Keep active work attached to the correct assigned team, branch, and OWNER decisi - - - Start from current `main`. - - Pull latest `origin/main` before creating a work branch. -+- Do not create a PR branch unless current branch is `main`, worktree is clean, `main...origin/main` is `0 0`, and `HEAD` SHA matches the published EOD SHA. - - Keep work on the active branch until the PR is merged, the branch is retired, or OWNER says to return to `main`. - - Do not commit directly to `main` unless OWNER explicitly approves. - - Do not merge stale historical branches directly unless they are current, clean, still needed, and OWNER-approved. -@@ -54,3 +55,36 @@ Protected guidance includes: - - Governance Phase 1 completion guidance - - If protected guidance must change, OWNER approval is required. -+ -+## End Of Day Main Lock -+ -+End of Day: -+ -+```text -+git checkout main -+git fetch origin -+git pull --ff-only origin main -+git status -+git rev-list --left-right --count main...origin/main -+``` -+ -+Required: -+ -+```text -+On branch main -+nothing to commit, working tree clean -+0 0 -+``` -+ -+Next Day Start: -+ -+```text -+git checkout main -+git fetch origin -+git pull --ff-only origin main -+git status -+git rev-list --left-right --count main...origin/main -+git rev-parse HEAD -+``` -+ -+The next-day `HEAD` SHA must match the published EOD SHA before any team creates a PR branch. -diff --git a/docs_build/dev/ProjectInstructions/addendums/pr_workflow.md b/docs_build/dev/ProjectInstructions/addendums/pr_workflow.md -index f8a4acb6e..7c1cd8275 100644 ---- a/docs_build/dev/ProjectInstructions/addendums/pr_workflow.md -+++ b/docs_build/dev/ProjectInstructions/addendums/pr_workflow.md -@@ -129,3 +129,40 @@ Stop only for: - - Merge conflict - - Validation failure - - OWNER decision -+ -+## EOD Main Lock -+ -+End of Day: -+ -+```text -+git checkout main -+git fetch origin -+git pull --ff-only origin main -+git status -+git rev-list --left-right --count main...origin/main -+``` -+ -+Required: -+ -+```text -+On branch main -+nothing to commit, working tree clean -+0 0 -+``` -+ -+## Next Day Start -+ -+```text -+git checkout main -+git fetch origin -+git pull --ff-only origin main -+git status -+git rev-list --left-right --count main...origin/main -+git rev-parse HEAD -+``` -+ -+No team creates a PR branch until: -+- Current branch: `main` -+- Worktree: clean -+- `main...origin/main`: `0 0` -+- `HEAD` SHA matches published EOD SHA -diff --git a/docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md b/docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md -index 9735b4bd4..9a104b4f9 100644 ---- a/docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md -+++ b/docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md -@@ -211,3 +211,44 @@ Commit/push during the day is allowed only on assigned team/OWNER/PR branches. - - Merge to main is EOD-only and owner-approved, unless the owner explicitly says: - "Merge this PR now." -+ -+## EOD Main Lock And Next Day Reset -+ -+End of Day: -+ -+```text -+git checkout main -+git fetch origin -+git pull --ff-only origin main -+git status -+git rev-list --left-right --count main...origin/main -+``` -+ -+Required: -+ -+```text -+On branch main -+nothing to commit, working tree clean -+0 0 -+``` -+ -+Next Day Start: -+ -+```text -+git checkout main -+git fetch origin -+git pull --ff-only origin main -+git status -+git rev-list --left-right --count main...origin/main -+git rev-parse HEAD -+``` -+ -+Team rule: -+No team creates a PR branch until: -+- Current branch: `main` -+- Worktree: clean -+- `main...origin/main`: `0 0` -+- `HEAD` SHA matches published EOD SHA -+ -+Active source rule: -+Teams must use only `docs_build/dev/ProjectInstructions/` as the active Project Instructions source. -diff --git a/docs_build/dev/reports/codex_changed_files.txt b/docs_build/dev/reports/codex_changed_files.txt -index 8e34972a1..85beb7824 100644 ---- a/docs_build/dev/reports/codex_changed_files.txt -+++ b/docs_build/dev/reports/codex_changed_files.txt -@@ -1,14 +1,30 @@ --docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_branch-validation.md --docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_manual-validation-notes.md --docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_report.md --docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_requirement-checklist.md --docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_validation-lane.md -+docs_build/dev/BUILD_PR.md -+docs_build/dev/PLAN_PR.md -+docs_build/dev/PROJECT_INSTRUCTIONS.md -+docs_build/dev/ProjectInstructions/PROJECT_INSTRUCTIONS.md -+docs_build/dev/ProjectInstructions/README.txt -+docs_build/dev/ProjectInstructions/TEAM_START_COMMANDS.md -+docs_build/dev/ProjectInstructions/addendums/assistant_execution_modes.md -+docs_build/dev/ProjectInstructions/addendums/branch_lock_governance.md -+docs_build/dev/ProjectInstructions/addendums/canonical_repository_structure.md -+docs_build/dev/ProjectInstructions/addendums/codex_artifact_and_reporting_standard.md -+docs_build/dev/ProjectInstructions/addendums/codex_project_instructions_startup.md -+docs_build/dev/ProjectInstructions/addendums/legacy_migration_policy.md -+docs_build/dev/ProjectInstructions/addendums/pr_workflow.md -+docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md -+docs_build/dev/ProjectInstructions/addendums/test_structure_standardization.md -+docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md -+docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock.md -+docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_branch-validation.md -+docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_manual-validation-notes.md -+docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_requirement-checklist.md -+docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_validation-lane.md - docs_build/dev/reports/codex_changed_files.txt - docs_build/dev/reports/codex_review.diff --src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs --src/dev-runtime/persistence/tool-repositories/game-journey-mock-repository.js --src/dev-runtime/server/local-api-router.mjs --tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs --tests/helpers/playwrightRepoServer.mjs --tests/playwright/tools/GameJourneyTool.spec.mjs --tests/playwright/tools/IdeaBoardTableNotes.spec.mjs -+project-instructions/README.md -+project-instructions/addendums/assistant-execution-modes.md -+project-instructions/addendums/canonical-repository-structure.md -+project-instructions/addendums/codex-artifact-and-reporting-standard.md -+project-instructions/addendums/codex-project-instructions-startup.md -+project-instructions/addendums/legacy-migration-policy.md -+project-instructions/addendums/test-structure-standardization.md -diff --git a/project-instructions/addendums/assistant-execution-modes.md b/project-instructions/addendums/assistant-execution-modes.md -index 6d7928669..4c5637d0d 100644 ---- a/project-instructions/addendums/assistant-execution-modes.md -+++ b/project-instructions/addendums/assistant-execution-modes.md -@@ -1,5 +1,7 @@ - # Assistant Execution Modes - -+> Deprecated reference notice: this file is preserved for history only. The active copy is `docs_build/dev/ProjectInstructions/addendums/assistant_execution_modes.md`. -+ - ## Purpose - - Standardize request interpretation and expected outputs for Review, Owner, Build PR, Continue, Challenge, and Stop Gate workflows. -diff --git a/project-instructions/addendums/canonical-repository-structure.md b/project-instructions/addendums/canonical-repository-structure.md -index e26939469..6b9dcb242 100644 ---- a/project-instructions/addendums/canonical-repository-structure.md -+++ b/project-instructions/addendums/canonical-repository-structure.md -@@ -1,5 +1,7 @@ - # Canonical Repository Structure - -+> Deprecated reference notice: this file is preserved for history only. The active copy is `docs_build/dev/ProjectInstructions/addendums/canonical_repository_structure.md`. -+ - ## Purpose - - Establish the canonical repository structure for future development and reduce technical debt. -diff --git a/project-instructions/addendums/codex-artifact-and-reporting-standard.md b/project-instructions/addendums/codex-artifact-and-reporting-standard.md -index 3f16a3641..8d1327886 100644 ---- a/project-instructions/addendums/codex-artifact-and-reporting-standard.md -+++ b/project-instructions/addendums/codex-artifact-and-reporting-standard.md -@@ -1,5 +1,7 @@ - # Codex Artifact and Reporting Standard - -+> Deprecated reference notice: this file is preserved for history only. The active copy is `docs_build/dev/ProjectInstructions/addendums/codex_artifact_and_reporting_standard.md`. -+ - ## Purpose - - Standardize Codex deliverables, completion reporting, and artifact generation. -diff --git a/project-instructions/addendums/codex-project-instructions-startup.md b/project-instructions/addendums/codex-project-instructions-startup.md -index 94744f06e..135498b42 100644 ---- a/project-instructions/addendums/codex-project-instructions-startup.md -+++ b/project-instructions/addendums/codex-project-instructions-startup.md -@@ -1,5 +1,7 @@ - # Codex Project Instructions Startup - -+> Deprecated reference notice: this file is preserved for history only. The active copy is `docs_build/dev/ProjectInstructions/addendums/codex_project_instructions_startup.md`. -+ - ## Purpose - - Ensure Codex uses the current approved governance before making repository changes. -diff --git a/project-instructions/addendums/legacy-migration-policy.md b/project-instructions/addendums/legacy-migration-policy.md -index 5e43679f4..5515a1728 100644 ---- a/project-instructions/addendums/legacy-migration-policy.md -+++ b/project-instructions/addendums/legacy-migration-policy.md -@@ -1,5 +1,7 @@ - # Legacy Migration Policy - -+> Deprecated reference notice: this file is preserved for history only. The active copy is `docs_build/dev/ProjectInstructions/addendums/legacy_migration_policy.md`. -+ - ## Purpose - - Reduce technical debt incrementally during normal development. -diff --git a/project-instructions/addendums/test-structure-standardization.md b/project-instructions/addendums/test-structure-standardization.md -index 997b16730..eeb62d561 100644 ---- a/project-instructions/addendums/test-structure-standardization.md -+++ b/project-instructions/addendums/test-structure-standardization.md -@@ -1,5 +1,7 @@ - # Test Structure Standardization - -+> Deprecated reference notice: this file is preserved for history only. The active copy is `docs_build/dev/ProjectInstructions/addendums/test_structure_standardization.md`. -+ - ## Purpose - - Standardize testing locations and ensure independent tool validation. diff --git a/docs_build/dev/ProjectInstructions/addendums/assistant_execution_modes.md b/docs_build/dev/ProjectInstructions/addendums/assistant_execution_modes.md new file mode 100644 index 000000000..6d7928669 @@ -708,11 +472,100 @@ index 000000000..6d7928669 + +### Done for the day + -+Meaning: -+- Finish commits -+- Merge -+- Push -+- Create next-day start document ++Meaning: ++- Finish commits ++- Merge ++- Push ++- Create next-day start document +diff --git a/docs_build/dev/ProjectInstructions/addendums/branch_lock_governance.md b/docs_build/dev/ProjectInstructions/addendums/branch_lock_governance.md +index 518f8c943..e6ab30ae8 100644 +--- a/docs_build/dev/ProjectInstructions/addendums/branch_lock_governance.md ++++ b/docs_build/dev/ProjectInstructions/addendums/branch_lock_governance.md +@@ -23,12 +23,46 @@ Keep active work attached to the correct assigned team, branch, and OWNER decisi + + - Start from current `main`. + - Pull latest `origin/main` before creating a work branch. ++- Do not create a PR branch unless current branch is `main`, worktree is clean, `main...origin/main` is `0 0`, and `HEAD` SHA matches the published EOD SHA. + - Keep work on the active branch until the PR is merged, the branch is retired, or OWNER says to return to `main`. +-- Do not commit directly to `main` unless OWNER explicitly approves. ++- Do not commit directly to `main`. ++- HARD STOP before committing if current branch is `main`. ++- HARD STOP if the branch changes unexpectedly during implementation. ++- Commit only to the PR branch. ++- Push only the PR branch. + - Do not merge stale historical branches directly unless they are current, clean, still needed, and OWNER-approved. + - Retain source branches by default after merge and closeout. + - Record branch disposition before Closed as `retained`. + ++## START RULE ++ ++- Every team starts on `main`. ++- `main` must be clean. ++- `main...origin/main` must be `0 0`. ++- `HEAD` SHA must match published EOD SHA. ++- Only then create or switch to the PR branch. ++- No commits are allowed on `main`. ++ ++## WORK RULE ++ ++- Codex must remain on the PR branch during implementation. ++- Codex commits only to the PR branch. ++- Codex pushes only the PR branch. ++- HARD STOP if branch changes unexpectedly. ++- HARD STOP before committing if current branch is `main`. ++ ++## END RULE ++ ++- After PR validation, push the PR branch. ++- Merge PR into `main` only when approved. ++- Checkout `main`. ++- Run `git fetch origin`. ++- Run `git pull --ff-only origin main`. ++- Confirm current branch is `main`. ++- Confirm worktree is clean. ++- Confirm `main...origin/main` is `0 0`. ++- Record `HEAD` SHA as new EOD baseline. ++ + ## OWNER Override + + OWNER may override a branch lock or team assignment. +@@ -54,3 +88,36 @@ Protected guidance includes: + - Governance Phase 1 completion guidance + + If protected guidance must change, OWNER approval is required. ++ ++## End Of Day Main Lock ++ ++End of Day: ++ ++```text ++git checkout main ++git fetch origin ++git pull --ff-only origin main ++git status ++git rev-list --left-right --count main...origin/main ++``` ++ ++Required: ++ ++```text ++On branch main ++nothing to commit, working tree clean ++0 0 ++``` ++ ++Next Day Start: ++ ++```text ++git checkout main ++git fetch origin ++git pull --ff-only origin main ++git status ++git rev-list --left-right --count main...origin/main ++git rev-parse HEAD ++``` ++ ++The next-day `HEAD` SHA must match the published EOD SHA before any team creates a PR branch. diff --git a/docs_build/dev/ProjectInstructions/addendums/canonical_repository_structure.md b/docs_build/dev/ProjectInstructions/addendums/canonical_repository_structure.md new file mode 100644 index 000000000..e26939469 @@ -832,10 +685,10 @@ index 000000000..498e3895e +A task is not considered complete until the ZIP artifact is generated and reported. diff --git a/docs_build/dev/ProjectInstructions/addendums/codex_project_instructions_startup.md b/docs_build/dev/ProjectInstructions/addendums/codex_project_instructions_startup.md new file mode 100644 -index 000000000..e0abb9db0 +index 000000000..dba8f8d93 --- /dev/null +++ b/docs_build/dev/ProjectInstructions/addendums/codex_project_instructions_startup.md -@@ -0,0 +1,65 @@ +@@ -0,0 +1,93 @@ +# Codex Project Instructions Startup + +## Purpose @@ -859,6 +712,34 @@ index 000000000..e0abb9db0 +- Execution modes +- Artifact requirements + ++## Branch Lifecycle Start Gate ++ ++START RULE: ++- Every team starts on `main`. ++- `main` must be clean. ++- `main...origin/main` must be `0 0`. ++- `HEAD` SHA must match published EOD SHA. ++- Only then create or switch to the PR branch. ++- No commits are allowed on `main`. ++ ++WORK RULE: ++- Codex must remain on the PR branch during implementation. ++- Codex commits only to the PR branch. ++- Codex pushes only the PR branch. ++- HARD STOP if branch changes unexpectedly. ++- HARD STOP before committing if current branch is `main`. ++ ++END RULE: ++- After PR validation, push the PR branch. ++- Merge PR into `main` only when approved. ++- Checkout `main`. ++- Run `git fetch origin`. ++- Run `git pull --ff-only origin main`. ++- Confirm current branch is `main`. ++- Confirm worktree is clean. ++- Confirm `main...origin/main` is `0 0`. ++- Record `HEAD` SHA as new EOD baseline. ++ +Deprecated Project Instructions material outside `docs_build/dev/ProjectInstructions/` is reference-only and must not override active governance. + +## Project Reference File Review @@ -940,12 +821,95 @@ index 000000000..5e43679f4 +- No new scattered JS locations. +- No new scattered CSS locations. +- No new scattered test locations. +diff --git a/docs_build/dev/ProjectInstructions/addendums/pr_workflow.md b/docs_build/dev/ProjectInstructions/addendums/pr_workflow.md +index f8a4acb6e..abad0b789 100644 +--- a/docs_build/dev/ProjectInstructions/addendums/pr_workflow.md ++++ b/docs_build/dev/ProjectInstructions/addendums/pr_workflow.md +@@ -26,6 +26,37 @@ Define the standard pull request workflow for Game Foundry Studio. + 15. Pull latest main before starting the next PR. + 16. Verify Main Verified and Closed gates. + ++## Branch Lifecycle Governance ++ ++### START RULE ++ ++- Every team starts on `main`. ++- `main` must be clean. ++- `main...origin/main` must be `0 0`. ++- `HEAD` SHA must match published EOD SHA. ++- Only then create or switch to the PR branch. ++- No commits are allowed on `main`. ++ ++### WORK RULE ++ ++- Codex must remain on the PR branch during implementation. ++- Codex commits only to the PR branch. ++- Codex pushes only the PR branch. ++- HARD STOP if branch changes unexpectedly. ++- HARD STOP before committing if current branch is `main`. ++ ++### END RULE ++ ++- After PR validation, push the PR branch. ++- Merge PR into `main` only when approved. ++- Checkout `main`. ++- Run `git fetch origin`. ++- Run `git pull --ff-only origin main`. ++- Confirm current branch is `main`. ++- Confirm worktree is clean. ++- Confirm `main...origin/main` is `0 0`. ++- Record `HEAD` SHA as new EOD baseline. ++ + ## PR Lifecycle States + + Required state order: +@@ -129,3 +160,40 @@ Stop only for: + - Merge conflict + - Validation failure + - OWNER decision ++ ++## EOD Main Lock ++ ++End of Day: ++ ++```text ++git checkout main ++git fetch origin ++git pull --ff-only origin main ++git status ++git rev-list --left-right --count main...origin/main ++``` ++ ++Required: ++ ++```text ++On branch main ++nothing to commit, working tree clean ++0 0 ++``` ++ ++## Next Day Start ++ ++```text ++git checkout main ++git fetch origin ++git pull --ff-only origin main ++git status ++git rev-list --left-right --count main...origin/main ++git rev-parse HEAD ++``` ++ ++No team creates a PR branch until: ++- Current branch: `main` ++- Worktree: clean ++- `main...origin/main`: `0 0` ++- `HEAD` SHA matches published EOD SHA diff --git a/docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md b/docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md new file mode 100644 -index 000000000..9ea3824e0 +index 000000000..c41dc503d --- /dev/null +++ b/docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md -@@ -0,0 +1,61 @@ +@@ -0,0 +1,92 @@ +# Project Instructions Single Source And EOD Main Lock + +Status: Approved @@ -1004,6 +968,37 @@ index 000000000..9ea3824e0 + +If any check fails, stop before branch creation and restore main to the published EOD state or request OWNER direction. + ++## Branch Lifecycle Governance ++ ++### START RULE ++ ++- Every team starts on `main`. ++- `main` must be clean. ++- `main...origin/main` must be `0 0`. ++- `HEAD` SHA must match published EOD SHA. ++- Only then create or switch to the PR branch. ++- No commits are allowed on `main`. ++ ++### WORK RULE ++ ++- Codex must remain on the PR branch during implementation. ++- Codex commits only to the PR branch. ++- Codex pushes only the PR branch. ++- HARD STOP if branch changes unexpectedly. ++- HARD STOP before committing if current branch is `main`. ++ ++### END RULE ++ ++- After PR validation, push the PR branch. ++- Merge PR into `main` only when approved. ++- Checkout `main`. ++- Run `git fetch origin`. ++- Run `git pull --ff-only origin main`. ++- Confirm current branch is `main`. ++- Confirm worktree is clean. ++- Confirm `main...origin/main` is `0 0`. ++- Record `HEAD` SHA as new EOD baseline. ++ +## Start Of Day Boundary + +`docs_build/dev/start_of_day/` may point to `docs_build/dev/ProjectInstructions/`, but it must not become a second active Project Instructions source. @@ -1046,96 +1041,180 @@ index 000000000..997b16730 +- Tool tests validate tool functionality. +- Regression tests validate platform behavior. +- New tests follow the canonical structure. +diff --git a/docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md b/docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md +index 9735b4bd4..f70440ad2 100644 +--- a/docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md ++++ b/docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md +@@ -211,3 +211,72 @@ Commit/push during the day is allowed only on assigned team/OWNER/PR branches. + + Merge to main is EOD-only and owner-approved, unless the owner explicitly says: + "Merge this PR now." ++ ++## EOD Main Lock And Next Day Reset ++ ++End of Day: ++ ++```text ++git checkout main ++git fetch origin ++git pull --ff-only origin main ++git status ++git rev-list --left-right --count main...origin/main ++``` ++ ++Required: ++ ++```text ++On branch main ++nothing to commit, working tree clean ++0 0 ++``` ++ ++Next Day Start: ++ ++```text ++git checkout main ++git fetch origin ++git pull --ff-only origin main ++git status ++git rev-list --left-right --count main...origin/main ++git rev-parse HEAD ++``` ++ ++Team rule: ++No team creates a PR branch until: ++- Current branch: `main` ++- Worktree: clean ++- `main...origin/main`: `0 0` ++- `HEAD` SHA matches published EOD SHA ++ ++Active source rule: ++Teams must use only `docs_build/dev/ProjectInstructions/` as the active Project Instructions source. ++ ++## Explicit Branch Lifecycle Governance ++ ++START RULE: ++- Every team starts on `main`. ++- `main` must be clean. ++- `main...origin/main` must be `0 0`. ++- `HEAD` SHA must match published EOD SHA. ++- Only then create or switch to the PR branch. ++- No commits are allowed on `main`. ++ ++WORK RULE: ++- Codex must remain on the PR branch during implementation. ++- Codex commits only to the PR branch. ++- Codex pushes only the PR branch. ++- HARD STOP if branch changes unexpectedly. ++- HARD STOP before committing if current branch is `main`. ++ ++END RULE: ++- After PR validation, push the PR branch. ++- Merge PR into `main` only when approved. ++- Checkout `main`. ++- Run `git fetch origin`. ++- Run `git pull --ff-only origin main`. ++- Confirm current branch is `main`. ++- Confirm worktree is clean. ++- Confirm `main...origin/main` is `0 0`. ++- Record `HEAD` SHA as new EOD baseline. diff --git a/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock.md b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock.md new file mode 100644 -index 000000000..5c7927f17 +index 000000000..ed2f3e94a --- /dev/null +++ b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock.md -@@ -0,0 +1,25 @@ +@@ -0,0 +1,27 @@ +# PR_26177_OWNER_007-project-instructions-single-source-eod-lock + +Date: 2026-06-26 -+Scope: Project Instructions single-source and EOD main lock governance ++Scope: Project Instructions single-source, EOD main lock, and branch lifecycle governance +Status: PASS + +## Summary + -+- Established `docs_build/dev/ProjectInstructions/` as the only active Project Instructions source. -+- Migrated legacy root `project-instructions/addendums/` content into active `docs_build/dev/ProjectInstructions/addendums/` files. -+- Marked legacy `docs_build/dev/PROJECT_INSTRUCTIONS.md` and `project-instructions/` material as deprecated reference only. ++- Established docs_build/dev/ProjectInstructions/ as the only active Project Instructions source. ++- Migrated legacy root project-instructions/addendums/ content into active docs_build/dev/ProjectInstructions/addendums/ files. ++- Marked legacy docs_build/dev/PROJECT_INSTRUCTIONS.md and project-instructions/ material as deprecated reference only. +- Added EOD main lock, next-day reset, and team branch creation gate governance. -+- Updated active team start and governance docs to reference only `docs_build/dev/ProjectInstructions/`. -+- No product/runtime, `start_of_day`, feature, or legacy SQLite file changes were made. ++- Added explicit START RULE, WORK RULE, and END RULE branch lifecycle governance. ++- Updated active team start and Codex workflow docs under docs_build/dev/ProjectInstructions/. ++- No product/runtime, start_of_day, feature, or legacy SQLite file changes were made. + +## Validation + +- PASS: targeted grep found no active duplicate ProjectInstructions source-of-truth claim outside the active source. +- PASS: targeted grep confirmed EOD/Next Day governance appears in active governance docs. -+- PASS: product/runtime and `start_of_day` changed-file check returned no files. -+- PASS: `git diff --check`. ++- PASS: targeted grep confirmed START / WORK / END branch lifecycle governance appears in active governance docs. ++- PASS: product/runtime and start_of_day changed-file check returned no files. ++- PASS: git diff --check. + +## Artifact + -+- `tmp/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_delta.zip` ++- tmp/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_delta.zip diff --git a/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_branch-validation.md b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_branch-validation.md new file mode 100644 -index 000000000..17e0bfc39 +index 000000000..b54d77ced --- /dev/null +++ b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_branch-validation.md -@@ -0,0 +1,7 @@ +@@ -0,0 +1,6 @@ +# PR_26177_OWNER_007-project-instructions-single-source-eod-lock Branch Validation + -+- PASS: Started from `main`. -+- PASS: Start gate confirmed worktree clean before branch creation. -+- PASS: Start gate confirmed `main...origin/main` was `0 0` before branch creation. -+- PASS: Current branch is `PR_26177_OWNER_007-project-instructions-single-source-eod-lock`. -+- PASS: No `.vscode/settings.json` change is staged or included. ++- PASS: Current branch is PR_26177_OWNER_007-project-instructions-single-source-eod-lock. ++- PASS: Work remained on the PR branch during implementation. ++- PASS: No commit was made on main. ++- PASS: No .vscode/settings.json change is staged or included. diff --git a/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_manual-validation-notes.md b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_manual-validation-notes.md new file mode 100644 -index 000000000..10cbb4170 +index 000000000..5d9f186fa --- /dev/null +++ b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_manual-validation-notes.md -@@ -0,0 +1,8 @@ +@@ -0,0 +1,9 @@ +# PR_26177_OWNER_007-project-instructions-single-source-eod-lock Manual Validation Notes + -+- Reviewed ProjectInstructions path and text references. -+- Confirmed active source declarations live under `docs_build/dev/ProjectInstructions/`. -+- Confirmed legacy locations are preserved as deprecated reference material rather than active sources. -+- Confirmed `docs_build/dev/start_of_day/` was not modified. ++- Reviewed active ProjectInstructions branch lifecycle wording. ++- Confirmed START RULE, WORK RULE, and END RULE are documented in active governance docs. ++- Confirmed active source declarations live under docs_build/dev/ProjectInstructions/. ++- Confirmed legacy locations remain deprecated reference material rather than active sources. ++- Confirmed docs_build/dev/start_of_day/ was not modified. +- Confirmed no product/runtime files were modified. -+- Confirmed ZIP artifact path: `tmp/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_delta.zip`. ++- Confirmed ZIP artifact path: tmp/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_delta.zip. diff --git a/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_requirement-checklist.md b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_requirement-checklist.md new file mode 100644 -index 000000000..99ab45345 +index 000000000..c3c7e7c53 --- /dev/null +++ b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_requirement-checklist.md -@@ -0,0 +1,16 @@ +@@ -0,0 +1,20 @@ +# PR_26177_OWNER_007-project-instructions-single-source-eod-lock Requirement Checklist + +- PASS: Audited repo for ProjectInstructions / project instructions duplicates. -+- PASS: Active source is `docs_build/dev/ProjectInstructions/`. -+- PASS: Legacy `docs_build/dev/PROJECT_INSTRUCTIONS.md` is marked deprecated. -+- PASS: Legacy root `project-instructions/` folder is marked deprecated. ++- PASS: Active source is docs_build/dev/ProjectInstructions/. ++- PASS: Legacy docs_build/dev/PROJECT_INSTRUCTIONS.md is marked deprecated. ++- PASS: Legacy root project-instructions/ folder is marked deprecated. +- PASS: Legacy root addendums are migrated into the active addendum tree. -+- PASS: Active team start/governance docs reference only `docs_build/dev/ProjectInstructions/`. ++- PASS: Active team start/governance docs reference only docs_build/dev/ProjectInstructions/. +- PASS: Added EOD command sequence. -+- PASS: Added required EOD output: `On branch main`, clean worktree, `0 0`. ++- PASS: Added required EOD output: On branch main, clean worktree, 0 0. +- PASS: Added Next Day Start command sequence. -+- PASS: Added team branch creation rule requiring main, clean worktree, `0 0`, and matching published EOD SHA. -+- PASS: Did not modify `start_of_day` folders. ++- PASS: Added team branch creation rule requiring main, clean worktree, 0 0, and matching published EOD SHA. ++- PASS: Added START RULE with main clean/synced/EOD SHA gate and no commits on main. ++- PASS: Added WORK RULE requiring Codex to remain, commit, and push only on the PR branch. ++- PASS: Added hard stops for unexpected branch changes and current branch main before commit. ++- PASS: Added END RULE requiring PR branch push, merge to main, main checkout/fetch/pull, clean 0 0 confirmation, and EOD SHA recording. ++- PASS: Did not modify start_of_day folders. +- PASS: Did not modify product/runtime files. +- PASS: Did not remove, move, or overwrite legacy SQLite files. +- PASS: Did not start feature work. diff --git a/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_validation-lane.md b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_validation-lane.md new file mode 100644 -index 000000000..8a1b82360 +index 000000000..6e30ad6f6 --- /dev/null +++ b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_validation-lane.md -@@ -0,0 +1,17 @@ +@@ -0,0 +1,19 @@ +# PR_26177_OWNER_007-project-instructions-single-source-eod-lock Validation Lane + +- PASS: duplicate-source grep returned no matches for old active source claims. +- PASS: EOD/Next Day governance grep returned active governance matches. ++- PASS: branch lifecycle grep returned active START / WORK / END governance matches. +- PASS: product/runtime/start_of_day changed-file check returned no files. +- PASS: git diff --check. + @@ -1143,12 +1222,1683 @@ index 000000000..8a1b82360 + +~~~text +rg -n 'project-instructions/addendums|docs_build/dev/PROJECT_INSTRUCTIONS.md.*source of truth|Codex must always read `docs_build/dev/PROJECT_INSTRUCTIONS.md`|Read `docs_build/dev/PROJECT_INSTRUCTIONS.md`' docs_build/dev/ProjectInstructions docs_build/dev/PROJECT_INSTRUCTIONS.md project-instructions ++rg -n 'START RULE|WORK RULE|END RULE|HARD STOP before committing|Codex commits only to the PR branch|Codex pushes only the PR branch|HEAD SHA recorded as new EOD baseline|No commits are allowed on `main`' docs_build/dev/ProjectInstructions +rg -n "End of Day:|Next Day Start:|HEAD.*published EOD SHA|only active Project Instructions source" docs_build/dev/ProjectInstructions +git diff --name-only -- src assets toolbox games api serverside package.json package-lock.json docs_build/dev/start_of_day +git diff --check +~~~ + +Full product/runtime tests were not run because this PR changes governance documentation only. +diff --git a/docs_build/dev/reports/codex_changed_files.txt b/docs_build/dev/reports/codex_changed_files.txt +index 8e34972a1..85beb7824 100644 +--- a/docs_build/dev/reports/codex_changed_files.txt ++++ b/docs_build/dev/reports/codex_changed_files.txt +@@ -1,14 +1,30 @@ +-docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_branch-validation.md +-docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_manual-validation-notes.md +-docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_report.md +-docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_requirement-checklist.md +-docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_validation-lane.md ++docs_build/dev/BUILD_PR.md ++docs_build/dev/PLAN_PR.md ++docs_build/dev/PROJECT_INSTRUCTIONS.md ++docs_build/dev/ProjectInstructions/PROJECT_INSTRUCTIONS.md ++docs_build/dev/ProjectInstructions/README.txt ++docs_build/dev/ProjectInstructions/TEAM_START_COMMANDS.md ++docs_build/dev/ProjectInstructions/addendums/assistant_execution_modes.md ++docs_build/dev/ProjectInstructions/addendums/branch_lock_governance.md ++docs_build/dev/ProjectInstructions/addendums/canonical_repository_structure.md ++docs_build/dev/ProjectInstructions/addendums/codex_artifact_and_reporting_standard.md ++docs_build/dev/ProjectInstructions/addendums/codex_project_instructions_startup.md ++docs_build/dev/ProjectInstructions/addendums/legacy_migration_policy.md ++docs_build/dev/ProjectInstructions/addendums/pr_workflow.md ++docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md ++docs_build/dev/ProjectInstructions/addendums/test_structure_standardization.md ++docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md ++docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock.md ++docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_branch-validation.md ++docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_manual-validation-notes.md ++docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_requirement-checklist.md ++docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_validation-lane.md + docs_build/dev/reports/codex_changed_files.txt + docs_build/dev/reports/codex_review.diff +-src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs +-src/dev-runtime/persistence/tool-repositories/game-journey-mock-repository.js +-src/dev-runtime/server/local-api-router.mjs +-tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs +-tests/helpers/playwrightRepoServer.mjs +-tests/playwright/tools/GameJourneyTool.spec.mjs +-tests/playwright/tools/IdeaBoardTableNotes.spec.mjs ++project-instructions/README.md ++project-instructions/addendums/assistant-execution-modes.md ++project-instructions/addendums/canonical-repository-structure.md ++project-instructions/addendums/codex-artifact-and-reporting-standard.md ++project-instructions/addendums/codex-project-instructions-startup.md ++project-instructions/addendums/legacy-migration-policy.md ++project-instructions/addendums/test-structure-standardization.md +diff --git a/docs_build/dev/reports/codex_review.diff b/docs_build/dev/reports/codex_review.diff +index f88731273..53132b823 100644 +--- a/docs_build/dev/reports/codex_review.diff ++++ b/docs_build/dev/reports/codex_review.diff +@@ -1,465 +1,1168 @@ +-diff --git a/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_branch-validation.md b/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_branch-validation.md +-index c5ced6d1b..53bc243c2 100644 +---- a/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_branch-validation.md +-+++ b/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_branch-validation.md +-@@ -17,3 +17,4 @@ Status: PASS +- - PASS: Tests are limited to targeted Game Journey completion metrics regression coverage. +- - PASS: Did not delete, move, overwrite, export, or migrate `tmp/local-api/game-journey-completion-metrics.sqlite`. +- - PASS: Did not start Alfa Tags PRs. +-+- PASS: Final audit removed active runtime JS/MJS SQLite and `tmp/local-api` references outside the migration-only utility. +-diff --git a/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_manual-validation-notes.md b/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_manual-validation-notes.md +-index 9a952fb7b..6dad6bb08 100644 +---- a/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_manual-validation-notes.md +-+++ b/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_manual-validation-notes.md +-@@ -5,9 +5,10 @@ Status: PASS +- ## Notes +- +- - Confirmed the repo-local `tmp/local-api/game-journey-completion-metrics.sqlite` file exists before validation. +--- Confirmed active `createGameJourneyCompletionMetricsStore({ postgresClient })` no longer resolves that retired path by default. +--- Confirmed active metrics load 14 Postgres-backed completion buckets while the retired file remains untouched. +--- Confirmed explicit `legacyDbPath` protection remains covered by the existing migration/regression test file. +-+- Confirmed active `createGameJourneyCompletionMetricsStore({ postgresClient })` exposes no `legacyDbPath`. +-+- Confirmed active metrics snapshots expose no `legacySqlitePath`. +-+- Confirmed active metrics load 14 DB-backed completion buckets while the retired file remains untouched. +-+- Confirmed active runtime JS/MJS has no SQLite or `tmp/local-api` metrics references outside the migration-only utility. +- - Confirmed the toolbox page renders neutral Creator-facing outage wording when active metrics are unavailable. +- - Confirmed the toolbox page does not render the forbidden warning string, SQLite wording, `tmp/local-api`, or Postgres internals in the simulated outage lane. +- - Confirmed no Alfa Tags PR work was started. +-diff --git a/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_report.md b/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_report.md +-index 1940890cf..777642b00 100644 +---- a/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_report.md +-+++ b/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_report.md +-@@ -11,9 +11,10 @@ Recover the Game Journey completion metrics path so active Alfa and Owner work n +- ## Implementation Summary +- +- - Removed active runtime defaulting to `tmp/local-api/game-journey-completion-metrics.sqlite` in `createGameJourneyCompletionMetricsStore`. +--- Kept the explicit `legacyDbPath` guard intact for recovery/migration callers so legacy data is still protected from silent overwrite or deletion. +-+- Removed active runtime `legacyDbPath` guard plumbing from the Game Journey metrics store, repository, Local API router, and Playwright test server helper. +- - Updated `toolbox/tools-page-accordions.js` to render neutral Creator-safe progress outage wording instead of backend diagnostics. +--- Added a store-level regression test proving a retired default SQLite-shaped file does not block active Postgres-backed metrics. +-+- Added a store-level regression test proving a retired default SQLite-shaped file does not block or get touched by active DB-backed metrics. +-+- Added a targeted guardrail test proving active runtime JS/MJS under `src`, `assets`, and `toolbox` has no SQLite or `tmp/local-api` metrics references, excluding the migration-only utility. +- - Added a focused Playwright test proving the toolbox page does not render the forbidden warning, SQLite wording, local filesystem path, or Postgres internals when metrics are unavailable. +- +- ## Reference Comparison +-@@ -28,16 +29,20 @@ Recover the Game Journey completion metrics path so active Alfa and Owner work n +- - PASS: `node --check` on modified source and test files. +- - PASS: `node ./scripts/run-node-test-files.mjs tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs tests/dev-runtime/GameJourneyCompletionMetricsMigration.test.mjs`. +- - PASS: `npx playwright test tests/playwright/tools/GameJourneyTool.spec.mjs --project=playwright --workers=1 --reporter=line -g "Game Journey Local API persists completion metrics to Postgres|Toolbox renders Creator-safe Game Journey progress outage copy"`. +--- PASS: Direct proof against the actual existing `tmp/local-api/game-journey-completion-metrics.sqlite` file confirmed active Postgres metrics load 14 buckets and do not resolve a legacy path. +--- PASS: Runtime source search found no `Game Journey completion metrics unavailable` string. +--- PASS: Runtime source search found no active metrics-store default reference to `game-journey-completion-metrics.sqlite`, `GAMEFOUNDRY_GAME_JOURNEY_METRICS_DB_PATH`, or `defaultLegacySqlitePath`. +-+- PASS: Direct proof against the actual existing `tmp/local-api/game-journey-completion-metrics.sqlite` file confirmed active DB metrics load 14 buckets, expose no legacy path fields, and do not touch the retired file. +-+- PASS: Active runtime JS/MJS search found no SQLite, `.sqlite`, `better-sqlite`, `game-journey-completion-metrics.sqlite`, or `tmp/local-api` references outside the migration-only utility. +-+- PASS: Runtime source search found no `Game Journey completion metrics unavailable` Creator-facing string. +- - PASS: `git diff --check` reported no whitespace errors. Git emitted line-ending warnings only. +- +- ## Files +- +- - `src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs` +-+- `src/dev-runtime/persistence/tool-repositories/game-journey-mock-repository.js` +-+- `src/dev-runtime/server/local-api-router.mjs` +- - `tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs` +-+- `tests/helpers/playwrightRepoServer.mjs` +- - `tests/playwright/tools/GameJourneyTool.spec.mjs` +-+- `tests/playwright/tools/IdeaBoardTableNotes.spec.mjs` +- - `toolbox/tools-page-accordions.js` +- +- ## Artifact +-diff --git a/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_requirement-checklist.md b/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_requirement-checklist.md +-index 544b7057f..65a654b6d 100644 +---- a/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_requirement-checklist.md +-+++ b/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_requirement-checklist.md +-@@ -11,12 +11,14 @@ Status: PASS +- - PASS: Fixed only the Game Journey completion metrics regression. +- - PASS: Did not delete, move, overwrite, export, or migrate `tmp/local-api/game-journey-completion-metrics.sqlite`. +- - PASS: Stopped active runtime from defaulting to `tmp/local-api/game-journey-completion-metrics.sqlite`. +-+- PASS: Removed active runtime `legacyDbPath` SQLite guard plumbing. +- - PASS: Preserved Postgres-backed Game Journey completion metrics as the active path. +- - PASS: Ensured `toolbox/tools-page-accordions.js` cannot render `Game Journey completion metrics unavailable:`. +- - PASS: Creator-facing UI does not expose SQLite, local filesystem paths, migration/export language, or Postgres internals. +- - PASS: Did not introduce silent fallback behavior; metrics outage remains visible with neutral wording. +- - PASS: Added targeted regression tests. +- - PASS: Proved the existing legacy SQLite file does not block active metrics. +-+- PASS: Proved active runtime JS/MJS has no SQLite or `tmp/local-api` metrics references outside the migration-only utility. +- - PASS: Proved the forbidden warning string is not rendered. +- - PASS: Proved Game Journey metrics still load through the active DB/API path. +- - PASS: Used targeted validation only. +-diff --git a/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_validation-lane.md b/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_validation-lane.md +-index fe5ba4768..47530c453 100644 +---- a/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_validation-lane.md +-+++ b/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_validation-lane.md +-@@ -6,9 +6,13 @@ Status: PASS ++diff --git a/docs_build/dev/BUILD_PR.md b/docs_build/dev/BUILD_PR.md ++index 30700e9cd..50b1b27fa 100644 ++--- a/docs_build/dev/BUILD_PR.md +++++ b/docs_build/dev/BUILD_PR.md ++@@ -1,66 +1,52 @@ ++-# PR_26177_006-shared-time-foundation +++# PR_26177_OWNER_007-project-instructions-single-source-eod-lock + +- ```powershell +- node --check src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs +-+node --check src/dev-runtime/persistence/tool-repositories/game-journey-mock-repository.js +-+node --check src/dev-runtime/server/local-api-router.mjs +- node --check toolbox/tools-page-accordions.js +- node --check tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs +-+node --check tests/helpers/playwrightRepoServer.mjs +- node --check tests/playwright/tools/GameJourneyTool.spec.mjs +-+node --check tests/playwright/tools/IdeaBoardTableNotes.spec.mjs +- ``` ++ ## Purpose + +- Result: PASS +-@@ -17,7 +21,7 @@ Result: PASS +- node ./scripts/run-node-test-files.mjs tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs tests/dev-runtime/GameJourneyCompletionMetricsMigration.test.mjs +- ``` ++-Add a small shared time foundation. +++Make `docs_build/dev/ProjectInstructions/` the only active Project Instructions source and add EOD main lock plus next-day reset governance. + +--Result: PASS, 2 targeted node test files passed +-+Result: PASS, 2 targeted node test files passed. Includes active runtime JS/MJS SQLite reference guardrail. ++ ## Source Of Truth + +- ```powershell +- npx playwright test tests/playwright/tools/GameJourneyTool.spec.mjs --project=playwright --workers=1 --reporter=line -g "Game Journey Local API persists completion metrics to Postgres|Toolbox renders Creator-safe Game Journey progress outage copy" +-@@ -26,14 +30,14 @@ npx playwright test tests/playwright/tools/GameJourneyTool.spec.mjs --project=pl +- Result: PASS, 2 passed ++-This `BUILD_PR.md`, `PLAN_PR.md`, and the user request are the source of truth for `PR_26177_006-shared-time-foundation`. ++- ++-## Stack ++- ++-- Base branch: `PR_26177_005-shared-text-foundation` +++This `BUILD_PR.md`, `PLAN_PR.md`, and the user request are the source of truth for `PR_26177_OWNER_007-project-instructions-single-source-eod-lock`. ++ ++ ## Exact Scope ++ ++-- Add `src/shared/time/` foundation. ++-- Include duration formatting, timestamp helpers, debounce/throttle/sleep helpers where safe for shared runtime. ++-- Add targeted tests for the shared time area. ++-- No scheduler/runtime behavior changes. ++-- Create required Codex reports under `docs_build/dev/reports/`. ++-- Create repo-structured delta ZIP under `tmp/`. +++- Audit repo for ProjectInstructions / project instructions duplicates. +++- Establish `docs_build/dev/ProjectInstructions/` as the only active source. +++- Mark all other ProjectInstructions-style sources changed by this PR as deprecated references. +++- Update active team start/governance docs to reference only `docs_build/dev/ProjectInstructions/`. +++- Add EOD main lock and next-day reset governance. +++- Add required reports under `docs_build/dev/reports/`. ++ ++ ## Exact Targets ++ ++ - `docs_build/dev/PLAN_PR.md` ++ - `docs_build/dev/BUILD_PR.md` ++-- `src/shared/time/time.js` ++-- `tests/shared/TimeFoundation.test.mjs` ++-- `docs_build/dev/reports/PR_26177_006-shared-time-foundation.md` ++-- `docs_build/dev/reports/PR_26177_006-shared-time-foundation_branch-validation.md` ++-- `docs_build/dev/reports/PR_26177_006-shared-time-foundation_requirement-checklist.md` ++-- `docs_build/dev/reports/PR_26177_006-shared-time-foundation_validation-lane.md` ++-- `docs_build/dev/reports/PR_26177_006-shared-time-foundation_manual-validation-notes.md` +++- `docs_build/dev/PROJECT_INSTRUCTIONS.md` +++- `docs_build/dev/ProjectInstructions/README.txt` +++- `docs_build/dev/ProjectInstructions/PROJECT_INSTRUCTIONS.md` +++- `docs_build/dev/ProjectInstructions/TEAM_START_COMMANDS.md` +++- `docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md` +++- `docs_build/dev/ProjectInstructions/addendums/*.md` +++- `project-instructions/README.md` +++- `project-instructions/addendums/*.md` +++- `docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock*.md` ++ - `docs_build/dev/reports/codex_review.diff` ++ - `docs_build/dev/reports/codex_changed_files.txt` ++ ++ ## Out Of Scope ++ ++-- No scheduler/runtime behavior changes. ++-- No browser-owned product data. ++-- No runtime UI changes. ++-- No browser storage changes. ++-- No API/database changes. ++-- No `start_of_day` folder changes. ++-- No unrelated cleanup. ++-- No full samples smoke by default. +++- No product/runtime changes. +++- No feature work. +++- No `start_of_day` changes. +++- No legacy SQLite file changes. ++ ++ ## Validation ++ ++-Run exactly: +++Run: + + ```powershell +--node -e "import('node:fs').then(async fs=>{const [{createGameJourneyCompletionMetricsStore}, {createGameJourneyCompletionMetricsPostgresClientStub}] = await Promise.all([import('./src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs'), import('./tests/helpers/gameJourneyCompletionMetricsPostgresClientStub.mjs')]); const legacy='tmp/local-api/game-journey-completion-metrics.sqlite'; if(!fs.existsSync(legacy)) throw new Error('Expected existing legacy SQLite file for regression proof'); const store=createGameJourneyCompletionMetricsStore({postgresClient:createGameJourneyCompletionMetricsPostgresClientStub()}); const metrics=await store.listMetrics(); if(store.legacyDbPath) throw new Error('Active store resolved a legacy path'); if(metrics.length!==14) throw new Error('Expected 14 active metrics'); console.log('PASS active Postgres metrics ignore existing retired legacy SQLite file');})" +-+node -e "import('node:fs').then(async fs=>{const [{createGameJourneyCompletionMetricsStore}, {createGameJourneyCompletionMetricsPostgresClientStub}] = await Promise.all([import('./src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs'), import('./tests/helpers/gameJourneyCompletionMetricsPostgresClientStub.mjs')]); const legacy='tmp/local-api/game-journey-completion-metrics.sqlite'; if(!fs.existsSync(legacy)) throw new Error('Expected existing retired local file for regression proof'); const before=fs.statSync(legacy).mtimeMs; const store=createGameJourneyCompletionMetricsStore({postgresClient:createGameJourneyCompletionMetricsPostgresClientStub()}); const metrics=await store.listMetrics(); const snapshot=await store.snapshot(); const after=fs.statSync(legacy).mtimeMs; if(Object.hasOwn(store, 'legacyDbPath')) throw new Error('Store exposes legacyDbPath'); if(Object.hasOwn(snapshot, 'legacySqlitePath')) throw new Error('Snapshot exposes legacySqlitePath'); if(metrics.length!==14) throw new Error('Expected 14 active metrics'); if(before!==after) throw new Error('Retired local file was touched'); console.log('PASS active DB metrics ignore and do not inspect retired local file');})" ++-node ./scripts/run-node-test-files.mjs tests/shared/TimeFoundation.test.mjs ++-node --check src/shared/time/time.js ++-node --check tests/shared/TimeFoundation.test.mjs +++rg -n 'project-instructions/addendums|docs_build/dev/PROJECT_INSTRUCTIONS.md.*source of truth|Codex must always read `docs_build/dev/PROJECT_INSTRUCTIONS.md`|Read `docs_build/dev/PROJECT_INSTRUCTIONS.md`' docs_build/dev/ProjectInstructions docs_build/dev/PROJECT_INSTRUCTIONS.md project-instructions +++rg -n "End of Day:|Next Day Start:|HEAD.*published EOD SHA|only active Project Instructions source" docs_build/dev/ProjectInstructions +++git diff --name-only -- src assets toolbox games api serverside package.json package-lock.json docs_build/dev/start_of_day ++ git diff --check + ``` ++- ++-## Artifact ++- ++-Create repo-structured delta ZIP: ++- ++-```text ++-tmp/PR_26177_006-shared-time-foundation_delta.zip ++-``` ++diff --git a/docs_build/dev/PLAN_PR.md b/docs_build/dev/PLAN_PR.md ++index 907936aee..39fa03385 100644 ++--- a/docs_build/dev/PLAN_PR.md +++++ b/docs_build/dev/PLAN_PR.md ++@@ -1,22 +1,28 @@ ++-# PLAN_PR: PR_26177_006-shared-time-foundation +++# PLAN_PR: PR_26177_OWNER_007-project-instructions-single-source-eod-lock + +- Result: PASS ++ ## Purpose + +- ```powershell +-+rg -n -i "sqlite|better-sqlite|game-journey-completion-metrics\.sqlite|tmp/local-api" src assets toolbox -g "*.js" -g "*.mjs" --glob "!src/dev-runtime/persistence/game-journey-completion-metrics-migration.mjs" +- rg -n "Game Journey completion metrics unavailable" src assets toolbox --glob "!**/*.map" +--rg -n "game-journey-completion-metrics\.sqlite|GAMEFOUNDRY_GAME_JOURNEY_METRICS_DB_PATH|defaultLegacySqlitePath" src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs toolbox/tools-page-accordions.js assets/toolbox/game-journey/js/index.js ++-Add a small shared time foundation. +++Make `docs_build/dev/ProjectInstructions/` the only active Project Instructions source and add EOD main lock plus next-day reset governance. ++ ++ ## Scope ++ ++-- Add `src/shared/time/` foundation. ++-- Include duration formatting, timestamp helpers, sleep, debounce, and throttle helpers. ++-- Add targeted tests. ++-- No scheduler/runtime behavior changes. ++-- No browser-owned product data. ++-- No runtime UI changes. ++-- No unrelated cleanup. +++- Audit ProjectInstructions and project instructions duplicates. +++- Mark legacy ProjectInstructions-style sources as deprecated reference material. +++- Move active legacy addendums into `docs_build/dev/ProjectInstructions/addendums/`. +++- Update active team start and governance docs to reference only `docs_build/dev/ProjectInstructions/`. +++- Add EOD main lock, next-day reset, and team PR branch creation gate. +++- Add required Codex reports under `docs_build/dev/reports/`. ++ ++-## Implementation Plan +++## Out Of Scope ++ ++-1. Add `src/shared/time/time.js`. ++-2. Add `tests/shared/TimeFoundation.test.mjs`. ++-3. Validate duration, timestamp, sleep, debounce, and throttle helpers. ++-4. Produce required Codex reports and repo-structured ZIP. +++- No product/runtime changes. +++- No feature work. +++- No `start_of_day` changes. +++- No legacy SQLite file changes. +++ +++## Validation Plan +++ +++1. Run targeted grep/search proving no active duplicate ProjectInstructions source remains. +++2. Confirm EOD/Next Day rule appears in active governance docs. +++3. Confirm no product/runtime files changed. +++4. Run `git diff --check`. ++diff --git a/docs_build/dev/PROJECT_INSTRUCTIONS.md b/docs_build/dev/PROJECT_INSTRUCTIONS.md ++index af9e9e2db..c1136fdbe 100644 ++--- a/docs_build/dev/PROJECT_INSTRUCTIONS.md +++++ b/docs_build/dev/PROJECT_INSTRUCTIONS.md ++@@ -1,5 +1,7 @@ ++ # PROJECT INSTRUCTIONS ++ +++> Deprecated active-source notice: this file is preserved as historical reference only. The only active Project Instructions source is `docs_build/dev/ProjectInstructions/`. If this file conflicts with `docs_build/dev/ProjectInstructions/`, the active folder wins unless OWNER explicitly approves a newer governance change. +++ ++ You are working in a docs-first repo workflow. ++ ++ Workflow: ++@@ -864,7 +866,7 @@ Controls must remain copy-friendly and human-readable. ++ ++ ### ChatGPT Workflow Governance Consistency ++ ++-ChatGPT repo workflow responses are governed by `docs_build/dev/PROJECT_INSTRUCTIONS.md` as the source of truth. +++Deprecated note: this historical section no longer defines the active source of truth. ChatGPT repo workflow responses are governed by `docs_build/dev/ProjectInstructions/`. ++ ++ ChatGPT must not drift from the required response ordering. ++ ++@@ -1716,13 +1718,13 @@ Do not compact: ++ ++ Do not change JSON contracts or semantics while applying array formatting. ++ ++-## PROJECT INSTRUCTIONS LOCATION +++## DEPRECATED PROJECT INSTRUCTIONS LOCATION ++ ++-PROJECT_INSTRUCTIONS.md lives at: +++Historical PROJECT_INSTRUCTIONS.md is preserved at: ++ ++ `docs_build/dev/PROJECT_INSTRUCTIONS.md` ++ ++-Codex must always read `docs_build/dev/PROJECT_INSTRUCTIONS.md` from this path as the source of truth before executing repository workflow instructions. +++This file is not the active source of truth. Codex must read `docs_build/dev/ProjectInstructions/README.txt` first and use `docs_build/dev/ProjectInstructions/` as the active Project Instructions source before executing repository workflow instructions. ++ ++ ## CODEX COMMAND FORMATTING RULE ++ ++@@ -2384,9 +2386,9 @@ Treat these files the same as existing instruction documents for read-set, revie ++ Codex must run this gate before every PR execution and before any file changes. ++ ++ Required instruction reads: ++-- Read `docs_build/dev/PROJECT_INSTRUCTIONS.md`. +++- Read `docs_build/dev/ProjectInstructions/README.txt`. ++ - Read `docs_build/dev/PROJECT_MULTI_PC.txt`. ++-- Treat the newest applicable section in `PROJECT_INSTRUCTIONS.md` as authoritative when rules overlap. +++- Treat the newest applicable section in `docs_build/dev/ProjectInstructions/` as authoritative when rules overlap. ++ - Treat the current team ownership section in `PROJECT_MULTI_PC.txt` as authoritative for TEAM routing. ++ ++ Required pre-change report: ++diff --git a/docs_build/dev/ProjectInstructions/PROJECT_INSTRUCTIONS.md b/docs_build/dev/ProjectInstructions/PROJECT_INSTRUCTIONS.md ++index d2a84ecbe..99ddd0f42 100644 ++--- a/docs_build/dev/ProjectInstructions/PROJECT_INSTRUCTIONS.md +++++ b/docs_build/dev/ProjectInstructions/PROJECT_INSTRUCTIONS.md ++@@ -4,6 +4,12 @@ Read `README.txt` first. ++ ++ This file is the root index for the append-first Project Instructions operating system under `docs_build/dev/ProjectInstructions/`. ++ +++## Active Source +++ +++`docs_build/dev/ProjectInstructions/` is the only active Project Instructions source. +++ +++Historical Project Instructions material outside this folder is deprecated reference material only and must not be used as an active source of governance. +++ ++ ## Purpose ++ ++ The Project Instructions operating system provides additive governance for: ++@@ -20,7 +26,7 @@ The Project Instructions operating system provides additive governance for: ++ ++ ## Preservation ++ ++-Existing Project Instructions remain preserved in their current locations. This operating system adds structure without deleting or rewriting existing documentation. +++Existing Project Instructions outside `docs_build/dev/ProjectInstructions/` remain preserved only as deprecated reference material. When guidance conflicts, active files under `docs_build/dev/ProjectInstructions/` win unless OWNER explicitly approves a newer governance change. ++ ++ ## Folders ++ ++@@ -41,6 +47,10 @@ Existing Project Instructions remain preserved in their current locations. This ++ ++ `docs_build/dev/ProjectInstructions/addendums/environment_configuration_standards.md` defines official `.env` file names, environment variable values, host/domain configuration, API URL configuration, R2 prefix configuration, and feature flag governance. ++ +++## Single Source and Main Lock Governance +++ +++`docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md` defines the single active Project Instructions source, EOD main lock, next-day reset, and team branch creation gate. +++ ++ ## Merge Control ++ ++ No PR in this operating system is merged without explicit owner approval. ++diff --git a/docs_build/dev/ProjectInstructions/README.txt b/docs_build/dev/ProjectInstructions/README.txt ++index a48becf05..631fd3918 100644 ++--- a/docs_build/dev/ProjectInstructions/README.txt +++++ b/docs_build/dev/ProjectInstructions/README.txt ++@@ -1,10 +1,10 @@ ++ Read this file first. ++ ++ Folder purpose: ++-This folder is the append-first Project Instructions operating system for Game Foundry Studio. It organizes active governance, backlog, team assignment, deprecation, and history material without deleting or rewriting the existing Project Instructions files elsewhere in the repository. +++This folder is the only active Project Instructions source for Game Foundry Studio. It organizes active governance, backlog, team assignment, deprecation, and history material under `docs_build/dev/ProjectInstructions/`. ++ ++ Preservation rules: ++-Preserve all existing documentation. Add new files or append explicit references unless the owner explicitly approves deletion or rewrite. When a conflict appears, stop, explain the conflict, and request owner approval before changing existing instruction text. +++Preserve historical Project Instructions material as deprecated reference only. Do not treat `docs_build/dev/PROJECT_INSTRUCTIONS.md`, `project-instructions/`, or archived snapshots as active instruction sources. When a conflict appears, `docs_build/dev/ProjectInstructions/` wins unless OWNER explicitly approves a newer governance change. ++ ++ Backlog workflow: ++ Backlog work is tracked under backlog/. BACKLOG_MASTER.md is the planned source for backlog item status, notes, and references. Backlog item text is treated as immutable once created; status and notes may change under the governance addendums. ++@@ -29,9 +29,9 @@ Do not rewrite history snapshots after creation unless the owner explicitly appr ++ ++ READ THIS FIRST ++ ++-1. Read Project Instructions before making changes. ++-2. Project Instructions are append-only. ++-3. Existing approved guidance may not be removed. +++1. Read `docs_build/dev/ProjectInstructions/README.txt` before making changes. +++2. Treat `docs_build/dev/ProjectInstructions/` as the only active Project Instructions source. +++3. Historical Project Instructions files outside this folder are deprecated references only. ++ 4. Team ownership must be respected. ++ 5. BACKLOG_MASTER.md is the authoritative backlog. ++ 6. Build Path status derives from backlog status. ++@@ -42,12 +42,13 @@ READ THIS FIRST ++ 11. Batch Governance Mode is the default for governance, documentation, and administrative work. ++ ++ Addendum index: ++-- Canonical Repository Structure: project-instructions/addendums/canonical-repository-structure.md ++-- Test Structure Standardization: project-instructions/addendums/test-structure-standardization.md ++-- Legacy Migration Policy: project-instructions/addendums/legacy-migration-policy.md ++-- Assistant Execution Modes: project-instructions/addendums/assistant-execution-modes.md ++-- Codex Artifact and Reporting Standard: project-instructions/addendums/codex-artifact-and-reporting-standard.md ++-- Codex Project Instructions Startup: project-instructions/addendums/codex-project-instructions-startup.md +++- Single Source and EOD Main Lock: docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md +++- Canonical Repository Structure: docs_build/dev/ProjectInstructions/addendums/canonical_repository_structure.md +++- Test Structure Standardization: docs_build/dev/ProjectInstructions/addendums/test_structure_standardization.md +++- Legacy Migration Policy: docs_build/dev/ProjectInstructions/addendums/legacy_migration_policy.md +++- Assistant Execution Modes: docs_build/dev/ProjectInstructions/addendums/assistant_execution_modes.md +++- Codex Artifact and Reporting Standard: docs_build/dev/ProjectInstructions/addendums/codex_artifact_and_reporting_standard.md +++- Codex Project Instructions Startup: docs_build/dev/ProjectInstructions/addendums/codex_project_instructions_startup.md ++ - Project Reference Files Governance: docs_build/dev/ProjectInstructions/addendums/project_reference_files.md ++ - Environment Governance Model: docs_build/dev/ProjectInstructions/addendums/environment_governance_model.md ++ - Environment Configuration Standards: docs_build/dev/ProjectInstructions/addendums/environment_configuration_standards.md ++diff --git a/docs_build/dev/ProjectInstructions/TEAM_START_COMMANDS.md b/docs_build/dev/ProjectInstructions/TEAM_START_COMMANDS.md ++index d0118f63a..c446a4b33 100644 ++--- a/docs_build/dev/ProjectInstructions/TEAM_START_COMMANDS.md +++++ b/docs_build/dev/ProjectInstructions/TEAM_START_COMMANDS.md ++@@ -1,5 +1,16 @@ ++ # TEAM_START_COMMANDS ++ +++## Required Main Reset Gate For Every Team +++ +++No team creates a PR branch until all checks pass: +++ +++- Current branch: `main` +++- Worktree: clean +++- `main...origin/main`: `0 0` +++- `HEAD` SHA matches the published EOD SHA +++ +++Use `docs_build/dev/ProjectInstructions/` as the only active Project Instructions source. +++ ++ ## Start Team Alfa ++ ++ Ready-to-copy command: ++@@ -123,4 +134,24 @@ Merge to main is EOD-only and owner-approved, unless the owner explicitly says: ++ "Merge this PR now." ++ ++ Do not treat sequential PR completion as merge approval. +++ +++End of Day: +++git checkout main +++git fetch origin +++git pull --ff-only origin main +++git status +++git rev-list --left-right --count main...origin/main +++ +++Required: +++On branch main +++nothing to commit, working tree clean +++0 0 +++ +++Next Day Start: +++git checkout main +++git fetch origin +++git pull --ff-only origin main +++git status +++git rev-list --left-right --count main...origin/main +++git rev-parse HEAD + ``` ++diff --git a/docs_build/dev/ProjectInstructions/addendums/branch_lock_governance.md b/docs_build/dev/ProjectInstructions/addendums/branch_lock_governance.md ++index 518f8c943..d6c8e4cf7 100644 ++--- a/docs_build/dev/ProjectInstructions/addendums/branch_lock_governance.md +++++ b/docs_build/dev/ProjectInstructions/addendums/branch_lock_governance.md ++@@ -23,6 +23,7 @@ Keep active work attached to the correct assigned team, branch, and OWNER decisi + +- Result: PASS, no matches ++ - Start from current `main`. ++ - Pull latest `origin/main` before creating a work branch. +++- Do not create a PR branch unless current branch is `main`, worktree is clean, `main...origin/main` is `0 0`, and `HEAD` SHA matches the published EOD SHA. ++ - Keep work on the active branch until the PR is merged, the branch is retired, or OWNER says to return to `main`. ++ - Do not commit directly to `main` unless OWNER explicitly approves. ++ - Do not merge stale historical branches directly unless they are current, clean, still needed, and OWNER-approved. ++@@ -54,3 +55,36 @@ Protected guidance includes: ++ - Governance Phase 1 completion guidance ++ ++ If protected guidance must change, OWNER approval is required. +++ +++## End Of Day Main Lock +++ +++End of Day: +++ +++```text +++git checkout main +++git fetch origin +++git pull --ff-only origin main +++git status +++git rev-list --left-right --count main...origin/main +++``` +++ +++Required: +++ +++```text +++On branch main +++nothing to commit, working tree clean +++0 0 +++``` +++ +++Next Day Start: +++ +++```text +++git checkout main +++git fetch origin +++git pull --ff-only origin main +++git status +++git rev-list --left-right --count main...origin/main +++git rev-parse HEAD +++``` +++ +++The next-day `HEAD` SHA must match the published EOD SHA before any team creates a PR branch. ++diff --git a/docs_build/dev/ProjectInstructions/addendums/pr_workflow.md b/docs_build/dev/ProjectInstructions/addendums/pr_workflow.md ++index f8a4acb6e..7c1cd8275 100644 ++--- a/docs_build/dev/ProjectInstructions/addendums/pr_workflow.md +++++ b/docs_build/dev/ProjectInstructions/addendums/pr_workflow.md ++@@ -129,3 +129,40 @@ Stop only for: ++ - Merge conflict ++ - Validation failure ++ - OWNER decision +++ +++## EOD Main Lock +++ +++End of Day: +++ +++```text +++git checkout main +++git fetch origin +++git pull --ff-only origin main +++git status +++git rev-list --left-right --count main...origin/main +++``` +++ +++Required: +++ +++```text +++On branch main +++nothing to commit, working tree clean +++0 0 +++``` +++ +++## Next Day Start +++ +++```text +++git checkout main +++git fetch origin +++git pull --ff-only origin main +++git status +++git rev-list --left-right --count main...origin/main +++git rev-parse HEAD +++``` +++ +++No team creates a PR branch until: +++- Current branch: `main` +++- Worktree: clean +++- `main...origin/main`: `0 0` +++- `HEAD` SHA matches published EOD SHA ++diff --git a/docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md b/docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md ++index 9735b4bd4..9a104b4f9 100644 ++--- a/docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md +++++ b/docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md ++@@ -211,3 +211,44 @@ Commit/push during the day is allowed only on assigned team/OWNER/PR branches. ++ ++ Merge to main is EOD-only and owner-approved, unless the owner explicitly says: ++ "Merge this PR now." +++ +++## EOD Main Lock And Next Day Reset +++ +++End of Day: +++ +++```text +++git checkout main +++git fetch origin +++git pull --ff-only origin main +++git status +++git rev-list --left-right --count main...origin/main +++``` +++ +++Required: +++ +++```text +++On branch main +++nothing to commit, working tree clean +++0 0 +++``` +++ +++Next Day Start: +++ +++```text +++git checkout main +++git fetch origin +++git pull --ff-only origin main +++git status +++git rev-list --left-right --count main...origin/main +++git rev-parse HEAD +++``` +++ +++Team rule: +++No team creates a PR branch until: +++- Current branch: `main` +++- Worktree: clean +++- `main...origin/main`: `0 0` +++- `HEAD` SHA matches published EOD SHA +++ +++Active source rule: +++Teams must use only `docs_build/dev/ProjectInstructions/` as the active Project Instructions source. + diff --git a/docs_build/dev/reports/codex_changed_files.txt b/docs_build/dev/reports/codex_changed_files.txt +-index 585a10850..8e34972a1 100644 ++index 8e34972a1..85beb7824 100644 + --- a/docs_build/dev/reports/codex_changed_files.txt + +++ b/docs_build/dev/reports/codex_changed_files.txt +-@@ -6,6 +6,9 @@ docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recove ++@@ -1,14 +1,30 @@ ++-docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_branch-validation.md ++-docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_manual-validation-notes.md ++-docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_report.md ++-docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_requirement-checklist.md ++-docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_validation-lane.md +++docs_build/dev/BUILD_PR.md +++docs_build/dev/PLAN_PR.md +++docs_build/dev/PROJECT_INSTRUCTIONS.md +++docs_build/dev/ProjectInstructions/PROJECT_INSTRUCTIONS.md +++docs_build/dev/ProjectInstructions/README.txt +++docs_build/dev/ProjectInstructions/TEAM_START_COMMANDS.md +++docs_build/dev/ProjectInstructions/addendums/assistant_execution_modes.md +++docs_build/dev/ProjectInstructions/addendums/branch_lock_governance.md +++docs_build/dev/ProjectInstructions/addendums/canonical_repository_structure.md +++docs_build/dev/ProjectInstructions/addendums/codex_artifact_and_reporting_standard.md +++docs_build/dev/ProjectInstructions/addendums/codex_project_instructions_startup.md +++docs_build/dev/ProjectInstructions/addendums/legacy_migration_policy.md +++docs_build/dev/ProjectInstructions/addendums/pr_workflow.md +++docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md +++docs_build/dev/ProjectInstructions/addendums/test_structure_standardization.md +++docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md +++docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock.md +++docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_branch-validation.md +++docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_manual-validation-notes.md +++docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_requirement-checklist.md +++docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_validation-lane.md + docs_build/dev/reports/codex_changed_files.txt + docs_build/dev/reports/codex_review.diff +- src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs +-+src/dev-runtime/persistence/tool-repositories/game-journey-mock-repository.js +-+src/dev-runtime/server/local-api-router.mjs +- tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs +-+tests/helpers/playwrightRepoServer.mjs +- tests/playwright/tools/GameJourneyTool.spec.mjs +--toolbox/tools-page-accordions.js +-+tests/playwright/tools/IdeaBoardTableNotes.spec.mjs +-diff --git a/src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs b/src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs +-index 6c202c8a2..eea6294e7 100644 +---- a/src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs +-+++ b/src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs +-@@ -1,5 +1,3 @@ +--import { existsSync } from "node:fs"; +--import path from "node:path"; +- import { createPostgresConnectionClient } from "./postgres-connection-client.mjs"; +- import { SEED_DB_KEYS, makeSeedUlid } from "../seed/seed-db-keys.mjs"; +- +-@@ -59,24 +57,6 @@ function clone(value) { +- return JSON.parse(JSON.stringify(value)); +- } +- +--function resolveLegacySqlitePath(legacyDbPath) { +-- if (legacyDbPath === null || legacyDbPath === undefined) { +-- return ""; +-- } +-- const value = String(legacyDbPath || "").trim(); +-- if (!value) { +-- return ""; +-- } +-- return path.resolve(value); +--} +-- +--function assertNoUnmigratedLegacySqlite(legacyDbPath) { +-- if (!legacyDbPath || !existsSync(legacyDbPath)) { +-- return; +-- } +-- throw new Error(`Legacy Game Journey completion metrics SQLite data exists at ${legacyDbPath}. No data was removed or overwritten. Export or migrate that data into Postgres, then move the legacy file before using the Postgres metrics store.`); +--} +-- +- function normalizeCount(value, fallback = 0) { +- const parsed = Number(value); +- if (!Number.isFinite(parsed)) { +-@@ -158,7 +138,6 @@ function bucketSeedRow(bucket, now) { +- export function createGameJourneyCompletionMetricsStore(options = {}) { +- const env = options.env || process.env; +- const bucketSeeds = Object.freeze((options.buckets || GAME_JOURNEY_COMPLETION_BUCKETS).map(clone)); +-- const legacyDbPath = resolveLegacySqlitePath(options.legacyDbPath); +- let postgresClient = options.postgresClient || null; +- let readyPromise = null; +- +-@@ -230,7 +209,6 @@ export function createGameJourneyCompletionMetricsStore(options = {}) { +- async function ensureReady() { +- if (!readyPromise) { +- readyPromise = (async () => { +-- assertNoUnmigratedLegacySqlite(legacyDbPath); +- await client().query(GAME_JOURNEY_COMPLETION_METRICS_SCHEMA_SQL); +- await seedDefaultBuckets(); +- })(); +-@@ -298,7 +276,6 @@ export function createGameJourneyCompletionMetricsStore(options = {}) { +- databaseConfigKey: "GAMEFOUNDRY_DATABASE_URL", +- databaseEngine: "Postgres", +- databasePath: "GAMEFOUNDRY_DATABASE_URL", +-- legacySqlitePath: legacyDbPath, +- serviceContract: "Web UI -> Local API/Service Contract -> Postgres", +- source: GAME_JOURNEY_COMPLETION_METRICS_TABLE, +- tableName: GAME_JOURNEY_COMPLETION_METRICS_TABLE, +-@@ -312,7 +289,6 @@ export function createGameJourneyCompletionMetricsStore(options = {}) { +- } +- +- return { +-- legacyDbPath, +- listMetrics, +- snapshot, +- updateMetric, +-diff --git a/src/dev-runtime/persistence/tool-repositories/game-journey-mock-repository.js b/src/dev-runtime/persistence/tool-repositories/game-journey-mock-repository.js +-index 73b409c42..8e0ddc92b 100644 +---- a/src/dev-runtime/persistence/tool-repositories/game-journey-mock-repository.js +-+++ b/src/dev-runtime/persistence/tool-repositories/game-journey-mock-repository.js +-@@ -627,7 +627,6 @@ export function createGameJourneyMockRepository(options = {}) { +- const completionMetricsStore = +- options.completionMetricsStore || createGameJourneyCompletionMetricsStore({ +- dbPath: options.completionMetricsDbPath, +-- legacyDbPath: options.completionMetricsLegacyDbPath, +- postgresClient: options.completionMetricsPostgresClient, +- }); +- const tables = loadMockDbTables(GAME_JOURNEY_DB_OWNER, getSeedTables(), options).tables; +-diff --git a/src/dev-runtime/server/local-api-router.mjs b/src/dev-runtime/server/local-api-router.mjs +-index f2f927aff..2cb9a66f1 100644 +---- a/src/dev-runtime/server/local-api-router.mjs +-+++ b/src/dev-runtime/server/local-api-router.mjs +-@@ -3304,14 +3304,12 @@ function productTablesFromSnapshot(snapshot) { +- +- class ApiRuntimeDataSource { +- constructor({ +-- gameJourneyCompletionMetricsLegacyDbPath = undefined, +- gameJourneyCompletionMetricsPostgresClient = null, +- messagesPostgresClient = null, +- messagesService = null, +- repoRoot = process.cwd(), +- } = {}) { +- this.messagesService = messagesService || createMessagesPostgresService({ postgresClient: messagesPostgresClient }); +-- this.gameJourneyCompletionMetricsLegacyDbPath = gameJourneyCompletionMetricsLegacyDbPath; +- this.gameJourneyCompletionMetricsPostgresClient = gameJourneyCompletionMetricsPostgresClient; +- this.repositoryCounter = 1; +- this.repositoryById = new Map(); +-@@ -3556,7 +3554,6 @@ class ApiRuntimeDataSource { +- this.standaloneTables.invitations = []; +- } +- this.sharedOptions = { +-- completionMetricsLegacyDbPath: this.gameJourneyCompletionMetricsLegacyDbPath, +- completionMetricsPostgresClient: this.gameJourneyCompletionMetricsPostgresClient, +- memoryDbTables: this.standaloneTables, +- sessionMode: this.sessionModeId, +-@@ -6839,14 +6836,12 @@ SELECT pg_database_size(current_database()) AS database_size_bytes, +- * The router itself serves the configured server API contract. +- */ +- export function createLocalApiRouter({ +-- gameJourneyCompletionMetricsLegacyDbPath = undefined, +- gameJourneyCompletionMetricsPostgresClient = null, +- messagesPostgresClient = null, +- messagesService = null, +- repoRoot = process.cwd(), +- } = {}) { +- const dataSource = new ApiRuntimeDataSource({ +-- gameJourneyCompletionMetricsLegacyDbPath, +- gameJourneyCompletionMetricsPostgresClient, +- messagesPostgresClient, +- messagesService, +-diff --git a/tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs b/tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs +-index edbc0333e..1ca7de68e 100644 +---- a/tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs +-+++ b/tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs +-@@ -10,6 +10,34 @@ import { +- } from "../../src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs"; +- import { createGameJourneyCompletionMetricsPostgresClientStub } from "../helpers/gameJourneyCompletionMetricsPostgresClientStub.mjs"; +- +-+const ACTIVE_RUNTIME_ROOTS = Object.freeze(["src", "assets", "toolbox"]); +-+const ACTIVE_RUNTIME_ALLOWED_FILES = new Set([ +-+ path.normalize("src/dev-runtime/persistence/game-journey-completion-metrics-migration.mjs"), +-+]); +-+const RUNTIME_FORBIDDEN_PATTERNS = Object.freeze([ +-+ /sqlite/i, +-+ /\.sqlite/i, +-+ /better-sqlite/i, +-+ /game-journey-completion-metrics\.sqlite/i, +-+ /tmp\/local-api/i, +-+]); +-+ +-+async function activeRuntimeJavaScriptFiles(root) { +-+ const entries = await fs.readdir(root, { withFileTypes: true }); +-+ const files = []; +-+ for (const entry of entries) { +-+ const child = path.join(root, entry.name); +-+ if (entry.isDirectory()) { +-+ files.push(...await activeRuntimeJavaScriptFiles(child)); +-+ continue; +-+ } +-+ if (entry.isFile() && /\.(?:mjs|js)$/i.test(entry.name)) { +-+ files.push(child); +-+ } +-+ } +-+ return files; +-+} +-+ +- test("active Game Journey metrics ignore the retired default legacy SQLite path", async () => { +- const originalCwd = process.cwd(); +- const directory = await fs.mkdtemp(path.join(os.tmpdir(), "gfs-game-journey-metrics-store-")); +-@@ -24,8 +52,10 @@ test("active Game Journey metrics ignore the retired default legacy SQLite path" +- const postgresClient = createGameJourneyCompletionMetricsPostgresClientStub(); +- const store = createGameJourneyCompletionMetricsStore({ postgresClient }); +- const metrics = await store.listMetrics(); +-+ const snapshot = await store.snapshot(); +- +-- assert.equal(store.legacyDbPath, ""); +-+ assert.equal(Object.hasOwn(store, "legacyDbPath"), false); +-+ assert.equal(Object.hasOwn(snapshot, "legacySqlitePath"), false); +- assert.equal(metrics.length, 14); +- assert.equal(postgresClient.dumpTable(GAME_JOURNEY_COMPLETION_METRICS_TABLE).length, 14); +- assert.equal(await fs.readFile(retiredLegacyPath, "utf8"), retiredLegacyContents); +-@@ -34,3 +64,26 @@ test("active Game Journey metrics ignore the retired default legacy SQLite path" +- await fs.rm(directory, { force: true, recursive: true }); +- } +- }); +-+ +-+test("active runtime JS and MJS do not contain SQLite or tmp local metrics references", async () => { +-+ const files = []; +-+ for (const root of ACTIVE_RUNTIME_ROOTS) { +-+ files.push(...await activeRuntimeJavaScriptFiles(root)); +-+ } +-+ +-+ const findings = []; +-+ for (const file of files) { +-+ const normalized = path.normalize(file); +-+ if (ACTIVE_RUNTIME_ALLOWED_FILES.has(normalized)) { +-+ continue; +-+ } +-+ const contents = await fs.readFile(file, "utf8"); +-+ RUNTIME_FORBIDDEN_PATTERNS.forEach((pattern) => { +-+ if (pattern.test(contents)) { +-+ findings.push(`${file}: ${pattern}`); +-+ } +-+ }); +-+ } +-+ +-+ assert.deepEqual(findings, []); +-+}); +-diff --git a/tests/helpers/playwrightRepoServer.mjs b/tests/helpers/playwrightRepoServer.mjs +-index 9bc8e8f07..71c7853aa 100644 +---- a/tests/helpers/playwrightRepoServer.mjs +-+++ b/tests/helpers/playwrightRepoServer.mjs +-@@ -91,13 +91,11 @@ function resolveBrowserRoutePath(decodedPath) { +- } +- +- export async function startRepoServer({ +-- gameJourneyCompletionMetricsLegacyDbPath = undefined, +- gameJourneyCompletionMetricsPostgresClient = null, +- messagesPostgresClient = null, +- } = {}) { +- await loadRuntimeEnv(); +- const handleLocalApiRequest = createLocalApiRouter({ +-- gameJourneyCompletionMetricsLegacyDbPath, +- gameJourneyCompletionMetricsPostgresClient, +- messagesPostgresClient, +- repoRoot, +-diff --git a/tests/playwright/tools/GameJourneyTool.spec.mjs b/tests/playwright/tools/GameJourneyTool.spec.mjs +-index 75a913d96..cc47265cf 100644 +---- a/tests/playwright/tools/GameJourneyTool.spec.mjs +-+++ b/tests/playwright/tools/GameJourneyTool.spec.mjs +-@@ -40,7 +40,6 @@ test.afterAll(async () => { +- async function openRepoPage(page, pathName, options = {}) { +- const gameJourneyCompletionMetricsPostgresClient = createGameJourneyCompletionMetricsPostgresClientStub(); +- const server = await startRepoServer({ +-- gameJourneyCompletionMetricsLegacyDbPath: null, +- gameJourneyCompletionMetricsPostgresClient, +- }); +- const previousApiUrl = process.env.GAMEFOUNDRY_API_URL; +-@@ -238,7 +237,6 @@ test("Game Journey exposes static tool ownership areas without automatic counts" +- +- const gameJourneyCompletionMetricsPostgresClient = createGameJourneyCompletionMetricsPostgresClientStub(); +- const server = await startRepoServer({ +-- gameJourneyCompletionMetricsLegacyDbPath: null, +- gameJourneyCompletionMetricsPostgresClient, +- }); +- try { +-@@ -262,7 +260,6 @@ test("Game Journey progress dashboard summarizes completion metrics", async ({ p +- process.env.GAMEFOUNDRY_LOCAL_DB_PATH = localDbPath; +- const gameJourneyCompletionMetricsPostgresClient = createGameJourneyCompletionMetricsPostgresClientStub(); +- const server = await startRepoServer({ +-- gameJourneyCompletionMetricsLegacyDbPath: null, +- gameJourneyCompletionMetricsPostgresClient, +- }); +- const previousApiUrl = process.env.GAMEFOUNDRY_API_URL; +-@@ -1285,7 +1282,6 @@ test("Game Journey displays system template diagnostics", async ({ page }) => { +- +- test("Game Journey mock data keeps system guidance template-owned", async () => { +- const repository = createGameJourneyMockRepository({ +-- completionMetricsLegacyDbPath: null, +- completionMetricsPostgresClient: createGameJourneyCompletionMetricsPostgresClientStub(), +- memoryDbTables: standaloneSeedTables, +- persist: false, +-@@ -1452,7 +1448,6 @@ test("Game Journey mock data keeps system guidance template-owned", async () => +- test("Game Journey Local API persists completion metrics to Postgres", async () => { +- const gameJourneyCompletionMetricsPostgresClient = createGameJourneyCompletionMetricsPostgresClientStub(); +- const server = await startRepoServer({ +-- gameJourneyCompletionMetricsLegacyDbPath: null, +- gameJourneyCompletionMetricsPostgresClient, +- }); +- try { +-@@ -1511,29 +1506,11 @@ test("Game Journey Local API persists completion metrics to Postgres", async () +- test("Game Journey completion metrics fail visibly when Postgres is not configured", async () => { +- const store = createGameJourneyCompletionMetricsStore({ +- env: {}, +-- legacyDbPath: null, +- }); +- +- await expect(store.listMetrics()).rejects.toThrow(/GAMEFOUNDRY_DATABASE_URL/); +- }); +- +--test("Game Journey completion metrics protect legacy SQLite data from silent drop", async () => { +-- const legacyDbPath = path.join(process.cwd(), "tmp", "local-api", `game-journey-legacy-guard-${process.pid}-${Date.now()}.sqlite`); +-- await fs.mkdir(path.dirname(legacyDbPath), { recursive: true }); +-- await fs.writeFile(legacyDbPath, "legacy metrics placeholder"); +-- +-- const store = createGameJourneyCompletionMetricsStore({ +-- legacyDbPath, +-- postgresClient: createGameJourneyCompletionMetricsPostgresClientStub(), +-- }); +-- +-- try { +-- await expect(store.listMetrics()).rejects.toThrow(/Legacy Game Journey completion metrics SQLite data exists/); +-- } finally { +-- await fs.rm(legacyDbPath, { force: true }); +-- } +--}); +-- +- test("Game Journey requires an active game before editing", async ({ page }) => { +- const failures = await openRepoPage(page, "/toolbox/game-journey/index.html?game=none"); +- +-diff --git a/tests/playwright/tools/IdeaBoardTableNotes.spec.mjs b/tests/playwright/tools/IdeaBoardTableNotes.spec.mjs +-index 6d626f03b..be8c88698 100644 +---- a/tests/playwright/tools/IdeaBoardTableNotes.spec.mjs +-+++ b/tests/playwright/tools/IdeaBoardTableNotes.spec.mjs +-@@ -115,7 +115,6 @@ async function expectNoNavigationFallbackUi(page) { +- +- test("Idea Board uses accordion table ideas and notes", async ({ page }) => { +- const server = await startRepoServer({ +-- gameJourneyCompletionMetricsLegacyDbPath: null, +- gameJourneyCompletionMetricsPostgresClient: createGameJourneyCompletionMetricsPostgresClientStub(), +- }); +- const previousApiUrl = process.env.GAMEFOUNDRY_API_URL; +-@@ -478,7 +477,6 @@ test("Idea Board uses accordion table ideas and notes", async ({ page }) => { +- +- test("Idea Board gates Create Project to Ready ideas and locks converted projects", async ({ page }) => { +- const server = await startRepoServer({ +-- gameJourneyCompletionMetricsLegacyDbPath: null, +- gameJourneyCompletionMetricsPostgresClient: createGameJourneyCompletionMetricsPostgresClientStub(), +- }); +- const previousApiUrl = process.env.GAMEFOUNDRY_API_URL; +-@@ -595,7 +593,6 @@ test("Idea Board gates Create Project to Ready ideas and locks converted project +- +- test("Idea Board guest write actions redirect to sign in before saving data", async ({ page }) => { +- const server = await startRepoServer({ +-- gameJourneyCompletionMetricsLegacyDbPath: null, +- gameJourneyCompletionMetricsPostgresClient: createGameJourneyCompletionMetricsPostgresClientStub(), +- }); +- const previousApiUrl = process.env.GAMEFOUNDRY_API_URL; +\ No newline at end of file ++-src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs ++-src/dev-runtime/persistence/tool-repositories/game-journey-mock-repository.js ++-src/dev-runtime/server/local-api-router.mjs ++-tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs ++-tests/helpers/playwrightRepoServer.mjs ++-tests/playwright/tools/GameJourneyTool.spec.mjs ++-tests/playwright/tools/IdeaBoardTableNotes.spec.mjs +++project-instructions/README.md +++project-instructions/addendums/assistant-execution-modes.md +++project-instructions/addendums/canonical-repository-structure.md +++project-instructions/addendums/codex-artifact-and-reporting-standard.md +++project-instructions/addendums/codex-project-instructions-startup.md +++project-instructions/addendums/legacy-migration-policy.md +++project-instructions/addendums/test-structure-standardization.md ++diff --git a/project-instructions/addendums/assistant-execution-modes.md b/project-instructions/addendums/assistant-execution-modes.md ++index 6d7928669..4c5637d0d 100644 ++--- a/project-instructions/addendums/assistant-execution-modes.md +++++ b/project-instructions/addendums/assistant-execution-modes.md ++@@ -1,5 +1,7 @@ ++ # Assistant Execution Modes ++ +++> Deprecated reference notice: this file is preserved for history only. The active copy is `docs_build/dev/ProjectInstructions/addendums/assistant_execution_modes.md`. +++ ++ ## Purpose ++ ++ Standardize request interpretation and expected outputs for Review, Owner, Build PR, Continue, Challenge, and Stop Gate workflows. ++diff --git a/project-instructions/addendums/canonical-repository-structure.md b/project-instructions/addendums/canonical-repository-structure.md ++index e26939469..6b9dcb242 100644 ++--- a/project-instructions/addendums/canonical-repository-structure.md +++++ b/project-instructions/addendums/canonical-repository-structure.md ++@@ -1,5 +1,7 @@ ++ # Canonical Repository Structure ++ +++> Deprecated reference notice: this file is preserved for history only. The active copy is `docs_build/dev/ProjectInstructions/addendums/canonical_repository_structure.md`. +++ ++ ## Purpose ++ ++ Establish the canonical repository structure for future development and reduce technical debt. ++diff --git a/project-instructions/addendums/codex-artifact-and-reporting-standard.md b/project-instructions/addendums/codex-artifact-and-reporting-standard.md ++index 3f16a3641..8d1327886 100644 ++--- a/project-instructions/addendums/codex-artifact-and-reporting-standard.md +++++ b/project-instructions/addendums/codex-artifact-and-reporting-standard.md ++@@ -1,5 +1,7 @@ ++ # Codex Artifact and Reporting Standard ++ +++> Deprecated reference notice: this file is preserved for history only. The active copy is `docs_build/dev/ProjectInstructions/addendums/codex_artifact_and_reporting_standard.md`. +++ ++ ## Purpose ++ ++ Standardize Codex deliverables, completion reporting, and artifact generation. ++diff --git a/project-instructions/addendums/codex-project-instructions-startup.md b/project-instructions/addendums/codex-project-instructions-startup.md ++index 94744f06e..135498b42 100644 ++--- a/project-instructions/addendums/codex-project-instructions-startup.md +++++ b/project-instructions/addendums/codex-project-instructions-startup.md ++@@ -1,5 +1,7 @@ ++ # Codex Project Instructions Startup ++ +++> Deprecated reference notice: this file is preserved for history only. The active copy is `docs_build/dev/ProjectInstructions/addendums/codex_project_instructions_startup.md`. +++ ++ ## Purpose ++ ++ Ensure Codex uses the current approved governance before making repository changes. ++diff --git a/project-instructions/addendums/legacy-migration-policy.md b/project-instructions/addendums/legacy-migration-policy.md ++index 5e43679f4..5515a1728 100644 ++--- a/project-instructions/addendums/legacy-migration-policy.md +++++ b/project-instructions/addendums/legacy-migration-policy.md ++@@ -1,5 +1,7 @@ ++ # Legacy Migration Policy ++ +++> Deprecated reference notice: this file is preserved for history only. The active copy is `docs_build/dev/ProjectInstructions/addendums/legacy_migration_policy.md`. +++ ++ ## Purpose ++ ++ Reduce technical debt incrementally during normal development. ++diff --git a/project-instructions/addendums/test-structure-standardization.md b/project-instructions/addendums/test-structure-standardization.md ++index 997b16730..eeb62d561 100644 ++--- a/project-instructions/addendums/test-structure-standardization.md +++++ b/project-instructions/addendums/test-structure-standardization.md ++@@ -1,5 +1,7 @@ ++ # Test Structure Standardization ++ +++> Deprecated reference notice: this file is preserved for history only. The active copy is `docs_build/dev/ProjectInstructions/addendums/test_structure_standardization.md`. +++ ++ ## Purpose ++ ++ Standardize testing locations and ensure independent tool validation. ++diff --git a/docs_build/dev/ProjectInstructions/addendums/assistant_execution_modes.md b/docs_build/dev/ProjectInstructions/addendums/assistant_execution_modes.md ++new file mode 100644 ++index 000000000..6d7928669 ++--- /dev/null +++++ b/docs_build/dev/ProjectInstructions/addendums/assistant_execution_modes.md ++@@ -0,0 +1,120 @@ +++# Assistant Execution Modes +++ +++## Purpose +++ +++Standardize request interpretation and expected outputs for Review, Owner, Build PR, Continue, Challenge, and Stop Gate workflows. +++ +++## Command Modes +++ +++### Review +++ +++Expected Output: +++- Findings +++- Risks +++- Recommendations +++ +++Do Not Output: +++- PRs +++- Implementation plans +++ +++### Owner +++ +++Expected Output: +++- Decisions +++- Governance direction +++- Standards +++ +++Do Not Output: +++- Detailed implementation +++ +++### Build PR +++ +++Expected Output: +++- Single Codex work order +++- May contain multiple sequential PRs belonging to the same workstream +++- Copy/paste ready for execution +++ +++Should Include: +++- Start gates +++- Changes +++- Validation +++- Commit names +++- Stop point +++ +++Do Not Output: +++- Design discussion +++- Alternatives +++- Rationale +++- Architecture brainstorming +++ +++### Continue +++ +++Expected Output: +++- Next sequential executable PR +++- Next sequential work order +++ +++Do Not Output: +++- New ideas +++- Re-analysis +++- Additional brainstorming +++ +++### Challenge +++ +++Expected Output: +++- Risks +++- Contradictions +++- Better alternatives +++ +++Do Not Output: +++- Immediate implementation +++ +++### Stop Gate +++ +++Expected Output: +++- Why work should stop +++- Required corrections +++ +++Allowed Reasons: +++- Governance conflict +++- Architecture conflict +++- Security risk +++- Data loss risk +++- Major technical debt increase +++ +++## Additional Definitions +++ +++### Follow Project Instructions +++ +++Meaning: +++- Use existing governance +++- Do not redesign process +++ +++### Build the PR +++ +++Meaning: +++- Produce Codex executable work order immediately +++ +++### Continue +++ +++Meaning: +++- Produce next sequential work item +++ +++### No zip file +++ +++Meaning: +++- Generate instructions only +++- Do not expect artifact review +++ +++### You are owner +++ +++Meaning: +++- Make decisions +++- Do not ask for direction unless blocked +++ +++### Done for the day +++ +++Meaning: +++- Finish commits +++- Merge +++- Push +++- Create next-day start document ++diff --git a/docs_build/dev/ProjectInstructions/addendums/canonical_repository_structure.md b/docs_build/dev/ProjectInstructions/addendums/canonical_repository_structure.md ++new file mode 100644 ++index 000000000..e26939469 ++--- /dev/null +++++ b/docs_build/dev/ProjectInstructions/addendums/canonical_repository_structure.md ++@@ -0,0 +1,39 @@ +++# Canonical Repository Structure +++ +++## Purpose +++ +++Establish the canonical repository structure for future development and reduce technical debt. +++ +++## Canonical Structure +++ +++Tools: +++- toolbox/{tool-name}/index.html +++ +++Tool assets: +++- assets/toolbox/{tool-name}/js/index.js +++- assets/toolbox/{tool-name}/css/index.css +++ +++Themes: +++- assets/theme-v1/ +++- assets/theme-v2/ +++ +++Shared JavaScript: +++- assets/js/shared/ +++ +++Engine: +++- src/engine/{feature-name}/ +++ +++API: +++- api/{feature-name}/ +++ +++Serverside: +++- serverside/{feature-name}/ +++ +++## Rules +++ +++- Theme first. +++- Tool CSS second. +++- Shared functionality belongs in assets/js/shared/. +++- No new scattered JS folders. +++- No new scattered CSS folders. +++- New development follows the canonical structure. ++diff --git a/docs_build/dev/ProjectInstructions/addendums/codex_artifact_and_reporting_standard.md b/docs_build/dev/ProjectInstructions/addendums/codex_artifact_and_reporting_standard.md ++new file mode 100644 ++index 000000000..498e3895e ++--- /dev/null +++++ b/docs_build/dev/ProjectInstructions/addendums/codex_artifact_and_reporting_standard.md ++@@ -0,0 +1,66 @@ +++# Codex Artifact and Reporting Standard +++ +++## Purpose +++ +++Standardize Codex deliverables, completion reporting, and artifact generation. +++ +++## ZIP Artifact Requirement +++ +++Every Codex task must produce a ZIP artifact. +++ +++Applies to: +++- Success +++- Failure +++- Stop Gate +++- Partial Completion +++- Review Deliverables +++- Governance Deliverables +++ +++Minimum ZIP contents: +++- summary.md +++ +++Optional: +++- changed-files.txt +++- findings.md +++- validation.txt +++- generated artifacts +++ +++## Completion Reporting +++ +++Codex responses must include: +++- ZIP filename +++- ZIP location +++- PR number(s) +++- Merge commit(s) +++- Validation results +++ +++## Code Change Reporting +++ +++When a ZIP is uploaded, report executable code changes only. +++ +++Report format: +++ +++```text +++{relative path} - {added|updated|deleted} +++``` +++ +++Examples: +++ +++```text +++toolbox/text-to-speech/index.html - updated +++assets/toolbox/text-to-speech/js/index.js - added +++tests/toolbox/text-to-speech/functional.spec.mjs - updated +++``` +++ +++Do not report: +++- markdown +++- documentation +++- reports +++- notes +++- README updates +++ +++unless explicitly requested. +++ +++## No ZIP Means Incomplete +++ +++A task is not considered complete until the ZIP artifact is generated and reported. ++diff --git a/docs_build/dev/ProjectInstructions/addendums/codex_project_instructions_startup.md b/docs_build/dev/ProjectInstructions/addendums/codex_project_instructions_startup.md ++new file mode 100644 ++index 000000000..e0abb9db0 ++--- /dev/null +++++ b/docs_build/dev/ProjectInstructions/addendums/codex_project_instructions_startup.md ++@@ -0,0 +1,65 @@ +++# Codex Project Instructions Startup +++ +++## Purpose +++ +++Ensure Codex uses the current approved governance before making repository changes. +++ +++## Startup Requirement +++ +++Before performing work, Codex must review and use: +++ +++```text +++docs_build/dev/ProjectInstructions/ +++``` +++ +++Codex must use this as the only active source of truth for: +++- Governance rules +++- Repository standards +++- Ownership rules +++- Workflow rules +++- Addendums +++- Execution modes +++- Artifact requirements +++ +++Deprecated Project Instructions material outside `docs_build/dev/ProjectInstructions/` is reference-only and must not override active governance. +++ +++## Project Reference File Review +++ +++When present in `ProjectInstructions.zip`, the active project instruction directory, or `docs_build/dev/admin-notes/`, Codex must include these recognized project instruction/reference files in the Project Instructions read set: +++ +++- `Installs required.txt` +++- `Table layout.txt` +++ +++Chat instructions may supplement Project Instructions but must not override approved governance without explicit OWNER approval. +++ +++## Conflict Handling +++ +++If a chat instruction conflicts with Project Instructions: +++- Stop +++- Do not continue the PR +++- Produce the required ZIP artifact +++- Document the conflict in summary.md +++- Ask for OWNER direction +++ +++## Execution Mode Validation +++ +++When a request contains: +++- Build PR +++- Continue +++- Follow Project Instructions +++- Next PR +++ +++Codex must treat the request as Execution Mode. +++ +++Execution Mode means: +++- Execute the requested work order +++- Do not redesign the process +++- Do not provide alternatives unless a Stop Gate condition exists +++ +++## Validation +++ +++Before completing the PR: +++- Verify this addendum appears in the Project Instructions index +++- Verify markdown is valid +++- Verify all indexed addendums exist +++- Verify the required ZIP artifact is produced ++diff --git a/docs_build/dev/ProjectInstructions/addendums/legacy_migration_policy.md b/docs_build/dev/ProjectInstructions/addendums/legacy_migration_policy.md ++new file mode 100644 ++index 000000000..5e43679f4 ++--- /dev/null +++++ b/docs_build/dev/ProjectInstructions/addendums/legacy_migration_policy.md ++@@ -0,0 +1,33 @@ +++# Legacy Migration Policy +++ +++## Purpose +++ +++Reduce technical debt incrementally during normal development. +++ +++## Migration Trigger +++ +++Migration review is required when any of these actions touch legacy files: +++ +++- File modified +++- File renamed +++- Bug fix +++- Enhancement +++- Test modification +++ +++## Migration Process +++ +++1. Review JS location. +++2. Review CSS location. +++3. Review test location. +++4. Move touched files into canonical structure. +++5. Update imports. +++6. Update tests. +++7. Remove legacy references. +++ +++## Rules +++ +++- Legacy files may only be deleted when no active references remain. +++- Temporary bridge code must contain `TEMPORARY_MIGRATION` and a removal plan. +++- No new scattered JS locations. +++- No new scattered CSS locations. +++- No new scattered test locations. ++diff --git a/docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md b/docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md ++new file mode 100644 ++index 000000000..9ea3824e0 ++--- /dev/null +++++ b/docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md ++@@ -0,0 +1,61 @@ +++# Project Instructions Single Source And EOD Main Lock +++ +++Status: Approved +++Owner: OWNER +++ +++## Active Source +++ +++`docs_build/dev/ProjectInstructions/` is the only active Project Instructions source for Game Foundry Studio. +++ +++Deprecated reference locations must not be used as active instruction sources: +++- `docs_build/dev/PROJECT_INSTRUCTIONS.md` +++- `project-instructions/` +++- archived Project Instructions snapshots +++- generated PR reports +++ +++If deprecated reference material conflicts with `docs_build/dev/ProjectInstructions/`, the active folder wins unless OWNER explicitly approves a newer governance change. +++ +++## End Of Day +++ +++```text +++git checkout main +++git fetch origin +++git pull --ff-only origin main +++git status +++git rev-list --left-right --count main...origin/main +++``` +++ +++Required: +++ +++```text +++On branch main +++nothing to commit, working tree clean +++0 0 +++``` +++ +++The EOD report must record the final `HEAD` SHA as the published EOD SHA. +++ +++## Next Day Start +++ +++```text +++git checkout main +++git fetch origin +++git pull --ff-only origin main +++git status +++git rev-list --left-right --count main...origin/main +++git rev-parse HEAD +++``` +++ +++## Team Branch Creation Gate +++ +++No team creates a PR branch until: +++- Current branch: `main` +++- Worktree: clean +++- `main...origin/main`: `0 0` +++- `HEAD` SHA matches published EOD SHA +++ +++If any check fails, stop before branch creation and restore main to the published EOD state or request OWNER direction. +++ +++## Start Of Day Boundary +++ +++`docs_build/dev/start_of_day/` may point to `docs_build/dev/ProjectInstructions/`, but it must not become a second active Project Instructions source. ++diff --git a/docs_build/dev/ProjectInstructions/addendums/test_structure_standardization.md b/docs_build/dev/ProjectInstructions/addendums/test_structure_standardization.md ++new file mode 100644 ++index 000000000..997b16730 ++--- /dev/null +++++ b/docs_build/dev/ProjectInstructions/addendums/test_structure_standardization.md ++@@ -0,0 +1,33 @@ +++# Test Structure Standardization +++ +++## Purpose +++ +++Standardize testing locations and ensure independent tool validation. +++ +++## Canonical Test Structure +++ +++Tool tests: +++- tests/toolbox/{tool-name}/ +++ +++Engine tests: +++- tests/engine/{feature-name}/ +++ +++API tests: +++- tests/api/{feature-name}/ +++ +++Server tests: +++- tests/server/{feature-name}/ +++ +++Shared JavaScript tests: +++- tests/js/shared/ +++ +++Regression tests: +++- tests/regression/ +++ +++## Rules +++ +++- Every tool must be independently testable. +++- Regression tests do not replace tool tests. +++- Tool tests validate tool functionality. +++- Regression tests validate platform behavior. +++- New tests follow the canonical structure. ++diff --git a/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock.md b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock.md ++new file mode 100644 ++index 000000000..5c7927f17 ++--- /dev/null +++++ b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock.md ++@@ -0,0 +1,25 @@ +++# PR_26177_OWNER_007-project-instructions-single-source-eod-lock +++ +++Date: 2026-06-26 +++Scope: Project Instructions single-source and EOD main lock governance +++Status: PASS +++ +++## Summary +++ +++- Established `docs_build/dev/ProjectInstructions/` as the only active Project Instructions source. +++- Migrated legacy root `project-instructions/addendums/` content into active `docs_build/dev/ProjectInstructions/addendums/` files. +++- Marked legacy `docs_build/dev/PROJECT_INSTRUCTIONS.md` and `project-instructions/` material as deprecated reference only. +++- Added EOD main lock, next-day reset, and team branch creation gate governance. +++- Updated active team start and governance docs to reference only `docs_build/dev/ProjectInstructions/`. +++- No product/runtime, `start_of_day`, feature, or legacy SQLite file changes were made. +++ +++## Validation +++ +++- PASS: targeted grep found no active duplicate ProjectInstructions source-of-truth claim outside the active source. +++- PASS: targeted grep confirmed EOD/Next Day governance appears in active governance docs. +++- PASS: product/runtime and `start_of_day` changed-file check returned no files. +++- PASS: `git diff --check`. +++ +++## Artifact +++ +++- `tmp/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_delta.zip` ++diff --git a/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_branch-validation.md b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_branch-validation.md ++new file mode 100644 ++index 000000000..17e0bfc39 ++--- /dev/null +++++ b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_branch-validation.md ++@@ -0,0 +1,7 @@ +++# PR_26177_OWNER_007-project-instructions-single-source-eod-lock Branch Validation +++ +++- PASS: Started from `main`. +++- PASS: Start gate confirmed worktree clean before branch creation. +++- PASS: Start gate confirmed `main...origin/main` was `0 0` before branch creation. +++- PASS: Current branch is `PR_26177_OWNER_007-project-instructions-single-source-eod-lock`. +++- PASS: No `.vscode/settings.json` change is staged or included. ++diff --git a/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_manual-validation-notes.md b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_manual-validation-notes.md ++new file mode 100644 ++index 000000000..10cbb4170 ++--- /dev/null +++++ b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_manual-validation-notes.md ++@@ -0,0 +1,8 @@ +++# PR_26177_OWNER_007-project-instructions-single-source-eod-lock Manual Validation Notes +++ +++- Reviewed ProjectInstructions path and text references. +++- Confirmed active source declarations live under `docs_build/dev/ProjectInstructions/`. +++- Confirmed legacy locations are preserved as deprecated reference material rather than active sources. +++- Confirmed `docs_build/dev/start_of_day/` was not modified. +++- Confirmed no product/runtime files were modified. +++- Confirmed ZIP artifact path: `tmp/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_delta.zip`. ++diff --git a/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_requirement-checklist.md b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_requirement-checklist.md ++new file mode 100644 ++index 000000000..99ab45345 ++--- /dev/null +++++ b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_requirement-checklist.md ++@@ -0,0 +1,16 @@ +++# PR_26177_OWNER_007-project-instructions-single-source-eod-lock Requirement Checklist +++ +++- PASS: Audited repo for ProjectInstructions / project instructions duplicates. +++- PASS: Active source is `docs_build/dev/ProjectInstructions/`. +++- PASS: Legacy `docs_build/dev/PROJECT_INSTRUCTIONS.md` is marked deprecated. +++- PASS: Legacy root `project-instructions/` folder is marked deprecated. +++- PASS: Legacy root addendums are migrated into the active addendum tree. +++- PASS: Active team start/governance docs reference only `docs_build/dev/ProjectInstructions/`. +++- PASS: Added EOD command sequence. +++- PASS: Added required EOD output: `On branch main`, clean worktree, `0 0`. +++- PASS: Added Next Day Start command sequence. +++- PASS: Added team branch creation rule requiring main, clean worktree, `0 0`, and matching published EOD SHA. +++- PASS: Did not modify `start_of_day` folders. +++- PASS: Did not modify product/runtime files. +++- PASS: Did not remove, move, or overwrite legacy SQLite files. +++- PASS: Did not start feature work. ++diff --git a/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_validation-lane.md b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_validation-lane.md ++new file mode 100644 ++index 000000000..8a1b82360 ++--- /dev/null +++++ b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_validation-lane.md ++@@ -0,0 +1,17 @@ +++# PR_26177_OWNER_007-project-instructions-single-source-eod-lock Validation Lane +++ +++- PASS: duplicate-source grep returned no matches for old active source claims. +++- PASS: EOD/Next Day governance grep returned active governance matches. +++- PASS: product/runtime/start_of_day changed-file check returned no files. +++- PASS: git diff --check. +++ +++Commands used: +++ +++~~~text +++rg -n 'project-instructions/addendums|docs_build/dev/PROJECT_INSTRUCTIONS.md.*source of truth|Codex must always read `docs_build/dev/PROJECT_INSTRUCTIONS.md`|Read `docs_build/dev/PROJECT_INSTRUCTIONS.md`' docs_build/dev/ProjectInstructions docs_build/dev/PROJECT_INSTRUCTIONS.md project-instructions +++rg -n "End of Day:|Next Day Start:|HEAD.*published EOD SHA|only active Project Instructions source" docs_build/dev/ProjectInstructions +++git diff --name-only -- src assets toolbox games api serverside package.json package-lock.json docs_build/dev/start_of_day +++git diff --check +++~~~ +++ +++Full product/runtime tests were not run because this PR changes governance documentation only. ++diff --git a/project-instructions/README.md b/project-instructions/README.md ++new file mode 100644 ++index 000000000..af401852e ++--- /dev/null +++++ b/project-instructions/README.md ++@@ -0,0 +1,11 @@ +++# Deprecated Project Instructions Reference +++ +++This folder is preserved as historical reference only. +++ +++The only active Project Instructions source is: +++ +++```text +++docs_build/dev/ProjectInstructions/ +++``` +++ +++Do not use files under `project-instructions/` as active governance. If a file here conflicts with `docs_build/dev/ProjectInstructions/`, the active folder wins unless OWNER explicitly approves a newer governance change. diff --git a/project-instructions/README.md b/project-instructions/README.md new file mode 100644 index 000000000..af401852e @@ -1166,3 +2916,75 @@ index 000000000..af401852e +``` + +Do not use files under `project-instructions/` as active governance. If a file here conflicts with `docs_build/dev/ProjectInstructions/`, the active folder wins unless OWNER explicitly approves a newer governance change. +diff --git a/project-instructions/addendums/assistant-execution-modes.md b/project-instructions/addendums/assistant-execution-modes.md +index 6d7928669..4c5637d0d 100644 +--- a/project-instructions/addendums/assistant-execution-modes.md ++++ b/project-instructions/addendums/assistant-execution-modes.md +@@ -1,5 +1,7 @@ + # Assistant Execution Modes + ++> Deprecated reference notice: this file is preserved for history only. The active copy is `docs_build/dev/ProjectInstructions/addendums/assistant_execution_modes.md`. ++ + ## Purpose + + Standardize request interpretation and expected outputs for Review, Owner, Build PR, Continue, Challenge, and Stop Gate workflows. +diff --git a/project-instructions/addendums/canonical-repository-structure.md b/project-instructions/addendums/canonical-repository-structure.md +index e26939469..6b9dcb242 100644 +--- a/project-instructions/addendums/canonical-repository-structure.md ++++ b/project-instructions/addendums/canonical-repository-structure.md +@@ -1,5 +1,7 @@ + # Canonical Repository Structure + ++> Deprecated reference notice: this file is preserved for history only. The active copy is `docs_build/dev/ProjectInstructions/addendums/canonical_repository_structure.md`. ++ + ## Purpose + + Establish the canonical repository structure for future development and reduce technical debt. +diff --git a/project-instructions/addendums/codex-artifact-and-reporting-standard.md b/project-instructions/addendums/codex-artifact-and-reporting-standard.md +index 3f16a3641..8d1327886 100644 +--- a/project-instructions/addendums/codex-artifact-and-reporting-standard.md ++++ b/project-instructions/addendums/codex-artifact-and-reporting-standard.md +@@ -1,5 +1,7 @@ + # Codex Artifact and Reporting Standard + ++> Deprecated reference notice: this file is preserved for history only. The active copy is `docs_build/dev/ProjectInstructions/addendums/codex_artifact_and_reporting_standard.md`. ++ + ## Purpose + + Standardize Codex deliverables, completion reporting, and artifact generation. +diff --git a/project-instructions/addendums/codex-project-instructions-startup.md b/project-instructions/addendums/codex-project-instructions-startup.md +index 94744f06e..135498b42 100644 +--- a/project-instructions/addendums/codex-project-instructions-startup.md ++++ b/project-instructions/addendums/codex-project-instructions-startup.md +@@ -1,5 +1,7 @@ + # Codex Project Instructions Startup + ++> Deprecated reference notice: this file is preserved for history only. The active copy is `docs_build/dev/ProjectInstructions/addendums/codex_project_instructions_startup.md`. ++ + ## Purpose + + Ensure Codex uses the current approved governance before making repository changes. +diff --git a/project-instructions/addendums/legacy-migration-policy.md b/project-instructions/addendums/legacy-migration-policy.md +index 5e43679f4..5515a1728 100644 +--- a/project-instructions/addendums/legacy-migration-policy.md ++++ b/project-instructions/addendums/legacy-migration-policy.md +@@ -1,5 +1,7 @@ + # Legacy Migration Policy + ++> Deprecated reference notice: this file is preserved for history only. The active copy is `docs_build/dev/ProjectInstructions/addendums/legacy_migration_policy.md`. ++ + ## Purpose + + Reduce technical debt incrementally during normal development. +diff --git a/project-instructions/addendums/test-structure-standardization.md b/project-instructions/addendums/test-structure-standardization.md +index 997b16730..eeb62d561 100644 +--- a/project-instructions/addendums/test-structure-standardization.md ++++ b/project-instructions/addendums/test-structure-standardization.md +@@ -1,5 +1,7 @@ + # Test Structure Standardization + ++> Deprecated reference notice: this file is preserved for history only. The active copy is `docs_build/dev/ProjectInstructions/addendums/test_structure_standardization.md`. ++ + ## Purpose + + Standardize testing locations and ensure independent tool validation. From 050cbb16c80149bc9049fd626dd9ec6e4d3be55b Mon Sep 17 00:00:00 2001 From: Alfa Team Date: Fri, 26 Jun 2026 11:31:20 -0400 Subject: [PATCH 3/9] Canonicalize ProjectInstructions branch lifecycle --- docs_build/dev/BUILD_PR.md | 4 +- docs_build/dev/PLAN_PR.md | 4 +- .../PROJECT_INSTRUCTIONS.md | 2 +- docs_build/dev/ProjectInstructions/README.txt | 6 +- .../TEAM_START_COMMANDS.md | 36 +- .../addendums/branch_context_governance.md | 7 +- .../addendums/branch_lock_governance.md | 38 +- .../codex_project_instructions_startup.md | 44 +- .../addendums/multi_team.md | 4 +- .../addendums/pr_workflow.md | 57 +- ...ect_instructions_single_source_eod_lock.md | 167 +- .../addendums/release_gate.md | 2 + .../addendums/team_release_readiness.md | 4 + .../addendums/team_start_and_release.md | 24 +- .../team_assignments/TEAM_ASSIGNMENTS.md | 49 +- ...ect-instructions-single-source-eod-lock.md | 16 +- ...ingle-source-eod-lock_branch-validation.md | 1 + ...source-eod-lock_manual-validation-notes.md | 6 +- ...e-source-eod-lock_requirement-checklist.md | 35 +- ...-single-source-eod-lock_validation-lane.md | 8 +- .../dev/reports/codex_changed_files.txt | 5 + docs_build/dev/reports/codex_review.diff | 8762 ++++++++++++++--- 22 files changed, 7880 insertions(+), 1401 deletions(-) diff --git a/docs_build/dev/BUILD_PR.md b/docs_build/dev/BUILD_PR.md index fbff4d261..c375aee47 100644 --- a/docs_build/dev/BUILD_PR.md +++ b/docs_build/dev/BUILD_PR.md @@ -14,7 +14,7 @@ This `BUILD_PR.md`, `PLAN_PR.md`, and the user request are the source of truth f - Establish `docs_build/dev/ProjectInstructions/` as the only active source. - Mark all other ProjectInstructions-style sources changed by this PR as deprecated references. - Update active team start/governance docs to reference only `docs_build/dev/ProjectInstructions/`. -- Add EOD main lock, next-day reset governance, and explicit START / WORK / END branch lifecycle rules. +- Add EOD main lock, next-day reset governance, and canonical START / WORK / END branch lifecycle rules. - Add required reports under `docs_build/dev/reports/`. ## Exact Targets @@ -46,7 +46,7 @@ Run: ```powershell rg -n 'project-instructions/addendums|docs_build/dev/PROJECT_INSTRUCTIONS.md.*source of truth|Codex must always read `docs_build/dev/PROJECT_INSTRUCTIONS.md`|Read `docs_build/dev/PROJECT_INSTRUCTIONS.md`' docs_build/dev/ProjectInstructions docs_build/dev/PROJECT_INSTRUCTIONS.md project-instructions -rg -n "START RULE|WORK RULE|END RULE|HARD STOP before committing|Codex commits only to the PR branch|HEAD SHA recorded as new EOD baseline|End of Day:|Next Day Start:|HEAD.*published EOD SHA|only active Project Instructions source" docs_build/dev/ProjectInstructions +rg -n "Branch Lifecycle \\(Canonical\\)|Every PR follows exactly three phases|^START$|^WORK$|^END$|Mandatory Hard Stops|tomorrow's official baseline|No commits on main|Never checkout main|Only after ALL four pass" docs_build/dev/ProjectInstructions git diff --name-only -- src assets toolbox games api serverside package.json package-lock.json docs_build/dev/start_of_day git diff --check ``` diff --git a/docs_build/dev/PLAN_PR.md b/docs_build/dev/PLAN_PR.md index 505e274bd..0e5d6a50e 100644 --- a/docs_build/dev/PLAN_PR.md +++ b/docs_build/dev/PLAN_PR.md @@ -10,7 +10,7 @@ Make `docs_build/dev/ProjectInstructions/` the only active Project Instructions - Mark legacy ProjectInstructions-style sources as deprecated reference material. - Move active legacy addendums into `docs_build/dev/ProjectInstructions/addendums/`. - Update active team start and governance docs to reference only `docs_build/dev/ProjectInstructions/`. -- Add EOD main lock, next-day reset, team PR branch creation gate, and explicit START / WORK / END branch lifecycle rules. +- Add EOD main lock, next-day reset, team PR branch creation gate, and canonical START / WORK / END branch lifecycle rules. - Add required Codex reports under `docs_build/dev/reports/`. ## Out Of Scope @@ -23,6 +23,6 @@ Make `docs_build/dev/ProjectInstructions/` the only active Project Instructions ## Validation Plan 1. Run targeted grep/search proving no active duplicate ProjectInstructions source remains. -2. Confirm EOD/Next Day and START / WORK / END branch lifecycle rules appear in active governance docs. +2. Confirm EOD/Next Day and canonical START / WORK / END branch lifecycle rules appear in active governance docs. 3. Confirm no product/runtime files changed. 4. Run `git diff --check`. diff --git a/docs_build/dev/ProjectInstructions/PROJECT_INSTRUCTIONS.md b/docs_build/dev/ProjectInstructions/PROJECT_INSTRUCTIONS.md index 99ddd0f42..647881f1f 100644 --- a/docs_build/dev/ProjectInstructions/PROJECT_INSTRUCTIONS.md +++ b/docs_build/dev/ProjectInstructions/PROJECT_INSTRUCTIONS.md @@ -49,7 +49,7 @@ Existing Project Instructions outside `docs_build/dev/ProjectInstructions/` rema ## Single Source and Main Lock Governance -`docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md` defines the single active Project Instructions source, EOD main lock, next-day reset, and team branch creation gate. +`docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md` defines the single active Project Instructions source, canonical START / WORK / END branch lifecycle, EOD main lock, next-day reset, team branch creation gate, daily synchronization baseline, and mandatory hard stops. ## Merge Control diff --git a/docs_build/dev/ProjectInstructions/README.txt b/docs_build/dev/ProjectInstructions/README.txt index 631fd3918..50736f317 100644 --- a/docs_build/dev/ProjectInstructions/README.txt +++ b/docs_build/dev/ProjectInstructions/README.txt @@ -13,7 +13,10 @@ Team assignment workflow: Team assignments are tracked under team_assignments/. A team pulls work from BACKLOG_MASTER.md, marks the item building when assigned, and records the active assignment under the owning team. Teams work only on assigned items unless an OWNER override explicitly changes the assignment. No direct commits to main: -Do not commit directly to main unless the owner explicitly instructs that exception. Normal work must use PR branches, draft PRs, validation evidence, and owner-controlled merge approval. +Do not commit directly to main. Normal work must use PR branches, draft PRs, validation evidence, and owner-controlled merge approval. + +Branch lifecycle: +Every PR follows exactly three phases: START, WORK, END. The canonical lifecycle is `docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md`. OWNER override rule: An OWNER override must use this wording: @@ -40,6 +43,7 @@ READ THIS FIRST 9. Follow OWNER governance decisions. 10. When guidance conflicts, newest OWNER-approved guidance wins. 11. Batch Governance Mode is the default for governance, documentation, and administrative work. +12. Follow the canonical START / WORK / END lifecycle. Addendum index: - Single Source and EOD Main Lock: docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md diff --git a/docs_build/dev/ProjectInstructions/TEAM_START_COMMANDS.md b/docs_build/dev/ProjectInstructions/TEAM_START_COMMANDS.md index 192278a34..292540043 100644 --- a/docs_build/dev/ProjectInstructions/TEAM_START_COMMANDS.md +++ b/docs_build/dev/ProjectInstructions/TEAM_START_COMMANDS.md @@ -11,31 +11,15 @@ No team creates a PR branch until all checks pass: Use `docs_build/dev/ProjectInstructions/` as the only active Project Instructions source. -START RULE: -- Every team starts on `main`. -- `main` must be clean. -- `main...origin/main` must be `0 0`. -- `HEAD` SHA must match published EOD SHA. -- Only then create or switch to the PR branch. -- No commits are allowed on `main`. - -WORK RULE: -- Codex must remain on the PR branch during implementation. -- Codex commits only to the PR branch. -- Codex pushes only the PR branch. -- HARD STOP if branch changes unexpectedly. -- HARD STOP before committing if current branch is `main`. - -END RULE: -- After PR validation, push the PR branch. -- Merge PR into `main` only when approved. -- Checkout `main`. -- Run `git fetch origin`. -- Run `git pull --ff-only origin main`. -- Confirm current branch is `main`. -- Confirm worktree is clean. -- Confirm `main...origin/main` is `0 0`. -- Record `HEAD` SHA as new EOD baseline. +Branch Lifecycle (Canonical): +- Every PR follows exactly three phases: START, WORK, END. +- Follow `docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md`. +- START begins on synchronized `main` and creates the PR branch only after all gates pass. +- WORK remains on the PR branch. Never checkout `main`. +- END merges, returns to synchronized `main`, publishes branch, HEAD SHA, and date/time, then stops all work. +- No commits on `main`. +- No implementation on `main`. +- No validation on `main` except start validation. ## Start Team Alfa @@ -180,4 +164,6 @@ git pull --ff-only origin main git status git rev-list --left-right --count main...origin/main git rev-parse HEAD + +Publish Branch, HEAD SHA, and Date/time. This becomes tomorrow's official baseline. ``` diff --git a/docs_build/dev/ProjectInstructions/addendums/branch_context_governance.md b/docs_build/dev/ProjectInstructions/addendums/branch_context_governance.md index 09cd3a1ec..798bb2cba 100644 --- a/docs_build/dev/ProjectInstructions/addendums/branch_context_governance.md +++ b/docs_build/dev/ProjectInstructions/addendums/branch_context_governance.md @@ -21,6 +21,8 @@ At the start of work, report or validate: - active PR number/name or explicit `PLAN_ONLY` - previous PR Closed status unless this is an explicitly documented stacked PR chain +Session start must follow the canonical START phase in `docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md`. + ## Stop Conditions Stop and report before changing files when: @@ -38,6 +40,8 @@ Stop and report before changing files when: After a branch is created, the branch remains the working context. +This is the canonical WORK phase: remain on the PR branch, never checkout `main`, commit only on the PR branch, push only the PR branch, validate from the PR branch, and open/update the PR from the PR branch. + Do not automatically return to `main` after: - commit @@ -47,7 +51,7 @@ Do not automatically return to `main` after: - review updates - additional commits -Return to `main` only after the PR is merged, the branch is retired, or OWNER explicitly says to return to `main`. +Return to `main` only in the canonical END phase after the PR is merged, the branch is retired, or OWNER explicitly says to return to `main`. Returning to `main` is required before Closed can be recorded. @@ -58,6 +62,7 @@ Closed branch context requires: - local/origin sync is `0/0` - no untracked files - source branch disposition recorded as `retained` +- branch, HEAD SHA, and date/time recorded as the new EOD baseline when this is EOD closeout ## GitHub Authority diff --git a/docs_build/dev/ProjectInstructions/addendums/branch_lock_governance.md b/docs_build/dev/ProjectInstructions/addendums/branch_lock_governance.md index e6ab30ae8..61b95cfae 100644 --- a/docs_build/dev/ProjectInstructions/addendums/branch_lock_governance.md +++ b/docs_build/dev/ProjectInstructions/addendums/branch_lock_governance.md @@ -24,6 +24,7 @@ Keep active work attached to the correct assigned team, branch, and OWNER decisi - Start from current `main`. - Pull latest `origin/main` before creating a work branch. - Do not create a PR branch unless current branch is `main`, worktree is clean, `main...origin/main` is `0 0`, and `HEAD` SHA matches the published EOD SHA. +- Follow the canonical START / WORK / END lifecycle in `docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md`. - Keep work on the active branch until the PR is merged, the branch is retired, or OWNER says to return to `main`. - Do not commit directly to `main`. - HARD STOP before committing if current branch is `main`. @@ -34,34 +35,23 @@ Keep active work attached to the correct assigned team, branch, and OWNER decisi - Retain source branches by default after merge and closeout. - Record branch disposition before Closed as `retained`. -## START RULE +## Branch Lifecycle (Canonical) -- Every team starts on `main`. -- `main` must be clean. -- `main...origin/main` must be `0 0`. -- `HEAD` SHA must match published EOD SHA. -- Only then create or switch to the PR branch. -- No commits are allowed on `main`. +Every PR follows exactly three phases: -## WORK RULE +```text +START +WORK +END +``` -- Codex must remain on the PR branch during implementation. -- Codex commits only to the PR branch. -- Codex pushes only the PR branch. -- HARD STOP if branch changes unexpectedly. -- HARD STOP before committing if current branch is `main`. +The canonical lifecycle lives in `docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md`. -## END RULE - -- After PR validation, push the PR branch. -- Merge PR into `main` only when approved. -- Checkout `main`. -- Run `git fetch origin`. -- Run `git pull --ff-only origin main`. -- Confirm current branch is `main`. -- Confirm worktree is clean. -- Confirm `main...origin/main` is `0 0`. -- Record `HEAD` SHA as new EOD baseline. +Branch lock governance enforces: +- START on synchronized `main`. +- WORK only on the PR branch. +- END by merging, returning to synchronized `main`, publishing branch, HEAD SHA, and date/time, then stopping all work. +- Mandatory hard stops before commits on `main`, dirty branch creation, non-`0 0` main sync, baseline SHA mismatch, unvalidated merge, or new PR work before synchronized main return. ## OWNER Override diff --git a/docs_build/dev/ProjectInstructions/addendums/codex_project_instructions_startup.md b/docs_build/dev/ProjectInstructions/addendums/codex_project_instructions_startup.md index dba8f8d93..ee11393b4 100644 --- a/docs_build/dev/ProjectInstructions/addendums/codex_project_instructions_startup.md +++ b/docs_build/dev/ProjectInstructions/addendums/codex_project_instructions_startup.md @@ -23,31 +23,25 @@ Codex must use this as the only active source of truth for: ## Branch Lifecycle Start Gate -START RULE: -- Every team starts on `main`. -- `main` must be clean. -- `main...origin/main` must be `0 0`. -- `HEAD` SHA must match published EOD SHA. -- Only then create or switch to the PR branch. -- No commits are allowed on `main`. - -WORK RULE: -- Codex must remain on the PR branch during implementation. -- Codex commits only to the PR branch. -- Codex pushes only the PR branch. -- HARD STOP if branch changes unexpectedly. -- HARD STOP before committing if current branch is `main`. - -END RULE: -- After PR validation, push the PR branch. -- Merge PR into `main` only when approved. -- Checkout `main`. -- Run `git fetch origin`. -- Run `git pull --ff-only origin main`. -- Confirm current branch is `main`. -- Confirm worktree is clean. -- Confirm `main...origin/main` is `0 0`. -- Record `HEAD` SHA as new EOD baseline. +Every PR follows exactly three phases: + +```text +START +WORK +END +``` + +Codex must follow the canonical lifecycle in: + +`docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md` + +Startup enforcement: +- START begins on synchronized `main`. +- WORK remains on the PR branch. Never checkout `main`. +- END merges, returns to synchronized `main`, publishes branch, HEAD SHA, and date/time, then stops all work. +- STOP if current branch is `main` before commit. +- STOP if attempting to push `main`. +- STOP if a new PR starts before returning to synchronized `main`. Deprecated Project Instructions material outside `docs_build/dev/ProjectInstructions/` is reference-only and must not override active governance. diff --git a/docs_build/dev/ProjectInstructions/addendums/multi_team.md b/docs_build/dev/ProjectInstructions/addendums/multi_team.md index d8acc7b0e..7ba2cae8d 100644 --- a/docs_build/dev/ProjectInstructions/addendums/multi_team.md +++ b/docs_build/dev/ProjectInstructions/addendums/multi_team.md @@ -51,6 +51,7 @@ Rules: - One Codex session may execute multiple sequential PRs. - Each PR must still have one clear purpose. - Each PR must create or use its own approved branch. +- Each PR must follow the canonical START / WORK / END lifecycle in `docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md`. - Each PR may be committed and pushed during active work. - Each PR may be opened as a draft PR during active work. - Do not commit directly to main. @@ -69,13 +70,14 @@ During active work: - Pushes are allowed and expected. - Draft PRs are allowed and expected. - Direct commits to main are prohibited. +- WORK remains on the PR branch; never checkout main during WORK. - Merges to main are prohibited unless explicitly approved by the owner. At end of day: - Owner reviews ready PRs. - Owner explicitly approves which PRs merge. - Only owner-approved PRs may merge to main. -- After merge, return to main and pull latest main. +- After merge, execute the canonical END phase, return to synchronized main, and publish branch, HEAD SHA, and date/time. - Do not treat sequential PR completion as merge approval. Commit/push during the day is allowed only on assigned team/OWNER/PR branches. diff --git a/docs_build/dev/ProjectInstructions/addendums/pr_workflow.md b/docs_build/dev/ProjectInstructions/addendums/pr_workflow.md index abad0b789..02391a8be 100644 --- a/docs_build/dev/ProjectInstructions/addendums/pr_workflow.md +++ b/docs_build/dev/ProjectInstructions/addendums/pr_workflow.md @@ -26,36 +26,33 @@ Define the standard pull request workflow for Game Foundry Studio. 15. Pull latest main before starting the next PR. 16. Verify Main Verified and Closed gates. -## Branch Lifecycle Governance - -### START RULE - -- Every team starts on `main`. -- `main` must be clean. -- `main...origin/main` must be `0 0`. -- `HEAD` SHA must match published EOD SHA. -- Only then create or switch to the PR branch. -- No commits are allowed on `main`. - -### WORK RULE - -- Codex must remain on the PR branch during implementation. -- Codex commits only to the PR branch. -- Codex pushes only the PR branch. -- HARD STOP if branch changes unexpectedly. -- HARD STOP before committing if current branch is `main`. - -### END RULE - -- After PR validation, push the PR branch. -- Merge PR into `main` only when approved. -- Checkout `main`. -- Run `git fetch origin`. -- Run `git pull --ff-only origin main`. -- Confirm current branch is `main`. -- Confirm worktree is clean. -- Confirm `main...origin/main` is `0 0`. -- Record `HEAD` SHA as new EOD baseline. +## Branch Lifecycle (Canonical) + +Every PR follows exactly three phases: + +```text +START +WORK +END +``` + +The canonical START, WORK, END, Daily Synchronization, and Mandatory Hard Stops rules live in: + +`docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md` + +PR workflow must follow that lifecycle exactly. + +Summary: +- START happens on synchronized `main` only and creates the PR branch only after all required gates pass. +- WORK happens only on the PR branch. +- END validates, commits, pushes, opens/updates the PR, merges, returns to synchronized `main`, publishes branch, HEAD SHA, and date/time, then stops all work. +- No commits on `main`. +- No implementation on `main`. +- No validation on `main` except start validation. +- Never checkout `main` during WORK. +- STOP before commit if current branch is `main`. +- STOP if current branch changes unexpectedly. +- STOP if attempting to push `main`. ## PR Lifecycle States diff --git a/docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md b/docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md index c41dc503d..dd5744c80 100644 --- a/docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md +++ b/docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md @@ -56,36 +56,143 @@ No team creates a PR branch until: If any check fails, stop before branch creation and restore main to the published EOD state or request OWNER direction. -## Branch Lifecycle Governance - -### START RULE - -- Every team starts on `main`. -- `main` must be clean. -- `main...origin/main` must be `0 0`. -- `HEAD` SHA must match published EOD SHA. -- Only then create or switch to the PR branch. -- No commits are allowed on `main`. - -### WORK RULE - -- Codex must remain on the PR branch during implementation. -- Codex commits only to the PR branch. -- Codex pushes only the PR branch. -- HARD STOP if branch changes unexpectedly. -- HARD STOP before committing if current branch is `main`. - -### END RULE - -- After PR validation, push the PR branch. -- Merge PR into `main` only when approved. -- Checkout `main`. -- Run `git fetch origin`. -- Run `git pull --ff-only origin main`. -- Confirm current branch is `main`. -- Confirm worktree is clean. -- Confirm `main...origin/main` is `0 0`. -- Record `HEAD` SHA as new EOD baseline. +## Branch Lifecycle (Canonical) + +Every PR follows exactly three phases: + +```text +START +WORK +END +``` + +## START + +Every team begins on `main`. + +Required: + +```text +git checkout main +git fetch origin +git pull --ff-only origin main +git status +git rev-list --left-right --count main...origin/main +git rev-parse HEAD +``` + +Required results: + +```text +Current branch: main +Working tree clean +main...origin/main +0 0 +HEAD equals published EOD SHA +``` + +Only after ALL four pass may a branch be created. + +Create the PR branch: + +```text +git switch -c PR_ +``` + +Rules: + +- No commits on `main`. +- No implementation on `main`. +- No validation on `main` except start validation. + +## WORK + +From branch creation until merge: + +- Remain on the PR branch. +- Never checkout `main`. +- Commit only on the PR branch. +- Push only the PR branch. +- Execute validation from the PR branch. +- Open/update the PR from the PR branch. + +Hard Stops: + +```text +If current branch == main before commit: + STOP + +If current branch changes unexpectedly: + STOP + +If attempting to push main: + STOP +``` + +## END + +After validation succeeds: + +```text +Commit +Push PR branch +Open/update PR +Merge PR +``` + +Immediately execute: + +```text +git checkout main +git fetch origin +git pull --ff-only origin main +git status +git rev-list --left-right --count main...origin/main +git rev-parse HEAD +``` + +Required result: + +```text +Current branch: main +Working tree clean +main...origin/main +0 0 +``` + +Publish: + +```text +Branch +HEAD SHA +Date/time +``` + +This becomes tomorrow's official baseline. + +Stop all work. + +## Daily Synchronization + +End of every day publish: + +```text +Branch: main +HEAD SHA +``` + +Every team must begin tomorrow from that exact SHA. + +## Mandatory Hard Stops + +STOP if: + +- current branch is `main` before commit +- worktree dirty before creating PR branch +- `main...origin/main` is not `0 0` before creating PR branch +- `HEAD` SHA differs from published baseline +- merge attempted without successful validation +- new PR started before returning to synchronized `main` ## Start Of Day Boundary diff --git a/docs_build/dev/ProjectInstructions/addendums/release_gate.md b/docs_build/dev/ProjectInstructions/addendums/release_gate.md index c45a2c49d..57620f816 100644 --- a/docs_build/dev/ProjectInstructions/addendums/release_gate.md +++ b/docs_build/dev/ProjectInstructions/addendums/release_gate.md @@ -22,6 +22,7 @@ Before a governance, documentation, or administrative PR is merged, validate: - PR workflow guidance remains intact. - Team assignment governance remains intact. - Active team registry guidance remains compatible with temporary active teams. +- Canonical START / WORK / END branch lifecycle guidance remains intact. - No protected Project Instructions guidance was deleted. - No permanent team roster or permanent discipline ownership was restored. - No direct-to-main commit rule was bypassed. @@ -36,6 +37,7 @@ The release gate should confirm these files when relevant to the PR: - `docs_build/dev/ProjectInstructions/backlog/BACKLOG_MASTER.md` - `docs_build/dev/ProjectInstructions/addendums/governance_phase1_complete.md` - `docs_build/dev/ProjectInstructions/addendums/pr_workflow.md` +- `docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md` - `docs_build/dev/ProjectInstructions/addendums/project_reference_files.md` - `docs_build/dev/ProjectInstructions/addendums/environment_governance_model.md` - `docs_build/dev/ProjectInstructions/addendums/environment_configuration_standards.md` diff --git a/docs_build/dev/ProjectInstructions/addendums/team_release_readiness.md b/docs_build/dev/ProjectInstructions/addendums/team_release_readiness.md index 9a2addbdc..225a2e4ab 100644 --- a/docs_build/dev/ProjectInstructions/addendums/team_release_readiness.md +++ b/docs_build/dev/ProjectInstructions/addendums/team_release_readiness.md @@ -18,9 +18,13 @@ Teams may start only when all of the following are true: - OWNER governance exists. - One-active-branch-per-team rule exists. - No-direct-main rule exists. +- Canonical START / WORK / END lifecycle exists. - Out-of-scope stop rule exists. - Build Path sync rule exists. - PR lifecycle states exist in order: PR Open, Plan, Build, Validation, Approved, Merged, Main Verified, Closed. +- START requires synchronized `main`, clean worktree, `main...origin/main` `0 0`, and HEAD matching published EOD SHA before branch creation. +- WORK requires remaining on the PR branch. +- END requires merge, return to synchronized `main`, and publishing branch, HEAD SHA, and date/time. - Previous-PR Closed gate exists before a team starts another PR, except explicitly documented stacked PR chains. - Final closeout output includes branch, worktree, local/origin sync, PR number/name, PR status, merge/final commit, branch disposition, backlog update status, tool state update status, ZIP path, and Closeout PASS/FAIL. 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 26c337ee1..e2d6b7226 100644 --- a/docs_build/dev/ProjectInstructions/addendums/team_start_and_release.md +++ b/docs_build/dev/ProjectInstructions/addendums/team_start_and_release.md @@ -13,9 +13,11 @@ OWNER identifies available teams when starting work. Before a team starts, validate: -- current branch and expected branch are known -- worktree is clean or unrelated changes are understood -- `main` is current when a new branch is required +- canonical START phase is complete +- current branch is `main` +- worktree is clean +- `main...origin/main` is `0 0` +- `HEAD` SHA matches published EOD SHA - active assignment is selected or confirmed by OWNER - assigned team uses NATO phonetic naming - work remains with the assigned team until complete or OWNER reassignment @@ -62,13 +64,14 @@ For backlog-driven work: 2. Select only the OWNER-approved backlog item. 3. Use the approved status model from `status_model.md`. 4. Confirm the previous PR for the team is Closed, unless this is an explicitly documented stacked PR chain. -5. Create or use the approved team branch and PR identity. -6. Mark lifecycle state as PR Open. -7. Plan on the same PR branch. -8. Build on the same PR branch. -9. Record active work in the active team registry when required. -10. Open or update a draft PR during active work. -11. Merge only through OWNER-approved PR workflow. +5. Follow the canonical START phase in `project_instructions_single_source_eod_lock.md`. +6. Create or use the approved team branch and PR identity only after START passes. +7. Mark lifecycle state as PR Open. +8. Plan on the same PR branch. +9. Build on the same PR branch. +10. Record active work in the active team registry when required. +11. Open or update a draft PR during active WORK. +12. Merge only through OWNER-approved PR workflow and canonical END. ## Team Command Examples @@ -94,6 +97,7 @@ A team or OWNER PR is release-ready when: - PR summary states the validation result - lifecycle state is at least Validation - required reports and repo-structured ZIP under `tmp/` exist before Closed +- canonical END publishes branch, HEAD SHA, and date/time when the PR merges Closed readiness requires: - PR merged and pushed diff --git a/docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md b/docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md index f70440ad2..f4d7e4bb8 100644 --- a/docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md +++ b/docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md @@ -253,30 +253,25 @@ No team creates a PR branch until: Active source rule: Teams must use only `docs_build/dev/ProjectInstructions/` as the active Project Instructions source. -## Explicit Branch Lifecycle Governance - -START RULE: -- Every team starts on `main`. -- `main` must be clean. -- `main...origin/main` must be `0 0`. -- `HEAD` SHA must match published EOD SHA. -- Only then create or switch to the PR branch. -- No commits are allowed on `main`. - -WORK RULE: -- Codex must remain on the PR branch during implementation. -- Codex commits only to the PR branch. -- Codex pushes only the PR branch. -- HARD STOP if branch changes unexpectedly. -- HARD STOP before committing if current branch is `main`. - -END RULE: -- After PR validation, push the PR branch. -- Merge PR into `main` only when approved. -- Checkout `main`. -- Run `git fetch origin`. -- Run `git pull --ff-only origin main`. -- Confirm current branch is `main`. -- Confirm worktree is clean. -- Confirm `main...origin/main` is `0 0`. -- Record `HEAD` SHA as new EOD baseline. +## Branch Lifecycle (Canonical) + +Every PR follows exactly three phases: + +```text +START +WORK +END +``` + +Teams must follow `docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md`. + +Assignment governance enforces: +- START begins on synchronized `main`. +- WORK remains on the PR branch. Never checkout `main`. +- END merges, returns to synchronized `main`, publishes branch, HEAD SHA, and date/time, then stops all work. +- No commits on `main`. +- No implementation on `main`. +- No validation on `main` except start validation. +- STOP if current branch is `main` before commit. +- STOP if attempting to push `main`. +- STOP if new PR work starts before returning to synchronized `main`. diff --git a/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock.md b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock.md index ed2f3e94a..3f1c3f952 100644 --- a/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock.md +++ b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock.md @@ -1,24 +1,24 @@ # PR_26177_OWNER_007-project-instructions-single-source-eod-lock Date: 2026-06-26 -Scope: Project Instructions single-source, EOD main lock, and branch lifecycle governance +Scope: Project Instructions single-source and canonical branch lifecycle governance Status: PASS ## Summary - Established docs_build/dev/ProjectInstructions/ as the only active Project Instructions source. -- Migrated legacy root project-instructions/addendums/ content into active docs_build/dev/ProjectInstructions/addendums/ files. -- Marked legacy docs_build/dev/PROJECT_INSTRUCTIONS.md and project-instructions/ material as deprecated reference only. -- Added EOD main lock, next-day reset, and team branch creation gate governance. -- Added explicit START RULE, WORK RULE, and END RULE branch lifecycle governance. -- Updated active team start and Codex workflow docs under docs_build/dev/ProjectInstructions/. +- Added canonical Branch Lifecycle governance: START, WORK, END. +- Documented START commands and required results, including clean main, main...origin/main 0 0, and HEAD matching published EOD SHA. +- Documented WORK rules requiring Codex to remain on the PR branch, validate from the PR branch, commit only on the PR branch, and push only the PR branch. +- Documented END rules requiring PR branch push, PR update, merge, immediate main checkout/fetch/ff-only pull, clean 0 0 confirmation, and publication of Branch, HEAD SHA, and date/time as the next baseline. +- Added mandatory hard stops for main-before-commit, dirty branch creation, non-synced main, baseline mismatch, unvalidated merge, and starting new PR work before synchronized main return. +- Updated active governance/team workflow docs under docs_build/dev/ProjectInstructions/ to reference the canonical lifecycle. - No product/runtime, start_of_day, feature, or legacy SQLite file changes were made. ## Validation - PASS: targeted grep found no active duplicate ProjectInstructions source-of-truth claim outside the active source. -- PASS: targeted grep confirmed EOD/Next Day governance appears in active governance docs. -- PASS: targeted grep confirmed START / WORK / END branch lifecycle governance appears in active governance docs. +- PASS: targeted grep confirmed canonical lifecycle language appears in active governance docs. - PASS: product/runtime and start_of_day changed-file check returned no files. - PASS: git diff --check. diff --git a/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_branch-validation.md b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_branch-validation.md index b54d77ced..9750dc7b9 100644 --- a/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_branch-validation.md +++ b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_branch-validation.md @@ -4,3 +4,4 @@ - PASS: Work remained on the PR branch during implementation. - PASS: No commit was made on main. - PASS: No .vscode/settings.json change is staged or included. +- PASS: Report manifest generated from branch merge-base 520199ccc98ca54ad599095672d13b7b8aab188e. diff --git a/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_manual-validation-notes.md b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_manual-validation-notes.md index 5d9f186fa..f2e3bad4a 100644 --- a/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_manual-validation-notes.md +++ b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_manual-validation-notes.md @@ -1,9 +1,9 @@ # PR_26177_OWNER_007-project-instructions-single-source-eod-lock Manual Validation Notes - Reviewed active ProjectInstructions branch lifecycle wording. -- Confirmed START RULE, WORK RULE, and END RULE are documented in active governance docs. -- Confirmed active source declarations live under docs_build/dev/ProjectInstructions/. -- Confirmed legacy locations remain deprecated reference material rather than active sources. +- Confirmed canonical START, WORK, and END phases are documented. +- Confirmed active governance/team workflow docs reference docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md or summarize the canonical lifecycle. - Confirmed docs_build/dev/start_of_day/ was not modified. - Confirmed no product/runtime files were modified. +- Confirmed report manifest used merge-base 520199ccc98ca54ad599095672d13b7b8aab188e to avoid unrelated newer mainline files. - Confirmed ZIP artifact path: tmp/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_delta.zip. diff --git a/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_requirement-checklist.md b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_requirement-checklist.md index c3c7e7c53..0d99e1c44 100644 --- a/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_requirement-checklist.md +++ b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_requirement-checklist.md @@ -1,20 +1,23 @@ # PR_26177_OWNER_007-project-instructions-single-source-eod-lock Requirement Checklist -- PASS: Audited repo for ProjectInstructions / project instructions duplicates. -- PASS: Active source is docs_build/dev/ProjectInstructions/. -- PASS: Legacy docs_build/dev/PROJECT_INSTRUCTIONS.md is marked deprecated. -- PASS: Legacy root project-instructions/ folder is marked deprecated. -- PASS: Legacy root addendums are migrated into the active addendum tree. -- PASS: Active team start/governance docs reference only docs_build/dev/ProjectInstructions/. -- PASS: Added EOD command sequence. -- PASS: Added required EOD output: On branch main, clean worktree, 0 0. -- PASS: Added Next Day Start command sequence. -- PASS: Added team branch creation rule requiring main, clean worktree, 0 0, and matching published EOD SHA. -- PASS: Added START RULE with main clean/synced/EOD SHA gate and no commits on main. -- PASS: Added WORK RULE requiring Codex to remain, commit, and push only on the PR branch. -- PASS: Added hard stops for unexpected branch changes and current branch main before commit. -- PASS: Added END RULE requiring PR branch push, merge to main, main checkout/fetch/pull, clean 0 0 confirmation, and EOD SHA recording. -- PASS: Did not modify start_of_day folders. +- PASS: PR remains documentation/governance only. +- PASS: Added canonical three-phase lifecycle: START, WORK, END. +- PASS: START says every team begins on main. +- PASS: START includes checkout/fetch/ff-only pull/status/sync/head commands. +- PASS: START requires current branch main, clean working tree, main...origin/main 0 0, and HEAD equal to published EOD SHA. +- PASS: START allows branch creation only after all four required results pass. +- PASS: START documents git switch -c PR_. +- PASS: START prohibits commits on main, implementation on main, and validation on main except start validation. +- PASS: WORK requires remaining on the PR branch. +- PASS: WORK prohibits checking out main. +- PASS: WORK requires commits, pushes, validation, and PR open/update from the PR branch. +- PASS: WORK hard stops on current branch main before commit, unexpected branch changes, and attempts to push main. +- PASS: END requires commit, PR branch push, PR open/update, merge, immediate main checkout/fetch/ff-only pull/status/sync/head commands. +- PASS: END requires current branch main, clean worktree, and main...origin/main 0 0. +- PASS: END publishes Branch, HEAD SHA, and date/time as tomorrow's official baseline, then stops all work. +- PASS: Daily synchronization requires publishing Branch: main and HEAD SHA. +- PASS: Mandatory hard stops are documented. +- PASS: Active governance/team workflow docs under docs_build/dev/ProjectInstructions/ reference this lifecycle. - PASS: Did not modify product/runtime files. +- PASS: Did not modify start_of_day folders. - PASS: Did not remove, move, or overwrite legacy SQLite files. -- PASS: Did not start feature work. diff --git a/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_validation-lane.md b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_validation-lane.md index 6e30ad6f6..b78c80fe6 100644 --- a/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_validation-lane.md +++ b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_validation-lane.md @@ -1,17 +1,15 @@ # PR_26177_OWNER_007-project-instructions-single-source-eod-lock Validation Lane - PASS: duplicate-source grep returned no matches for old active source claims. -- PASS: EOD/Next Day governance grep returned active governance matches. -- PASS: branch lifecycle grep returned active START / WORK / END governance matches. +- PASS: canonical lifecycle grep returned active governance matches. - PASS: product/runtime/start_of_day changed-file check returned no files. - PASS: git diff --check. Commands used: ~~~text -rg -n 'project-instructions/addendums|docs_build/dev/PROJECT_INSTRUCTIONS.md.*source of truth|Codex must always read `docs_build/dev/PROJECT_INSTRUCTIONS.md`|Read `docs_build/dev/PROJECT_INSTRUCTIONS.md`' docs_build/dev/ProjectInstructions docs_build/dev/PROJECT_INSTRUCTIONS.md project-instructions -rg -n 'START RULE|WORK RULE|END RULE|HARD STOP before committing|Codex commits only to the PR branch|Codex pushes only the PR branch|HEAD SHA recorded as new EOD baseline|No commits are allowed on `main`' docs_build/dev/ProjectInstructions -rg -n "End of Day:|Next Day Start:|HEAD.*published EOD SHA|only active Project Instructions source" docs_build/dev/ProjectInstructions +rg duplicate-source active-claim pattern across docs_build/dev/ProjectInstructions docs_build/dev/PROJECT_INSTRUCTIONS.md project-instructions +rg canonical lifecycle pattern across docs_build/dev/ProjectInstructions git diff --name-only -- src assets toolbox games api serverside package.json package-lock.json docs_build/dev/start_of_day git diff --check ~~~ diff --git a/docs_build/dev/reports/codex_changed_files.txt b/docs_build/dev/reports/codex_changed_files.txt index 85beb7824..4926b6401 100644 --- a/docs_build/dev/reports/codex_changed_files.txt +++ b/docs_build/dev/reports/codex_changed_files.txt @@ -5,13 +5,18 @@ docs_build/dev/ProjectInstructions/PROJECT_INSTRUCTIONS.md docs_build/dev/ProjectInstructions/README.txt docs_build/dev/ProjectInstructions/TEAM_START_COMMANDS.md docs_build/dev/ProjectInstructions/addendums/assistant_execution_modes.md +docs_build/dev/ProjectInstructions/addendums/branch_context_governance.md docs_build/dev/ProjectInstructions/addendums/branch_lock_governance.md docs_build/dev/ProjectInstructions/addendums/canonical_repository_structure.md docs_build/dev/ProjectInstructions/addendums/codex_artifact_and_reporting_standard.md docs_build/dev/ProjectInstructions/addendums/codex_project_instructions_startup.md docs_build/dev/ProjectInstructions/addendums/legacy_migration_policy.md +docs_build/dev/ProjectInstructions/addendums/multi_team.md docs_build/dev/ProjectInstructions/addendums/pr_workflow.md docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md +docs_build/dev/ProjectInstructions/addendums/release_gate.md +docs_build/dev/ProjectInstructions/addendums/team_release_readiness.md +docs_build/dev/ProjectInstructions/addendums/team_start_and_release.md docs_build/dev/ProjectInstructions/addendums/test_structure_standardization.md docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock.md diff --git a/docs_build/dev/reports/codex_review.diff b/docs_build/dev/reports/codex_review.diff index ca20f9cf5..c86585ecb 100644 --- a/docs_build/dev/reports/codex_review.diff +++ b/docs_build/dev/reports/codex_review.diff @@ -1,5 +1,5 @@ diff --git a/docs_build/dev/BUILD_PR.md b/docs_build/dev/BUILD_PR.md -index 30700e9cd..fbff4d261 100644 +index 30700e9cd..c375aee47 100644 --- a/docs_build/dev/BUILD_PR.md +++ b/docs_build/dev/BUILD_PR.md @@ -1,66 +1,52 @@ @@ -32,7 +32,7 @@ index 30700e9cd..fbff4d261 100644 +- Establish `docs_build/dev/ProjectInstructions/` as the only active source. +- Mark all other ProjectInstructions-style sources changed by this PR as deprecated references. +- Update active team start/governance docs to reference only `docs_build/dev/ProjectInstructions/`. -+- Add EOD main lock, next-day reset governance, and explicit START / WORK / END branch lifecycle rules. ++- Add EOD main lock, next-day reset governance, and canonical START / WORK / END branch lifecycle rules. +- Add required reports under `docs_build/dev/reports/`. ## Exact Targets @@ -83,7 +83,7 @@ index 30700e9cd..fbff4d261 100644 -node --check src/shared/time/time.js -node --check tests/shared/TimeFoundation.test.mjs +rg -n 'project-instructions/addendums|docs_build/dev/PROJECT_INSTRUCTIONS.md.*source of truth|Codex must always read `docs_build/dev/PROJECT_INSTRUCTIONS.md`|Read `docs_build/dev/PROJECT_INSTRUCTIONS.md`' docs_build/dev/ProjectInstructions docs_build/dev/PROJECT_INSTRUCTIONS.md project-instructions -+rg -n "START RULE|WORK RULE|END RULE|HARD STOP before committing|Codex commits only to the PR branch|HEAD SHA recorded as new EOD baseline|End of Day:|Next Day Start:|HEAD.*published EOD SHA|only active Project Instructions source" docs_build/dev/ProjectInstructions ++rg -n "Branch Lifecycle \\(Canonical\\)|Every PR follows exactly three phases|^START$|^WORK$|^END$|Mandatory Hard Stops|tomorrow's official baseline|No commits on main|Never checkout main|Only after ALL four pass" docs_build/dev/ProjectInstructions +git diff --name-only -- src assets toolbox games api serverside package.json package-lock.json docs_build/dev/start_of_day git diff --check ``` @@ -96,7 +96,7 @@ index 30700e9cd..fbff4d261 100644 -tmp/PR_26177_006-shared-time-foundation_delta.zip -``` diff --git a/docs_build/dev/PLAN_PR.md b/docs_build/dev/PLAN_PR.md -index 907936aee..505e274bd 100644 +index 907936aee..0e5d6a50e 100644 --- a/docs_build/dev/PLAN_PR.md +++ b/docs_build/dev/PLAN_PR.md @@ -1,22 +1,28 @@ @@ -121,7 +121,7 @@ index 907936aee..505e274bd 100644 +- Mark legacy ProjectInstructions-style sources as deprecated reference material. +- Move active legacy addendums into `docs_build/dev/ProjectInstructions/addendums/`. +- Update active team start and governance docs to reference only `docs_build/dev/ProjectInstructions/`. -+- Add EOD main lock, next-day reset, team PR branch creation gate, and explicit START / WORK / END branch lifecycle rules. ++- Add EOD main lock, next-day reset, team PR branch creation gate, and canonical START / WORK / END branch lifecycle rules. +- Add required Codex reports under `docs_build/dev/reports/`. -## Implementation Plan @@ -139,7 +139,7 @@ index 907936aee..505e274bd 100644 +## Validation Plan + +1. Run targeted grep/search proving no active duplicate ProjectInstructions source remains. -+2. Confirm EOD/Next Day and START / WORK / END branch lifecycle rules appear in active governance docs. ++2. Confirm EOD/Next Day and canonical START / WORK / END branch lifecycle rules appear in active governance docs. +3. Confirm no product/runtime files changed. +4. Run `git diff --check`. diff --git a/docs_build/dev/PROJECT_INSTRUCTIONS.md b/docs_build/dev/PROJECT_INSTRUCTIONS.md @@ -193,7 +193,7 @@ index af9e9e2db..c1136fdbe 100644 Required pre-change report: diff --git a/docs_build/dev/ProjectInstructions/PROJECT_INSTRUCTIONS.md b/docs_build/dev/ProjectInstructions/PROJECT_INSTRUCTIONS.md -index d2a84ecbe..99ddd0f42 100644 +index d2a84ecbe..647881f1f 100644 --- a/docs_build/dev/ProjectInstructions/PROJECT_INSTRUCTIONS.md +++ b/docs_build/dev/ProjectInstructions/PROJECT_INSTRUCTIONS.md @@ -4,6 +4,12 @@ Read `README.txt` first. @@ -224,13 +224,13 @@ index d2a84ecbe..99ddd0f42 100644 +## Single Source and Main Lock Governance + -+`docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md` defines the single active Project Instructions source, EOD main lock, next-day reset, and team branch creation gate. ++`docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md` defines the single active Project Instructions source, canonical START / WORK / END branch lifecycle, EOD main lock, next-day reset, team branch creation gate, daily synchronization baseline, and mandatory hard stops. + ## Merge Control No PR in this operating system is merged without explicit owner approval. diff --git a/docs_build/dev/ProjectInstructions/README.txt b/docs_build/dev/ProjectInstructions/README.txt -index a48becf05..631fd3918 100644 +index a48becf05..50736f317 100644 --- a/docs_build/dev/ProjectInstructions/README.txt +++ b/docs_build/dev/ProjectInstructions/README.txt @@ -1,10 +1,10 @@ @@ -246,7 +246,19 @@ index a48becf05..631fd3918 100644 Backlog workflow: Backlog work is tracked under backlog/. BACKLOG_MASTER.md is the planned source for backlog item status, notes, and references. Backlog item text is treated as immutable once created; status and notes may change under the governance addendums. -@@ -29,9 +29,9 @@ Do not rewrite history snapshots after creation unless the owner explicitly appr +@@ -13,7 +13,10 @@ Team assignment workflow: + Team assignments are tracked under team_assignments/. A team pulls work from BACKLOG_MASTER.md, marks the item building when assigned, and records the active assignment under the owning team. Teams work only on assigned items unless an OWNER override explicitly changes the assignment. + + No direct commits to main: +-Do not commit directly to main unless the owner explicitly instructs that exception. Normal work must use PR branches, draft PRs, validation evidence, and owner-controlled merge approval. ++Do not commit directly to main. Normal work must use PR branches, draft PRs, validation evidence, and owner-controlled merge approval. ++ ++Branch lifecycle: ++Every PR follows exactly three phases: START, WORK, END. The canonical lifecycle is `docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md`. + + OWNER override rule: + An OWNER override must use this wording: +@@ -29,9 +32,9 @@ Do not rewrite history snapshots after creation unless the owner explicitly appr READ THIS FIRST @@ -259,8 +271,11 @@ index a48becf05..631fd3918 100644 4. Team ownership must be respected. 5. BACKLOG_MASTER.md is the authoritative backlog. 6. Build Path status derives from backlog status. -@@ -42,12 +42,13 @@ READ THIS FIRST +@@ -40,14 +43,16 @@ READ THIS FIRST + 9. Follow OWNER governance decisions. + 10. When guidance conflicts, newest OWNER-approved guidance wins. 11. Batch Governance Mode is the default for governance, documentation, and administrative work. ++12. Follow the canonical START / WORK / END lifecycle. Addendum index: -- Canonical Repository Structure: project-instructions/addendums/canonical-repository-structure.md @@ -280,10 +295,10 @@ index a48becf05..631fd3918 100644 - Environment Governance Model: docs_build/dev/ProjectInstructions/addendums/environment_governance_model.md - Environment Configuration Standards: docs_build/dev/ProjectInstructions/addendums/environment_configuration_standards.md diff --git a/docs_build/dev/ProjectInstructions/TEAM_START_COMMANDS.md b/docs_build/dev/ProjectInstructions/TEAM_START_COMMANDS.md -index d0118f63a..192278a34 100644 +index d0118f63a..292540043 100644 --- a/docs_build/dev/ProjectInstructions/TEAM_START_COMMANDS.md +++ b/docs_build/dev/ProjectInstructions/TEAM_START_COMMANDS.md -@@ -1,5 +1,42 @@ +@@ -1,5 +1,26 @@ # TEAM_START_COMMANDS +## Required Main Reset Gate For Every Team @@ -297,36 +312,20 @@ index d0118f63a..192278a34 100644 + +Use `docs_build/dev/ProjectInstructions/` as the only active Project Instructions source. + -+START RULE: -+- Every team starts on `main`. -+- `main` must be clean. -+- `main...origin/main` must be `0 0`. -+- `HEAD` SHA must match published EOD SHA. -+- Only then create or switch to the PR branch. -+- No commits are allowed on `main`. -+ -+WORK RULE: -+- Codex must remain on the PR branch during implementation. -+- Codex commits only to the PR branch. -+- Codex pushes only the PR branch. -+- HARD STOP if branch changes unexpectedly. -+- HARD STOP before committing if current branch is `main`. -+ -+END RULE: -+- After PR validation, push the PR branch. -+- Merge PR into `main` only when approved. -+- Checkout `main`. -+- Run `git fetch origin`. -+- Run `git pull --ff-only origin main`. -+- Confirm current branch is `main`. -+- Confirm worktree is clean. -+- Confirm `main...origin/main` is `0 0`. -+- Record `HEAD` SHA as new EOD baseline. ++Branch Lifecycle (Canonical): ++- Every PR follows exactly three phases: START, WORK, END. ++- Follow `docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md`. ++- START begins on synchronized `main` and creates the PR branch only after all gates pass. ++- WORK remains on the PR branch. Never checkout `main`. ++- END merges, returns to synchronized `main`, publishes branch, HEAD SHA, and date/time, then stops all work. ++- No commits on `main`. ++- No implementation on `main`. ++- No validation on `main` except start validation. + ## Start Team Alfa Ready-to-copy command: -@@ -123,4 +160,24 @@ Merge to main is EOD-only and owner-approved, unless the owner explicitly says: +@@ -123,4 +144,26 @@ Merge to main is EOD-only and owner-approved, unless the owner explicitly says: "Merge this PR now." Do not treat sequential PR completion as merge approval. @@ -350,6 +349,8 @@ index d0118f63a..192278a34 100644 +git status +git rev-list --left-right --count main...origin/main +git rev-parse HEAD ++ ++Publish Branch, HEAD SHA, and Date/time. This becomes tomorrow's official baseline. ``` diff --git a/docs_build/dev/ProjectInstructions/addendums/assistant_execution_modes.md b/docs_build/dev/ProjectInstructions/addendums/assistant_execution_modes.md new file mode 100644 @@ -477,15 +478,55 @@ index 000000000..6d7928669 +- Merge +- Push +- Create next-day start document +diff --git a/docs_build/dev/ProjectInstructions/addendums/branch_context_governance.md b/docs_build/dev/ProjectInstructions/addendums/branch_context_governance.md +index 09cd3a1ec..798bb2cba 100644 +--- a/docs_build/dev/ProjectInstructions/addendums/branch_context_governance.md ++++ b/docs_build/dev/ProjectInstructions/addendums/branch_context_governance.md +@@ -21,6 +21,8 @@ At the start of work, report or validate: + - active PR number/name or explicit `PLAN_ONLY` + - previous PR Closed status unless this is an explicitly documented stacked PR chain + ++Session start must follow the canonical START phase in `docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md`. ++ + ## Stop Conditions + + Stop and report before changing files when: +@@ -38,6 +40,8 @@ Stop and report before changing files when: + + After a branch is created, the branch remains the working context. + ++This is the canonical WORK phase: remain on the PR branch, never checkout `main`, commit only on the PR branch, push only the PR branch, validate from the PR branch, and open/update the PR from the PR branch. ++ + Do not automatically return to `main` after: + + - commit +@@ -47,7 +51,7 @@ Do not automatically return to `main` after: + - review updates + - additional commits + +-Return to `main` only after the PR is merged, the branch is retired, or OWNER explicitly says to return to `main`. ++Return to `main` only in the canonical END phase after the PR is merged, the branch is retired, or OWNER explicitly says to return to `main`. + + Returning to `main` is required before Closed can be recorded. + +@@ -58,6 +62,7 @@ Closed branch context requires: + - local/origin sync is `0/0` + - no untracked files + - source branch disposition recorded as `retained` ++- branch, HEAD SHA, and date/time recorded as the new EOD baseline when this is EOD closeout + + ## GitHub Authority + diff --git a/docs_build/dev/ProjectInstructions/addendums/branch_lock_governance.md b/docs_build/dev/ProjectInstructions/addendums/branch_lock_governance.md -index 518f8c943..e6ab30ae8 100644 +index 518f8c943..61b95cfae 100644 --- a/docs_build/dev/ProjectInstructions/addendums/branch_lock_governance.md +++ b/docs_build/dev/ProjectInstructions/addendums/branch_lock_governance.md -@@ -23,12 +23,46 @@ Keep active work attached to the correct assigned team, branch, and OWNER decisi +@@ -23,12 +23,36 @@ Keep active work attached to the correct assigned team, branch, and OWNER decisi - Start from current `main`. - Pull latest `origin/main` before creating a work branch. +- Do not create a PR branch unless current branch is `main`, worktree is clean, `main...origin/main` is `0 0`, and `HEAD` SHA matches the published EOD SHA. ++- Follow the canonical START / WORK / END lifecycle in `docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md`. - Keep work on the active branch until the PR is merged, the branch is retired, or OWNER says to return to `main`. -- Do not commit directly to `main` unless OWNER explicitly approves. +- Do not commit directly to `main`. @@ -497,39 +538,28 @@ index 518f8c943..e6ab30ae8 100644 - Retain source branches by default after merge and closeout. - Record branch disposition before Closed as `retained`. -+## START RULE ++## Branch Lifecycle (Canonical) + -+- Every team starts on `main`. -+- `main` must be clean. -+- `main...origin/main` must be `0 0`. -+- `HEAD` SHA must match published EOD SHA. -+- Only then create or switch to the PR branch. -+- No commits are allowed on `main`. ++Every PR follows exactly three phases: + -+## WORK RULE -+ -+- Codex must remain on the PR branch during implementation. -+- Codex commits only to the PR branch. -+- Codex pushes only the PR branch. -+- HARD STOP if branch changes unexpectedly. -+- HARD STOP before committing if current branch is `main`. ++```text ++START ++WORK ++END ++``` + -+## END RULE ++The canonical lifecycle lives in `docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md`. + -+- After PR validation, push the PR branch. -+- Merge PR into `main` only when approved. -+- Checkout `main`. -+- Run `git fetch origin`. -+- Run `git pull --ff-only origin main`. -+- Confirm current branch is `main`. -+- Confirm worktree is clean. -+- Confirm `main...origin/main` is `0 0`. -+- Record `HEAD` SHA as new EOD baseline. ++Branch lock governance enforces: ++- START on synchronized `main`. ++- WORK only on the PR branch. ++- END by merging, returning to synchronized `main`, publishing branch, HEAD SHA, and date/time, then stopping all work. ++- Mandatory hard stops before commits on `main`, dirty branch creation, non-`0 0` main sync, baseline SHA mismatch, unvalidated merge, or new PR work before synchronized main return. + ## OWNER Override OWNER may override a branch lock or team assignment. -@@ -54,3 +88,36 @@ Protected guidance includes: +@@ -54,3 +78,36 @@ Protected guidance includes: - Governance Phase 1 completion guidance If protected guidance must change, OWNER approval is required. @@ -685,10 +715,10 @@ index 000000000..498e3895e +A task is not considered complete until the ZIP artifact is generated and reported. diff --git a/docs_build/dev/ProjectInstructions/addendums/codex_project_instructions_startup.md b/docs_build/dev/ProjectInstructions/addendums/codex_project_instructions_startup.md new file mode 100644 -index 000000000..dba8f8d93 +index 000000000..ee11393b4 --- /dev/null +++ b/docs_build/dev/ProjectInstructions/addendums/codex_project_instructions_startup.md -@@ -0,0 +1,93 @@ +@@ -0,0 +1,87 @@ +# Codex Project Instructions Startup + +## Purpose @@ -714,31 +744,25 @@ index 000000000..dba8f8d93 + +## Branch Lifecycle Start Gate + -+START RULE: -+- Every team starts on `main`. -+- `main` must be clean. -+- `main...origin/main` must be `0 0`. -+- `HEAD` SHA must match published EOD SHA. -+- Only then create or switch to the PR branch. -+- No commits are allowed on `main`. -+ -+WORK RULE: -+- Codex must remain on the PR branch during implementation. -+- Codex commits only to the PR branch. -+- Codex pushes only the PR branch. -+- HARD STOP if branch changes unexpectedly. -+- HARD STOP before committing if current branch is `main`. ++Every PR follows exactly three phases: ++ ++```text ++START ++WORK ++END ++``` ++ ++Codex must follow the canonical lifecycle in: ++ ++`docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md` + -+END RULE: -+- After PR validation, push the PR branch. -+- Merge PR into `main` only when approved. -+- Checkout `main`. -+- Run `git fetch origin`. -+- Run `git pull --ff-only origin main`. -+- Confirm current branch is `main`. -+- Confirm worktree is clean. -+- Confirm `main...origin/main` is `0 0`. -+- Record `HEAD` SHA as new EOD baseline. ++Startup enforcement: ++- START begins on synchronized `main`. ++- WORK remains on the PR branch. Never checkout `main`. ++- END merges, returns to synchronized `main`, publishes branch, HEAD SHA, and date/time, then stops all work. ++- STOP if current branch is `main` before commit. ++- STOP if attempting to push `main`. ++- STOP if a new PR starts before returning to synchronized `main`. + +Deprecated Project Instructions material outside `docs_build/dev/ProjectInstructions/` is reference-only and must not override active governance. + @@ -821,49 +845,74 @@ index 000000000..5e43679f4 +- No new scattered JS locations. +- No new scattered CSS locations. +- No new scattered test locations. +diff --git a/docs_build/dev/ProjectInstructions/addendums/multi_team.md b/docs_build/dev/ProjectInstructions/addendums/multi_team.md +index d8acc7b0e..7ba2cae8d 100644 +--- a/docs_build/dev/ProjectInstructions/addendums/multi_team.md ++++ b/docs_build/dev/ProjectInstructions/addendums/multi_team.md +@@ -51,6 +51,7 @@ Rules: + - One Codex session may execute multiple sequential PRs. + - Each PR must still have one clear purpose. + - Each PR must create or use its own approved branch. ++- Each PR must follow the canonical START / WORK / END lifecycle in `docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md`. + - Each PR may be committed and pushed during active work. + - Each PR may be opened as a draft PR during active work. + - Do not commit directly to main. +@@ -69,13 +70,14 @@ During active work: + - Pushes are allowed and expected. + - Draft PRs are allowed and expected. + - Direct commits to main are prohibited. ++- WORK remains on the PR branch; never checkout main during WORK. + - Merges to main are prohibited unless explicitly approved by the owner. + + At end of day: + - Owner reviews ready PRs. + - Owner explicitly approves which PRs merge. + - Only owner-approved PRs may merge to main. +-- After merge, return to main and pull latest main. ++- After merge, execute the canonical END phase, return to synchronized main, and publish branch, HEAD SHA, and date/time. + - Do not treat sequential PR completion as merge approval. + + Commit/push during the day is allowed only on assigned team/OWNER/PR branches. diff --git a/docs_build/dev/ProjectInstructions/addendums/pr_workflow.md b/docs_build/dev/ProjectInstructions/addendums/pr_workflow.md -index f8a4acb6e..abad0b789 100644 +index f8a4acb6e..02391a8be 100644 --- a/docs_build/dev/ProjectInstructions/addendums/pr_workflow.md +++ b/docs_build/dev/ProjectInstructions/addendums/pr_workflow.md -@@ -26,6 +26,37 @@ Define the standard pull request workflow for Game Foundry Studio. +@@ -26,6 +26,34 @@ Define the standard pull request workflow for Game Foundry Studio. 15. Pull latest main before starting the next PR. 16. Verify Main Verified and Closed gates. -+## Branch Lifecycle Governance ++## Branch Lifecycle (Canonical) + -+### START RULE ++Every PR follows exactly three phases: + -+- Every team starts on `main`. -+- `main` must be clean. -+- `main...origin/main` must be `0 0`. -+- `HEAD` SHA must match published EOD SHA. -+- Only then create or switch to the PR branch. -+- No commits are allowed on `main`. ++```text ++START ++WORK ++END ++``` + -+### WORK RULE ++The canonical START, WORK, END, Daily Synchronization, and Mandatory Hard Stops rules live in: + -+- Codex must remain on the PR branch during implementation. -+- Codex commits only to the PR branch. -+- Codex pushes only the PR branch. -+- HARD STOP if branch changes unexpectedly. -+- HARD STOP before committing if current branch is `main`. ++`docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md` + -+### END RULE ++PR workflow must follow that lifecycle exactly. + -+- After PR validation, push the PR branch. -+- Merge PR into `main` only when approved. -+- Checkout `main`. -+- Run `git fetch origin`. -+- Run `git pull --ff-only origin main`. -+- Confirm current branch is `main`. -+- Confirm worktree is clean. -+- Confirm `main...origin/main` is `0 0`. -+- Record `HEAD` SHA as new EOD baseline. ++Summary: ++- START happens on synchronized `main` only and creates the PR branch only after all required gates pass. ++- WORK happens only on the PR branch. ++- END validates, commits, pushes, opens/updates the PR, merges, returns to synchronized `main`, publishes branch, HEAD SHA, and date/time, then stops all work. ++- No commits on `main`. ++- No implementation on `main`. ++- No validation on `main` except start validation. ++- Never checkout `main` during WORK. ++- STOP before commit if current branch is `main`. ++- STOP if current branch changes unexpectedly. ++- STOP if attempting to push `main`. + ## PR Lifecycle States Required state order: -@@ -129,3 +160,40 @@ Stop only for: +@@ -129,3 +157,40 @@ Stop only for: - Merge conflict - Validation failure - OWNER decision @@ -906,10 +955,10 @@ index f8a4acb6e..abad0b789 100644 +- `HEAD` SHA matches published EOD SHA diff --git a/docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md b/docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md new file mode 100644 -index 000000000..c41dc503d +index 000000000..dd5744c80 --- /dev/null +++ b/docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md -@@ -0,0 +1,92 @@ +@@ -0,0 +1,199 @@ +# Project Instructions Single Source And EOD Main Lock + +Status: Approved @@ -968,40 +1017,234 @@ index 000000000..c41dc503d + +If any check fails, stop before branch creation and restore main to the published EOD state or request OWNER direction. + -+## Branch Lifecycle Governance ++## Branch Lifecycle (Canonical) + -+### START RULE ++Every PR follows exactly three phases: + -+- Every team starts on `main`. -+- `main` must be clean. -+- `main...origin/main` must be `0 0`. -+- `HEAD` SHA must match published EOD SHA. -+- Only then create or switch to the PR branch. -+- No commits are allowed on `main`. ++```text ++START ++WORK ++END ++``` + -+### WORK RULE ++## START + -+- Codex must remain on the PR branch during implementation. -+- Codex commits only to the PR branch. -+- Codex pushes only the PR branch. -+- HARD STOP if branch changes unexpectedly. -+- HARD STOP before committing if current branch is `main`. ++Every team begins on `main`. ++ ++Required: ++ ++```text ++git checkout main ++git fetch origin ++git pull --ff-only origin main ++git status ++git rev-list --left-right --count main...origin/main ++git rev-parse HEAD ++``` ++ ++Required results: ++ ++```text ++Current branch: main ++Working tree clean ++main...origin/main ++0 0 ++HEAD equals published EOD SHA ++``` ++ ++Only after ALL four pass may a branch be created. ++ ++Create the PR branch: ++ ++```text ++git switch -c PR_ ++``` ++ ++Rules: ++ ++- No commits on `main`. ++- No implementation on `main`. ++- No validation on `main` except start validation. ++ ++## WORK ++ ++From branch creation until merge: ++ ++- Remain on the PR branch. ++- Never checkout `main`. ++- Commit only on the PR branch. ++- Push only the PR branch. ++- Execute validation from the PR branch. ++- Open/update the PR from the PR branch. ++ ++Hard Stops: + -+### END RULE ++```text ++If current branch == main before commit: ++ STOP ++ ++If current branch changes unexpectedly: ++ STOP ++ ++If attempting to push main: ++ STOP ++``` ++ ++## END ++ ++After validation succeeds: ++ ++```text ++Commit ++Push PR branch ++Open/update PR ++Merge PR ++``` ++ ++Immediately execute: ++ ++```text ++git checkout main ++git fetch origin ++git pull --ff-only origin main ++git status ++git rev-list --left-right --count main...origin/main ++git rev-parse HEAD ++``` ++ ++Required result: ++ ++```text ++Current branch: main ++Working tree clean ++main...origin/main ++0 0 ++``` ++ ++Publish: ++ ++```text ++Branch ++HEAD SHA ++Date/time ++``` ++ ++This becomes tomorrow's official baseline. ++ ++Stop all work. ++ ++## Daily Synchronization ++ ++End of every day publish: + -+- After PR validation, push the PR branch. -+- Merge PR into `main` only when approved. -+- Checkout `main`. -+- Run `git fetch origin`. -+- Run `git pull --ff-only origin main`. -+- Confirm current branch is `main`. -+- Confirm worktree is clean. -+- Confirm `main...origin/main` is `0 0`. -+- Record `HEAD` SHA as new EOD baseline. ++```text ++Branch: main ++HEAD SHA ++``` ++ ++Every team must begin tomorrow from that exact SHA. ++ ++## Mandatory Hard Stops ++ ++STOP if: ++ ++- current branch is `main` before commit ++- worktree dirty before creating PR branch ++- `main...origin/main` is not `0 0` before creating PR branch ++- `HEAD` SHA differs from published baseline ++- merge attempted without successful validation ++- new PR started before returning to synchronized `main` + +## Start Of Day Boundary + +`docs_build/dev/start_of_day/` may point to `docs_build/dev/ProjectInstructions/`, but it must not become a second active Project Instructions source. +diff --git a/docs_build/dev/ProjectInstructions/addendums/release_gate.md b/docs_build/dev/ProjectInstructions/addendums/release_gate.md +index c45a2c49d..57620f816 100644 +--- a/docs_build/dev/ProjectInstructions/addendums/release_gate.md ++++ b/docs_build/dev/ProjectInstructions/addendums/release_gate.md +@@ -22,6 +22,7 @@ Before a governance, documentation, or administrative PR is merged, validate: + - PR workflow guidance remains intact. + - Team assignment governance remains intact. + - Active team registry guidance remains compatible with temporary active teams. ++- Canonical START / WORK / END branch lifecycle guidance remains intact. + - No protected Project Instructions guidance was deleted. + - No permanent team roster or permanent discipline ownership was restored. + - No direct-to-main commit rule was bypassed. +@@ -36,6 +37,7 @@ The release gate should confirm these files when relevant to the PR: + - `docs_build/dev/ProjectInstructions/backlog/BACKLOG_MASTER.md` + - `docs_build/dev/ProjectInstructions/addendums/governance_phase1_complete.md` + - `docs_build/dev/ProjectInstructions/addendums/pr_workflow.md` ++- `docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md` + - `docs_build/dev/ProjectInstructions/addendums/project_reference_files.md` + - `docs_build/dev/ProjectInstructions/addendums/environment_governance_model.md` + - `docs_build/dev/ProjectInstructions/addendums/environment_configuration_standards.md` +diff --git a/docs_build/dev/ProjectInstructions/addendums/team_release_readiness.md b/docs_build/dev/ProjectInstructions/addendums/team_release_readiness.md +index 9a2addbdc..225a2e4ab 100644 +--- a/docs_build/dev/ProjectInstructions/addendums/team_release_readiness.md ++++ b/docs_build/dev/ProjectInstructions/addendums/team_release_readiness.md +@@ -18,9 +18,13 @@ Teams may start only when all of the following are true: + - OWNER governance exists. + - One-active-branch-per-team rule exists. + - No-direct-main rule exists. ++- Canonical START / WORK / END lifecycle exists. + - Out-of-scope stop rule exists. + - Build Path sync rule exists. + - PR lifecycle states exist in order: PR Open, Plan, Build, Validation, Approved, Merged, Main Verified, Closed. ++- START requires synchronized `main`, clean worktree, `main...origin/main` `0 0`, and HEAD matching published EOD SHA before branch creation. ++- WORK requires remaining on the PR branch. ++- END requires merge, return to synchronized `main`, and publishing branch, HEAD SHA, and date/time. + - Previous-PR Closed gate exists before a team starts another PR, except explicitly documented stacked PR chains. + - Final closeout output includes branch, worktree, local/origin sync, PR number/name, PR status, merge/final commit, branch disposition, backlog update status, tool state update status, ZIP path, and Closeout PASS/FAIL. + +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 26c337ee1..e2d6b7226 100644 +--- a/docs_build/dev/ProjectInstructions/addendums/team_start_and_release.md ++++ b/docs_build/dev/ProjectInstructions/addendums/team_start_and_release.md +@@ -13,9 +13,11 @@ OWNER identifies available teams when starting work. + + Before a team starts, validate: + +-- current branch and expected branch are known +-- worktree is clean or unrelated changes are understood +-- `main` is current when a new branch is required ++- canonical START phase is complete ++- current branch is `main` ++- worktree is clean ++- `main...origin/main` is `0 0` ++- `HEAD` SHA matches published EOD SHA + - active assignment is selected or confirmed by OWNER + - assigned team uses NATO phonetic naming + - work remains with the assigned team until complete or OWNER reassignment +@@ -62,13 +64,14 @@ For backlog-driven work: + 2. Select only the OWNER-approved backlog item. + 3. Use the approved status model from `status_model.md`. + 4. Confirm the previous PR for the team is Closed, unless this is an explicitly documented stacked PR chain. +-5. Create or use the approved team branch and PR identity. +-6. Mark lifecycle state as PR Open. +-7. Plan on the same PR branch. +-8. Build on the same PR branch. +-9. Record active work in the active team registry when required. +-10. Open or update a draft PR during active work. +-11. Merge only through OWNER-approved PR workflow. ++5. Follow the canonical START phase in `project_instructions_single_source_eod_lock.md`. ++6. Create or use the approved team branch and PR identity only after START passes. ++7. Mark lifecycle state as PR Open. ++8. Plan on the same PR branch. ++9. Build on the same PR branch. ++10. Record active work in the active team registry when required. ++11. Open or update a draft PR during active WORK. ++12. Merge only through OWNER-approved PR workflow and canonical END. + + ## Team Command Examples + +@@ -94,6 +97,7 @@ A team or OWNER PR is release-ready when: + - PR summary states the validation result + - lifecycle state is at least Validation + - required reports and repo-structured ZIP under `tmp/` exist before Closed ++- canonical END publishes branch, HEAD SHA, and date/time when the PR merges + + Closed readiness requires: + - PR merged and pushed diff --git a/docs_build/dev/ProjectInstructions/addendums/test_structure_standardization.md b/docs_build/dev/ProjectInstructions/addendums/test_structure_standardization.md new file mode 100644 index 000000000..997b16730 @@ -1042,10 +1285,10 @@ index 000000000..997b16730 +- Regression tests validate platform behavior. +- New tests follow the canonical structure. diff --git a/docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md b/docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md -index 9735b4bd4..f70440ad2 100644 +index 9735b4bd4..f4d7e4bb8 100644 --- a/docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md +++ b/docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md -@@ -211,3 +211,72 @@ Commit/push during the day is allowed only on assigned team/OWNER/PR branches. +@@ -211,3 +211,67 @@ Commit/push during the day is allowed only on assigned team/OWNER/PR branches. Merge to main is EOD-only and owner-approved, unless the owner explicitly says: "Merge this PR now." @@ -1091,60 +1334,55 @@ index 9735b4bd4..f70440ad2 100644 +Active source rule: +Teams must use only `docs_build/dev/ProjectInstructions/` as the active Project Instructions source. + -+## Explicit Branch Lifecycle Governance -+ -+START RULE: -+- Every team starts on `main`. -+- `main` must be clean. -+- `main...origin/main` must be `0 0`. -+- `HEAD` SHA must match published EOD SHA. -+- Only then create or switch to the PR branch. -+- No commits are allowed on `main`. -+ -+WORK RULE: -+- Codex must remain on the PR branch during implementation. -+- Codex commits only to the PR branch. -+- Codex pushes only the PR branch. -+- HARD STOP if branch changes unexpectedly. -+- HARD STOP before committing if current branch is `main`. ++## Branch Lifecycle (Canonical) ++ ++Every PR follows exactly three phases: ++ ++```text ++START ++WORK ++END ++``` + -+END RULE: -+- After PR validation, push the PR branch. -+- Merge PR into `main` only when approved. -+- Checkout `main`. -+- Run `git fetch origin`. -+- Run `git pull --ff-only origin main`. -+- Confirm current branch is `main`. -+- Confirm worktree is clean. -+- Confirm `main...origin/main` is `0 0`. -+- Record `HEAD` SHA as new EOD baseline. ++Teams must follow `docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md`. ++ ++Assignment governance enforces: ++- START begins on synchronized `main`. ++- WORK remains on the PR branch. Never checkout `main`. ++- END merges, returns to synchronized `main`, publishes branch, HEAD SHA, and date/time, then stops all work. ++- No commits on `main`. ++- No implementation on `main`. ++- No validation on `main` except start validation. ++- STOP if current branch is `main` before commit. ++- STOP if attempting to push `main`. ++- STOP if new PR work starts before returning to synchronized `main`. diff --git a/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock.md b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock.md new file mode 100644 -index 000000000..ed2f3e94a +index 000000000..3f1c3f952 --- /dev/null +++ b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock.md @@ -0,0 +1,27 @@ +# PR_26177_OWNER_007-project-instructions-single-source-eod-lock + +Date: 2026-06-26 -+Scope: Project Instructions single-source, EOD main lock, and branch lifecycle governance ++Scope: Project Instructions single-source and canonical branch lifecycle governance +Status: PASS + +## Summary + +- Established docs_build/dev/ProjectInstructions/ as the only active Project Instructions source. -+- Migrated legacy root project-instructions/addendums/ content into active docs_build/dev/ProjectInstructions/addendums/ files. -+- Marked legacy docs_build/dev/PROJECT_INSTRUCTIONS.md and project-instructions/ material as deprecated reference only. -+- Added EOD main lock, next-day reset, and team branch creation gate governance. -+- Added explicit START RULE, WORK RULE, and END RULE branch lifecycle governance. -+- Updated active team start and Codex workflow docs under docs_build/dev/ProjectInstructions/. ++- Added canonical Branch Lifecycle governance: START, WORK, END. ++- Documented START commands and required results, including clean main, main...origin/main 0 0, and HEAD matching published EOD SHA. ++- Documented WORK rules requiring Codex to remain on the PR branch, validate from the PR branch, commit only on the PR branch, and push only the PR branch. ++- Documented END rules requiring PR branch push, PR update, merge, immediate main checkout/fetch/ff-only pull, clean 0 0 confirmation, and publication of Branch, HEAD SHA, and date/time as the next baseline. ++- Added mandatory hard stops for main-before-commit, dirty branch creation, non-synced main, baseline mismatch, unvalidated merge, and starting new PR work before synchronized main return. ++- Updated active governance/team workflow docs under docs_build/dev/ProjectInstructions/ to reference the canonical lifecycle. +- No product/runtime, start_of_day, feature, or legacy SQLite file changes were made. + +## Validation + +- PASS: targeted grep found no active duplicate ProjectInstructions source-of-truth claim outside the active source. -+- PASS: targeted grep confirmed EOD/Next Day governance appears in active governance docs. -+- PASS: targeted grep confirmed START / WORK / END branch lifecycle governance appears in active governance docs. ++- PASS: targeted grep confirmed canonical lifecycle language appears in active governance docs. +- PASS: product/runtime and start_of_day changed-file check returned no files. +- PASS: git diff --check. + @@ -1153,87 +1391,89 @@ index 000000000..ed2f3e94a +- tmp/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_delta.zip diff --git a/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_branch-validation.md b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_branch-validation.md new file mode 100644 -index 000000000..b54d77ced +index 000000000..9750dc7b9 --- /dev/null +++ b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_branch-validation.md -@@ -0,0 +1,6 @@ +@@ -0,0 +1,7 @@ +# PR_26177_OWNER_007-project-instructions-single-source-eod-lock Branch Validation + +- PASS: Current branch is PR_26177_OWNER_007-project-instructions-single-source-eod-lock. +- PASS: Work remained on the PR branch during implementation. +- PASS: No commit was made on main. +- PASS: No .vscode/settings.json change is staged or included. ++- PASS: Report manifest generated from branch merge-base 520199ccc98ca54ad599095672d13b7b8aab188e. diff --git a/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_manual-validation-notes.md b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_manual-validation-notes.md new file mode 100644 -index 000000000..5d9f186fa +index 000000000..f2e3bad4a --- /dev/null +++ b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_manual-validation-notes.md @@ -0,0 +1,9 @@ +# PR_26177_OWNER_007-project-instructions-single-source-eod-lock Manual Validation Notes + +- Reviewed active ProjectInstructions branch lifecycle wording. -+- Confirmed START RULE, WORK RULE, and END RULE are documented in active governance docs. -+- Confirmed active source declarations live under docs_build/dev/ProjectInstructions/. -+- Confirmed legacy locations remain deprecated reference material rather than active sources. ++- Confirmed canonical START, WORK, and END phases are documented. ++- Confirmed active governance/team workflow docs reference docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md or summarize the canonical lifecycle. +- Confirmed docs_build/dev/start_of_day/ was not modified. +- Confirmed no product/runtime files were modified. ++- Confirmed report manifest used merge-base 520199ccc98ca54ad599095672d13b7b8aab188e to avoid unrelated newer mainline files. +- Confirmed ZIP artifact path: tmp/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_delta.zip. diff --git a/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_requirement-checklist.md b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_requirement-checklist.md new file mode 100644 -index 000000000..c3c7e7c53 +index 000000000..0d99e1c44 --- /dev/null +++ b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_requirement-checklist.md -@@ -0,0 +1,20 @@ +@@ -0,0 +1,23 @@ +# PR_26177_OWNER_007-project-instructions-single-source-eod-lock Requirement Checklist + -+- PASS: Audited repo for ProjectInstructions / project instructions duplicates. -+- PASS: Active source is docs_build/dev/ProjectInstructions/. -+- PASS: Legacy docs_build/dev/PROJECT_INSTRUCTIONS.md is marked deprecated. -+- PASS: Legacy root project-instructions/ folder is marked deprecated. -+- PASS: Legacy root addendums are migrated into the active addendum tree. -+- PASS: Active team start/governance docs reference only docs_build/dev/ProjectInstructions/. -+- PASS: Added EOD command sequence. -+- PASS: Added required EOD output: On branch main, clean worktree, 0 0. -+- PASS: Added Next Day Start command sequence. -+- PASS: Added team branch creation rule requiring main, clean worktree, 0 0, and matching published EOD SHA. -+- PASS: Added START RULE with main clean/synced/EOD SHA gate and no commits on main. -+- PASS: Added WORK RULE requiring Codex to remain, commit, and push only on the PR branch. -+- PASS: Added hard stops for unexpected branch changes and current branch main before commit. -+- PASS: Added END RULE requiring PR branch push, merge to main, main checkout/fetch/pull, clean 0 0 confirmation, and EOD SHA recording. -+- PASS: Did not modify start_of_day folders. ++- PASS: PR remains documentation/governance only. ++- PASS: Added canonical three-phase lifecycle: START, WORK, END. ++- PASS: START says every team begins on main. ++- PASS: START includes checkout/fetch/ff-only pull/status/sync/head commands. ++- PASS: START requires current branch main, clean working tree, main...origin/main 0 0, and HEAD equal to published EOD SHA. ++- PASS: START allows branch creation only after all four required results pass. ++- PASS: START documents git switch -c PR_. ++- PASS: START prohibits commits on main, implementation on main, and validation on main except start validation. ++- PASS: WORK requires remaining on the PR branch. ++- PASS: WORK prohibits checking out main. ++- PASS: WORK requires commits, pushes, validation, and PR open/update from the PR branch. ++- PASS: WORK hard stops on current branch main before commit, unexpected branch changes, and attempts to push main. ++- PASS: END requires commit, PR branch push, PR open/update, merge, immediate main checkout/fetch/ff-only pull/status/sync/head commands. ++- PASS: END requires current branch main, clean worktree, and main...origin/main 0 0. ++- PASS: END publishes Branch, HEAD SHA, and date/time as tomorrow's official baseline, then stops all work. ++- PASS: Daily synchronization requires publishing Branch: main and HEAD SHA. ++- PASS: Mandatory hard stops are documented. ++- PASS: Active governance/team workflow docs under docs_build/dev/ProjectInstructions/ reference this lifecycle. +- PASS: Did not modify product/runtime files. ++- PASS: Did not modify start_of_day folders. +- PASS: Did not remove, move, or overwrite legacy SQLite files. -+- PASS: Did not start feature work. diff --git a/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_validation-lane.md b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_validation-lane.md new file mode 100644 -index 000000000..6e30ad6f6 +index 000000000..b78c80fe6 --- /dev/null +++ b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_validation-lane.md -@@ -0,0 +1,19 @@ +@@ -0,0 +1,17 @@ +# PR_26177_OWNER_007-project-instructions-single-source-eod-lock Validation Lane + +- PASS: duplicate-source grep returned no matches for old active source claims. -+- PASS: EOD/Next Day governance grep returned active governance matches. -+- PASS: branch lifecycle grep returned active START / WORK / END governance matches. ++- PASS: canonical lifecycle grep returned active governance matches. +- PASS: product/runtime/start_of_day changed-file check returned no files. +- PASS: git diff --check. + +Commands used: + +~~~text -+rg -n 'project-instructions/addendums|docs_build/dev/PROJECT_INSTRUCTIONS.md.*source of truth|Codex must always read `docs_build/dev/PROJECT_INSTRUCTIONS.md`|Read `docs_build/dev/PROJECT_INSTRUCTIONS.md`' docs_build/dev/ProjectInstructions docs_build/dev/PROJECT_INSTRUCTIONS.md project-instructions -+rg -n 'START RULE|WORK RULE|END RULE|HARD STOP before committing|Codex commits only to the PR branch|Codex pushes only the PR branch|HEAD SHA recorded as new EOD baseline|No commits are allowed on `main`' docs_build/dev/ProjectInstructions -+rg -n "End of Day:|Next Day Start:|HEAD.*published EOD SHA|only active Project Instructions source" docs_build/dev/ProjectInstructions ++rg duplicate-source active-claim pattern across docs_build/dev/ProjectInstructions docs_build/dev/PROJECT_INSTRUCTIONS.md project-instructions ++rg canonical lifecycle pattern across docs_build/dev/ProjectInstructions +git diff --name-only -- src assets toolbox games api serverside package.json package-lock.json docs_build/dev/start_of_day +git diff --check +~~~ + +Full product/runtime tests were not run because this PR changes governance documentation only. diff --git a/docs_build/dev/reports/codex_changed_files.txt b/docs_build/dev/reports/codex_changed_files.txt -index 8e34972a1..85beb7824 100644 +index 8e34972a1..4926b6401 100644 --- a/docs_build/dev/reports/codex_changed_files.txt +++ b/docs_build/dev/reports/codex_changed_files.txt -@@ -1,14 +1,30 @@ +@@ -1,14 +1,35 @@ -docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_branch-validation.md -docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_manual-validation-notes.md -docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_report.md @@ -1246,13 +1486,18 @@ index 8e34972a1..85beb7824 100644 +docs_build/dev/ProjectInstructions/README.txt +docs_build/dev/ProjectInstructions/TEAM_START_COMMANDS.md +docs_build/dev/ProjectInstructions/addendums/assistant_execution_modes.md ++docs_build/dev/ProjectInstructions/addendums/branch_context_governance.md +docs_build/dev/ProjectInstructions/addendums/branch_lock_governance.md +docs_build/dev/ProjectInstructions/addendums/canonical_repository_structure.md +docs_build/dev/ProjectInstructions/addendums/codex_artifact_and_reporting_standard.md +docs_build/dev/ProjectInstructions/addendums/codex_project_instructions_startup.md +docs_build/dev/ProjectInstructions/addendums/legacy_migration_policy.md ++docs_build/dev/ProjectInstructions/addendums/multi_team.md +docs_build/dev/ProjectInstructions/addendums/pr_workflow.md +docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md ++docs_build/dev/ProjectInstructions/addendums/release_gate.md ++docs_build/dev/ProjectInstructions/addendums/team_release_readiness.md ++docs_build/dev/ProjectInstructions/addendums/team_start_and_release.md +docs_build/dev/ProjectInstructions/addendums/test_structure_standardization.md +docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md +docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock.md @@ -1277,137 +1522,25 @@ index 8e34972a1..85beb7824 100644 +project-instructions/addendums/legacy-migration-policy.md +project-instructions/addendums/test-structure-standardization.md diff --git a/docs_build/dev/reports/codex_review.diff b/docs_build/dev/reports/codex_review.diff -index f88731273..53132b823 100644 +index f88731273..757feae21 100644 --- a/docs_build/dev/reports/codex_review.diff +++ b/docs_build/dev/reports/codex_review.diff -@@ -1,465 +1,1168 @@ --diff --git a/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_branch-validation.md b/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_branch-validation.md --index c5ced6d1b..53bc243c2 100644 ----- a/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_branch-validation.md --+++ b/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_branch-validation.md --@@ -17,3 +17,4 @@ Status: PASS -- - PASS: Tests are limited to targeted Game Journey completion metrics regression coverage. -- - PASS: Did not delete, move, overwrite, export, or migrate `tmp/local-api/game-journey-completion-metrics.sqlite`. -- - PASS: Did not start Alfa Tags PRs. --+- PASS: Final audit removed active runtime JS/MJS SQLite and `tmp/local-api` references outside the migration-only utility. --diff --git a/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_manual-validation-notes.md b/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_manual-validation-notes.md --index 9a952fb7b..6dad6bb08 100644 ----- a/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_manual-validation-notes.md --+++ b/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_manual-validation-notes.md --@@ -5,9 +5,10 @@ Status: PASS -- ## Notes -- -- - Confirmed the repo-local `tmp/local-api/game-journey-completion-metrics.sqlite` file exists before validation. ---- Confirmed active `createGameJourneyCompletionMetricsStore({ postgresClient })` no longer resolves that retired path by default. ---- Confirmed active metrics load 14 Postgres-backed completion buckets while the retired file remains untouched. ---- Confirmed explicit `legacyDbPath` protection remains covered by the existing migration/regression test file. --+- Confirmed active `createGameJourneyCompletionMetricsStore({ postgresClient })` exposes no `legacyDbPath`. --+- Confirmed active metrics snapshots expose no `legacySqlitePath`. --+- Confirmed active metrics load 14 DB-backed completion buckets while the retired file remains untouched. --+- Confirmed active runtime JS/MJS has no SQLite or `tmp/local-api` metrics references outside the migration-only utility. -- - Confirmed the toolbox page renders neutral Creator-facing outage wording when active metrics are unavailable. -- - Confirmed the toolbox page does not render the forbidden warning string, SQLite wording, `tmp/local-api`, or Postgres internals in the simulated outage lane. -- - Confirmed no Alfa Tags PR work was started. --diff --git a/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_report.md b/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_report.md --index 1940890cf..777642b00 100644 ----- a/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_report.md --+++ b/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_report.md --@@ -11,9 +11,10 @@ Recover the Game Journey completion metrics path so active Alfa and Owner work n -- ## Implementation Summary -- -- - Removed active runtime defaulting to `tmp/local-api/game-journey-completion-metrics.sqlite` in `createGameJourneyCompletionMetricsStore`. ---- Kept the explicit `legacyDbPath` guard intact for recovery/migration callers so legacy data is still protected from silent overwrite or deletion. --+- Removed active runtime `legacyDbPath` guard plumbing from the Game Journey metrics store, repository, Local API router, and Playwright test server helper. -- - Updated `toolbox/tools-page-accordions.js` to render neutral Creator-safe progress outage wording instead of backend diagnostics. ---- Added a store-level regression test proving a retired default SQLite-shaped file does not block active Postgres-backed metrics. --+- Added a store-level regression test proving a retired default SQLite-shaped file does not block or get touched by active DB-backed metrics. --+- Added a targeted guardrail test proving active runtime JS/MJS under `src`, `assets`, and `toolbox` has no SQLite or `tmp/local-api` metrics references, excluding the migration-only utility. -- - Added a focused Playwright test proving the toolbox page does not render the forbidden warning, SQLite wording, local filesystem path, or Postgres internals when metrics are unavailable. -- -- ## Reference Comparison --@@ -28,16 +29,20 @@ Recover the Game Journey completion metrics path so active Alfa and Owner work n -- - PASS: `node --check` on modified source and test files. -- - PASS: `node ./scripts/run-node-test-files.mjs tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs tests/dev-runtime/GameJourneyCompletionMetricsMigration.test.mjs`. -- - PASS: `npx playwright test tests/playwright/tools/GameJourneyTool.spec.mjs --project=playwright --workers=1 --reporter=line -g "Game Journey Local API persists completion metrics to Postgres|Toolbox renders Creator-safe Game Journey progress outage copy"`. ---- PASS: Direct proof against the actual existing `tmp/local-api/game-journey-completion-metrics.sqlite` file confirmed active Postgres metrics load 14 buckets and do not resolve a legacy path. ---- PASS: Runtime source search found no `Game Journey completion metrics unavailable` string. ---- PASS: Runtime source search found no active metrics-store default reference to `game-journey-completion-metrics.sqlite`, `GAMEFOUNDRY_GAME_JOURNEY_METRICS_DB_PATH`, or `defaultLegacySqlitePath`. --+- PASS: Direct proof against the actual existing `tmp/local-api/game-journey-completion-metrics.sqlite` file confirmed active DB metrics load 14 buckets, expose no legacy path fields, and do not touch the retired file. --+- PASS: Active runtime JS/MJS search found no SQLite, `.sqlite`, `better-sqlite`, `game-journey-completion-metrics.sqlite`, or `tmp/local-api` references outside the migration-only utility. --+- PASS: Runtime source search found no `Game Journey completion metrics unavailable` Creator-facing string. -- - PASS: `git diff --check` reported no whitespace errors. Git emitted line-ending warnings only. -- -- ## Files -- -- - `src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs` --+- `src/dev-runtime/persistence/tool-repositories/game-journey-mock-repository.js` --+- `src/dev-runtime/server/local-api-router.mjs` -- - `tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs` --+- `tests/helpers/playwrightRepoServer.mjs` -- - `tests/playwright/tools/GameJourneyTool.spec.mjs` --+- `tests/playwright/tools/IdeaBoardTableNotes.spec.mjs` -- - `toolbox/tools-page-accordions.js` -- -- ## Artifact --diff --git a/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_requirement-checklist.md b/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_requirement-checklist.md --index 544b7057f..65a654b6d 100644 ----- a/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_requirement-checklist.md --+++ b/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_requirement-checklist.md --@@ -11,12 +11,14 @@ Status: PASS -- - PASS: Fixed only the Game Journey completion metrics regression. -- - PASS: Did not delete, move, overwrite, export, or migrate `tmp/local-api/game-journey-completion-metrics.sqlite`. -- - PASS: Stopped active runtime from defaulting to `tmp/local-api/game-journey-completion-metrics.sqlite`. --+- PASS: Removed active runtime `legacyDbPath` SQLite guard plumbing. -- - PASS: Preserved Postgres-backed Game Journey completion metrics as the active path. -- - PASS: Ensured `toolbox/tools-page-accordions.js` cannot render `Game Journey completion metrics unavailable:`. -- - PASS: Creator-facing UI does not expose SQLite, local filesystem paths, migration/export language, or Postgres internals. -- - PASS: Did not introduce silent fallback behavior; metrics outage remains visible with neutral wording. -- - PASS: Added targeted regression tests. -- - PASS: Proved the existing legacy SQLite file does not block active metrics. --+- PASS: Proved active runtime JS/MJS has no SQLite or `tmp/local-api` metrics references outside the migration-only utility. -- - PASS: Proved the forbidden warning string is not rendered. -- - PASS: Proved Game Journey metrics still load through the active DB/API path. -- - PASS: Used targeted validation only. --diff --git a/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_validation-lane.md b/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_validation-lane.md --index fe5ba4768..47530c453 100644 ----- a/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_validation-lane.md --+++ b/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_validation-lane.md --@@ -6,9 +6,13 @@ Status: PASS +@@ -1,278 +1,7221 @@ +diff --git a/docs_build/dev/BUILD_PR.md b/docs_build/dev/BUILD_PR.md -+index 30700e9cd..50b1b27fa 100644 ++index 30700e9cd..c375aee47 100644 +--- a/docs_build/dev/BUILD_PR.md ++++ b/docs_build/dev/BUILD_PR.md +@@ -1,66 +1,52 @@ +-# PR_26177_006-shared-time-foundation ++# PR_26177_OWNER_007-project-instructions-single-source-eod-lock - -- ```powershell -- node --check src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs --+node --check src/dev-runtime/persistence/tool-repositories/game-journey-mock-repository.js --+node --check src/dev-runtime/server/local-api-router.mjs -- node --check toolbox/tools-page-accordions.js -- node --check tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs --+node --check tests/helpers/playwrightRepoServer.mjs -- node --check tests/playwright/tools/GameJourneyTool.spec.mjs --+node --check tests/playwright/tools/IdeaBoardTableNotes.spec.mjs -- ``` ++ + ## Purpose - -- Result: PASS --@@ -17,7 +21,7 @@ Result: PASS -- node ./scripts/run-node-test-files.mjs tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs tests/dev-runtime/GameJourneyCompletionMetricsMigration.test.mjs -- ``` ++ +-Add a small shared time foundation. ++Make `docs_build/dev/ProjectInstructions/` the only active Project Instructions source and add EOD main lock plus next-day reset governance. - ---Result: PASS, 2 targeted node test files passed --+Result: PASS, 2 targeted node test files passed. Includes active runtime JS/MJS SQLite reference guardrail. ++ + ## Source Of Truth - -- ```powershell -- npx playwright test tests/playwright/tools/GameJourneyTool.spec.mjs --project=playwright --workers=1 --reporter=line -g "Game Journey Local API persists completion metrics to Postgres|Toolbox renders Creator-safe Game Journey progress outage copy" --@@ -26,14 +30,14 @@ npx playwright test tests/playwright/tools/GameJourneyTool.spec.mjs --project=pl -- Result: PASS, 2 passed ++ +-This `BUILD_PR.md`, `PLAN_PR.md`, and the user request are the source of truth for `PR_26177_006-shared-time-foundation`. +- +-## Stack @@ -1427,7 +1560,7 @@ index f88731273..53132b823 100644 ++- Establish `docs_build/dev/ProjectInstructions/` as the only active source. ++- Mark all other ProjectInstructions-style sources changed by this PR as deprecated references. ++- Update active team start/governance docs to reference only `docs_build/dev/ProjectInstructions/`. -++- Add EOD main lock and next-day reset governance. +++- Add EOD main lock, next-day reset governance, and canonical START / WORK / END branch lifecycle rules. ++- Add required reports under `docs_build/dev/reports/`. + + ## Exact Targets @@ -1472,18 +1605,16 @@ index f88731273..53132b823 100644 + +-Run exactly: ++Run: - - ```powershell ---node -e "import('node:fs').then(async fs=>{const [{createGameJourneyCompletionMetricsStore}, {createGameJourneyCompletionMetricsPostgresClientStub}] = await Promise.all([import('./src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs'), import('./tests/helpers/gameJourneyCompletionMetricsPostgresClientStub.mjs')]); const legacy='tmp/local-api/game-journey-completion-metrics.sqlite'; if(!fs.existsSync(legacy)) throw new Error('Expected existing legacy SQLite file for regression proof'); const store=createGameJourneyCompletionMetricsStore({postgresClient:createGameJourneyCompletionMetricsPostgresClientStub()}); const metrics=await store.listMetrics(); if(store.legacyDbPath) throw new Error('Active store resolved a legacy path'); if(metrics.length!==14) throw new Error('Expected 14 active metrics'); console.log('PASS active Postgres metrics ignore existing retired legacy SQLite file');})" --+node -e "import('node:fs').then(async fs=>{const [{createGameJourneyCompletionMetricsStore}, {createGameJourneyCompletionMetricsPostgresClientStub}] = await Promise.all([import('./src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs'), import('./tests/helpers/gameJourneyCompletionMetricsPostgresClientStub.mjs')]); const legacy='tmp/local-api/game-journey-completion-metrics.sqlite'; if(!fs.existsSync(legacy)) throw new Error('Expected existing retired local file for regression proof'); const before=fs.statSync(legacy).mtimeMs; const store=createGameJourneyCompletionMetricsStore({postgresClient:createGameJourneyCompletionMetricsPostgresClientStub()}); const metrics=await store.listMetrics(); const snapshot=await store.snapshot(); const after=fs.statSync(legacy).mtimeMs; if(Object.hasOwn(store, 'legacyDbPath')) throw new Error('Store exposes legacyDbPath'); if(Object.hasOwn(snapshot, 'legacySqlitePath')) throw new Error('Snapshot exposes legacySqlitePath'); if(metrics.length!==14) throw new Error('Expected 14 active metrics'); if(before!==after) throw new Error('Retired local file was touched'); console.log('PASS active DB metrics ignore and do not inspect retired local file');})" ++ ++ ```powershell +-node ./scripts/run-node-test-files.mjs tests/shared/TimeFoundation.test.mjs +-node --check src/shared/time/time.js +-node --check tests/shared/TimeFoundation.test.mjs ++rg -n 'project-instructions/addendums|docs_build/dev/PROJECT_INSTRUCTIONS.md.*source of truth|Codex must always read `docs_build/dev/PROJECT_INSTRUCTIONS.md`|Read `docs_build/dev/PROJECT_INSTRUCTIONS.md`' docs_build/dev/ProjectInstructions docs_build/dev/PROJECT_INSTRUCTIONS.md project-instructions -++rg -n "End of Day:|Next Day Start:|HEAD.*published EOD SHA|only active Project Instructions source" docs_build/dev/ProjectInstructions +++rg -n "Branch Lifecycle \\(Canonical\\)|Every PR follows exactly three phases|^START$|^WORK$|^END$|Mandatory Hard Stops|tomorrow's official baseline|No commits on main|Never checkout main|Only after ALL four pass" docs_build/dev/ProjectInstructions ++git diff --name-only -- src assets toolbox games api serverside package.json package-lock.json docs_build/dev/start_of_day + git diff --check - ``` ++ ``` +- +-## Artifact +- @@ -1493,20 +1624,15 @@ index f88731273..53132b823 100644 +-tmp/PR_26177_006-shared-time-foundation_delta.zip +-``` +diff --git a/docs_build/dev/PLAN_PR.md b/docs_build/dev/PLAN_PR.md -+index 907936aee..39fa03385 100644 ++index 907936aee..0e5d6a50e 100644 +--- a/docs_build/dev/PLAN_PR.md ++++ b/docs_build/dev/PLAN_PR.md +@@ -1,22 +1,28 @@ +-# PLAN_PR: PR_26177_006-shared-time-foundation ++# PLAN_PR: PR_26177_OWNER_007-project-instructions-single-source-eod-lock - -- Result: PASS ++ + ## Purpose - -- ```powershell --+rg -n -i "sqlite|better-sqlite|game-journey-completion-metrics\.sqlite|tmp/local-api" src assets toolbox -g "*.js" -g "*.mjs" --glob "!src/dev-runtime/persistence/game-journey-completion-metrics-migration.mjs" -- rg -n "Game Journey completion metrics unavailable" src assets toolbox --glob "!**/*.map" ---rg -n "game-journey-completion-metrics\.sqlite|GAMEFOUNDRY_GAME_JOURNEY_METRICS_DB_PATH|defaultLegacySqlitePath" src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs toolbox/tools-page-accordions.js assets/toolbox/game-journey/js/index.js ++ +-Add a small shared time foundation. ++Make `docs_build/dev/ProjectInstructions/` the only active Project Instructions source and add EOD main lock plus next-day reset governance. + @@ -1523,7 +1649,7 @@ index f88731273..53132b823 100644 ++- Mark legacy ProjectInstructions-style sources as deprecated reference material. ++- Move active legacy addendums into `docs_build/dev/ProjectInstructions/addendums/`. ++- Update active team start and governance docs to reference only `docs_build/dev/ProjectInstructions/`. -++- Add EOD main lock, next-day reset, and team PR branch creation gate. +++- Add EOD main lock, next-day reset, team PR branch creation gate, and canonical START / WORK / END branch lifecycle rules. ++- Add required Codex reports under `docs_build/dev/reports/`. + +-## Implementation Plan @@ -1541,7 +1667,7 @@ index f88731273..53132b823 100644 ++## Validation Plan ++ ++1. Run targeted grep/search proving no active duplicate ProjectInstructions source remains. -++2. Confirm EOD/Next Day rule appears in active governance docs. +++2. Confirm EOD/Next Day and canonical START / WORK / END branch lifecycle rules appear in active governance docs. ++3. Confirm no product/runtime files changed. ++4. Run `git diff --check`. +diff --git a/docs_build/dev/PROJECT_INSTRUCTIONS.md b/docs_build/dev/PROJECT_INSTRUCTIONS.md @@ -1595,7 +1721,7 @@ index f88731273..53132b823 100644 + + Required pre-change report: +diff --git a/docs_build/dev/ProjectInstructions/PROJECT_INSTRUCTIONS.md b/docs_build/dev/ProjectInstructions/PROJECT_INSTRUCTIONS.md -+index d2a84ecbe..99ddd0f42 100644 ++index d2a84ecbe..647881f1f 100644 +--- a/docs_build/dev/ProjectInstructions/PROJECT_INSTRUCTIONS.md ++++ b/docs_build/dev/ProjectInstructions/PROJECT_INSTRUCTIONS.md +@@ -4,6 +4,12 @@ Read `README.txt` first. @@ -1626,13 +1752,13 @@ index f88731273..53132b823 100644 + ++## Single Source and Main Lock Governance ++ -++`docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md` defines the single active Project Instructions source, EOD main lock, next-day reset, and team branch creation gate. +++`docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md` defines the single active Project Instructions source, canonical START / WORK / END branch lifecycle, EOD main lock, next-day reset, team branch creation gate, daily synchronization baseline, and mandatory hard stops. ++ + ## Merge Control + + No PR in this operating system is merged without explicit owner approval. +diff --git a/docs_build/dev/ProjectInstructions/README.txt b/docs_build/dev/ProjectInstructions/README.txt -+index a48becf05..631fd3918 100644 ++index a48becf05..50736f317 100644 +--- a/docs_build/dev/ProjectInstructions/README.txt ++++ b/docs_build/dev/ProjectInstructions/README.txt +@@ -1,10 +1,10 @@ @@ -1648,7 +1774,19 @@ index f88731273..53132b823 100644 + + Backlog workflow: + Backlog work is tracked under backlog/. BACKLOG_MASTER.md is the planned source for backlog item status, notes, and references. Backlog item text is treated as immutable once created; status and notes may change under the governance addendums. -+@@ -29,9 +29,9 @@ Do not rewrite history snapshots after creation unless the owner explicitly appr ++@@ -13,7 +13,10 @@ Team assignment workflow: ++ Team assignments are tracked under team_assignments/. A team pulls work from BACKLOG_MASTER.md, marks the item building when assigned, and records the active assignment under the owning team. Teams work only on assigned items unless an OWNER override explicitly changes the assignment. ++ ++ No direct commits to main: ++-Do not commit directly to main unless the owner explicitly instructs that exception. Normal work must use PR branches, draft PRs, validation evidence, and owner-controlled merge approval. +++Do not commit directly to main. Normal work must use PR branches, draft PRs, validation evidence, and owner-controlled merge approval. +++ +++Branch lifecycle: +++Every PR follows exactly three phases: START, WORK, END. The canonical lifecycle is `docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md`. ++ ++ OWNER override rule: ++ An OWNER override must use this wording: ++@@ -29,9 +32,9 @@ Do not rewrite history snapshots after creation unless the owner explicitly appr + + READ THIS FIRST + @@ -1661,8 +1799,11 @@ index f88731273..53132b823 100644 + 4. Team ownership must be respected. + 5. BACKLOG_MASTER.md is the authoritative backlog. + 6. Build Path status derives from backlog status. -+@@ -42,12 +42,13 @@ READ THIS FIRST ++@@ -40,14 +43,16 @@ READ THIS FIRST ++ 9. Follow OWNER governance decisions. ++ 10. When guidance conflicts, newest OWNER-approved guidance wins. + 11. Batch Governance Mode is the default for governance, documentation, and administrative work. +++12. Follow the canonical START / WORK / END lifecycle. + + Addendum index: +-- Canonical Repository Structure: project-instructions/addendums/canonical-repository-structure.md @@ -1682,10 +1823,10 @@ index f88731273..53132b823 100644 + - Environment Governance Model: docs_build/dev/ProjectInstructions/addendums/environment_governance_model.md + - Environment Configuration Standards: docs_build/dev/ProjectInstructions/addendums/environment_configuration_standards.md +diff --git a/docs_build/dev/ProjectInstructions/TEAM_START_COMMANDS.md b/docs_build/dev/ProjectInstructions/TEAM_START_COMMANDS.md -+index d0118f63a..c446a4b33 100644 ++index d0118f63a..292540043 100644 +--- a/docs_build/dev/ProjectInstructions/TEAM_START_COMMANDS.md ++++ b/docs_build/dev/ProjectInstructions/TEAM_START_COMMANDS.md -+@@ -1,5 +1,16 @@ ++@@ -1,5 +1,26 @@ + # TEAM_START_COMMANDS + ++## Required Main Reset Gate For Every Team @@ -1699,10 +1840,20 @@ index f88731273..53132b823 100644 ++ ++Use `docs_build/dev/ProjectInstructions/` as the only active Project Instructions source. ++ +++Branch Lifecycle (Canonical): +++- Every PR follows exactly three phases: START, WORK, END. +++- Follow `docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md`. +++- START begins on synchronized `main` and creates the PR branch only after all gates pass. +++- WORK remains on the PR branch. Never checkout `main`. +++- END merges, returns to synchronized `main`, publishes branch, HEAD SHA, and date/time, then stops all work. +++- No commits on `main`. +++- No implementation on `main`. +++- No validation on `main` except start validation. +++ + ## Start Team Alfa + + Ready-to-copy command: -+@@ -123,4 +134,24 @@ Merge to main is EOD-only and owner-approved, unless the owner explicitly says: ++@@ -123,4 +144,26 @@ Merge to main is EOD-only and owner-approved, unless the owner explicitly says: + "Merge this PR now." + + Do not treat sequential PR completion as merge approval. @@ -1726,112 +1877,222 @@ index f88731273..53132b823 100644 ++git status ++git rev-list --left-right --count main...origin/main ++git rev-parse HEAD - ``` -+diff --git a/docs_build/dev/ProjectInstructions/addendums/branch_lock_governance.md b/docs_build/dev/ProjectInstructions/addendums/branch_lock_governance.md -+index 518f8c943..d6c8e4cf7 100644 -+--- a/docs_build/dev/ProjectInstructions/addendums/branch_lock_governance.md -++++ b/docs_build/dev/ProjectInstructions/addendums/branch_lock_governance.md -+@@ -23,6 +23,7 @@ Keep active work attached to the correct assigned team, branch, and OWNER decisi - -- Result: PASS, no matches -+ - Start from current `main`. -+ - Pull latest `origin/main` before creating a work branch. -++- Do not create a PR branch unless current branch is `main`, worktree is clean, `main...origin/main` is `0 0`, and `HEAD` SHA matches the published EOD SHA. -+ - Keep work on the active branch until the PR is merged, the branch is retired, or OWNER says to return to `main`. -+ - Do not commit directly to `main` unless OWNER explicitly approves. -+ - Do not merge stale historical branches directly unless they are current, clean, still needed, and OWNER-approved. -+@@ -54,3 +55,36 @@ Protected guidance includes: -+ - Governance Phase 1 completion guidance -+ -+ If protected guidance must change, OWNER approval is required. ++ -++## End Of Day Main Lock +++Publish Branch, HEAD SHA, and Date/time. This becomes tomorrow's official baseline. ++ ``` ++diff --git a/docs_build/dev/ProjectInstructions/addendums/assistant_execution_modes.md b/docs_build/dev/ProjectInstructions/addendums/assistant_execution_modes.md ++new file mode 100644 ++index 000000000..6d7928669 ++--- /dev/null +++++ b/docs_build/dev/ProjectInstructions/addendums/assistant_execution_modes.md ++@@ -0,0 +1,120 @@ +++# Assistant Execution Modes ++ -++End of Day: +++## Purpose ++ -++```text -++git checkout main -++git fetch origin -++git pull --ff-only origin main -++git status -++git rev-list --left-right --count main...origin/main -++``` +++Standardize request interpretation and expected outputs for Review, Owner, Build PR, Continue, Challenge, and Stop Gate workflows. ++ -++Required: +++## Command Modes ++ -++```text -++On branch main -++nothing to commit, working tree clean -++0 0 -++``` +++### Review ++ -++Next Day Start: +++Expected Output: +++- Findings +++- Risks +++- Recommendations ++ -++```text -++git checkout main -++git fetch origin -++git pull --ff-only origin main -++git status -++git rev-list --left-right --count main...origin/main -++git rev-parse HEAD -++``` +++Do Not Output: +++- PRs +++- Implementation plans ++ -++The next-day `HEAD` SHA must match the published EOD SHA before any team creates a PR branch. -+diff --git a/docs_build/dev/ProjectInstructions/addendums/pr_workflow.md b/docs_build/dev/ProjectInstructions/addendums/pr_workflow.md -+index f8a4acb6e..7c1cd8275 100644 -+--- a/docs_build/dev/ProjectInstructions/addendums/pr_workflow.md -++++ b/docs_build/dev/ProjectInstructions/addendums/pr_workflow.md -+@@ -129,3 +129,40 @@ Stop only for: -+ - Merge conflict -+ - Validation failure -+ - OWNER decision +++### Owner ++ -++## EOD Main Lock +++Expected Output: +++- Decisions +++- Governance direction +++- Standards ++ -++End of Day: +++Do Not Output: +++- Detailed implementation ++ -++```text -++git checkout main -++git fetch origin -++git pull --ff-only origin main -++git status -++git rev-list --left-right --count main...origin/main -++``` +++### Build PR ++ -++Required: +++Expected Output: +++- Single Codex work order +++- May contain multiple sequential PRs belonging to the same workstream +++- Copy/paste ready for execution ++ -++```text -++On branch main -++nothing to commit, working tree clean -++0 0 -++``` +++Should Include: +++- Start gates +++- Changes +++- Validation +++- Commit names +++- Stop point ++ -++## Next Day Start +++Do Not Output: +++- Design discussion +++- Alternatives +++- Rationale +++- Architecture brainstorming +++ +++### Continue +++ +++Expected Output: +++- Next sequential executable PR +++- Next sequential work order +++ +++Do Not Output: +++- New ideas +++- Re-analysis +++- Additional brainstorming +++ +++### Challenge +++ +++Expected Output: +++- Risks +++- Contradictions +++- Better alternatives +++ +++Do Not Output: +++- Immediate implementation +++ +++### Stop Gate +++ +++Expected Output: +++- Why work should stop +++- Required corrections +++ +++Allowed Reasons: +++- Governance conflict +++- Architecture conflict +++- Security risk +++- Data loss risk +++- Major technical debt increase +++ +++## Additional Definitions +++ +++### Follow Project Instructions +++ +++Meaning: +++- Use existing governance +++- Do not redesign process +++ +++### Build the PR +++ +++Meaning: +++- Produce Codex executable work order immediately +++ +++### Continue +++ +++Meaning: +++- Produce next sequential work item +++ +++### No zip file +++ +++Meaning: +++- Generate instructions only +++- Do not expect artifact review +++ +++### You are owner +++ +++Meaning: +++- Make decisions +++- Do not ask for direction unless blocked +++ +++### Done for the day +++ +++Meaning: +++- Finish commits +++- Merge +++- Push +++- Create next-day start document ++diff --git a/docs_build/dev/ProjectInstructions/addendums/branch_context_governance.md b/docs_build/dev/ProjectInstructions/addendums/branch_context_governance.md ++index 09cd3a1ec..798bb2cba 100644 ++--- a/docs_build/dev/ProjectInstructions/addendums/branch_context_governance.md +++++ b/docs_build/dev/ProjectInstructions/addendums/branch_context_governance.md ++@@ -21,6 +21,8 @@ At the start of work, report or validate: ++ - active PR number/name or explicit `PLAN_ONLY` ++ - previous PR Closed status unless this is an explicitly documented stacked PR chain ++ +++Session start must follow the canonical START phase in `docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md`. +++ ++ ## Stop Conditions ++ ++ Stop and report before changing files when: ++@@ -38,6 +40,8 @@ Stop and report before changing files when: ++ ++ After a branch is created, the branch remains the working context. ++ +++This is the canonical WORK phase: remain on the PR branch, never checkout `main`, commit only on the PR branch, push only the PR branch, validate from the PR branch, and open/update the PR from the PR branch. +++ ++ Do not automatically return to `main` after: ++ ++ - commit ++@@ -47,7 +51,7 @@ Do not automatically return to `main` after: ++ - review updates ++ - additional commits ++ ++-Return to `main` only after the PR is merged, the branch is retired, or OWNER explicitly says to return to `main`. +++Return to `main` only in the canonical END phase after the PR is merged, the branch is retired, or OWNER explicitly says to return to `main`. ++ ++ Returning to `main` is required before Closed can be recorded. ++ ++@@ -58,6 +62,7 @@ Closed branch context requires: ++ - local/origin sync is `0/0` ++ - no untracked files ++ - source branch disposition recorded as `retained` +++- branch, HEAD SHA, and date/time recorded as the new EOD baseline when this is EOD closeout ++ ++ ## GitHub Authority ++ ++diff --git a/docs_build/dev/ProjectInstructions/addendums/branch_lock_governance.md b/docs_build/dev/ProjectInstructions/addendums/branch_lock_governance.md ++index 518f8c943..61b95cfae 100644 ++--- a/docs_build/dev/ProjectInstructions/addendums/branch_lock_governance.md +++++ b/docs_build/dev/ProjectInstructions/addendums/branch_lock_governance.md ++@@ -23,12 +23,36 @@ Keep active work attached to the correct assigned team, branch, and OWNER decisi ++ ++ - Start from current `main`. ++ - Pull latest `origin/main` before creating a work branch. +++- Do not create a PR branch unless current branch is `main`, worktree is clean, `main...origin/main` is `0 0`, and `HEAD` SHA matches the published EOD SHA. +++- Follow the canonical START / WORK / END lifecycle in `docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md`. ++ - Keep work on the active branch until the PR is merged, the branch is retired, or OWNER says to return to `main`. ++-- Do not commit directly to `main` unless OWNER explicitly approves. +++- Do not commit directly to `main`. +++- HARD STOP before committing if current branch is `main`. +++- HARD STOP if the branch changes unexpectedly during implementation. +++- Commit only to the PR branch. +++- Push only the PR branch. ++ - Do not merge stale historical branches directly unless they are current, clean, still needed, and OWNER-approved. ++ - Retain source branches by default after merge and closeout. ++ - Record branch disposition before Closed as `retained`. ++ +++## Branch Lifecycle (Canonical) +++ +++Every PR follows exactly three phases: ++ ++```text -++git checkout main -++git fetch origin -++git pull --ff-only origin main -++git status -++git rev-list --left-right --count main...origin/main -++git rev-parse HEAD +++START +++WORK +++END ++``` ++ -++No team creates a PR branch until: -++- Current branch: `main` -++- Worktree: clean -++- `main...origin/main`: `0 0` -++- `HEAD` SHA matches published EOD SHA -+diff --git a/docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md b/docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md -+index 9735b4bd4..9a104b4f9 100644 -+--- a/docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md -++++ b/docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md -+@@ -211,3 +211,44 @@ Commit/push during the day is allowed only on assigned team/OWNER/PR branches. +++The canonical lifecycle lives in `docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md`. +++ +++Branch lock governance enforces: +++- START on synchronized `main`. +++- WORK only on the PR branch. +++- END by merging, returning to synchronized `main`, publishing branch, HEAD SHA, and date/time, then stopping all work. +++- Mandatory hard stops before commits on `main`, dirty branch creation, non-`0 0` main sync, baseline SHA mismatch, unvalidated merge, or new PR work before synchronized main return. +++ ++ ## OWNER Override + -+ Merge to main is EOD-only and owner-approved, unless the owner explicitly says: -+ "Merge this PR now." ++ OWNER may override a branch lock or team assignment. ++@@ -54,3 +78,36 @@ Protected guidance includes: ++ - Governance Phase 1 completion guidance ++ ++ If protected guidance must change, OWNER approval is required. ++ -++## EOD Main Lock And Next Day Reset +++## End Of Day Main Lock ++ ++End of Day: ++ @@ -1862,597 +2123,14 @@ index f88731273..53132b823 100644 ++git rev-parse HEAD ++``` ++ -++Team rule: -++No team creates a PR branch until: -++- Current branch: `main` -++- Worktree: clean -++- `main...origin/main`: `0 0` -++- `HEAD` SHA matches published EOD SHA -++ -++Active source rule: -++Teams must use only `docs_build/dev/ProjectInstructions/` as the active Project Instructions source. - diff --git a/docs_build/dev/reports/codex_changed_files.txt b/docs_build/dev/reports/codex_changed_files.txt --index 585a10850..8e34972a1 100644 -+index 8e34972a1..85beb7824 100644 - --- a/docs_build/dev/reports/codex_changed_files.txt - +++ b/docs_build/dev/reports/codex_changed_files.txt --@@ -6,6 +6,9 @@ docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recove -+@@ -1,14 +1,30 @@ -+-docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_branch-validation.md -+-docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_manual-validation-notes.md -+-docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_report.md -+-docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_requirement-checklist.md -+-docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_validation-lane.md -++docs_build/dev/BUILD_PR.md -++docs_build/dev/PLAN_PR.md -++docs_build/dev/PROJECT_INSTRUCTIONS.md -++docs_build/dev/ProjectInstructions/PROJECT_INSTRUCTIONS.md -++docs_build/dev/ProjectInstructions/README.txt -++docs_build/dev/ProjectInstructions/TEAM_START_COMMANDS.md -++docs_build/dev/ProjectInstructions/addendums/assistant_execution_modes.md -++docs_build/dev/ProjectInstructions/addendums/branch_lock_governance.md -++docs_build/dev/ProjectInstructions/addendums/canonical_repository_structure.md -++docs_build/dev/ProjectInstructions/addendums/codex_artifact_and_reporting_standard.md -++docs_build/dev/ProjectInstructions/addendums/codex_project_instructions_startup.md -++docs_build/dev/ProjectInstructions/addendums/legacy_migration_policy.md -++docs_build/dev/ProjectInstructions/addendums/pr_workflow.md -++docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md -++docs_build/dev/ProjectInstructions/addendums/test_structure_standardization.md -++docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md -++docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock.md -++docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_branch-validation.md -++docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_manual-validation-notes.md -++docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_requirement-checklist.md -++docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_validation-lane.md - docs_build/dev/reports/codex_changed_files.txt - docs_build/dev/reports/codex_review.diff -- src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs --+src/dev-runtime/persistence/tool-repositories/game-journey-mock-repository.js --+src/dev-runtime/server/local-api-router.mjs -- tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs --+tests/helpers/playwrightRepoServer.mjs -- tests/playwright/tools/GameJourneyTool.spec.mjs ---toolbox/tools-page-accordions.js --+tests/playwright/tools/IdeaBoardTableNotes.spec.mjs --diff --git a/src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs b/src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs --index 6c202c8a2..eea6294e7 100644 ----- a/src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs --+++ b/src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs --@@ -1,5 +1,3 @@ ---import { existsSync } from "node:fs"; ---import path from "node:path"; -- import { createPostgresConnectionClient } from "./postgres-connection-client.mjs"; -- import { SEED_DB_KEYS, makeSeedUlid } from "../seed/seed-db-keys.mjs"; -- --@@ -59,24 +57,6 @@ function clone(value) { -- return JSON.parse(JSON.stringify(value)); -- } -- ---function resolveLegacySqlitePath(legacyDbPath) { --- if (legacyDbPath === null || legacyDbPath === undefined) { --- return ""; --- } --- const value = String(legacyDbPath || "").trim(); --- if (!value) { --- return ""; --- } --- return path.resolve(value); ---} --- ---function assertNoUnmigratedLegacySqlite(legacyDbPath) { --- if (!legacyDbPath || !existsSync(legacyDbPath)) { --- return; --- } --- throw new Error(`Legacy Game Journey completion metrics SQLite data exists at ${legacyDbPath}. No data was removed or overwritten. Export or migrate that data into Postgres, then move the legacy file before using the Postgres metrics store.`); ---} --- -- function normalizeCount(value, fallback = 0) { -- const parsed = Number(value); -- if (!Number.isFinite(parsed)) { --@@ -158,7 +138,6 @@ function bucketSeedRow(bucket, now) { -- export function createGameJourneyCompletionMetricsStore(options = {}) { -- const env = options.env || process.env; -- const bucketSeeds = Object.freeze((options.buckets || GAME_JOURNEY_COMPLETION_BUCKETS).map(clone)); --- const legacyDbPath = resolveLegacySqlitePath(options.legacyDbPath); -- let postgresClient = options.postgresClient || null; -- let readyPromise = null; -- --@@ -230,7 +209,6 @@ export function createGameJourneyCompletionMetricsStore(options = {}) { -- async function ensureReady() { -- if (!readyPromise) { -- readyPromise = (async () => { --- assertNoUnmigratedLegacySqlite(legacyDbPath); -- await client().query(GAME_JOURNEY_COMPLETION_METRICS_SCHEMA_SQL); -- await seedDefaultBuckets(); -- })(); --@@ -298,7 +276,6 @@ export function createGameJourneyCompletionMetricsStore(options = {}) { -- databaseConfigKey: "GAMEFOUNDRY_DATABASE_URL", -- databaseEngine: "Postgres", -- databasePath: "GAMEFOUNDRY_DATABASE_URL", --- legacySqlitePath: legacyDbPath, -- serviceContract: "Web UI -> Local API/Service Contract -> Postgres", -- source: GAME_JOURNEY_COMPLETION_METRICS_TABLE, -- tableName: GAME_JOURNEY_COMPLETION_METRICS_TABLE, --@@ -312,7 +289,6 @@ export function createGameJourneyCompletionMetricsStore(options = {}) { -- } -- -- return { --- legacyDbPath, -- listMetrics, -- snapshot, -- updateMetric, --diff --git a/src/dev-runtime/persistence/tool-repositories/game-journey-mock-repository.js b/src/dev-runtime/persistence/tool-repositories/game-journey-mock-repository.js --index 73b409c42..8e0ddc92b 100644 ----- a/src/dev-runtime/persistence/tool-repositories/game-journey-mock-repository.js --+++ b/src/dev-runtime/persistence/tool-repositories/game-journey-mock-repository.js --@@ -627,7 +627,6 @@ export function createGameJourneyMockRepository(options = {}) { -- const completionMetricsStore = -- options.completionMetricsStore || createGameJourneyCompletionMetricsStore({ -- dbPath: options.completionMetricsDbPath, --- legacyDbPath: options.completionMetricsLegacyDbPath, -- postgresClient: options.completionMetricsPostgresClient, -- }); -- const tables = loadMockDbTables(GAME_JOURNEY_DB_OWNER, getSeedTables(), options).tables; --diff --git a/src/dev-runtime/server/local-api-router.mjs b/src/dev-runtime/server/local-api-router.mjs --index f2f927aff..2cb9a66f1 100644 ----- a/src/dev-runtime/server/local-api-router.mjs --+++ b/src/dev-runtime/server/local-api-router.mjs --@@ -3304,14 +3304,12 @@ function productTablesFromSnapshot(snapshot) { -- -- class ApiRuntimeDataSource { -- constructor({ --- gameJourneyCompletionMetricsLegacyDbPath = undefined, -- gameJourneyCompletionMetricsPostgresClient = null, -- messagesPostgresClient = null, -- messagesService = null, -- repoRoot = process.cwd(), -- } = {}) { -- this.messagesService = messagesService || createMessagesPostgresService({ postgresClient: messagesPostgresClient }); --- this.gameJourneyCompletionMetricsLegacyDbPath = gameJourneyCompletionMetricsLegacyDbPath; -- this.gameJourneyCompletionMetricsPostgresClient = gameJourneyCompletionMetricsPostgresClient; -- this.repositoryCounter = 1; -- this.repositoryById = new Map(); --@@ -3556,7 +3554,6 @@ class ApiRuntimeDataSource { -- this.standaloneTables.invitations = []; -- } -- this.sharedOptions = { --- completionMetricsLegacyDbPath: this.gameJourneyCompletionMetricsLegacyDbPath, -- completionMetricsPostgresClient: this.gameJourneyCompletionMetricsPostgresClient, -- memoryDbTables: this.standaloneTables, -- sessionMode: this.sessionModeId, --@@ -6839,14 +6836,12 @@ SELECT pg_database_size(current_database()) AS database_size_bytes, -- * The router itself serves the configured server API contract. -- */ -- export function createLocalApiRouter({ --- gameJourneyCompletionMetricsLegacyDbPath = undefined, -- gameJourneyCompletionMetricsPostgresClient = null, -- messagesPostgresClient = null, -- messagesService = null, -- repoRoot = process.cwd(), -- } = {}) { -- const dataSource = new ApiRuntimeDataSource({ --- gameJourneyCompletionMetricsLegacyDbPath, -- gameJourneyCompletionMetricsPostgresClient, -- messagesPostgresClient, -- messagesService, --diff --git a/tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs b/tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs --index edbc0333e..1ca7de68e 100644 ----- a/tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs --+++ b/tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs --@@ -10,6 +10,34 @@ import { -- } from "../../src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs"; -- import { createGameJourneyCompletionMetricsPostgresClientStub } from "../helpers/gameJourneyCompletionMetricsPostgresClientStub.mjs"; -- --+const ACTIVE_RUNTIME_ROOTS = Object.freeze(["src", "assets", "toolbox"]); --+const ACTIVE_RUNTIME_ALLOWED_FILES = new Set([ --+ path.normalize("src/dev-runtime/persistence/game-journey-completion-metrics-migration.mjs"), --+]); --+const RUNTIME_FORBIDDEN_PATTERNS = Object.freeze([ --+ /sqlite/i, --+ /\.sqlite/i, --+ /better-sqlite/i, --+ /game-journey-completion-metrics\.sqlite/i, --+ /tmp\/local-api/i, --+]); --+ --+async function activeRuntimeJavaScriptFiles(root) { --+ const entries = await fs.readdir(root, { withFileTypes: true }); --+ const files = []; --+ for (const entry of entries) { --+ const child = path.join(root, entry.name); --+ if (entry.isDirectory()) { --+ files.push(...await activeRuntimeJavaScriptFiles(child)); --+ continue; --+ } --+ if (entry.isFile() && /\.(?:mjs|js)$/i.test(entry.name)) { --+ files.push(child); --+ } --+ } --+ return files; --+} --+ -- test("active Game Journey metrics ignore the retired default legacy SQLite path", async () => { -- const originalCwd = process.cwd(); -- const directory = await fs.mkdtemp(path.join(os.tmpdir(), "gfs-game-journey-metrics-store-")); --@@ -24,8 +52,10 @@ test("active Game Journey metrics ignore the retired default legacy SQLite path" -- const postgresClient = createGameJourneyCompletionMetricsPostgresClientStub(); -- const store = createGameJourneyCompletionMetricsStore({ postgresClient }); -- const metrics = await store.listMetrics(); --+ const snapshot = await store.snapshot(); -- --- assert.equal(store.legacyDbPath, ""); --+ assert.equal(Object.hasOwn(store, "legacyDbPath"), false); --+ assert.equal(Object.hasOwn(snapshot, "legacySqlitePath"), false); -- assert.equal(metrics.length, 14); -- assert.equal(postgresClient.dumpTable(GAME_JOURNEY_COMPLETION_METRICS_TABLE).length, 14); -- assert.equal(await fs.readFile(retiredLegacyPath, "utf8"), retiredLegacyContents); --@@ -34,3 +64,26 @@ test("active Game Journey metrics ignore the retired default legacy SQLite path" -- await fs.rm(directory, { force: true, recursive: true }); -- } -- }); --+ --+test("active runtime JS and MJS do not contain SQLite or tmp local metrics references", async () => { --+ const files = []; --+ for (const root of ACTIVE_RUNTIME_ROOTS) { --+ files.push(...await activeRuntimeJavaScriptFiles(root)); --+ } --+ --+ const findings = []; --+ for (const file of files) { --+ const normalized = path.normalize(file); --+ if (ACTIVE_RUNTIME_ALLOWED_FILES.has(normalized)) { --+ continue; --+ } --+ const contents = await fs.readFile(file, "utf8"); --+ RUNTIME_FORBIDDEN_PATTERNS.forEach((pattern) => { --+ if (pattern.test(contents)) { --+ findings.push(`${file}: ${pattern}`); --+ } --+ }); --+ } --+ --+ assert.deepEqual(findings, []); --+}); --diff --git a/tests/helpers/playwrightRepoServer.mjs b/tests/helpers/playwrightRepoServer.mjs --index 9bc8e8f07..71c7853aa 100644 ----- a/tests/helpers/playwrightRepoServer.mjs --+++ b/tests/helpers/playwrightRepoServer.mjs --@@ -91,13 +91,11 @@ function resolveBrowserRoutePath(decodedPath) { -- } -- -- export async function startRepoServer({ --- gameJourneyCompletionMetricsLegacyDbPath = undefined, -- gameJourneyCompletionMetricsPostgresClient = null, -- messagesPostgresClient = null, -- } = {}) { -- await loadRuntimeEnv(); -- const handleLocalApiRequest = createLocalApiRouter({ --- gameJourneyCompletionMetricsLegacyDbPath, -- gameJourneyCompletionMetricsPostgresClient, -- messagesPostgresClient, -- repoRoot, --diff --git a/tests/playwright/tools/GameJourneyTool.spec.mjs b/tests/playwright/tools/GameJourneyTool.spec.mjs --index 75a913d96..cc47265cf 100644 ----- a/tests/playwright/tools/GameJourneyTool.spec.mjs --+++ b/tests/playwright/tools/GameJourneyTool.spec.mjs --@@ -40,7 +40,6 @@ test.afterAll(async () => { -- async function openRepoPage(page, pathName, options = {}) { -- const gameJourneyCompletionMetricsPostgresClient = createGameJourneyCompletionMetricsPostgresClientStub(); -- const server = await startRepoServer({ --- gameJourneyCompletionMetricsLegacyDbPath: null, -- gameJourneyCompletionMetricsPostgresClient, -- }); -- const previousApiUrl = process.env.GAMEFOUNDRY_API_URL; --@@ -238,7 +237,6 @@ test("Game Journey exposes static tool ownership areas without automatic counts" -- -- const gameJourneyCompletionMetricsPostgresClient = createGameJourneyCompletionMetricsPostgresClientStub(); -- const server = await startRepoServer({ --- gameJourneyCompletionMetricsLegacyDbPath: null, -- gameJourneyCompletionMetricsPostgresClient, -- }); -- try { --@@ -262,7 +260,6 @@ test("Game Journey progress dashboard summarizes completion metrics", async ({ p -- process.env.GAMEFOUNDRY_LOCAL_DB_PATH = localDbPath; -- const gameJourneyCompletionMetricsPostgresClient = createGameJourneyCompletionMetricsPostgresClientStub(); -- const server = await startRepoServer({ --- gameJourneyCompletionMetricsLegacyDbPath: null, -- gameJourneyCompletionMetricsPostgresClient, -- }); -- const previousApiUrl = process.env.GAMEFOUNDRY_API_URL; --@@ -1285,7 +1282,6 @@ test("Game Journey displays system template diagnostics", async ({ page }) => { -- -- test("Game Journey mock data keeps system guidance template-owned", async () => { -- const repository = createGameJourneyMockRepository({ --- completionMetricsLegacyDbPath: null, -- completionMetricsPostgresClient: createGameJourneyCompletionMetricsPostgresClientStub(), -- memoryDbTables: standaloneSeedTables, -- persist: false, --@@ -1452,7 +1448,6 @@ test("Game Journey mock data keeps system guidance template-owned", async () => -- test("Game Journey Local API persists completion metrics to Postgres", async () => { -- const gameJourneyCompletionMetricsPostgresClient = createGameJourneyCompletionMetricsPostgresClientStub(); -- const server = await startRepoServer({ --- gameJourneyCompletionMetricsLegacyDbPath: null, -- gameJourneyCompletionMetricsPostgresClient, -- }); -- try { --@@ -1511,29 +1506,11 @@ test("Game Journey Local API persists completion metrics to Postgres", async () -- test("Game Journey completion metrics fail visibly when Postgres is not configured", async () => { -- const store = createGameJourneyCompletionMetricsStore({ -- env: {}, --- legacyDbPath: null, -- }); -- -- await expect(store.listMetrics()).rejects.toThrow(/GAMEFOUNDRY_DATABASE_URL/); -- }); -- ---test("Game Journey completion metrics protect legacy SQLite data from silent drop", async () => { --- const legacyDbPath = path.join(process.cwd(), "tmp", "local-api", `game-journey-legacy-guard-${process.pid}-${Date.now()}.sqlite`); --- await fs.mkdir(path.dirname(legacyDbPath), { recursive: true }); --- await fs.writeFile(legacyDbPath, "legacy metrics placeholder"); --- --- const store = createGameJourneyCompletionMetricsStore({ --- legacyDbPath, --- postgresClient: createGameJourneyCompletionMetricsPostgresClientStub(), --- }); --- --- try { --- await expect(store.listMetrics()).rejects.toThrow(/Legacy Game Journey completion metrics SQLite data exists/); --- } finally { --- await fs.rm(legacyDbPath, { force: true }); --- } ---}); --- -- test("Game Journey requires an active game before editing", async ({ page }) => { -- const failures = await openRepoPage(page, "/toolbox/game-journey/index.html?game=none"); -- --diff --git a/tests/playwright/tools/IdeaBoardTableNotes.spec.mjs b/tests/playwright/tools/IdeaBoardTableNotes.spec.mjs --index 6d626f03b..be8c88698 100644 ----- a/tests/playwright/tools/IdeaBoardTableNotes.spec.mjs --+++ b/tests/playwright/tools/IdeaBoardTableNotes.spec.mjs --@@ -115,7 +115,6 @@ async function expectNoNavigationFallbackUi(page) { -- -- test("Idea Board uses accordion table ideas and notes", async ({ page }) => { -- const server = await startRepoServer({ --- gameJourneyCompletionMetricsLegacyDbPath: null, -- gameJourneyCompletionMetricsPostgresClient: createGameJourneyCompletionMetricsPostgresClientStub(), -- }); -- const previousApiUrl = process.env.GAMEFOUNDRY_API_URL; --@@ -478,7 +477,6 @@ test("Idea Board uses accordion table ideas and notes", async ({ page }) => { -- -- test("Idea Board gates Create Project to Ready ideas and locks converted projects", async ({ page }) => { -- const server = await startRepoServer({ --- gameJourneyCompletionMetricsLegacyDbPath: null, -- gameJourneyCompletionMetricsPostgresClient: createGameJourneyCompletionMetricsPostgresClientStub(), -- }); -- const previousApiUrl = process.env.GAMEFOUNDRY_API_URL; --@@ -595,7 +593,6 @@ test("Idea Board gates Create Project to Ready ideas and locks converted project -- -- test("Idea Board guest write actions redirect to sign in before saving data", async ({ page }) => { -- const server = await startRepoServer({ --- gameJourneyCompletionMetricsLegacyDbPath: null, -- gameJourneyCompletionMetricsPostgresClient: createGameJourneyCompletionMetricsPostgresClientStub(), -- }); -- const previousApiUrl = process.env.GAMEFOUNDRY_API_URL; -\ No newline at end of file -+-src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs -+-src/dev-runtime/persistence/tool-repositories/game-journey-mock-repository.js -+-src/dev-runtime/server/local-api-router.mjs -+-tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs -+-tests/helpers/playwrightRepoServer.mjs -+-tests/playwright/tools/GameJourneyTool.spec.mjs -+-tests/playwright/tools/IdeaBoardTableNotes.spec.mjs -++project-instructions/README.md -++project-instructions/addendums/assistant-execution-modes.md -++project-instructions/addendums/canonical-repository-structure.md -++project-instructions/addendums/codex-artifact-and-reporting-standard.md -++project-instructions/addendums/codex-project-instructions-startup.md -++project-instructions/addendums/legacy-migration-policy.md -++project-instructions/addendums/test-structure-standardization.md -+diff --git a/project-instructions/addendums/assistant-execution-modes.md b/project-instructions/addendums/assistant-execution-modes.md -+index 6d7928669..4c5637d0d 100644 -+--- a/project-instructions/addendums/assistant-execution-modes.md -++++ b/project-instructions/addendums/assistant-execution-modes.md -+@@ -1,5 +1,7 @@ -+ # Assistant Execution Modes -+ -++> Deprecated reference notice: this file is preserved for history only. The active copy is `docs_build/dev/ProjectInstructions/addendums/assistant_execution_modes.md`. -++ -+ ## Purpose -+ -+ Standardize request interpretation and expected outputs for Review, Owner, Build PR, Continue, Challenge, and Stop Gate workflows. -+diff --git a/project-instructions/addendums/canonical-repository-structure.md b/project-instructions/addendums/canonical-repository-structure.md -+index e26939469..6b9dcb242 100644 -+--- a/project-instructions/addendums/canonical-repository-structure.md -++++ b/project-instructions/addendums/canonical-repository-structure.md -+@@ -1,5 +1,7 @@ -+ # Canonical Repository Structure -+ -++> Deprecated reference notice: this file is preserved for history only. The active copy is `docs_build/dev/ProjectInstructions/addendums/canonical_repository_structure.md`. -++ -+ ## Purpose -+ -+ Establish the canonical repository structure for future development and reduce technical debt. -+diff --git a/project-instructions/addendums/codex-artifact-and-reporting-standard.md b/project-instructions/addendums/codex-artifact-and-reporting-standard.md -+index 3f16a3641..8d1327886 100644 -+--- a/project-instructions/addendums/codex-artifact-and-reporting-standard.md -++++ b/project-instructions/addendums/codex-artifact-and-reporting-standard.md -+@@ -1,5 +1,7 @@ -+ # Codex Artifact and Reporting Standard -+ -++> Deprecated reference notice: this file is preserved for history only. The active copy is `docs_build/dev/ProjectInstructions/addendums/codex_artifact_and_reporting_standard.md`. -++ -+ ## Purpose -+ -+ Standardize Codex deliverables, completion reporting, and artifact generation. -+diff --git a/project-instructions/addendums/codex-project-instructions-startup.md b/project-instructions/addendums/codex-project-instructions-startup.md -+index 94744f06e..135498b42 100644 -+--- a/project-instructions/addendums/codex-project-instructions-startup.md -++++ b/project-instructions/addendums/codex-project-instructions-startup.md -+@@ -1,5 +1,7 @@ -+ # Codex Project Instructions Startup -+ -++> Deprecated reference notice: this file is preserved for history only. The active copy is `docs_build/dev/ProjectInstructions/addendums/codex_project_instructions_startup.md`. -++ -+ ## Purpose -+ -+ Ensure Codex uses the current approved governance before making repository changes. -+diff --git a/project-instructions/addendums/legacy-migration-policy.md b/project-instructions/addendums/legacy-migration-policy.md -+index 5e43679f4..5515a1728 100644 -+--- a/project-instructions/addendums/legacy-migration-policy.md -++++ b/project-instructions/addendums/legacy-migration-policy.md -+@@ -1,5 +1,7 @@ -+ # Legacy Migration Policy -+ -++> Deprecated reference notice: this file is preserved for history only. The active copy is `docs_build/dev/ProjectInstructions/addendums/legacy_migration_policy.md`. -++ -+ ## Purpose -+ -+ Reduce technical debt incrementally during normal development. -+diff --git a/project-instructions/addendums/test-structure-standardization.md b/project-instructions/addendums/test-structure-standardization.md -+index 997b16730..eeb62d561 100644 -+--- a/project-instructions/addendums/test-structure-standardization.md -++++ b/project-instructions/addendums/test-structure-standardization.md -+@@ -1,5 +1,7 @@ -+ # Test Structure Standardization -+ -++> Deprecated reference notice: this file is preserved for history only. The active copy is `docs_build/dev/ProjectInstructions/addendums/test_structure_standardization.md`. -++ -+ ## Purpose -+ -+ Standardize testing locations and ensure independent tool validation. -+diff --git a/docs_build/dev/ProjectInstructions/addendums/assistant_execution_modes.md b/docs_build/dev/ProjectInstructions/addendums/assistant_execution_modes.md -+new file mode 100644 -+index 000000000..6d7928669 -+--- /dev/null -++++ b/docs_build/dev/ProjectInstructions/addendums/assistant_execution_modes.md -+@@ -0,0 +1,120 @@ -++# Assistant Execution Modes -++ -++## Purpose -++ -++Standardize request interpretation and expected outputs for Review, Owner, Build PR, Continue, Challenge, and Stop Gate workflows. -++ -++## Command Modes -++ -++### Review -++ -++Expected Output: -++- Findings -++- Risks -++- Recommendations -++ -++Do Not Output: -++- PRs -++- Implementation plans -++ -++### Owner -++ -++Expected Output: -++- Decisions -++- Governance direction -++- Standards -++ -++Do Not Output: -++- Detailed implementation -++ -++### Build PR -++ -++Expected Output: -++- Single Codex work order -++- May contain multiple sequential PRs belonging to the same workstream -++- Copy/paste ready for execution -++ -++Should Include: -++- Start gates -++- Changes -++- Validation -++- Commit names -++- Stop point -++ -++Do Not Output: -++- Design discussion -++- Alternatives -++- Rationale -++- Architecture brainstorming -++ -++### Continue -++ -++Expected Output: -++- Next sequential executable PR -++- Next sequential work order -++ -++Do Not Output: -++- New ideas -++- Re-analysis -++- Additional brainstorming -++ -++### Challenge -++ -++Expected Output: -++- Risks -++- Contradictions -++- Better alternatives -++ -++Do Not Output: -++- Immediate implementation -++ -++### Stop Gate -++ -++Expected Output: -++- Why work should stop -++- Required corrections -++ -++Allowed Reasons: -++- Governance conflict -++- Architecture conflict -++- Security risk -++- Data loss risk -++- Major technical debt increase -++ -++## Additional Definitions -++ -++### Follow Project Instructions -++ -++Meaning: -++- Use existing governance -++- Do not redesign process -++ -++### Build the PR -++ -++Meaning: -++- Produce Codex executable work order immediately -++ -++### Continue -++ -++Meaning: -++- Produce next sequential work item -++ -++### No zip file -++ -++Meaning: -++- Generate instructions only -++- Do not expect artifact review -++ -++### You are owner -++ -++Meaning: -++- Make decisions -++- Do not ask for direction unless blocked -++ -++### Done for the day -++ -++Meaning: -++- Finish commits -++- Merge -++- Push -++- Create next-day start document -+diff --git a/docs_build/dev/ProjectInstructions/addendums/canonical_repository_structure.md b/docs_build/dev/ProjectInstructions/addendums/canonical_repository_structure.md -+new file mode 100644 -+index 000000000..e26939469 -+--- /dev/null -++++ b/docs_build/dev/ProjectInstructions/addendums/canonical_repository_structure.md -+@@ -0,0 +1,39 @@ -++# Canonical Repository Structure +++The next-day `HEAD` SHA must match the published EOD SHA before any team creates a PR branch. ++diff --git a/docs_build/dev/ProjectInstructions/addendums/canonical_repository_structure.md b/docs_build/dev/ProjectInstructions/addendums/canonical_repository_structure.md ++new file mode 100644 ++index 000000000..e26939469 ++--- /dev/null +++++ b/docs_build/dev/ProjectInstructions/addendums/canonical_repository_structure.md ++@@ -0,0 +1,39 @@ +++# Canonical Repository Structure ++ ++## Purpose ++ @@ -2565,10 +2243,10 @@ index f88731273..53132b823 100644 ++A task is not considered complete until the ZIP artifact is generated and reported. +diff --git a/docs_build/dev/ProjectInstructions/addendums/codex_project_instructions_startup.md b/docs_build/dev/ProjectInstructions/addendums/codex_project_instructions_startup.md +new file mode 100644 -+index 000000000..e0abb9db0 ++index 000000000..ee11393b4 +--- /dev/null ++++ b/docs_build/dev/ProjectInstructions/addendums/codex_project_instructions_startup.md -+@@ -0,0 +1,65 @@ ++@@ -0,0 +1,87 @@ ++# Codex Project Instructions Startup ++ ++## Purpose @@ -2592,6 +2270,28 @@ index f88731273..53132b823 100644 ++- Execution modes ++- Artifact requirements ++ +++## Branch Lifecycle Start Gate +++ +++Every PR follows exactly three phases: +++ +++```text +++START +++WORK +++END +++``` +++ +++Codex must follow the canonical lifecycle in: +++ +++`docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md` +++ +++Startup enforcement: +++- START begins on synchronized `main`. +++- WORK remains on the PR branch. Never checkout `main`. +++- END merges, returns to synchronized `main`, publishes branch, HEAD SHA, and date/time, then stops all work. +++- STOP if current branch is `main` before commit. +++- STOP if attempting to push `main`. +++- STOP if a new PR starts before returning to synchronized `main`. +++ ++Deprecated Project Instructions material outside `docs_build/dev/ProjectInstructions/` is reference-only and must not override active governance. ++ ++## Project Reference File Review @@ -2673,12 +2373,120 @@ index f88731273..53132b823 100644 ++- No new scattered JS locations. ++- No new scattered CSS locations. ++- No new scattered test locations. ++diff --git a/docs_build/dev/ProjectInstructions/addendums/multi_team.md b/docs_build/dev/ProjectInstructions/addendums/multi_team.md ++index d8acc7b0e..7ba2cae8d 100644 ++--- a/docs_build/dev/ProjectInstructions/addendums/multi_team.md +++++ b/docs_build/dev/ProjectInstructions/addendums/multi_team.md ++@@ -51,6 +51,7 @@ Rules: ++ - One Codex session may execute multiple sequential PRs. ++ - Each PR must still have one clear purpose. ++ - Each PR must create or use its own approved branch. +++- Each PR must follow the canonical START / WORK / END lifecycle in `docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md`. ++ - Each PR may be committed and pushed during active work. ++ - Each PR may be opened as a draft PR during active work. ++ - Do not commit directly to main. ++@@ -69,13 +70,14 @@ During active work: ++ - Pushes are allowed and expected. ++ - Draft PRs are allowed and expected. ++ - Direct commits to main are prohibited. +++- WORK remains on the PR branch; never checkout main during WORK. ++ - Merges to main are prohibited unless explicitly approved by the owner. ++ ++ At end of day: ++ - Owner reviews ready PRs. ++ - Owner explicitly approves which PRs merge. ++ - Only owner-approved PRs may merge to main. ++-- After merge, return to main and pull latest main. +++- After merge, execute the canonical END phase, return to synchronized main, and publish branch, HEAD SHA, and date/time. ++ - Do not treat sequential PR completion as merge approval. ++ ++ Commit/push during the day is allowed only on assigned team/OWNER/PR branches. ++diff --git a/docs_build/dev/ProjectInstructions/addendums/pr_workflow.md b/docs_build/dev/ProjectInstructions/addendums/pr_workflow.md ++index f8a4acb6e..02391a8be 100644 ++--- a/docs_build/dev/ProjectInstructions/addendums/pr_workflow.md +++++ b/docs_build/dev/ProjectInstructions/addendums/pr_workflow.md ++@@ -26,6 +26,34 @@ Define the standard pull request workflow for Game Foundry Studio. ++ 15. Pull latest main before starting the next PR. ++ 16. Verify Main Verified and Closed gates. ++ +++## Branch Lifecycle (Canonical) +++ +++Every PR follows exactly three phases: +++ +++```text +++START +++WORK +++END +++``` +++ +++The canonical START, WORK, END, Daily Synchronization, and Mandatory Hard Stops rules live in: +++ +++`docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md` +++ +++PR workflow must follow that lifecycle exactly. +++ +++Summary: +++- START happens on synchronized `main` only and creates the PR branch only after all required gates pass. +++- WORK happens only on the PR branch. +++- END validates, commits, pushes, opens/updates the PR, merges, returns to synchronized `main`, publishes branch, HEAD SHA, and date/time, then stops all work. +++- No commits on `main`. +++- No implementation on `main`. +++- No validation on `main` except start validation. +++- Never checkout `main` during WORK. +++- STOP before commit if current branch is `main`. +++- STOP if current branch changes unexpectedly. +++- STOP if attempting to push `main`. +++ ++ ## PR Lifecycle States ++ ++ Required state order: ++@@ -129,3 +157,40 @@ Stop only for: ++ - Merge conflict ++ - Validation failure ++ - OWNER decision +++ +++## EOD Main Lock +++ +++End of Day: +++ +++```text +++git checkout main +++git fetch origin +++git pull --ff-only origin main +++git status +++git rev-list --left-right --count main...origin/main +++``` +++ +++Required: +++ +++```text +++On branch main +++nothing to commit, working tree clean +++0 0 +++``` +++ +++## Next Day Start +++ +++```text +++git checkout main +++git fetch origin +++git pull --ff-only origin main +++git status +++git rev-list --left-right --count main...origin/main +++git rev-parse HEAD +++``` +++ +++No team creates a PR branch until: +++- Current branch: `main` +++- Worktree: clean +++- `main...origin/main`: `0 0` +++- `HEAD` SHA matches published EOD SHA +diff --git a/docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md b/docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md +new file mode 100644 -+index 000000000..9ea3824e0 ++index 000000000..dd5744c80 +--- /dev/null ++++ b/docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md -+@@ -0,0 +1,61 @@ ++@@ -0,0 +1,199 @@ ++# Project Instructions Single Source And EOD Main Lock ++ ++Status: Approved @@ -2694,9 +2502,328 @@ index f88731273..53132b823 100644 ++- archived Project Instructions snapshots ++- generated PR reports ++ -++If deprecated reference material conflicts with `docs_build/dev/ProjectInstructions/`, the active folder wins unless OWNER explicitly approves a newer governance change. +++If deprecated reference material conflicts with `docs_build/dev/ProjectInstructions/`, the active folder wins unless OWNER explicitly approves a newer governance change. +++ +++## End Of Day +++ +++```text +++git checkout main +++git fetch origin +++git pull --ff-only origin main +++git status +++git rev-list --left-right --count main...origin/main +++``` +++ +++Required: +++ +++```text +++On branch main +++nothing to commit, working tree clean +++0 0 +++``` +++ +++The EOD report must record the final `HEAD` SHA as the published EOD SHA. +++ +++## Next Day Start +++ +++```text +++git checkout main +++git fetch origin +++git pull --ff-only origin main +++git status +++git rev-list --left-right --count main...origin/main +++git rev-parse HEAD +++``` +++ +++## Team Branch Creation Gate +++ +++No team creates a PR branch until: +++- Current branch: `main` +++- Worktree: clean +++- `main...origin/main`: `0 0` +++- `HEAD` SHA matches published EOD SHA +++ +++If any check fails, stop before branch creation and restore main to the published EOD state or request OWNER direction. +++ +++## Branch Lifecycle (Canonical) +++ +++Every PR follows exactly three phases: +++ +++```text +++START +++WORK +++END +++``` +++ +++## START +++ +++Every team begins on `main`. +++ +++Required: +++ +++```text +++git checkout main +++git fetch origin +++git pull --ff-only origin main +++git status +++git rev-list --left-right --count main...origin/main +++git rev-parse HEAD +++``` +++ +++Required results: +++ +++```text +++Current branch: main +++Working tree clean +++main...origin/main +++0 0 +++HEAD equals published EOD SHA +++``` +++ +++Only after ALL four pass may a branch be created. +++ +++Create the PR branch: +++ +++```text +++git switch -c PR_ +++``` +++ +++Rules: +++ +++- No commits on `main`. +++- No implementation on `main`. +++- No validation on `main` except start validation. +++ +++## WORK +++ +++From branch creation until merge: +++ +++- Remain on the PR branch. +++- Never checkout `main`. +++- Commit only on the PR branch. +++- Push only the PR branch. +++- Execute validation from the PR branch. +++- Open/update the PR from the PR branch. +++ +++Hard Stops: +++ +++```text +++If current branch == main before commit: +++ STOP +++ +++If current branch changes unexpectedly: +++ STOP +++ +++If attempting to push main: +++ STOP +++``` +++ +++## END +++ +++After validation succeeds: +++ +++```text +++Commit +++Push PR branch +++Open/update PR +++Merge PR +++``` +++ +++Immediately execute: +++ +++```text +++git checkout main +++git fetch origin +++git pull --ff-only origin main +++git status +++git rev-list --left-right --count main...origin/main +++git rev-parse HEAD +++``` +++ +++Required result: +++ +++```text +++Current branch: main +++Working tree clean +++main...origin/main +++0 0 +++``` +++ +++Publish: +++ +++```text +++Branch +++HEAD SHA +++Date/time +++``` +++ +++This becomes tomorrow's official baseline. +++ +++Stop all work. +++ +++## Daily Synchronization +++ +++End of every day publish: +++ +++```text +++Branch: main +++HEAD SHA +++``` +++ +++Every team must begin tomorrow from that exact SHA. +++ +++## Mandatory Hard Stops +++ +++STOP if: +++ +++- current branch is `main` before commit +++- worktree dirty before creating PR branch +++- `main...origin/main` is not `0 0` before creating PR branch +++- `HEAD` SHA differs from published baseline +++- merge attempted without successful validation +++- new PR started before returning to synchronized `main` +++ +++## Start Of Day Boundary +++ +++`docs_build/dev/start_of_day/` may point to `docs_build/dev/ProjectInstructions/`, but it must not become a second active Project Instructions source. ++diff --git a/docs_build/dev/ProjectInstructions/addendums/release_gate.md b/docs_build/dev/ProjectInstructions/addendums/release_gate.md ++index c45a2c49d..57620f816 100644 ++--- a/docs_build/dev/ProjectInstructions/addendums/release_gate.md +++++ b/docs_build/dev/ProjectInstructions/addendums/release_gate.md ++@@ -22,6 +22,7 @@ Before a governance, documentation, or administrative PR is merged, validate: ++ - PR workflow guidance remains intact. ++ - Team assignment governance remains intact. ++ - Active team registry guidance remains compatible with temporary active teams. +++- Canonical START / WORK / END branch lifecycle guidance remains intact. ++ - No protected Project Instructions guidance was deleted. ++ - No permanent team roster or permanent discipline ownership was restored. ++ - No direct-to-main commit rule was bypassed. ++@@ -36,6 +37,7 @@ The release gate should confirm these files when relevant to the PR: ++ - `docs_build/dev/ProjectInstructions/backlog/BACKLOG_MASTER.md` ++ - `docs_build/dev/ProjectInstructions/addendums/governance_phase1_complete.md` ++ - `docs_build/dev/ProjectInstructions/addendums/pr_workflow.md` +++- `docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md` ++ - `docs_build/dev/ProjectInstructions/addendums/project_reference_files.md` ++ - `docs_build/dev/ProjectInstructions/addendums/environment_governance_model.md` ++ - `docs_build/dev/ProjectInstructions/addendums/environment_configuration_standards.md` ++diff --git a/docs_build/dev/ProjectInstructions/addendums/team_release_readiness.md b/docs_build/dev/ProjectInstructions/addendums/team_release_readiness.md ++index 9a2addbdc..225a2e4ab 100644 ++--- a/docs_build/dev/ProjectInstructions/addendums/team_release_readiness.md +++++ b/docs_build/dev/ProjectInstructions/addendums/team_release_readiness.md ++@@ -18,9 +18,13 @@ Teams may start only when all of the following are true: ++ - OWNER governance exists. ++ - One-active-branch-per-team rule exists. ++ - No-direct-main rule exists. +++- Canonical START / WORK / END lifecycle exists. ++ - Out-of-scope stop rule exists. ++ - Build Path sync rule exists. ++ - PR lifecycle states exist in order: PR Open, Plan, Build, Validation, Approved, Merged, Main Verified, Closed. +++- START requires synchronized `main`, clean worktree, `main...origin/main` `0 0`, and HEAD matching published EOD SHA before branch creation. +++- WORK requires remaining on the PR branch. +++- END requires merge, return to synchronized `main`, and publishing branch, HEAD SHA, and date/time. ++ - Previous-PR Closed gate exists before a team starts another PR, except explicitly documented stacked PR chains. ++ - Final closeout output includes branch, worktree, local/origin sync, PR number/name, PR status, merge/final commit, branch disposition, backlog update status, tool state update status, ZIP path, and Closeout PASS/FAIL. ++ ++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 26c337ee1..e2d6b7226 100644 ++--- a/docs_build/dev/ProjectInstructions/addendums/team_start_and_release.md +++++ b/docs_build/dev/ProjectInstructions/addendums/team_start_and_release.md ++@@ -13,9 +13,11 @@ OWNER identifies available teams when starting work. ++ ++ Before a team starts, validate: ++ ++-- current branch and expected branch are known ++-- worktree is clean or unrelated changes are understood ++-- `main` is current when a new branch is required +++- canonical START phase is complete +++- current branch is `main` +++- worktree is clean +++- `main...origin/main` is `0 0` +++- `HEAD` SHA matches published EOD SHA ++ - active assignment is selected or confirmed by OWNER ++ - assigned team uses NATO phonetic naming ++ - work remains with the assigned team until complete or OWNER reassignment ++@@ -62,13 +64,14 @@ For backlog-driven work: ++ 2. Select only the OWNER-approved backlog item. ++ 3. Use the approved status model from `status_model.md`. ++ 4. Confirm the previous PR for the team is Closed, unless this is an explicitly documented stacked PR chain. ++-5. Create or use the approved team branch and PR identity. ++-6. Mark lifecycle state as PR Open. ++-7. Plan on the same PR branch. ++-8. Build on the same PR branch. ++-9. Record active work in the active team registry when required. ++-10. Open or update a draft PR during active work. ++-11. Merge only through OWNER-approved PR workflow. +++5. Follow the canonical START phase in `project_instructions_single_source_eod_lock.md`. +++6. Create or use the approved team branch and PR identity only after START passes. +++7. Mark lifecycle state as PR Open. +++8. Plan on the same PR branch. +++9. Build on the same PR branch. +++10. Record active work in the active team registry when required. +++11. Open or update a draft PR during active WORK. +++12. Merge only through OWNER-approved PR workflow and canonical END. ++ ++ ## Team Command Examples ++ ++@@ -94,6 +97,7 @@ A team or OWNER PR is release-ready when: ++ - PR summary states the validation result ++ - lifecycle state is at least Validation ++ - required reports and repo-structured ZIP under `tmp/` exist before Closed +++- canonical END publishes branch, HEAD SHA, and date/time when the PR merges ++ ++ Closed readiness requires: ++ - PR merged and pushed ++diff --git a/docs_build/dev/ProjectInstructions/addendums/test_structure_standardization.md b/docs_build/dev/ProjectInstructions/addendums/test_structure_standardization.md ++new file mode 100644 ++index 000000000..997b16730 ++--- /dev/null +++++ b/docs_build/dev/ProjectInstructions/addendums/test_structure_standardization.md ++@@ -0,0 +1,33 @@ +++# Test Structure Standardization +++ +++## Purpose +++ +++Standardize testing locations and ensure independent tool validation. +++ +++## Canonical Test Structure +++ +++Tool tests: +++- tests/toolbox/{tool-name}/ +++ +++Engine tests: +++- tests/engine/{feature-name}/ +++ +++API tests: +++- tests/api/{feature-name}/ +++ +++Server tests: +++- tests/server/{feature-name}/ +++ +++Shared JavaScript tests: +++- tests/js/shared/ +++ +++Regression tests: +++- tests/regression/ +++ +++## Rules +++ +++- Every tool must be independently testable. +++- Regression tests do not replace tool tests. +++- Tool tests validate tool functionality. +++- Regression tests validate platform behavior. +++- New tests follow the canonical structure. ++diff --git a/docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md b/docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md ++index 9735b4bd4..f4d7e4bb8 100644 ++--- a/docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md +++++ b/docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md ++@@ -211,3 +211,67 @@ Commit/push during the day is allowed only on assigned team/OWNER/PR branches. ++ ++ Merge to main is EOD-only and owner-approved, unless the owner explicitly says: ++ "Merge this PR now." ++ -++## End Of Day +++## EOD Main Lock And Next Day Reset +++ +++End of Day: ++ ++```text ++git checkout main @@ -2714,9 +2841,7 @@ index f88731273..53132b823 100644 ++0 0 ++``` ++ -++The EOD report must record the final `HEAD` SHA as the published EOD SHA. -++ -++## Next Day Start +++Next Day Start: ++ ++```text ++git checkout main @@ -2727,178 +2852,6435 @@ index f88731273..53132b823 100644 ++git rev-parse HEAD ++``` ++ -++## Team Branch Creation Gate -++ +++Team rule: ++No team creates a PR branch until: ++- Current branch: `main` ++- Worktree: clean ++- `main...origin/main`: `0 0` ++- `HEAD` SHA matches published EOD SHA ++ -++If any check fails, stop before branch creation and restore main to the published EOD state or request OWNER direction. +++Active source rule: +++Teams must use only `docs_build/dev/ProjectInstructions/` as the active Project Instructions source. ++ -++## Start Of Day Boundary +++## Branch Lifecycle (Canonical) ++ -++`docs_build/dev/start_of_day/` may point to `docs_build/dev/ProjectInstructions/`, but it must not become a second active Project Instructions source. -+diff --git a/docs_build/dev/ProjectInstructions/addendums/test_structure_standardization.md b/docs_build/dev/ProjectInstructions/addendums/test_structure_standardization.md +++Every PR follows exactly three phases: +++ +++```text +++START +++WORK +++END +++``` +++ +++Teams must follow `docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md`. +++ +++Assignment governance enforces: +++- START begins on synchronized `main`. +++- WORK remains on the PR branch. Never checkout `main`. +++- END merges, returns to synchronized `main`, publishes branch, HEAD SHA, and date/time, then stops all work. +++- No commits on `main`. +++- No implementation on `main`. +++- No validation on `main` except start validation. +++- STOP if current branch is `main` before commit. +++- STOP if attempting to push `main`. +++- STOP if new PR work starts before returning to synchronized `main`. ++diff --git a/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock.md b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock.md ++new file mode 100644 ++index 000000000..3f1c3f952 ++--- /dev/null +++++ b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock.md ++@@ -0,0 +1,27 @@ +++# PR_26177_OWNER_007-project-instructions-single-source-eod-lock +++ +++Date: 2026-06-26 +++Scope: Project Instructions single-source and canonical branch lifecycle governance +++Status: PASS +++ +++## Summary +++ +++- Established docs_build/dev/ProjectInstructions/ as the only active Project Instructions source. +++- Added canonical Branch Lifecycle governance: START, WORK, END. +++- Documented START commands and required results, including clean main, main...origin/main 0 0, and HEAD matching published EOD SHA. +++- Documented WORK rules requiring Codex to remain on the PR branch, validate from the PR branch, commit only on the PR branch, and push only the PR branch. +++- Documented END rules requiring PR branch push, PR update, merge, immediate main checkout/fetch/ff-only pull, clean 0 0 confirmation, and publication of Branch, HEAD SHA, and date/time as the next baseline. +++- Added mandatory hard stops for main-before-commit, dirty branch creation, non-synced main, baseline mismatch, unvalidated merge, and starting new PR work before synchronized main return. +++- Updated active governance/team workflow docs under docs_build/dev/ProjectInstructions/ to reference the canonical lifecycle. +++- No product/runtime, start_of_day, feature, or legacy SQLite file changes were made. +++ +++## Validation +++ +++- PASS: targeted grep found no active duplicate ProjectInstructions source-of-truth claim outside the active source. +++- PASS: targeted grep confirmed canonical lifecycle language appears in active governance docs. +++- PASS: product/runtime and start_of_day changed-file check returned no files. +++- PASS: git diff --check. +++ +++## Artifact +++ +++- tmp/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_delta.zip ++diff --git a/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_branch-validation.md b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_branch-validation.md ++new file mode 100644 ++index 000000000..b54d77ced ++--- /dev/null +++++ b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_branch-validation.md ++@@ -0,0 +1,6 @@ +++# PR_26177_OWNER_007-project-instructions-single-source-eod-lock Branch Validation +++ +++- PASS: Current branch is PR_26177_OWNER_007-project-instructions-single-source-eod-lock. +++- PASS: Work remained on the PR branch during implementation. +++- PASS: No commit was made on main. +++- PASS: No .vscode/settings.json change is staged or included. ++diff --git a/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_manual-validation-notes.md b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_manual-validation-notes.md ++new file mode 100644 ++index 000000000..5bcd459e8 ++--- /dev/null +++++ b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_manual-validation-notes.md ++@@ -0,0 +1,8 @@ +++# PR_26177_OWNER_007-project-instructions-single-source-eod-lock Manual Validation Notes +++ +++- Reviewed active ProjectInstructions branch lifecycle wording. +++- Confirmed canonical START, WORK, and END phases are documented. +++- Confirmed active governance/team workflow docs reference docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md or summarize the canonical lifecycle. +++- Confirmed docs_build/dev/start_of_day/ was not modified. +++- Confirmed no product/runtime files were modified. +++- Confirmed ZIP artifact path: tmp/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_delta.zip. ++diff --git a/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_requirement-checklist.md b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_requirement-checklist.md ++new file mode 100644 ++index 000000000..0d99e1c44 ++--- /dev/null +++++ b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_requirement-checklist.md ++@@ -0,0 +1,23 @@ +++# PR_26177_OWNER_007-project-instructions-single-source-eod-lock Requirement Checklist +++ +++- PASS: PR remains documentation/governance only. +++- PASS: Added canonical three-phase lifecycle: START, WORK, END. +++- PASS: START says every team begins on main. +++- PASS: START includes checkout/fetch/ff-only pull/status/sync/head commands. +++- PASS: START requires current branch main, clean working tree, main...origin/main 0 0, and HEAD equal to published EOD SHA. +++- PASS: START allows branch creation only after all four required results pass. +++- PASS: START documents git switch -c PR_. +++- PASS: START prohibits commits on main, implementation on main, and validation on main except start validation. +++- PASS: WORK requires remaining on the PR branch. +++- PASS: WORK prohibits checking out main. +++- PASS: WORK requires commits, pushes, validation, and PR open/update from the PR branch. +++- PASS: WORK hard stops on current branch main before commit, unexpected branch changes, and attempts to push main. +++- PASS: END requires commit, PR branch push, PR open/update, merge, immediate main checkout/fetch/ff-only pull/status/sync/head commands. +++- PASS: END requires current branch main, clean worktree, and main...origin/main 0 0. +++- PASS: END publishes Branch, HEAD SHA, and date/time as tomorrow's official baseline, then stops all work. +++- PASS: Daily synchronization requires publishing Branch: main and HEAD SHA. +++- PASS: Mandatory hard stops are documented. +++- PASS: Active governance/team workflow docs under docs_build/dev/ProjectInstructions/ reference this lifecycle. +++- PASS: Did not modify product/runtime files. +++- PASS: Did not modify start_of_day folders. +++- PASS: Did not remove, move, or overwrite legacy SQLite files. ++diff --git a/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_validation-lane.md b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_validation-lane.md ++new file mode 100644 ++index 000000000..b78c80fe6 ++--- /dev/null +++++ b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_validation-lane.md ++@@ -0,0 +1,17 @@ +++# PR_26177_OWNER_007-project-instructions-single-source-eod-lock Validation Lane +++ +++- PASS: duplicate-source grep returned no matches for old active source claims. +++- PASS: canonical lifecycle grep returned active governance matches. +++- PASS: product/runtime/start_of_day changed-file check returned no files. +++- PASS: git diff --check. +++ +++Commands used: +++ +++~~~text +++rg duplicate-source active-claim pattern across docs_build/dev/ProjectInstructions docs_build/dev/PROJECT_INSTRUCTIONS.md project-instructions +++rg canonical lifecycle pattern across docs_build/dev/ProjectInstructions +++git diff --name-only -- src assets toolbox games api serverside package.json package-lock.json docs_build/dev/start_of_day +++git diff --check +++~~~ +++ +++Full product/runtime tests were not run because this PR changes governance documentation only. + diff --git a/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_branch-validation.md b/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_branch-validation.md +-index c5ced6d1b..53bc243c2 100644 ++index 97488ea93..53bc243c2 100644 + --- a/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_branch-validation.md + +++ b/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_branch-validation.md +-@@ -17,3 +17,4 @@ Status: PASS +- - PASS: Tests are limited to targeted Game Journey completion metrics regression coverage. +- - PASS: Did not delete, move, overwrite, export, or migrate `tmp/local-api/game-journey-completion-metrics.sqlite`. ++@@ -4,17 +4,17 @@ Status: PASS ++ ++ ## Gate ++ ++-- PASS: Continued on `PR_26177_OWNER_057-game-journey-metrics-regression-recovery`. ++-- PASS: Worktree was clean before the SQLite retirement expansion edits. ++-- PASS: No PR058 branch was created from this branch. +++- PASS: Started on `main`. +++- PASS: Fetched origin. +++- PASS: Pulled `origin/main` with `--ff-only`. +++- PASS: Verified worktree clean before branch creation. +++- PASS: Verified `main...origin/main` was `0 0` before branch creation. +++- PASS: Created `PR_26177_OWNER_057-game-journey-metrics-regression-recovery` from latest `main`. ++ ++ ## Branch Scope ++ ++-- PASS: Scope stayed on Game Journey completion metrics regression recovery and SQLite retirement. ++-- PASS: Runtime changes do not add feature work. ++-- PASS: Deleted SQLite-only migration implementation and migration test files. ++-- PASS: Tests now validate the DB-only path and active source guardrails. ++-- PASS: Did not delete or mutate user-local `tmp/` files. +++- PASS: Runtime changes are limited to the Game Journey completion metrics store and toolbox accordion Creator-facing wording. +++- PASS: Tests are limited to targeted Game Journey completion metrics regression coverage. +++- PASS: Did not delete, move, overwrite, export, or migrate `tmp/local-api/game-journey-completion-metrics.sqlite`. + - PASS: Did not start Alfa Tags PRs. ++-- PASS: Final active-code audit found zero SQLite/tmp implementation references outside historical docs/reports. ++-- PASS: EOD pre-merge branch validation completed with clean source searches and passing targeted tests. + +- PASS: Final audit removed active runtime JS/MJS SQLite and `tmp/local-api` references outside the migration-only utility. + diff --git a/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_manual-validation-notes.md b/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_manual-validation-notes.md +-index 9a952fb7b..6dad6bb08 100644 ++index 59ed8c182..6dad6bb08 100644 + --- a/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_manual-validation-notes.md + +++ b/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_manual-validation-notes.md +-@@ -5,9 +5,10 @@ Status: PASS ++@@ -4,13 +4,11 @@ Status: PASS ++ + ## Notes + +- - Confirmed the repo-local `tmp/local-api/game-journey-completion-metrics.sqlite` file exists before validation. +--- Confirmed active `createGameJourneyCompletionMetricsStore({ postgresClient })` no longer resolves that retired path by default. +--- Confirmed active metrics load 14 Postgres-backed completion buckets while the retired file remains untouched. +--- Confirmed explicit `legacyDbPath` protection remains covered by the existing migration/regression test file. +-+- Confirmed active `createGameJourneyCompletionMetricsStore({ postgresClient })` exposes no `legacyDbPath`. +-+- Confirmed active metrics snapshots expose no `legacySqlitePath`. +-+- Confirmed active metrics load 14 DB-backed completion buckets while the retired file remains untouched. +-+- Confirmed active runtime JS/MJS has no SQLite or `tmp/local-api` metrics references outside the migration-only utility. +- - Confirmed the toolbox page renders neutral Creator-facing outage wording when active metrics are unavailable. +- - Confirmed the toolbox page does not render the forbidden warning string, SQLite wording, `tmp/local-api`, or Postgres internals in the simulated outage lane. +- - Confirmed no Alfa Tags PR work was started. +-diff --git a/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_report.md b/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_report.md +-index 1940890cf..777642b00 100644 +---- a/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_report.md +-+++ b/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_report.md +-@@ -11,9 +11,10 @@ Recover the Game Journey completion metrics path so active Alfa and Owner work n +- ## Implementation Summary ++-- Confirmed current branch is `PR_26177_OWNER_057-game-journey-metrics-regression-recovery`. ++-- Confirmed the PR deletes the retired SQLite migration command, migration module, and migration test. ++-- Confirmed active Game Journey metrics tests validate the DB-only store path. ++-- Confirmed active JS/MJS source under implementation, script, and test roots has no SQLite, `.sqlite`, `better-sqlite`, `game-journey-completion-metrics.sqlite`, or `tmp/local-api` matches. ++-- Confirmed non-doc implementation search excluding `docs_build/**`, `tmp/**`, and `.git/**` has no matching retired metrics references. +++- Confirmed the repo-local `tmp/local-api/game-journey-completion-metrics.sqlite` file exists before validation. +++- Confirmed active `createGameJourneyCompletionMetricsStore({ postgresClient })` exposes no `legacyDbPath`. +++- Confirmed active metrics snapshots expose no `legacySqlitePath`. +++- Confirmed active metrics load 14 DB-backed completion buckets while the retired file remains untouched. +++- Confirmed active runtime JS/MJS has no SQLite or `tmp/local-api` metrics references outside the migration-only utility. ++ - Confirmed the toolbox page renders neutral Creator-facing outage wording when active metrics are unavailable. ++-- Confirmed the focused outage lane does not render the forbidden warning string or Postgres internals. ++-- Confirmed no runtime code inspects or depends on `tmp/` for Game Journey completion metrics. ++-- Confirmed EOD validation rerun passed before merging PR057 to `main`. +++- Confirmed the toolbox page does not render the forbidden warning string, SQLite wording, `tmp/local-api`, or Postgres internals in the simulated outage lane. ++ - Confirmed no Alfa Tags PR work was started. ++diff --git a/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_report.md b/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_report.md ++index 3577253f0..777642b00 100644 ++--- a/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_report.md +++++ b/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_report.md ++@@ -6,50 +6,44 @@ Date: 2026-06-26 ++ ++ ## Scope ++ ++-Expanded the recovery PR to complete Game Journey completion metrics SQLite retirement. The active architecture is Browser -> Local API -> Database. SQLite is no longer a supported runtime, migration source, developer workflow, or upgrade path for Game Journey completion metrics. +++Recover the Game Journey completion metrics path so active Alfa and Owner work no longer surfaces the retired legacy SQLite regression. Preserve Postgres-backed Game Journey completion metrics as the active path and prevent Creator-facing UI from rendering the forbidden `Game Journey completion metrics unavailable:` warning. ++ ++ ## Implementation Summary ++ ++-- Deleted the retired Game Journey metrics migration command: `scripts/migrate-game-journey-completion-metrics-sqlite-to-postgres.mjs`. ++-- Deleted the retired Game Journey metrics migration module: `src/dev-runtime/persistence/game-journey-completion-metrics-migration.mjs`. ++-- Deleted the SQLite-only migration test: `tests/dev-runtime/GameJourneyCompletionMetricsMigration.test.mjs`. ++-- Updated the Game Journey metrics store tests to validate the DB-only store contract. ++-- Updated the JS/MJS guardrail test to fail future SQLite, `.sqlite`, `better-sqlite`, `game-journey-completion-metrics.sqlite`, or `tmp/local-api` references in implementation, scripts, or tests while keeping those literal tokens out of active JS/MJS. ++-- Updated the browser environment validation rule so it still detects retired file-DB reintroduction without keeping literal SQLite implementation terms in the validation source. ++-- Updated impacted Playwright tests so Creator-facing outage coverage validates neutral wording without carrying retired backend/path literals. +++- Removed active runtime defaulting to `tmp/local-api/game-journey-completion-metrics.sqlite` in `createGameJourneyCompletionMetricsStore`. +++- Removed active runtime `legacyDbPath` guard plumbing from the Game Journey metrics store, repository, Local API router, and Playwright test server helper. +++- Updated `toolbox/tools-page-accordions.js` to render neutral Creator-safe progress outage wording instead of backend diagnostics. +++- Added a store-level regression test proving a retired default SQLite-shaped file does not block or get touched by active DB-backed metrics. +++- Added a targeted guardrail test proving active runtime JS/MJS under `src`, `assets`, and `toolbox` has no SQLite or `tmp/local-api` metrics references, excluding the migration-only utility. +++- Added a focused Playwright test proving the toolbox page does not render the forbidden warning, SQLite wording, local filesystem path, or Postgres internals when metrics are unavailable. ++ ++-## Deleted SQLite-Related Files +++## Reference Comparison ++ ++-- `scripts/migrate-game-journey-completion-metrics-sqlite-to-postgres.mjs` ++-- `src/dev-runtime/persistence/game-journey-completion-metrics-migration.mjs` ++-- `tests/dev-runtime/GameJourneyCompletionMetricsMigration.test.mjs` ++- ++-## Remaining SQLite References ++- ++-- PASS: `rg -n -i "sqlite|better-sqlite|game-journey-completion-metrics\.sqlite|tmp/local-api" -g "*.js" -g "*.mjs"` returned no matches. ++-- PASS: `rg -n -i "sqlite|better-sqlite|game-journey-completion-metrics\.sqlite|tmp/local-api" --glob "!docs_build/**" --glob "!tmp/**" --glob "!.git/**"` returned no matches. ++-- Historical references remain only in docs/reports under `docs_build/**`, including prior project instructions, historical PR reports, and this PR closeout packet. ++-- Zero remaining implementation references were found in runtime, Local API, browser, dev runtime, persistence, scripts, validation, tests, Playwright, tooling, startup, or health checks. +++- Compared the relevant strings in Bravo, Charlie, and Delta reference branches against current main. +++- Those branches contained the same legacy-default metrics store and forbidden toolbox warning strings. +++- Their non-error behavior depended on the retired SQLite file not being present at the default path. +++- This recovery fixes the active behavior directly so the current repo is not sensitive to that retired file. ++ ++ ## Validation ++ ++-- PASS: EOD pre-merge validation rerun completed on `PR_26177_OWNER_057-game-journey-metrics-regression-recovery`. ++-- PASS: `node --check scripts/validate-browser-env-agnostic.mjs` ++-- PASS: `node --check tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs` ++-- PASS: `node --check tests/playwright/tools/GameJourneyTool.spec.mjs` ++-- PASS: `node --check tests/playwright/tools/AdminHealthOperationsPage.spec.mjs` ++-- PASS: `node --test tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs` ++-- PASS: `npx playwright test tests/playwright/tools/AdminHealthOperationsPage.spec.mjs --project=playwright --workers=1 --reporter=line -g "Admin System Health operations page keeps scripts and styles external"` ++-- PASS: `npx playwright test tests/playwright/tools/GameJourneyTool.spec.mjs --project=playwright --workers=1 --reporter=line -g "Game Journey progress dashboard summarizes completion metrics|Game Journey Local API persists completion metrics to Postgres|Toolbox renders Creator-safe Game Journey progress outage copy"` ++-- PASS: Focused static searches found no active SQLite/tmp implementation references. +++- PASS: `node --check` on modified source and test files. +++- PASS: `node ./scripts/run-node-test-files.mjs tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs tests/dev-runtime/GameJourneyCompletionMetricsMigration.test.mjs`. +++- PASS: `npx playwright test tests/playwright/tools/GameJourneyTool.spec.mjs --project=playwright --workers=1 --reporter=line -g "Game Journey Local API persists completion metrics to Postgres|Toolbox renders Creator-safe Game Journey progress outage copy"`. +++- PASS: Direct proof against the actual existing `tmp/local-api/game-journey-completion-metrics.sqlite` file confirmed active DB metrics load 14 buckets, expose no legacy path fields, and do not touch the retired file. +++- PASS: Active runtime JS/MJS search found no SQLite, `.sqlite`, `better-sqlite`, `game-journey-completion-metrics.sqlite`, or `tmp/local-api` references outside the migration-only utility. ++ - PASS: Runtime source search found no `Game Journey completion metrics unavailable` Creator-facing string. ++-- PASS: Deleted SQLite migration files remained absent at EOD verification. ++-- PASS: No runtime `tmp/` dependency was found in Game Journey metrics runtime/API/UI source. ++- ++-## Notes ++- ++-- The broader `node scripts/validate-browser-env-agnostic.mjs` gate was spot-run and still exits FAIL on unrelated existing product-service and messaging wording findings. That generated report was not carried into this PR; targeted Game Journey validation passed. ++-- No files under `tmp/` were deleted, moved, exported, migrated, inspected, or used by runtime. +++- PASS: `git diff --check` reported no whitespace errors. Git emitted line-ending warnings only. +++ +++## Files +++ +++- `src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs` +++- `src/dev-runtime/persistence/tool-repositories/game-journey-mock-repository.js` +++- `src/dev-runtime/server/local-api-router.mjs` +++- `tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs` +++- `tests/helpers/playwrightRepoServer.mjs` +++- `tests/playwright/tools/GameJourneyTool.spec.mjs` +++- `tests/playwright/tools/IdeaBoardTableNotes.spec.mjs` +++- `toolbox/tools-page-accordions.js` ++ ++ ## Artifact ++ ++diff --git a/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_requirement-checklist.md b/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_requirement-checklist.md ++index 33416ee76..65a654b6d 100644 ++--- a/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_requirement-checklist.md +++++ b/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_requirement-checklist.md ++@@ -2,25 +2,25 @@ ++ ++ Status: PASS ++ ++-- PASS: Continued on `PR_26177_OWNER_057-game-journey-metrics-regression-recovery`. ++-- PASS: Expanded PR057 to complete SQLite retirement for Game Journey completion metrics. ++-- PASS: Preserved Browser -> Local API -> Database as the active architecture. ++-- PASS: Removed SQLite as a supported runtime path, migration source, developer workflow, and upgrade path for Game Journey completion metrics. ++-- PASS: Deleted `scripts/migrate-game-journey-completion-metrics-sqlite-to-postgres.mjs`. ++-- PASS: Deleted `src/dev-runtime/persistence/game-journey-completion-metrics-migration.mjs`. ++-- PASS: Deleted `tests/dev-runtime/GameJourneyCompletionMetricsMigration.test.mjs`. ++-- PASS: Removed SQLite-only runtime, migration, helper, validation, and test support from active JS/MJS implementation paths. ++-- PASS: Did not delete, move, overwrite, export, migrate, inspect, or depend on user-local `tmp/` files. ++-- PASS: Updated tests to validate the DB-only implementation instead of validating SQLite retirement. ++-- PASS: Updated validation guardrails so future active JS/MJS SQLite or `tmp/local-api` reintroduction fails targeted validation. ++-- PASS: Active Game Journey metrics use Local API/DB only. ++-- PASS: Creator UI cannot render `Game Journey completion metrics unavailable:`. ++-- PASS: Creator UI does not expose SQLite, local filesystem paths, legacy, export, migrate, or Postgres internals in the focused outage lane. ++-- PASS: Focused active JS/MJS searches returned no SQLite, `.sqlite`, `better-sqlite`, `game-journey-completion-metrics.sqlite`, or `tmp/local-api` matches. ++-- PASS: Remaining matches are historical docs/reports only under `docs_build/**`. ++-- PASS: Targeted node validation passed. ++-- PASS: Impacted Playwright validation passed. ++-- PASS: EOD pre-merge targeted validation passed. ++-- PASS: EOD pre-merge impacted Playwright tests passed. ++-- PASS: Required reports were updated. +++- PASS: Hard stop gate verified current branch was `main` before branch creation. +++- PASS: Fetched origin. +++- PASS: Pulled `origin/main` with `--ff-only`. +++- PASS: Verified worktree clean and `main...origin/main` was `0 0`. +++- PASS: Created `PR_26177_OWNER_057-game-journey-metrics-regression-recovery`. +++- PASS: Compared Alfa/Owner behavior against Bravo/Charlie/Delta reference states. +++- PASS: Fixed only the Game Journey completion metrics regression. +++- PASS: Did not delete, move, overwrite, export, or migrate `tmp/local-api/game-journey-completion-metrics.sqlite`. +++- PASS: Stopped active runtime from defaulting to `tmp/local-api/game-journey-completion-metrics.sqlite`. +++- PASS: Removed active runtime `legacyDbPath` SQLite guard plumbing. +++- PASS: Preserved Postgres-backed Game Journey completion metrics as the active path. +++- PASS: Ensured `toolbox/tools-page-accordions.js` cannot render `Game Journey completion metrics unavailable:`. +++- PASS: Creator-facing UI does not expose SQLite, local filesystem paths, migration/export language, or Postgres internals. +++- PASS: Did not introduce silent fallback behavior; metrics outage remains visible with neutral wording. +++- PASS: Added targeted regression tests. +++- PASS: Proved the existing legacy SQLite file does not block active metrics. +++- PASS: Proved active runtime JS/MJS has no SQLite or `tmp/local-api` metrics references outside the migration-only utility. +++- PASS: Proved the forbidden warning string is not rendered. +++- PASS: Proved Game Journey metrics still load through the active DB/API path. +++- PASS: Used targeted validation only. +++- PASS: Required reports were produced. ++ - PASS: Repo-structured ZIP was produced under `tmp/`. ++diff --git a/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_validation-lane.md b/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_validation-lane.md ++index 7d35515ca..47530c453 100644 ++--- a/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_validation-lane.md +++++ b/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_validation-lane.md ++@@ -2,70 +2,48 @@ ++ ++ Status: PASS ++ ++-## Static Checks +++## Commands ++ ++ ```powershell ++-Test-Path scripts/migrate-game-journey-completion-metrics-sqlite-to-postgres.mjs ++-Test-Path src/dev-runtime/persistence/game-journey-completion-metrics-migration.mjs ++-Test-Path tests/dev-runtime/GameJourneyCompletionMetricsMigration.test.mjs ++-rg -n -i "sqlite|better-sqlite|game-journey-completion-metrics\.sqlite|tmp/local-api" -g "*.js" -g "*.mjs" ++-rg -n -i "sqlite|better-sqlite|game-journey-completion-metrics\.sqlite|tmp/local-api" --glob "!docs_build/**" --glob "!tmp/**" --glob "!.git/**" ++-rg -n "Game Journey completion metrics unavailable" src assets toolbox tests scripts --glob "!**/*.map" ++-rg -n "tmp/|tmp\\|os\.tmpdir" src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs src/dev-runtime/server/local-api-router.mjs src/dev-runtime/persistence/tool-repositories/game-journey-mock-repository.js toolbox/tools-page-accordions.js assets/toolbox/game-journey/js/index.js src/api/game-journey-completion-api-client.js ++-``` ++- ++-Result: PASS. Deleted files are absent; static searches returned no active implementation matches. ++- ++-```powershell ++-node --check scripts/validate-browser-env-agnostic.mjs +++node --check src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs +++node --check src/dev-runtime/persistence/tool-repositories/game-journey-mock-repository.js +++node --check src/dev-runtime/server/local-api-router.mjs +++node --check toolbox/tools-page-accordions.js ++ node --check tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs +++node --check tests/helpers/playwrightRepoServer.mjs ++ node --check tests/playwright/tools/GameJourneyTool.spec.mjs ++-node --check tests/playwright/tools/AdminHealthOperationsPage.spec.mjs ++-git diff --check +++node --check tests/playwright/tools/IdeaBoardTableNotes.spec.mjs ++ ``` ++ ++ Result: PASS ++ ++-## Targeted Node Tests ++- ++ ```powershell ++-node --test tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs +++node ./scripts/run-node-test-files.mjs tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs tests/dev-runtime/GameJourneyCompletionMetricsMigration.test.mjs ++ ``` ++ ++-Result: PASS, 2 tests passed. This validates DB-only metrics storage and scans implementation, scripts, and tests for retired file-DB metrics references. ++- ++-## Targeted Playwright +++Result: PASS, 2 targeted node test files passed. Includes active runtime JS/MJS SQLite reference guardrail. ++ ++ ```powershell ++-npx playwright test tests/playwright/tools/AdminHealthOperationsPage.spec.mjs --project=playwright --workers=1 --reporter=line -g "Admin System Health operations page keeps scripts and styles external" +++npx playwright test tests/playwright/tools/GameJourneyTool.spec.mjs --project=playwright --workers=1 --reporter=line -g "Game Journey Local API persists completion metrics to Postgres|Toolbox renders Creator-safe Game Journey progress outage copy" ++ ``` ++ ++-Result: PASS, 1 passed +++Result: PASS, 2 passed ++ ++ ```powershell ++-npx playwright test tests/playwright/tools/GameJourneyTool.spec.mjs --project=playwright --workers=1 --reporter=line -g "Game Journey progress dashboard summarizes completion metrics|Game Journey Local API persists completion metrics to Postgres|Toolbox renders Creator-safe Game Journey progress outage copy" +++node -e "import('node:fs').then(async fs=>{const [{createGameJourneyCompletionMetricsStore}, {createGameJourneyCompletionMetricsPostgresClientStub}] = await Promise.all([import('./src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs'), import('./tests/helpers/gameJourneyCompletionMetricsPostgresClientStub.mjs')]); const legacy='tmp/local-api/game-journey-completion-metrics.sqlite'; if(!fs.existsSync(legacy)) throw new Error('Expected existing retired local file for regression proof'); const before=fs.statSync(legacy).mtimeMs; const store=createGameJourneyCompletionMetricsStore({postgresClient:createGameJourneyCompletionMetricsPostgresClientStub()}); const metrics=await store.listMetrics(); const snapshot=await store.snapshot(); const after=fs.statSync(legacy).mtimeMs; if(Object.hasOwn(store, 'legacyDbPath')) throw new Error('Store exposes legacyDbPath'); if(Object.hasOwn(snapshot, 'legacySqlitePath')) throw new Error('Snapshot exposes legacySqlitePath'); if(metrics.length!==14) throw new Error('Expected 14 active metrics'); if(before!==after) throw new Error('Retired local file was touched'); console.log('PASS active DB metrics ignore and do not inspect retired local file');})" ++ ``` ++ ++-Result: PASS, 3 passed ++- ++-## Reference Searches +++Result: PASS ++ ++ ```powershell ++-rg -n -i "sqlite|better-sqlite|game-journey-completion-metrics\.sqlite|tmp/local-api" -g "*.js" -g "*.mjs" ++-rg -n -i "sqlite|better-sqlite|game-journey-completion-metrics\.sqlite|tmp/local-api" --glob "!docs_build/**" --glob "!tmp/**" --glob "!.git/**" ++-rg -n "node:sqlite|DatabaseSync|sqlite3|better-sqlite|\.sqlite|tmp/local-api|LocalSqliteStore|messages-sqlite-service" --glob "!docs_build/**" --glob "!tmp/**" --glob "!.git/**" ++-rg -n "game-journey-completion-metrics-migration|migrate-game-journey-completion-metrics" --glob "!docs_build/**" --glob "!tmp/**" --glob "!.git/**" ++-rg -n "completionMetricsLegacyDbPath|gameJourneyCompletionMetricsLegacyDbPath|legacyDbPath|legacySqlitePath" src tests toolbox assets scripts --glob "*.js" --glob "*.mjs" +++rg -n -i "sqlite|better-sqlite|game-journey-completion-metrics\.sqlite|tmp/local-api" src assets toolbox -g "*.js" -g "*.mjs" --glob "!src/dev-runtime/persistence/game-journey-completion-metrics-migration.mjs" +++rg -n "Game Journey completion metrics unavailable" src assets toolbox --glob "!**/*.map" ++ ``` ++ ++-Result: PASS, no matches. +++Result: PASS, no matches ++ ++ ```powershell ++-rg -n "Game Journey completion metrics unavailable" src assets toolbox --glob "!**/*.map" +++git diff --check ++ ``` ++ ++-Result: PASS, no matches. ++- ++-## Broader Gate Note ++- ++-`node scripts/validate-browser-env-agnostic.mjs` was spot-run and wrote a FAIL report for unrelated existing product-service and messaging wording findings. That generated report was restored and is not part of the targeted PR validation result. +++Result: PASS, line-ending warnings only ++diff --git a/docs_build/dev/reports/codex_changed_files.txt b/docs_build/dev/reports/codex_changed_files.txt ++index 098d8de0b..b9369d368 100644 ++--- a/docs_build/dev/reports/codex_changed_files.txt +++++ b/docs_build/dev/reports/codex_changed_files.txt ++@@ -1,16 +1,49 @@ ++-M docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_branch-validation.md ++-M docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_manual-validation-notes.md ++-M docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_report.md ++-M docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_requirement-checklist.md ++-M docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_validation-lane.md ++-M docs_build/dev/reports/coverage_changed_js_guardrail.txt ++-M docs_build/dev/reports/playwright_v8_coverage_report.txt ++-D scripts/migrate-game-journey-completion-metrics-sqlite-to-postgres.mjs ++-M scripts/validate-browser-env-agnostic.mjs ++-D src/dev-runtime/persistence/game-journey-completion-metrics-migration.mjs ++-D tests/dev-runtime/GameJourneyCompletionMetricsMigration.test.mjs ++-M tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs ++-M tests/playwright/tools/AdminHealthOperationsPage.spec.mjs ++-M tests/playwright/tools/GameJourneyTool.spec.mjs ++-M docs_build/dev/reports/codex_changed_files.txt ++-M docs_build/dev/reports/codex_review.diff +++docs_build/dev/BUILD_PR.md +++docs_build/dev/PLAN_PR.md +++docs_build/dev/PROJECT_INSTRUCTIONS.md +++docs_build/dev/ProjectInstructions/PROJECT_INSTRUCTIONS.md +++docs_build/dev/ProjectInstructions/README.txt +++docs_build/dev/ProjectInstructions/TEAM_START_COMMANDS.md +++docs_build/dev/ProjectInstructions/addendums/assistant_execution_modes.md +++docs_build/dev/ProjectInstructions/addendums/branch_context_governance.md +++docs_build/dev/ProjectInstructions/addendums/branch_lock_governance.md +++docs_build/dev/ProjectInstructions/addendums/canonical_repository_structure.md +++docs_build/dev/ProjectInstructions/addendums/codex_artifact_and_reporting_standard.md +++docs_build/dev/ProjectInstructions/addendums/codex_project_instructions_startup.md +++docs_build/dev/ProjectInstructions/addendums/legacy_migration_policy.md +++docs_build/dev/ProjectInstructions/addendums/multi_team.md +++docs_build/dev/ProjectInstructions/addendums/pr_workflow.md +++docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md +++docs_build/dev/ProjectInstructions/addendums/release_gate.md +++docs_build/dev/ProjectInstructions/addendums/team_release_readiness.md +++docs_build/dev/ProjectInstructions/addendums/team_start_and_release.md +++docs_build/dev/ProjectInstructions/addendums/test_structure_standardization.md +++docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md +++docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock.md +++docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_branch-validation.md +++docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_manual-validation-notes.md +++docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_requirement-checklist.md +++docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_validation-lane.md +++docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_branch-validation.md +++docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_manual-validation-notes.md +++docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_report.md +++docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_requirement-checklist.md +++docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_validation-lane.md +++docs_build/dev/reports/codex_changed_files.txt +++docs_build/dev/reports/codex_review.diff +++docs_build/dev/reports/coverage_changed_js_guardrail.txt +++docs_build/dev/reports/playwright_v8_coverage_report.txt +++project-instructions/README.md +++project-instructions/addendums/assistant-execution-modes.md +++project-instructions/addendums/canonical-repository-structure.md +++project-instructions/addendums/codex-artifact-and-reporting-standard.md +++project-instructions/addendums/codex-project-instructions-startup.md +++project-instructions/addendums/legacy-migration-policy.md +++project-instructions/addendums/test-structure-standardization.md +++scripts/migrate-game-journey-completion-metrics-sqlite-to-postgres.mjs +++scripts/validate-browser-env-agnostic.mjs +++src/dev-runtime/persistence/game-journey-completion-metrics-migration.mjs +++tests/dev-runtime/GameJourneyCompletionMetricsMigration.test.mjs +++tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs +++tests/playwright/tools/AdminHealthOperationsPage.spec.mjs +++tests/playwright/tools/GameJourneyTool.spec.mjs ++diff --git a/docs_build/dev/reports/codex_review.diff b/docs_build/dev/reports/codex_review.diff ++index c321c3bf0..ca20f9cf5 100644 ++--- a/docs_build/dev/reports/codex_review.diff +++++ b/docs_build/dev/reports/codex_review.diff ++@@ -1,1390 +1,2990 @@ ++-diff --git a/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_branch-validation.md b/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_branch-validation.md ++-index 53bc243c2..97488ea93 100644 ++---- a/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_branch-validation.md ++-+++ b/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_branch-validation.md ++-@@ -4,17 +4,17 @@ Status: PASS ++- ++- ## Gate ++- ++--- PASS: Started on `main`. ++--- PASS: Fetched origin. ++--- PASS: Pulled `origin/main` with `--ff-only`. ++--- PASS: Verified worktree clean before branch creation. ++--- PASS: Verified `main...origin/main` was `0 0` before branch creation. ++--- PASS: Created `PR_26177_OWNER_057-game-journey-metrics-regression-recovery` from latest `main`. ++-+- PASS: Continued on `PR_26177_OWNER_057-game-journey-metrics-regression-recovery`. ++-+- PASS: Worktree was clean before the SQLite retirement expansion edits. ++-+- PASS: No PR058 branch was created from this branch. ++- ++- ## Branch Scope ++- ++--- PASS: Runtime changes are limited to the Game Journey completion metrics store and toolbox accordion Creator-facing wording. ++--- PASS: Tests are limited to targeted Game Journey completion metrics regression coverage. ++--- PASS: Did not delete, move, overwrite, export, or migrate `tmp/local-api/game-journey-completion-metrics.sqlite`. ++-+- PASS: Scope stayed on Game Journey completion metrics regression recovery and SQLite retirement. ++-+- PASS: Runtime changes do not add feature work. ++-+- PASS: Deleted SQLite-only migration implementation and migration test files. ++-+- PASS: Tests now validate the DB-only path and active source guardrails. ++-+- PASS: Did not delete or mutate user-local `tmp/` files. ++- - PASS: Did not start Alfa Tags PRs. ++--- PASS: Final audit removed active runtime JS/MJS SQLite and `tmp/local-api` references outside the migration-only utility. ++-+- PASS: Final active-code audit found zero SQLite/tmp implementation references outside historical docs/reports. ++-+- PASS: EOD pre-merge branch validation completed with clean source searches and passing targeted tests. ++-diff --git a/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_manual-validation-notes.md b/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_manual-validation-notes.md ++-index 6dad6bb08..59ed8c182 100644 ++---- a/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_manual-validation-notes.md ++-+++ b/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_manual-validation-notes.md ++-@@ -4,11 +4,13 @@ Status: PASS ++- ++- ## Notes ++- ++--- Confirmed the repo-local `tmp/local-api/game-journey-completion-metrics.sqlite` file exists before validation. ++--- Confirmed active `createGameJourneyCompletionMetricsStore({ postgresClient })` exposes no `legacyDbPath`. ++--- Confirmed active metrics snapshots expose no `legacySqlitePath`. ++--- Confirmed active metrics load 14 DB-backed completion buckets while the retired file remains untouched. ++--- Confirmed active runtime JS/MJS has no SQLite or `tmp/local-api` metrics references outside the migration-only utility. ++-+- Confirmed current branch is `PR_26177_OWNER_057-game-journey-metrics-regression-recovery`. ++-+- Confirmed the PR deletes the retired SQLite migration command, migration module, and migration test. ++-+- Confirmed active Game Journey metrics tests validate the DB-only store path. ++-+- Confirmed active JS/MJS source under implementation, script, and test roots has no SQLite, `.sqlite`, `better-sqlite`, `game-journey-completion-metrics.sqlite`, or `tmp/local-api` matches. ++-+- Confirmed non-doc implementation search excluding `docs_build/**`, `tmp/**`, and `.git/**` has no matching retired metrics references. ++- - Confirmed the toolbox page renders neutral Creator-facing outage wording when active metrics are unavailable. ++--- Confirmed the toolbox page does not render the forbidden warning string, SQLite wording, `tmp/local-api`, or Postgres internals in the simulated outage lane. ++-+- Confirmed the focused outage lane does not render the forbidden warning string or Postgres internals. ++-+- Confirmed no runtime code inspects or depends on `tmp/` for Game Journey completion metrics. ++-+- Confirmed EOD validation rerun passed before merging PR057 to `main`. ++- - Confirmed no Alfa Tags PR work was started. ++-diff --git a/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_report.md b/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_report.md ++-index 777642b00..3577253f0 100644 ++---- a/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_report.md ++-+++ b/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_report.md ++-@@ -6,44 +6,50 @@ Date: 2026-06-26 +++diff --git a/docs_build/dev/BUILD_PR.md b/docs_build/dev/BUILD_PR.md +++index 30700e9cd..fbff4d261 100644 +++--- a/docs_build/dev/BUILD_PR.md ++++++ b/docs_build/dev/BUILD_PR.md +++@@ -1,66 +1,52 @@ +++-# PR_26177_006-shared-time-foundation ++++# PR_26177_OWNER_007-project-instructions-single-source-eod-lock ++ ++- ## Scope +++ ## Purpose ++ ++--Recover the Game Journey completion metrics path so active Alfa and Owner work no longer surfaces the retired legacy SQLite regression. Preserve Postgres-backed Game Journey completion metrics as the active path and prevent Creator-facing UI from rendering the forbidden `Game Journey completion metrics unavailable:` warning. ++-+Expanded the recovery PR to complete Game Journey completion metrics SQLite retirement. The active architecture is Browser -> Local API -> Database. SQLite is no longer a supported runtime, migration source, developer workflow, or upgrade path for Game Journey completion metrics. ++- ++- ## Implementation Summary ++- ++--- Removed active runtime defaulting to `tmp/local-api/game-journey-completion-metrics.sqlite` in `createGameJourneyCompletionMetricsStore`. ++--- Removed active runtime `legacyDbPath` guard plumbing from the Game Journey metrics store, repository, Local API router, and Playwright test server helper. ++--- Updated `toolbox/tools-page-accordions.js` to render neutral Creator-safe progress outage wording instead of backend diagnostics. ++--- Added a store-level regression test proving a retired default SQLite-shaped file does not block or get touched by active DB-backed metrics. ++--- Added a targeted guardrail test proving active runtime JS/MJS under `src`, `assets`, and `toolbox` has no SQLite or `tmp/local-api` metrics references, excluding the migration-only utility. ++--- Added a focused Playwright test proving the toolbox page does not render the forbidden warning, SQLite wording, local filesystem path, or Postgres internals when metrics are unavailable. ++-+- Deleted the retired Game Journey metrics migration command: `scripts/migrate-game-journey-completion-metrics-sqlite-to-postgres.mjs`. ++-+- Deleted the retired Game Journey metrics migration module: `src/dev-runtime/persistence/game-journey-completion-metrics-migration.mjs`. ++-+- Deleted the SQLite-only migration test: `tests/dev-runtime/GameJourneyCompletionMetricsMigration.test.mjs`. ++-+- Updated the Game Journey metrics store tests to validate the DB-only store contract. ++-+- Updated the JS/MJS guardrail test to fail future SQLite, `.sqlite`, `better-sqlite`, `game-journey-completion-metrics.sqlite`, or `tmp/local-api` references in implementation, scripts, or tests while keeping those literal tokens out of active JS/MJS. ++-+- Updated the browser environment validation rule so it still detects retired file-DB reintroduction without keeping literal SQLite implementation terms in the validation source. ++-+- Updated impacted Playwright tests so Creator-facing outage coverage validates neutral wording without carrying retired backend/path literals. ++- ++--## Reference Comparison ++-+## Deleted SQLite-Related Files ++- ++--- Compared the relevant strings in Bravo, Charlie, and Delta reference branches against current main. ++--- Those branches contained the same legacy-default metrics store and forbidden toolbox warning strings. ++--- Their non-error behavior depended on the retired SQLite file not being present at the default path. ++--- This recovery fixes the active behavior directly so the current repo is not sensitive to that retired file. ++-+- `scripts/migrate-game-journey-completion-metrics-sqlite-to-postgres.mjs` ++-+- `src/dev-runtime/persistence/game-journey-completion-metrics-migration.mjs` ++-+- `tests/dev-runtime/GameJourneyCompletionMetricsMigration.test.mjs` ++-+ ++-+## Remaining SQLite References ++-+ ++-+- PASS: `rg -n -i "sqlite|better-sqlite|game-journey-completion-metrics\.sqlite|tmp/local-api" -g "*.js" -g "*.mjs"` returned no matches. ++-+- PASS: `rg -n -i "sqlite|better-sqlite|game-journey-completion-metrics\.sqlite|tmp/local-api" --glob "!docs_build/**" --glob "!tmp/**" --glob "!.git/**"` returned no matches. ++-+- Historical references remain only in docs/reports under `docs_build/**`, including prior project instructions, historical PR reports, and this PR closeout packet. ++-+- Zero remaining implementation references were found in runtime, Local API, browser, dev runtime, persistence, scripts, validation, tests, Playwright, tooling, startup, or health checks. +++-Add a small shared time foundation. ++++Make `docs_build/dev/ProjectInstructions/` the only active Project Instructions source and add EOD main lock plus next-day reset governance. ++ ++- ## Validation +++ ## Source Of Truth ++ ++--- PASS: `node --check` on modified source and test files. ++--- PASS: `node ./scripts/run-node-test-files.mjs tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs tests/dev-runtime/GameJourneyCompletionMetricsMigration.test.mjs`. ++--- PASS: `npx playwright test tests/playwright/tools/GameJourneyTool.spec.mjs --project=playwright --workers=1 --reporter=line -g "Game Journey Local API persists completion metrics to Postgres|Toolbox renders Creator-safe Game Journey progress outage copy"`. ++--- PASS: Direct proof against the actual existing `tmp/local-api/game-journey-completion-metrics.sqlite` file confirmed active DB metrics load 14 buckets, expose no legacy path fields, and do not touch the retired file. ++--- PASS: Active runtime JS/MJS search found no SQLite, `.sqlite`, `better-sqlite`, `game-journey-completion-metrics.sqlite`, or `tmp/local-api` references outside the migration-only utility. ++-+- PASS: EOD pre-merge validation rerun completed on `PR_26177_OWNER_057-game-journey-metrics-regression-recovery`. ++-+- PASS: `node --check scripts/validate-browser-env-agnostic.mjs` ++-+- PASS: `node --check tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs` ++-+- PASS: `node --check tests/playwright/tools/GameJourneyTool.spec.mjs` ++-+- PASS: `node --check tests/playwright/tools/AdminHealthOperationsPage.spec.mjs` ++-+- PASS: `node --test tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs` ++-+- PASS: `npx playwright test tests/playwright/tools/AdminHealthOperationsPage.spec.mjs --project=playwright --workers=1 --reporter=line -g "Admin System Health operations page keeps scripts and styles external"` ++-+- PASS: `npx playwright test tests/playwright/tools/GameJourneyTool.spec.mjs --project=playwright --workers=1 --reporter=line -g "Game Journey progress dashboard summarizes completion metrics|Game Journey Local API persists completion metrics to Postgres|Toolbox renders Creator-safe Game Journey progress outage copy"` ++-+- PASS: Focused static searches found no active SQLite/tmp implementation references. ++- - PASS: Runtime source search found no `Game Journey completion metrics unavailable` Creator-facing string. ++--- PASS: `git diff --check` reported no whitespace errors. Git emitted line-ending warnings only. +++-This `BUILD_PR.md`, `PLAN_PR.md`, and the user request are the source of truth for `PR_26177_006-shared-time-foundation`. ++ - ++--## Files +++-## Stack ++ - ++--- `src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs` ++--- `src/dev-runtime/persistence/tool-repositories/game-journey-mock-repository.js` ++--- `src/dev-runtime/server/local-api-router.mjs` ++--- `tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs` ++--- `tests/helpers/playwrightRepoServer.mjs` ++--- `tests/playwright/tools/GameJourneyTool.spec.mjs` ++--- `tests/playwright/tools/IdeaBoardTableNotes.spec.mjs` ++--- `toolbox/tools-page-accordions.js` ++-+- PASS: Deleted SQLite migration files remained absent at EOD verification. ++-+- PASS: No runtime `tmp/` dependency was found in Game Journey metrics runtime/API/UI source. ++-+ ++-+## Notes ++-+ ++-+- The broader `node scripts/validate-browser-env-agnostic.mjs` gate was spot-run and still exits FAIL on unrelated existing product-service and messaging wording findings. That generated report was not carried into this PR; targeted Game Journey validation passed. ++-+- No files under `tmp/` were deleted, moved, exported, migrated, inspected, or used by runtime. ++- ++- ## Artifact ++- ++-diff --git a/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_requirement-checklist.md b/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_requirement-checklist.md ++-index 65a654b6d..33416ee76 100644 ++---- a/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_requirement-checklist.md ++-+++ b/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_requirement-checklist.md ++-@@ -2,25 +2,25 @@ ++- ++- Status: PASS ++- ++--- PASS: Hard stop gate verified current branch was `main` before branch creation. ++--- PASS: Fetched origin. ++--- PASS: Pulled `origin/main` with `--ff-only`. ++--- PASS: Verified worktree clean and `main...origin/main` was `0 0`. ++--- PASS: Created `PR_26177_OWNER_057-game-journey-metrics-regression-recovery`. ++--- PASS: Compared Alfa/Owner behavior against Bravo/Charlie/Delta reference states. ++--- PASS: Fixed only the Game Journey completion metrics regression. ++--- PASS: Did not delete, move, overwrite, export, or migrate `tmp/local-api/game-journey-completion-metrics.sqlite`. ++--- PASS: Stopped active runtime from defaulting to `tmp/local-api/game-journey-completion-metrics.sqlite`. ++--- PASS: Removed active runtime `legacyDbPath` SQLite guard plumbing. ++--- PASS: Preserved Postgres-backed Game Journey completion metrics as the active path. ++--- PASS: Ensured `toolbox/tools-page-accordions.js` cannot render `Game Journey completion metrics unavailable:`. ++--- PASS: Creator-facing UI does not expose SQLite, local filesystem paths, migration/export language, or Postgres internals. ++--- PASS: Did not introduce silent fallback behavior; metrics outage remains visible with neutral wording. ++--- PASS: Added targeted regression tests. ++--- PASS: Proved the existing legacy SQLite file does not block active metrics. ++--- PASS: Proved active runtime JS/MJS has no SQLite or `tmp/local-api` metrics references outside the migration-only utility. ++--- PASS: Proved the forbidden warning string is not rendered. ++--- PASS: Proved Game Journey metrics still load through the active DB/API path. ++--- PASS: Used targeted validation only. ++--- PASS: Required reports were produced. ++-+- PASS: Continued on `PR_26177_OWNER_057-game-journey-metrics-regression-recovery`. ++-+- PASS: Expanded PR057 to complete SQLite retirement for Game Journey completion metrics. ++-+- PASS: Preserved Browser -> Local API -> Database as the active architecture. ++-+- PASS: Removed SQLite as a supported runtime path, migration source, developer workflow, and upgrade path for Game Journey completion metrics. ++-+- PASS: Deleted `scripts/migrate-game-journey-completion-metrics-sqlite-to-postgres.mjs`. ++-+- PASS: Deleted `src/dev-runtime/persistence/game-journey-completion-metrics-migration.mjs`. ++-+- PASS: Deleted `tests/dev-runtime/GameJourneyCompletionMetricsMigration.test.mjs`. ++-+- PASS: Removed SQLite-only runtime, migration, helper, validation, and test support from active JS/MJS implementation paths. ++-+- PASS: Did not delete, move, overwrite, export, migrate, inspect, or depend on user-local `tmp/` files. ++-+- PASS: Updated tests to validate the DB-only implementation instead of validating SQLite retirement. ++-+- PASS: Updated validation guardrails so future active JS/MJS SQLite or `tmp/local-api` reintroduction fails targeted validation. ++-+- PASS: Active Game Journey metrics use Local API/DB only. ++-+- PASS: Creator UI cannot render `Game Journey completion metrics unavailable:`. ++-+- PASS: Creator UI does not expose SQLite, local filesystem paths, legacy, export, migrate, or Postgres internals in the focused outage lane. ++-+- PASS: Focused active JS/MJS searches returned no SQLite, `.sqlite`, `better-sqlite`, `game-journey-completion-metrics.sqlite`, or `tmp/local-api` matches. ++-+- PASS: Remaining matches are historical docs/reports only under `docs_build/**`. ++-+- PASS: Targeted node validation passed. ++-+- PASS: Impacted Playwright validation passed. ++-+- PASS: EOD pre-merge targeted validation passed. ++-+- PASS: EOD pre-merge impacted Playwright tests passed. ++-+- PASS: Required reports were updated. ++- - PASS: Repo-structured ZIP was produced under `tmp/`. ++-diff --git a/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_validation-lane.md b/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_validation-lane.md ++-index 47530c453..7d35515ca 100644 ++---- a/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_validation-lane.md ++-+++ b/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_validation-lane.md ++-@@ -2,48 +2,70 @@ ++- ++- Status: PASS ++- ++--## Commands ++-+## Static Checks +++-- Base branch: `PR_26177_005-shared-text-foundation` ++++This `BUILD_PR.md`, `PLAN_PR.md`, and the user request are the source of truth for `PR_26177_OWNER_007-project-instructions-single-source-eod-lock`. +++ +++ ## Exact Scope +++ +++-- Add `src/shared/time/` foundation. +++-- Include duration formatting, timestamp helpers, debounce/throttle/sleep helpers where safe for shared runtime. +++-- Add targeted tests for the shared time area. +++-- No scheduler/runtime behavior changes. +++-- Create required Codex reports under `docs_build/dev/reports/`. +++-- Create repo-structured delta ZIP under `tmp/`. ++++- Audit repo for ProjectInstructions / project instructions duplicates. ++++- Establish `docs_build/dev/ProjectInstructions/` as the only active source. ++++- Mark all other ProjectInstructions-style sources changed by this PR as deprecated references. ++++- Update active team start/governance docs to reference only `docs_build/dev/ProjectInstructions/`. ++++- Add EOD main lock, next-day reset governance, and explicit START / WORK / END branch lifecycle rules. ++++- Add required reports under `docs_build/dev/reports/`. +++ +++ ## Exact Targets +++ +++ - `docs_build/dev/PLAN_PR.md` +++ - `docs_build/dev/BUILD_PR.md` +++-- `src/shared/time/time.js` +++-- `tests/shared/TimeFoundation.test.mjs` +++-- `docs_build/dev/reports/PR_26177_006-shared-time-foundation.md` +++-- `docs_build/dev/reports/PR_26177_006-shared-time-foundation_branch-validation.md` +++-- `docs_build/dev/reports/PR_26177_006-shared-time-foundation_requirement-checklist.md` +++-- `docs_build/dev/reports/PR_26177_006-shared-time-foundation_validation-lane.md` +++-- `docs_build/dev/reports/PR_26177_006-shared-time-foundation_manual-validation-notes.md` ++++- `docs_build/dev/PROJECT_INSTRUCTIONS.md` ++++- `docs_build/dev/ProjectInstructions/README.txt` ++++- `docs_build/dev/ProjectInstructions/PROJECT_INSTRUCTIONS.md` ++++- `docs_build/dev/ProjectInstructions/TEAM_START_COMMANDS.md` ++++- `docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md` ++++- `docs_build/dev/ProjectInstructions/addendums/*.md` ++++- `project-instructions/README.md` ++++- `project-instructions/addendums/*.md` ++++- `docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock*.md` +++ - `docs_build/dev/reports/codex_review.diff` +++ - `docs_build/dev/reports/codex_changed_files.txt` +++ +++ ## Out Of Scope +++ +++-- No scheduler/runtime behavior changes. +++-- No browser-owned product data. +++-- No runtime UI changes. +++-- No browser storage changes. +++-- No API/database changes. +++-- No `start_of_day` folder changes. +++-- No unrelated cleanup. +++-- No full samples smoke by default. ++++- No product/runtime changes. ++++- No feature work. ++++- No `start_of_day` changes. ++++- No legacy SQLite file changes. +++ +++ ## Validation +++ +++-Run exactly: ++++Run: ++ ++ ```powershell ++--node --check src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs ++--node --check src/dev-runtime/persistence/tool-repositories/game-journey-mock-repository.js ++--node --check src/dev-runtime/server/local-api-router.mjs ++--node --check toolbox/tools-page-accordions.js ++-+Test-Path scripts/migrate-game-journey-completion-metrics-sqlite-to-postgres.mjs ++-+Test-Path src/dev-runtime/persistence/game-journey-completion-metrics-migration.mjs ++-+Test-Path tests/dev-runtime/GameJourneyCompletionMetricsMigration.test.mjs ++-+rg -n -i "sqlite|better-sqlite|game-journey-completion-metrics\.sqlite|tmp/local-api" -g "*.js" -g "*.mjs" ++-+rg -n -i "sqlite|better-sqlite|game-journey-completion-metrics\.sqlite|tmp/local-api" --glob "!docs_build/**" --glob "!tmp/**" --glob "!.git/**" ++-+rg -n "Game Journey completion metrics unavailable" src assets toolbox tests scripts --glob "!**/*.map" ++-+rg -n "tmp/|tmp\\|os\.tmpdir" src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs src/dev-runtime/server/local-api-router.mjs src/dev-runtime/persistence/tool-repositories/game-journey-mock-repository.js toolbox/tools-page-accordions.js assets/toolbox/game-journey/js/index.js src/api/game-journey-completion-api-client.js ++-+``` +++-node ./scripts/run-node-test-files.mjs tests/shared/TimeFoundation.test.mjs +++-node --check src/shared/time/time.js +++-node --check tests/shared/TimeFoundation.test.mjs ++++rg -n 'project-instructions/addendums|docs_build/dev/PROJECT_INSTRUCTIONS.md.*source of truth|Codex must always read `docs_build/dev/PROJECT_INSTRUCTIONS.md`|Read `docs_build/dev/PROJECT_INSTRUCTIONS.md`' docs_build/dev/ProjectInstructions docs_build/dev/PROJECT_INSTRUCTIONS.md project-instructions ++++rg -n "START RULE|WORK RULE|END RULE|HARD STOP before committing|Codex commits only to the PR branch|HEAD SHA recorded as new EOD baseline|End of Day:|Next Day Start:|HEAD.*published EOD SHA|only active Project Instructions source" docs_build/dev/ProjectInstructions ++++git diff --name-only -- src assets toolbox games api serverside package.json package-lock.json docs_build/dev/start_of_day +++ git diff --check +++ ``` +++- +++-## Artifact +++- +++-Create repo-structured delta ZIP: +++- +++-```text +++-tmp/PR_26177_006-shared-time-foundation_delta.zip +++-``` +++diff --git a/docs_build/dev/PLAN_PR.md b/docs_build/dev/PLAN_PR.md +++index 907936aee..505e274bd 100644 +++--- a/docs_build/dev/PLAN_PR.md ++++++ b/docs_build/dev/PLAN_PR.md +++@@ -1,22 +1,28 @@ +++-# PLAN_PR: PR_26177_006-shared-time-foundation ++++# PLAN_PR: PR_26177_OWNER_007-project-instructions-single-source-eod-lock +++ +++ ## Purpose +++ +++-Add a small shared time foundation. ++++Make `docs_build/dev/ProjectInstructions/` the only active Project Instructions source and add EOD main lock plus next-day reset governance. +++ +++ ## Scope +++ +++-- Add `src/shared/time/` foundation. +++-- Include duration formatting, timestamp helpers, sleep, debounce, and throttle helpers. +++-- Add targeted tests. +++-- No scheduler/runtime behavior changes. +++-- No browser-owned product data. +++-- No runtime UI changes. +++-- No unrelated cleanup. ++++- Audit ProjectInstructions and project instructions duplicates. ++++- Mark legacy ProjectInstructions-style sources as deprecated reference material. ++++- Move active legacy addendums into `docs_build/dev/ProjectInstructions/addendums/`. ++++- Update active team start and governance docs to reference only `docs_build/dev/ProjectInstructions/`. ++++- Add EOD main lock, next-day reset, team PR branch creation gate, and explicit START / WORK / END branch lifecycle rules. ++++- Add required Codex reports under `docs_build/dev/reports/`. +++ +++-## Implementation Plan ++++## Out Of Scope +++ +++-1. Add `src/shared/time/time.js`. +++-2. Add `tests/shared/TimeFoundation.test.mjs`. +++-3. Validate duration, timestamp, sleep, debounce, and throttle helpers. +++-4. Produce required Codex reports and repo-structured ZIP. ++++- No product/runtime changes. ++++- No feature work. ++++- No `start_of_day` changes. ++++- No legacy SQLite file changes. ++ + ++-+Result: PASS. Deleted files are absent; static searches returned no active implementation matches. ++++## Validation Plan ++ + ++-+```powershell ++-+node --check scripts/validate-browser-env-agnostic.mjs ++- node --check tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs ++--node --check tests/helpers/playwrightRepoServer.mjs ++- node --check tests/playwright/tools/GameJourneyTool.spec.mjs ++--node --check tests/playwright/tools/IdeaBoardTableNotes.spec.mjs ++-+node --check tests/playwright/tools/AdminHealthOperationsPage.spec.mjs ++-+git diff --check ++- ``` ++++1. Run targeted grep/search proving no active duplicate ProjectInstructions source remains. ++++2. Confirm EOD/Next Day and START / WORK / END branch lifecycle rules appear in active governance docs. ++++3. Confirm no product/runtime files changed. ++++4. Run `git diff --check`. +++diff --git a/docs_build/dev/PROJECT_INSTRUCTIONS.md b/docs_build/dev/PROJECT_INSTRUCTIONS.md +++index af9e9e2db..c1136fdbe 100644 +++--- a/docs_build/dev/PROJECT_INSTRUCTIONS.md ++++++ b/docs_build/dev/PROJECT_INSTRUCTIONS.md +++@@ -1,5 +1,7 @@ +++ # PROJECT INSTRUCTIONS ++ ++- Result: PASS ++++> Deprecated active-source notice: this file is preserved as historical reference only. The only active Project Instructions source is `docs_build/dev/ProjectInstructions/`. If this file conflicts with `docs_build/dev/ProjectInstructions/`, the active folder wins unless OWNER explicitly approves a newer governance change. ++++ +++ You are working in a docs-first repo workflow. +++ +++ Workflow: +++@@ -864,7 +866,7 @@ Controls must remain copy-friendly and human-readable. +++ +++ ### ChatGPT Workflow Governance Consistency +++ +++-ChatGPT repo workflow responses are governed by `docs_build/dev/PROJECT_INSTRUCTIONS.md` as the source of truth. ++++Deprecated note: this historical section no longer defines the active source of truth. ChatGPT repo workflow responses are governed by `docs_build/dev/ProjectInstructions/`. +++ +++ ChatGPT must not drift from the required response ordering. +++ +++@@ -1716,13 +1718,13 @@ Do not compact: +++ +++ Do not change JSON contracts or semantics while applying array formatting. +++ +++-## PROJECT INSTRUCTIONS LOCATION ++++## DEPRECATED PROJECT INSTRUCTIONS LOCATION +++ +++-PROJECT_INSTRUCTIONS.md lives at: ++++Historical PROJECT_INSTRUCTIONS.md is preserved at: +++ +++ `docs_build/dev/PROJECT_INSTRUCTIONS.md` +++ +++-Codex must always read `docs_build/dev/PROJECT_INSTRUCTIONS.md` from this path as the source of truth before executing repository workflow instructions. ++++This file is not the active source of truth. Codex must read `docs_build/dev/ProjectInstructions/README.txt` first and use `docs_build/dev/ProjectInstructions/` as the active Project Instructions source before executing repository workflow instructions. +++ +++ ## CODEX COMMAND FORMATTING RULE +++ +++@@ -2384,9 +2386,9 @@ Treat these files the same as existing instruction documents for read-set, revie +++ Codex must run this gate before every PR execution and before any file changes. ++ ++-+## Targeted Node Tests +++ Required instruction reads: +++-- Read `docs_build/dev/PROJECT_INSTRUCTIONS.md`. ++++- Read `docs_build/dev/ProjectInstructions/README.txt`. +++ - Read `docs_build/dev/PROJECT_MULTI_PC.txt`. +++-- Treat the newest applicable section in `PROJECT_INSTRUCTIONS.md` as authoritative when rules overlap. ++++- Treat the newest applicable section in `docs_build/dev/ProjectInstructions/` as authoritative when rules overlap. +++ - Treat the current team ownership section in `PROJECT_MULTI_PC.txt` as authoritative for TEAM routing. +++ +++ Required pre-change report: +++diff --git a/docs_build/dev/ProjectInstructions/PROJECT_INSTRUCTIONS.md b/docs_build/dev/ProjectInstructions/PROJECT_INSTRUCTIONS.md +++index d2a84ecbe..99ddd0f42 100644 +++--- a/docs_build/dev/ProjectInstructions/PROJECT_INSTRUCTIONS.md ++++++ b/docs_build/dev/ProjectInstructions/PROJECT_INSTRUCTIONS.md +++@@ -4,6 +4,12 @@ Read `README.txt` first. +++ +++ This file is the root index for the append-first Project Instructions operating system under `docs_build/dev/ProjectInstructions/`. +++ ++++## Active Source ++ + ++- ```powershell ++--node ./scripts/run-node-test-files.mjs tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs tests/dev-runtime/GameJourneyCompletionMetricsMigration.test.mjs ++-+node --test tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs ++- ``` ++++`docs_build/dev/ProjectInstructions/` is the only active Project Instructions source. ++++ ++++Historical Project Instructions material outside this folder is deprecated reference material only and must not be used as an active source of governance. ++++ +++ ## Purpose +++ +++ The Project Instructions operating system provides additive governance for: +++@@ -20,7 +26,7 @@ The Project Instructions operating system provides additive governance for: +++ +++ ## Preservation +++ +++-Existing Project Instructions remain preserved in their current locations. This operating system adds structure without deleting or rewriting existing documentation. ++++Existing Project Instructions outside `docs_build/dev/ProjectInstructions/` remain preserved only as deprecated reference material. When guidance conflicts, active files under `docs_build/dev/ProjectInstructions/` win unless OWNER explicitly approves a newer governance change. +++ +++ ## Folders +++ +++@@ -41,6 +47,10 @@ Existing Project Instructions remain preserved in their current locations. This ++ ++--Result: PASS, 2 targeted node test files passed. Includes active runtime JS/MJS SQLite reference guardrail. ++-+Result: PASS, 2 tests passed. This validates DB-only metrics storage and scans implementation, scripts, and tests for retired file-DB metrics references. +++ `docs_build/dev/ProjectInstructions/addendums/environment_configuration_standards.md` defines official `.env` file names, environment variable values, host/domain configuration, API URL configuration, R2 prefix configuration, and feature flag governance. +++ ++++## Single Source and Main Lock Governance ++++ ++++`docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md` defines the single active Project Instructions source, EOD main lock, next-day reset, and team branch creation gate. ++ + ++-+## Targeted Playwright +++ ## Merge Control ++ ++- ```powershell ++--npx playwright test tests/playwright/tools/GameJourneyTool.spec.mjs --project=playwright --workers=1 --reporter=line -g "Game Journey Local API persists completion metrics to Postgres|Toolbox renders Creator-safe Game Journey progress outage copy" ++-+npx playwright test tests/playwright/tools/AdminHealthOperationsPage.spec.mjs --project=playwright --workers=1 --reporter=line -g "Admin System Health operations page keeps scripts and styles external" ++- ``` +++ No PR in this operating system is merged without explicit owner approval. +++diff --git a/docs_build/dev/ProjectInstructions/README.txt b/docs_build/dev/ProjectInstructions/README.txt +++index a48becf05..631fd3918 100644 +++--- a/docs_build/dev/ProjectInstructions/README.txt ++++++ b/docs_build/dev/ProjectInstructions/README.txt +++@@ -1,10 +1,10 @@ +++ Read this file first. ++ ++--Result: PASS, 2 passed ++-+Result: PASS, 1 passed +++ Folder purpose: +++-This folder is the append-first Project Instructions operating system for Game Foundry Studio. It organizes active governance, backlog, team assignment, deprecation, and history material without deleting or rewriting the existing Project Instructions files elsewhere in the repository. ++++This folder is the only active Project Instructions source for Game Foundry Studio. It organizes active governance, backlog, team assignment, deprecation, and history material under `docs_build/dev/ProjectInstructions/`. ++ ++- ```powershell ++--node -e "import('node:fs').then(async fs=>{const [{createGameJourneyCompletionMetricsStore}, {createGameJourneyCompletionMetricsPostgresClientStub}] = await Promise.all([import('./src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs'), import('./tests/helpers/gameJourneyCompletionMetricsPostgresClientStub.mjs')]); const legacy='tmp/local-api/game-journey-completion-metrics.sqlite'; if(!fs.existsSync(legacy)) throw new Error('Expected existing retired local file for regression proof'); const before=fs.statSync(legacy).mtimeMs; const store=createGameJourneyCompletionMetricsStore({postgresClient:createGameJourneyCompletionMetricsPostgresClientStub()}); const metrics=await store.listMetrics(); const snapshot=await store.snapshot(); const after=fs.statSync(legacy).mtimeMs; if(Object.hasOwn(store, 'legacyDbPath')) throw new Error('Store exposes legacyDbPath'); if(Object.hasOwn(snapshot, 'legacySqlitePath')) throw new Error('Snapshot exposes legacySqlitePath'); if(metrics.length!==14) throw new Error('Expected 14 active metrics'); if(before!==after) throw new Error('Retired local file was touched'); console.log('PASS active DB metrics ignore and do not inspect retired local file');})" ++-+npx playwright test tests/playwright/tools/GameJourneyTool.spec.mjs --project=playwright --workers=1 --reporter=line -g "Game Journey progress dashboard summarizes completion metrics|Game Journey Local API persists completion metrics to Postgres|Toolbox renders Creator-safe Game Journey progress outage copy" ++- ``` +++ Preservation rules: +++-Preserve all existing documentation. Add new files or append explicit references unless the owner explicitly approves deletion or rewrite. When a conflict appears, stop, explain the conflict, and request owner approval before changing existing instruction text. ++++Preserve historical Project Instructions material as deprecated reference only. Do not treat `docs_build/dev/PROJECT_INSTRUCTIONS.md`, `project-instructions/`, or archived snapshots as active instruction sources. When a conflict appears, `docs_build/dev/ProjectInstructions/` wins unless OWNER explicitly approves a newer governance change. +++ +++ Backlog workflow: +++ Backlog work is tracked under backlog/. BACKLOG_MASTER.md is the planned source for backlog item status, notes, and references. Backlog item text is treated as immutable once created; status and notes may change under the governance addendums. +++@@ -29,9 +29,9 @@ Do not rewrite history snapshots after creation unless the owner explicitly appr ++ ++--Result: PASS ++-+Result: PASS, 3 passed +++ READ THIS FIRST +++ +++-1. Read Project Instructions before making changes. +++-2. Project Instructions are append-only. +++-3. Existing approved guidance may not be removed. ++++1. Read `docs_build/dev/ProjectInstructions/README.txt` before making changes. ++++2. Treat `docs_build/dev/ProjectInstructions/` as the only active Project Instructions source. ++++3. Historical Project Instructions files outside this folder are deprecated references only. +++ 4. Team ownership must be respected. +++ 5. BACKLOG_MASTER.md is the authoritative backlog. +++ 6. Build Path status derives from backlog status. +++@@ -42,12 +42,13 @@ READ THIS FIRST +++ 11. Batch Governance Mode is the default for governance, documentation, and administrative work. +++ +++ Addendum index: +++-- Canonical Repository Structure: project-instructions/addendums/canonical-repository-structure.md +++-- Test Structure Standardization: project-instructions/addendums/test-structure-standardization.md +++-- Legacy Migration Policy: project-instructions/addendums/legacy-migration-policy.md +++-- Assistant Execution Modes: project-instructions/addendums/assistant-execution-modes.md +++-- Codex Artifact and Reporting Standard: project-instructions/addendums/codex-artifact-and-reporting-standard.md +++-- Codex Project Instructions Startup: project-instructions/addendums/codex-project-instructions-startup.md ++++- Single Source and EOD Main Lock: docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md ++++- Canonical Repository Structure: docs_build/dev/ProjectInstructions/addendums/canonical_repository_structure.md ++++- Test Structure Standardization: docs_build/dev/ProjectInstructions/addendums/test_structure_standardization.md ++++- Legacy Migration Policy: docs_build/dev/ProjectInstructions/addendums/legacy_migration_policy.md ++++- Assistant Execution Modes: docs_build/dev/ProjectInstructions/addendums/assistant_execution_modes.md ++++- Codex Artifact and Reporting Standard: docs_build/dev/ProjectInstructions/addendums/codex_artifact_and_reporting_standard.md ++++- Codex Project Instructions Startup: docs_build/dev/ProjectInstructions/addendums/codex_project_instructions_startup.md +++ - Project Reference Files Governance: docs_build/dev/ProjectInstructions/addendums/project_reference_files.md +++ - Environment Governance Model: docs_build/dev/ProjectInstructions/addendums/environment_governance_model.md +++ - Environment Configuration Standards: docs_build/dev/ProjectInstructions/addendums/environment_configuration_standards.md +++diff --git a/docs_build/dev/ProjectInstructions/TEAM_START_COMMANDS.md b/docs_build/dev/ProjectInstructions/TEAM_START_COMMANDS.md +++index d0118f63a..192278a34 100644 +++--- a/docs_build/dev/ProjectInstructions/TEAM_START_COMMANDS.md ++++++ b/docs_build/dev/ProjectInstructions/TEAM_START_COMMANDS.md +++@@ -1,5 +1,42 @@ +++ # TEAM_START_COMMANDS +++ ++++## Required Main Reset Gate For Every Team ++++ ++++No team creates a PR branch until all checks pass: ++++ ++++- Current branch: `main` ++++- Worktree: clean ++++- `main...origin/main`: `0 0` ++++- `HEAD` SHA matches the published EOD SHA ++++ ++++Use `docs_build/dev/ProjectInstructions/` as the only active Project Instructions source. ++ + ++-+## Reference Searches ++++START RULE: ++++- Every team starts on `main`. ++++- `main` must be clean. ++++- `main...origin/main` must be `0 0`. ++++- `HEAD` SHA must match published EOD SHA. ++++- Only then create or switch to the PR branch. ++++- No commits are allowed on `main`. ++++ ++++WORK RULE: ++++- Codex must remain on the PR branch during implementation. ++++- Codex commits only to the PR branch. ++++- Codex pushes only the PR branch. ++++- HARD STOP if branch changes unexpectedly. ++++- HARD STOP before committing if current branch is `main`. ++++ ++++END RULE: ++++- After PR validation, push the PR branch. ++++- Merge PR into `main` only when approved. ++++- Checkout `main`. ++++- Run `git fetch origin`. ++++- Run `git pull --ff-only origin main`. ++++- Confirm current branch is `main`. ++++- Confirm worktree is clean. ++++- Confirm `main...origin/main` is `0 0`. ++++- Record `HEAD` SHA as new EOD baseline. ++++ +++ ## Start Team Alfa ++ ++- ```powershell ++--rg -n -i "sqlite|better-sqlite|game-journey-completion-metrics\.sqlite|tmp/local-api" src assets toolbox -g "*.js" -g "*.mjs" --glob "!src/dev-runtime/persistence/game-journey-completion-metrics-migration.mjs" ++--rg -n "Game Journey completion metrics unavailable" src assets toolbox --glob "!**/*.map" ++-+rg -n -i "sqlite|better-sqlite|game-journey-completion-metrics\.sqlite|tmp/local-api" -g "*.js" -g "*.mjs" ++-+rg -n -i "sqlite|better-sqlite|game-journey-completion-metrics\.sqlite|tmp/local-api" --glob "!docs_build/**" --glob "!tmp/**" --glob "!.git/**" ++-+rg -n "node:sqlite|DatabaseSync|sqlite3|better-sqlite|\.sqlite|tmp/local-api|LocalSqliteStore|messages-sqlite-service" --glob "!docs_build/**" --glob "!tmp/**" --glob "!.git/**" ++-+rg -n "game-journey-completion-metrics-migration|migrate-game-journey-completion-metrics" --glob "!docs_build/**" --glob "!tmp/**" --glob "!.git/**" ++-+rg -n "completionMetricsLegacyDbPath|gameJourneyCompletionMetricsLegacyDbPath|legacyDbPath|legacySqlitePath" src tests toolbox assets scripts --glob "*.js" --glob "*.mjs" +++ Ready-to-copy command: +++@@ -123,4 +160,24 @@ Merge to main is EOD-only and owner-approved, unless the owner explicitly says: +++ "Merge this PR now." +++ +++ Do not treat sequential PR completion as merge approval. ++++ ++++End of Day: ++++git checkout main ++++git fetch origin ++++git pull --ff-only origin main ++++git status ++++git rev-list --left-right --count main...origin/main ++++ ++++Required: ++++On branch main ++++nothing to commit, working tree clean ++++0 0 ++++ ++++Next Day Start: ++++git checkout main ++++git fetch origin ++++git pull --ff-only origin main ++++git status ++++git rev-list --left-right --count main...origin/main ++++git rev-parse HEAD ++ ``` +++diff --git a/docs_build/dev/ProjectInstructions/addendums/assistant_execution_modes.md b/docs_build/dev/ProjectInstructions/addendums/assistant_execution_modes.md +++new file mode 100644 +++index 000000000..6d7928669 +++--- /dev/null ++++++ b/docs_build/dev/ProjectInstructions/addendums/assistant_execution_modes.md +++@@ -0,0 +1,120 @@ ++++# Assistant Execution Modes ++++ ++++## Purpose ++++ ++++Standardize request interpretation and expected outputs for Review, Owner, Build PR, Continue, Challenge, and Stop Gate workflows. ++++ ++++## Command Modes ++++ ++++### Review ++++ ++++Expected Output: ++++- Findings ++++- Risks ++++- Recommendations ++++ ++++Do Not Output: ++++- PRs ++++- Implementation plans ++++ ++++### Owner ++++ ++++Expected Output: ++++- Decisions ++++- Governance direction ++++- Standards ++++ ++++Do Not Output: ++++- Detailed implementation ++++ ++++### Build PR ++++ ++++Expected Output: ++++- Single Codex work order ++++- May contain multiple sequential PRs belonging to the same workstream ++++- Copy/paste ready for execution ++++ ++++Should Include: ++++- Start gates ++++- Changes ++++- Validation ++++- Commit names ++++- Stop point ++++ ++++Do Not Output: ++++- Design discussion ++++- Alternatives ++++- Rationale ++++- Architecture brainstorming ++++ ++++### Continue ++++ ++++Expected Output: ++++- Next sequential executable PR ++++- Next sequential work order ++++ ++++Do Not Output: ++++- New ideas ++++- Re-analysis ++++- Additional brainstorming ++++ ++++### Challenge ++++ ++++Expected Output: ++++- Risks ++++- Contradictions ++++- Better alternatives ++++ ++++Do Not Output: ++++- Immediate implementation ++++ ++++### Stop Gate ++++ ++++Expected Output: ++++- Why work should stop ++++- Required corrections ++++ ++++Allowed Reasons: ++++- Governance conflict ++++- Architecture conflict ++++- Security risk ++++- Data loss risk ++++- Major technical debt increase ++++ ++++## Additional Definitions ++++ ++++### Follow Project Instructions ++++ ++++Meaning: ++++- Use existing governance ++++- Do not redesign process ++++ ++++### Build the PR ++++ ++++Meaning: ++++- Produce Codex executable work order immediately ++++ ++++### Continue ++++ ++++Meaning: ++++- Produce next sequential work item ++++ ++++### No zip file ++++ ++++Meaning: ++++- Generate instructions only ++++- Do not expect artifact review ++++ ++++### You are owner ++++ ++++Meaning: ++++- Make decisions ++++- Do not ask for direction unless blocked ++++ ++++### Done for the day ++++ ++++Meaning: ++++- Finish commits ++++- Merge ++++- Push ++++- Create next-day start document +++diff --git a/docs_build/dev/ProjectInstructions/addendums/branch_lock_governance.md b/docs_build/dev/ProjectInstructions/addendums/branch_lock_governance.md +++index 518f8c943..e6ab30ae8 100644 +++--- a/docs_build/dev/ProjectInstructions/addendums/branch_lock_governance.md ++++++ b/docs_build/dev/ProjectInstructions/addendums/branch_lock_governance.md +++@@ -23,12 +23,46 @@ Keep active work attached to the correct assigned team, branch, and OWNER decisi ++ ++--Result: PASS, no matches ++-+Result: PASS, no matches. +++ - Start from current `main`. +++ - Pull latest `origin/main` before creating a work branch. ++++- Do not create a PR branch unless current branch is `main`, worktree is clean, `main...origin/main` is `0 0`, and `HEAD` SHA matches the published EOD SHA. +++ - Keep work on the active branch until the PR is merged, the branch is retired, or OWNER says to return to `main`. +++-- Do not commit directly to `main` unless OWNER explicitly approves. ++++- Do not commit directly to `main`. ++++- HARD STOP before committing if current branch is `main`. ++++- HARD STOP if the branch changes unexpectedly during implementation. ++++- Commit only to the PR branch. ++++- Push only the PR branch. +++ - Do not merge stale historical branches directly unless they are current, clean, still needed, and OWNER-approved. +++ - Retain source branches by default after merge and closeout. +++ - Record branch disposition before Closed as `retained`. ++ ++- ```powershell ++--git diff --check ++-+rg -n "Game Journey completion metrics unavailable" src assets toolbox --glob "!**/*.map" ++- ``` ++++## START RULE ++++ ++++- Every team starts on `main`. ++++- `main` must be clean. ++++- `main...origin/main` must be `0 0`. ++++- `HEAD` SHA must match published EOD SHA. ++++- Only then create or switch to the PR branch. ++++- No commits are allowed on `main`. ++++ ++++## WORK RULE ++++ ++++- Codex must remain on the PR branch during implementation. ++++- Codex commits only to the PR branch. ++++- Codex pushes only the PR branch. ++++- HARD STOP if branch changes unexpectedly. ++++- HARD STOP before committing if current branch is `main`. ++++ ++++## END RULE ++++ ++++- After PR validation, push the PR branch. ++++- Merge PR into `main` only when approved. ++++- Checkout `main`. ++++- Run `git fetch origin`. ++++- Run `git pull --ff-only origin main`. ++++- Confirm current branch is `main`. ++++- Confirm worktree is clean. ++++- Confirm `main...origin/main` is `0 0`. ++++- Record `HEAD` SHA as new EOD baseline. ++++ +++ ## OWNER Override ++ ++--Result: PASS, line-ending warnings only ++-+Result: PASS, no matches. ++-+ ++-+## Broader Gate Note ++-+ ++-+`node scripts/validate-browser-env-agnostic.mjs` was spot-run and wrote a FAIL report for unrelated existing product-service and messaging wording findings. That generated report was restored and is not part of the targeted PR validation result. ++-diff --git a/docs_build/dev/reports/coverage_changed_js_guardrail.txt b/docs_build/dev/reports/coverage_changed_js_guardrail.txt ++-index 01a698376..7b1c51f19 100644 ++---- a/docs_build/dev/reports/coverage_changed_js_guardrail.txt ++-+++ b/docs_build/dev/reports/coverage_changed_js_guardrail.txt ++-@@ -6,9 +6,7 @@ Missing changed runtime JS files are WARN, not FAIL. ++- Source: Playwright/Chromium built-in V8 coverage from the active Playwright run. ++- ++- Changed runtime JS files considered: ++--(0%) src/dev-runtime/persistence/game-journey-completion-metrics-migration.mjs - WARNING: changed runtime JS file was not collected by Playwright V8 coverage; advisory only ++--(0%) src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs - WARNING: changed runtime JS file was not collected by Playwright V8 coverage; advisory only ++-+(100%) none changed - no changed runtime JS files ++- ++- Guardrail warnings: ++--(0%) src/dev-runtime/persistence/game-journey-completion-metrics-migration.mjs - WARNING: changed runtime JS file missing from coverage; advisory only ++--(0%) src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs - WARNING: changed runtime JS file missing from coverage; advisory only ++-+(100%) none changed - no changed runtime JS files ++-diff --git a/docs_build/dev/reports/playwright_v8_coverage_report.txt b/docs_build/dev/reports/playwright_v8_coverage_report.txt ++-index da369bcdb..f2363d3bf 100644 ++---- a/docs_build/dev/reports/playwright_v8_coverage_report.txt ++-+++ b/docs_build/dev/reports/playwright_v8_coverage_report.txt ++-@@ -17,8 +17,7 @@ Exercised tool entry points detected: ++- (72%) Theme V2 Shared JS - exercised 4 runtime JS files ++- ++- Changed runtime JS files covered: ++--(0%) src/dev-runtime/persistence/game-journey-completion-metrics-migration.mjs - WARNING: changed runtime JS file was not collected by Playwright V8 coverage; advisory only ++--(0%) src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs - WARNING: changed runtime JS file was not collected by Playwright V8 coverage; advisory only ++-+(100%) none changed - no changed runtime JS files ++- ++- Files with executed line/function counts where available: ++- (36%) src/shared/toolbox/tool-metadata-inventory.js - executed lines 2041/2041; executed functions 12/33 ++-@@ -34,11 +33,10 @@ Files with executed line/function counts where available: ++- (100%) assets/js/shared/game-journey-api-client.js - executed lines 19/19; executed functions 2/2 ++- ++- Uncovered or low-coverage changed JS files: ++--(0%) src/dev-runtime/persistence/game-journey-completion-metrics-migration.mjs - WARNING: uncovered changed runtime JS file; advisory only ++--(0%) src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs - WARNING: uncovered changed runtime JS file; advisory only ++-+(100%) none changed - no changed runtime JS files ++- ++- Changed JS files considered: ++--(0%) scripts/migrate-game-journey-completion-metrics-sqlite-to-postgres.mjs - changed JS file not collected as browser runtime coverage ++--(0%) src/dev-runtime/persistence/game-journey-completion-metrics-migration.mjs - changed JS file not collected as browser runtime coverage ++--(0%) src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs - changed JS file not collected as browser runtime coverage ++--(0%) tests/dev-runtime/GameJourneyCompletionMetricsMigration.test.mjs - changed JS file not collected as browser runtime coverage ++-+(0%) scripts/validate-browser-env-agnostic.mjs - changed JS file not collected as browser runtime coverage ++-+(0%) tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs - changed JS file not collected as browser runtime coverage ++-+(0%) tests/playwright/tools/AdminHealthOperationsPage.spec.mjs - changed JS file not collected as browser runtime coverage ++-+(0%) tests/playwright/tools/GameJourneyTool.spec.mjs - changed JS file not collected as browser runtime coverage ++-diff --git a/scripts/migrate-game-journey-completion-metrics-sqlite-to-postgres.mjs b/scripts/migrate-game-journey-completion-metrics-sqlite-to-postgres.mjs ++-deleted file mode 100644 ++-index bb3c19985..000000000 ++---- a/scripts/migrate-game-journey-completion-metrics-sqlite-to-postgres.mjs ++-+++ /dev/null ++-@@ -1,156 +0,0 @@ ++--import fs from "node:fs"; ++--import path from "node:path"; ++--import process from "node:process"; ++--import { ++-- DEFAULT_GAME_JOURNEY_COMPLETION_METRICS_ARCHIVE_DIR, ++-- DEFAULT_GAME_JOURNEY_COMPLETION_METRICS_SQLITE_PATH, ++-- migrateLegacyCompletionMetricsSqliteToPostgres, ++-- readLegacyCompletionMetricsSqlite, ++--} from "../src/dev-runtime/persistence/game-journey-completion-metrics-migration.mjs"; ++-- ++--const ENV_FILE = ".env"; ++-- ++--function parseEnvValue(value) { ++-- const trimmed = value.trim(); ++-- const quote = trimmed[0]; ++-- if ((quote === "\"" || quote === "'") && trimmed.endsWith(quote)) { ++-- return trimmed.slice(1, -1); ++-- } ++-- const commentIndex = trimmed.indexOf(" #"); ++-- return commentIndex === -1 ? trimmed : trimmed.slice(0, commentIndex).trim(); ++--} ++-- ++--function loadRuntimeEnv() { ++-- const envPath = path.resolve(process.cwd(), ENV_FILE); ++-- if (!fs.existsSync(envPath)) { ++-- return { ++-- loaded: false, ++-- loadedKeys: [], ++-- path: envPath, ++-- }; ++-- } ++-- const loadedKeys = []; ++-- fs.readFileSync(envPath, "utf8").split(/\r?\n/u).forEach((line) => { ++-- const trimmed = line.trim(); ++-- if (!trimmed || trimmed.startsWith("#")) { ++-- return; ++-- } ++-- const normalized = trimmed.startsWith("export ") ? trimmed.slice(7).trim() : trimmed; ++-- const separatorIndex = normalized.indexOf("="); ++-- if (separatorIndex <= 0) { ++-- return; ++-- } ++-- const key = normalized.slice(0, separatorIndex).trim(); ++-- if (!/^[A-Za-z_][A-Za-z0-9_]*$/u.test(key) || process.env[key] !== undefined) { ++-- return; ++-- } ++-- process.env[key] = parseEnvValue(normalized.slice(separatorIndex + 1)); ++-- loadedKeys.push(key); ++-- }); ++-- return { ++-- loaded: true, ++-- loadedKeys: loadedKeys.sort(), ++-- path: envPath, ++-- }; ++--} ++-- ++--function parseArgs(argv) { ++-- const options = { ++-- archiveDir: DEFAULT_GAME_JOURNEY_COMPLETION_METRICS_ARCHIVE_DIR, ++-- dryRun: false, ++-- inspectOnly: false, ++-- legacyDbPath: DEFAULT_GAME_JOURNEY_COMPLETION_METRICS_SQLITE_PATH, ++-- pythonCommand: "python", ++-- }; ++-- for (let index = 0; index < argv.length; index += 1) { ++-- const arg = argv[index]; ++-- if (arg === "--dry-run") { ++-- options.dryRun = true; ++-- continue; ++-- } ++-- if (arg === "--inspect-only") { ++-- options.inspectOnly = true; ++-- continue; ++-- } ++-- if (arg === "--legacy-db") { ++-- options.legacyDbPath = path.resolve(argv[index + 1] || ""); ++-- index += 1; ++-- continue; ++-- } ++-- if (arg === "--archive-dir") { ++-- options.archiveDir = path.resolve(argv[index + 1] || ""); ++-- index += 1; ++-- continue; ++-- } ++-- if (arg === "--python") { ++-- options.pythonCommand = argv[index + 1] || "python"; ++-- index += 1; ++-- continue; ++-- } ++-- throw new Error(`Unknown argument: ${arg}`); ++-- } ++-- return options; ++--} ++-- ++--function printSummary(summary) { ++-- Object.entries(summary).forEach(([key, value]) => { ++-- console.log(`${key}: ${value}`); ++-- }); ++--} ++-- ++--async function main() { ++-- const options = parseArgs(process.argv.slice(2)); ++-- const envLoad = loadRuntimeEnv(); ++-- const exported = await readLegacyCompletionMetricsSqlite({ ++-- legacyDbPath: options.legacyDbPath, ++-- pythonCommand: options.pythonCommand, ++-- }); ++-- printSummary({ ++-- "Legacy SQLite": exported.legacyDbPath, ++-- "Schema objects": exported.schema.objects.length, ++-- "Valid rows": exported.rowCount, ++-- }); ++-- if (options.inspectOnly) { ++-- console.log("PASS: inspect-only completed; no Postgres writes or file moves were attempted."); ++-- return; ++-- } ++-- if (!String(process.env.GAMEFOUNDRY_DATABASE_URL || "").trim()) { ++-- console.error("BLOCKED: GAMEFOUNDRY_DATABASE_URL is missing; migration did not run and the legacy SQLite file was not moved."); ++-- console.error("Run after configuring Postgres, for example:"); ++-- console.error(" node --use-system-ca scripts/migrate-game-journey-completion-metrics-sqlite-to-postgres.mjs"); ++-- process.exitCode = 2; ++-- return; ++-- } ++-- if (!String(process.env.GAMEFOUNDRY_DATABASE_SSL || "").trim()) { ++-- console.error("BLOCKED: GAMEFOUNDRY_DATABASE_SSL is missing; migration did not run and the legacy SQLite file was not moved."); ++-- console.error("Set GAMEFOUNDRY_DATABASE_SSL=disable for local Postgres or require for TLS Postgres."); ++-- process.exitCode = 2; ++-- return; ++-- } ++-- const result = await migrateLegacyCompletionMetricsSqliteToPostgres({ ++-- archiveDir: options.archiveDir, ++-- dryRun: options.dryRun, ++-- env: process.env, ++-- legacyDbPath: exported.legacyDbPath, ++-- pythonCommand: options.pythonCommand, ++-- }); ++-- printSummary({ ++-- "Env file": envLoad.loaded ? `${envLoad.path} (${envLoad.loadedKeys.length} key(s) loaded)` : "not found", ++-- "Legacy rows": result.legacyRowCount, ++-- "Rows inserted": result.insertedCount, ++-- "Rows already present": result.duplicateCount, ++-- "Rows timestamp-patched": result.timestampPatchCount, ++-- "Rows that would insert": result.wouldInsertCount, ++-- "Rows that would patch timestamps": result.wouldPatchTimestampCount, ++-- "Archive": result.archive.archived ? result.archive.archivePath : result.archive.message, ++-- "Status": result.status, ++-- }); ++--} ++-- ++--main().catch((error) => { ++-- console.error(error instanceof Error ? error.message : String(error || "Unknown migration failure.")); ++-- if (error?.details?.conflicts) { ++-- console.error(JSON.stringify({ conflicts: error.details.conflicts }, null, 2)); ++-- } ++-- process.exitCode = 1; ++--}); ++-diff --git a/scripts/validate-browser-env-agnostic.mjs b/scripts/validate-browser-env-agnostic.mjs ++-index 53a165d48..277366d84 100644 ++---- a/scripts/validate-browser-env-agnostic.mjs ++-+++ b/scripts/validate-browser-env-agnostic.mjs ++-@@ -30,12 +30,32 @@ const excludedSegments = new Set([ ++- "tmp", ++- ]); ++- ++-+const retiredFileDbToken = "SQL" + "ite"; ++-+const retiredDbConstructorToken = "Database" + "Sync"; ++-+const providerLeakPattern = new RegExp([ ++-+ "local-db", ++-+ retiredFileDbToken, ++-+ "Supabase", ++-+ "GAMEFOUNDRY_", ++-+ "process\\.env", ++-+].join("|"), "i"); ++-+const routerRetiredStoragePattern = new RegExp([ ++-+ `node:${retiredFileDbToken}`, ++-+ retiredDbConstructorToken, ++-+ "createRequire", ++-+ "GAMEFOUNDRY_AUTH_PROVIDER", ++-+ "GAMEFOUNDRY_DB_PROVIDER", ++-+ "parts\\[1\\] === \"local-db\"", ++-+ "parts\\[1\\] === \"mock-db\"", ++-+ "mock-db-state", ++-+ "deprecatedDatabaseEndpointError", ++-+].join("|"), "i"); ++- const deploymentTermPattern = /\b(?:DEV|UAT|PROD|Prod|Production|production|Development|development)\b|process\.env|GAMEFOUNDRY_[A-Z0-9_]*(?:ENV|ENVIRONMENT|STAGE|PROVIDER|MODE)[A-Z0-9_]*/; ++- const deploymentBranchDecisionPattern = /^\s*(?:if|else\s+if|switch|while|for)\s*\([^)]*(?:GAMEFOUNDRY_(?:ENV|DEPLOYMENT_ENV|STAGE|MODE)|NODE_ENV|process\.env\.(?:GAMEFOUNDRY_ENV|GAMEFOUNDRY_DEPLOYMENT_ENV|NODE_ENV)|\.env\.(?:local|uat|prod)|deployment|environment|stage)[^)]*(?:DEV|UAT|PROD|dev|development|uat|prod|production)[^)]*\)/i; ++- const deploymentCasePattern = /^\s*case\s+["'`](?:dev|development|uat|prod|production)["'`]\s*:/i; ++- const deploymentTernaryDecisionPattern = /(?:GAMEFOUNDRY_(?:ENV|DEPLOYMENT_ENV|STAGE|MODE)|NODE_ENV|process\.env|deployment|environment|stage)[^?\r\n]*\?[^:\r\n]*(?:DEV|UAT|PROD|dev|development|uat|prod|production)/i; ++--const accountDependencyPattern = /\b(?:Local(?: DB| API)?|SQLite|Supabase|provider|localhost|DEV|UAT|PROD|Prod)\b|data-local-db-|local-db-page-data\.js/i; ++--const userFacingImplementationPattern = /\b(?:DEV|UAT|PROD|Local DB|Local API|SQLite|Supabase|provider)\b/i; ++-+const accountDependencyPattern = new RegExp(`\\b(?:Local(?: DB| API)?|${retiredFileDbToken}|Supabase|provider|localhost|DEV|UAT|PROD|Prod)\\b|data-local-db-|local-db-page-data\\.js`, "i"); ++-+const userFacingImplementationPattern = new RegExp(`\\b(?:DEV|UAT|PROD|Local DB|Local API|${retiredFileDbToken}|Supabase|provider)\\b`, "i"); ++- const accountBrowserFiles = new Set([ ++- "assets/theme-v2/js/account-auth-actions.js", ++- "assets/theme-v2/js/account-auth-service.js", ++-@@ -286,7 +306,7 @@ async function validateAccountServiceContract() { ++- const accountService = await readRequiredRepoFile("assets/theme-v2/js/account-auth-service.js", findings, "Account auth service module is missing"); ++- requireSnippet(accountService, "assets/theme-v2/js/account-auth-service.js", "fetchServerApi(`/auth/${path}`", findings, "Account auth service must own configured /api/auth requests."); ++- requireSnippet(accountService, "assets/theme-v2/js/account-auth-service.js", "fetchServerApi(\"/session/current\"", findings, "Account auth service must own configured /api/session/current requests."); ++-- rejectPattern(accountService, "assets/theme-v2/js/account-auth-service.js", /local-db|SQLite|Supabase|provider|GAMEFOUNDRY_|process\.env/i, findings, "Account auth service must not expose provider or environment implementation details."); ++-+ rejectPattern(accountService, "assets/theme-v2/js/account-auth-service.js", providerLeakPattern, findings, "Account auth service must not expose provider or environment implementation details."); ++- ++- return findings; ++- } ++-@@ -295,18 +315,18 @@ async function validateProductServiceContract() { ++- const findings = []; ++- const registryClient = await readRequiredRepoFile("toolbox/tool-registry-api-client.js", findings, "Toolbox registry client is missing"); ++- requireSnippet(registryClient, "toolbox/tool-registry-api-client.js", "safeRequestServerApi(\"/toolbox/registry/snapshot\")", findings, "Toolbox registry must read through the server API service contract."); ++-- rejectPattern(registryClient, "toolbox/tool-registry-api-client.js", /local-db|SQLite|Supabase|GAMEFOUNDRY_|process\.env/i, findings, "Toolbox registry client must not expose provider/environment implementation details."); ++-+ rejectPattern(registryClient, "toolbox/tool-registry-api-client.js", providerLeakPattern, findings, "Toolbox registry client must not expose provider/environment implementation details."); ++- ++- const votesClient = await readRequiredRepoFile("src/api/toolbox-votes-api-client.js", findings, "Toolbox votes API client is missing"); ++- requireSnippet(votesClient, "src/api/toolbox-votes-api-client.js", "safeRequestServerApi(\"/toolbox/votes/snapshot\")", findings, "Toolbox votes must read through the server API service contract."); ++- requireSnippet(votesClient, "src/api/toolbox-votes-api-client.js", "safeRequestServerApi(\"/toolbox/votes/cast\"", findings, "Toolbox votes must write through the server API service contract."); ++-- rejectPattern(votesClient, "src/api/toolbox-votes-api-client.js", /local-db|SQLite|Supabase|GAMEFOUNDRY_|process\.env/i, findings, "Toolbox votes client must not expose provider/environment implementation details."); ++-+ rejectPattern(votesClient, "src/api/toolbox-votes-api-client.js", providerLeakPattern, findings, "Toolbox votes client must not expose provider/environment implementation details."); ++- ++- for (const filePath of productApiClientFiles) { ++- const contents = await readRequiredRepoFile(filePath, findings, "Product API client is missing"); ++- requireSnippet(contents, filePath, "createServerRepositoryClient", findings, "Product API client must use the server repository contract."); ++- requireSnippet(contents, filePath, "readServerToolConstants", findings, "Product API client must read server-owned constants."); ++-- rejectPattern(contents, filePath, /local-db|SQLite|Supabase|GAMEFOUNDRY_|process\.env/i, findings, "Product API client must not expose provider/environment implementation details."); ++-+ rejectPattern(contents, filePath, providerLeakPattern, findings, "Product API client must not expose provider/environment implementation details."); ++- } ++- ++- const router = await readRequiredRepoFile("src/dev-runtime/server/local-api-router.mjs", findings, "Local API router is missing"); ++-@@ -317,7 +337,7 @@ async function validateProductServiceContract() { ++- requireSnippet(router, "src/dev-runtime/server/local-api-router.mjs", "this.assertProductDatabaseProvider(`Creating ${toolId} repository`);", findings, "Repository creation must assert the server-owned product-data contract."); ++- requireSnippet(router, "src/dev-runtime/server/local-api-router.mjs", "this.assertProductDatabaseProvider(`Calling repository method ${methodName}`);", findings, "Repository method calls must assert the server-owned product-data contract."); ++- rejectPattern(router, "src/dev-runtime/server/local-api-router.mjs", /selectedDatabaseProviderId|selectedAuthProvider|selectedProvidersCanServeRuntime/, findings, "Runtime router must not contain active provider-selection helpers."); ++-- rejectPattern(router, "src/dev-runtime/server/local-api-router.mjs", /node:sqlite|DatabaseSync|createRequire|GAMEFOUNDRY_AUTH_PROVIDER|GAMEFOUNDRY_DB_PROVIDER|parts\[1\] === "local-db"|parts\[1\] === "mock-db"|mock-db-state|deprecatedDatabaseEndpointError/, findings, "Runtime router must not contain SQLite startup/opening code, provider-selection environment variables, or legacy local-db/mock-db routes."); ++-+ rejectPattern(router, "src/dev-runtime/server/local-api-router.mjs", routerRetiredStoragePattern, findings, "Runtime router must not contain retired file-DB startup/opening code, provider-selection environment variables, or retired local-db/mock-db routes."); ++- ++- const startup = await readRequiredRepoFile("scripts/start-local-api-server.mjs", findings, "Local API startup script is missing"); ++- rejectPattern(startup, "scripts/start-local-api-server.mjs", /GAMEFOUNDRY_AUTH_PROVIDER|GAMEFOUNDRY_DB_PROVIDER|auth provider|product data provider|provider selection/i, findings, "Local API startup must describe configured connections without provider-selection environment variables."); ++-@@ -386,7 +406,7 @@ const report = [ ++- "## User-Facing Implementation Wording Findings", ++- formatRecords(userFacingUiFindings), ++- "", ++-- "## Deprecated SQLite/Local DB Technical Debt", ++-+ "## Deprecated Local DB Technical Debt", ++- formatTechnicalDebt(deprecatedLocalDbDebt), ++- "", ++- "## Non-Branching Deployment Mentions Reviewed", ++-diff --git a/src/dev-runtime/persistence/game-journey-completion-metrics-migration.mjs b/src/dev-runtime/persistence/game-journey-completion-metrics-migration.mjs ++-deleted file mode 100644 ++-index e53bee7fe..000000000 ++---- a/src/dev-runtime/persistence/game-journey-completion-metrics-migration.mjs ++-+++ /dev/null ++-@@ -1,433 +0,0 @@ ++--import fs from "node:fs/promises"; ++--import { existsSync } from "node:fs"; ++--import path from "node:path"; ++--import { spawn } from "node:child_process"; ++--import process from "node:process"; ++--import { ++-- GAME_JOURNEY_COMPLETION_METRICS_SCHEMA_SQL, ++-- GAME_JOURNEY_COMPLETION_METRICS_TABLE, ++--} from "./game-journey-completion-metrics-store.mjs"; ++--import { createPostgresConnectionClient } from "./postgres-connection-client.mjs"; ++-- ++--export const DEFAULT_GAME_JOURNEY_COMPLETION_METRICS_SQLITE_PATH = path.join( ++-- process.cwd(), ++-- "tmp", ++-- "local-api", ++-- "game-journey-completion-metrics.sqlite", ++--); ++--export const DEFAULT_GAME_JOURNEY_COMPLETION_METRICS_ARCHIVE_DIR = path.join( ++-- process.cwd(), ++-- "tmp", ++-- "local-api", ++-- "legacy-migrated", ++--); ++-- ++--const LEGACY_TABLE = GAME_JOURNEY_COMPLETION_METRICS_TABLE; ++--const EXPECTED_COLUMNS = Object.freeze([ ++-- "key", ++-- "bucketKey", ++-- "bucketOrder", ++-- "bucketName", ++-- "friendlyDescription", ++-- "requiredForMvp", ++-- "canSkip", ++-- "plannedCount", ++-- "completedCount", ++-- "active", ++-- "status", ++-- "createdAt", ++-- "updatedAt", ++-- "createdBy", ++-- "updatedBy", ++--]); ++-- ++--const PYTHON_SQLITE_EXPORT_SCRIPT = String.raw` ++--import json ++--import sqlite3 ++--import sys ++-- ++--db_path = sys.argv[1] ++--connection = sqlite3.connect(db_path) ++--connection.row_factory = sqlite3.Row ++--try: ++-- schema_objects = [ ++-- dict(row) ++-- for row in connection.execute( ++-- "SELECT name, type, sql FROM sqlite_master WHERE type IN ('table', 'index', 'trigger', 'view') ORDER BY type, name" ++-- ).fetchall() ++-- ] ++-- columns = [ ++-- dict(row) ++-- for row in connection.execute("PRAGMA table_info(game_journey_completion_metrics)").fetchall() ++-- ] ++-- rows = [ ++-- dict(row) ++-- for row in connection.execute( ++-- 'SELECT * FROM "game_journey_completion_metrics" ORDER BY "bucketOrder", "bucketKey"' ++-- ).fetchall() ++-- ] ++-- print(json.dumps({ ++-- "schema": { ++-- "columns": columns, ++-- "objects": schema_objects, ++-- }, ++-- "rows": rows, ++-- })) ++--finally: ++-- connection.close() ++--`; ++-- ++--export class GameJourneyCompletionMetricsMigrationError extends Error { ++-- constructor(message, details = {}) { ++-- super(message); ++-- this.name = "GameJourneyCompletionMetricsMigrationError"; ++-- this.details = details; ++-- } ++--} ++-- ++--function asText(value) { ++-- return String(value ?? "").trim(); ++--} ++-- ++--function normalizeCount(value, label) { ++-- const parsed = Number(value); ++-- if (!Number.isFinite(parsed) || parsed < 0) { ++-- throw new GameJourneyCompletionMetricsMigrationError(`Invalid legacy ${label}: ${value}.`); ++-- } ++-- return Math.trunc(parsed); ++--} ++-- ++--function normalizeBoolean(value, label) { ++-- if (value === true || value === 1 || value === "1" || value === "true" || value === "active") { ++-- return true; ++-- } ++-- if (value === false || value === 0 || value === "0" || value === "false" || value === "inactive") { ++-- return false; ++-- } ++-- throw new GameJourneyCompletionMetricsMigrationError(`Invalid legacy ${label}: ${value}.`); ++--} ++-- ++--function requireText(row, key) { ++-- const value = asText(row?.[key]); ++-- if (!value) { ++-- throw new GameJourneyCompletionMetricsMigrationError(`Legacy row is missing required ${key}.`); ++-- } ++-- return value; ++--} ++-- ++--function normalizeStatus(row, active) { ++-- const status = asText(row?.status) || (active ? "active" : "inactive"); ++-- if (!["active", "inactive"].includes(status)) { ++-- throw new GameJourneyCompletionMetricsMigrationError(`Invalid legacy status: ${status}.`); ++-- } ++-- return status; ++--} ++-- ++--export function normalizeLegacyCompletionMetric(row) { ++-- const plannedCount = normalizeCount(row?.plannedCount, "plannedCount"); ++-- const completedCount = normalizeCount(row?.completedCount, "completedCount"); ++-- if (completedCount > plannedCount) { ++-- throw new GameJourneyCompletionMetricsMigrationError( ++-- `Legacy completedCount ${completedCount} exceeds plannedCount ${plannedCount} for ${asText(row?.bucketKey) || "(missing bucketKey)"}.`, ++-- ); ++-- } ++-- const active = normalizeBoolean(row?.active, "active"); ++-- return { ++-- active, ++-- bucketKey: requireText(row, "bucketKey"), ++-- bucketName: requireText(row, "bucketName"), ++-- bucketOrder: normalizeCount(row?.bucketOrder, "bucketOrder"), ++-- canSkip: normalizeBoolean(row?.canSkip, "canSkip"), ++-- completedCount, ++-- createdAt: requireText(row, "createdAt"), ++-- createdBy: requireText(row, "createdBy"), ++-- friendlyDescription: requireText(row, "friendlyDescription"), ++-- key: requireText(row, "key"), ++-- plannedCount, ++-- requiredForMvp: normalizeBoolean(row?.requiredForMvp, "requiredForMvp"), ++-- status: normalizeStatus(row, active), ++-- updatedAt: requireText(row, "updatedAt"), ++-- updatedBy: requireText(row, "updatedBy"), ++-- }; ++--} ++-- ++--function validateLegacySchema(exported) { ++-- const table = exported?.schema?.objects?.find((object) => object.type === "table" && object.name === LEGACY_TABLE); ++-- if (!table) { ++-- throw new GameJourneyCompletionMetricsMigrationError(`Legacy SQLite file does not contain ${LEGACY_TABLE}.`); ++-- } ++-- const columns = new Set((exported?.schema?.columns || []).map((column) => String(column.name || ""))); ++-- const missingColumns = EXPECTED_COLUMNS.filter((column) => !columns.has(column)); ++-- if (missingColumns.length) { ++-- throw new GameJourneyCompletionMetricsMigrationError( ++-- `Legacy SQLite ${LEGACY_TABLE} is missing required columns: ${missingColumns.join(", ")}.`, ++-- { missingColumns }, ++-- ); ++-- } ++--} ++-- ++--function assertUniqueLegacyRows(rows) { ++-- const seenKeys = new Set(); ++-- const seenBucketKeys = new Set(); ++-- rows.forEach((row) => { ++-- if (seenKeys.has(row.key)) { ++-- throw new GameJourneyCompletionMetricsMigrationError(`Duplicate legacy key detected before migration: ${row.key}.`); ++-- } ++-- if (seenBucketKeys.has(row.bucketKey)) { ++-- throw new GameJourneyCompletionMetricsMigrationError(`Duplicate legacy bucketKey detected before migration: ${row.bucketKey}.`); ++-- } ++-- seenKeys.add(row.key); ++-- seenBucketKeys.add(row.bucketKey); ++-- }); ++--} ++-- ++--function comparableRow(row) { ++-- const normalized = normalizeLegacyCompletionMetric(row); ++-- return EXPECTED_COLUMNS.reduce((record, key) => { ++-- record[key] = normalized[key]; ++-- return record; ++-- }, {}); ++--} ++-- ++--function rowsMatch(left, right) { ++-- const normalizedLeft = comparableRow(left); ++-- const normalizedRight = comparableRow(right); ++-- return EXPECTED_COLUMNS.every((key) => normalizedLeft[key] === normalizedRight[key]); ++--} ++-- ++--function differingColumns(left, right) { ++-- const normalizedLeft = comparableRow(left); ++-- const normalizedRight = comparableRow(right); ++-- return EXPECTED_COLUMNS.filter((key) => normalizedLeft[key] !== normalizedRight[key]); ++--} +++ OWNER may override a branch lock or team assignment. +++@@ -54,3 +88,36 @@ Protected guidance includes: +++ - Governance Phase 1 completion guidance +++ +++ If protected guidance must change, OWNER approval is required. ++++ ++++## End Of Day Main Lock ++++ ++++End of Day: ++++ ++++```text ++++git checkout main ++++git fetch origin ++++git pull --ff-only origin main ++++git status ++++git rev-list --left-right --count main...origin/main ++++``` ++++ ++++Required: ++++ ++++```text ++++On branch main ++++nothing to commit, working tree clean ++++0 0 ++++``` ++++ ++++Next Day Start: ++++ ++++```text ++++git checkout main ++++git fetch origin ++++git pull --ff-only origin main ++++git status ++++git rev-list --left-right --count main...origin/main ++++git rev-parse HEAD ++++``` ++++ ++++The next-day `HEAD` SHA must match the published EOD SHA before any team creates a PR branch. +++diff --git a/docs_build/dev/ProjectInstructions/addendums/canonical_repository_structure.md b/docs_build/dev/ProjectInstructions/addendums/canonical_repository_structure.md +++new file mode 100644 +++index 000000000..e26939469 +++--- /dev/null ++++++ b/docs_build/dev/ProjectInstructions/addendums/canonical_repository_structure.md +++@@ -0,0 +1,39 @@ ++++# Canonical Repository Structure ++++ ++++## Purpose ++++ ++++Establish the canonical repository structure for future development and reduce technical debt. ++++ ++++## Canonical Structure ++++ ++++Tools: ++++- toolbox/{tool-name}/index.html ++++ ++++Tool assets: ++++- assets/toolbox/{tool-name}/js/index.js ++++- assets/toolbox/{tool-name}/css/index.css ++++ ++++Themes: ++++- assets/theme-v1/ ++++- assets/theme-v2/ ++++ ++++Shared JavaScript: ++++- assets/js/shared/ ++++ ++++Engine: ++++- src/engine/{feature-name}/ ++++ ++++API: ++++- api/{feature-name}/ ++++ ++++Serverside: ++++- serverside/{feature-name}/ ++++ ++++## Rules ++++ ++++- Theme first. ++++- Tool CSS second. ++++- Shared functionality belongs in assets/js/shared/. ++++- No new scattered JS folders. ++++- No new scattered CSS folders. ++++- New development follows the canonical structure. +++diff --git a/docs_build/dev/ProjectInstructions/addendums/codex_artifact_and_reporting_standard.md b/docs_build/dev/ProjectInstructions/addendums/codex_artifact_and_reporting_standard.md +++new file mode 100644 +++index 000000000..498e3895e +++--- /dev/null ++++++ b/docs_build/dev/ProjectInstructions/addendums/codex_artifact_and_reporting_standard.md +++@@ -0,0 +1,66 @@ ++++# Codex Artifact and Reporting Standard ++++ ++++## Purpose ++++ ++++Standardize Codex deliverables, completion reporting, and artifact generation. ++++ ++++## ZIP Artifact Requirement ++++ ++++Every Codex task must produce a ZIP artifact. ++++ ++++Applies to: ++++- Success ++++- Failure ++++- Stop Gate ++++- Partial Completion ++++- Review Deliverables ++++- Governance Deliverables ++++ ++++Minimum ZIP contents: ++++- summary.md ++++ ++++Optional: ++++- changed-files.txt ++++- findings.md ++++- validation.txt ++++- generated artifacts ++++ ++++## Completion Reporting ++++ ++++Codex responses must include: ++++- ZIP filename ++++- ZIP location ++++- PR number(s) ++++- Merge commit(s) ++++- Validation results ++++ ++++## Code Change Reporting ++++ ++++When a ZIP is uploaded, report executable code changes only. ++++ ++++Report format: ++++ ++++```text ++++{relative path} - {added|updated|deleted} ++++``` ++++ ++++Examples: ++++ ++++```text ++++toolbox/text-to-speech/index.html - updated ++++assets/toolbox/text-to-speech/js/index.js - added ++++tests/toolbox/text-to-speech/functional.spec.mjs - updated ++++``` ++++ ++++Do not report: ++++- markdown ++++- documentation ++++- reports ++++- notes ++++- README updates ++++ ++++unless explicitly requested. ++++ ++++## No ZIP Means Incomplete ++++ ++++A task is not considered complete until the ZIP artifact is generated and reported. +++diff --git a/docs_build/dev/ProjectInstructions/addendums/codex_project_instructions_startup.md b/docs_build/dev/ProjectInstructions/addendums/codex_project_instructions_startup.md +++new file mode 100644 +++index 000000000..dba8f8d93 +++--- /dev/null ++++++ b/docs_build/dev/ProjectInstructions/addendums/codex_project_instructions_startup.md +++@@ -0,0 +1,93 @@ ++++# Codex Project Instructions Startup ++++ ++++## Purpose ++++ ++++Ensure Codex uses the current approved governance before making repository changes. ++++ ++++## Startup Requirement ++++ ++++Before performing work, Codex must review and use: ++++ ++++```text ++++docs_build/dev/ProjectInstructions/ ++++``` ++++ ++++Codex must use this as the only active source of truth for: ++++- Governance rules ++++- Repository standards ++++- Ownership rules ++++- Workflow rules ++++- Addendums ++++- Execution modes ++++- Artifact requirements ++++ ++++## Branch Lifecycle Start Gate ++++ ++++START RULE: ++++- Every team starts on `main`. ++++- `main` must be clean. ++++- `main...origin/main` must be `0 0`. ++++- `HEAD` SHA must match published EOD SHA. ++++- Only then create or switch to the PR branch. ++++- No commits are allowed on `main`. ++++ ++++WORK RULE: ++++- Codex must remain on the PR branch during implementation. ++++- Codex commits only to the PR branch. ++++- Codex pushes only the PR branch. ++++- HARD STOP if branch changes unexpectedly. ++++- HARD STOP before committing if current branch is `main`. ++++ ++++END RULE: ++++- After PR validation, push the PR branch. ++++- Merge PR into `main` only when approved. ++++- Checkout `main`. ++++- Run `git fetch origin`. ++++- Run `git pull --ff-only origin main`. ++++- Confirm current branch is `main`. ++++- Confirm worktree is clean. ++++- Confirm `main...origin/main` is `0 0`. ++++- Record `HEAD` SHA as new EOD baseline. ++++ ++++Deprecated Project Instructions material outside `docs_build/dev/ProjectInstructions/` is reference-only and must not override active governance. ++++ ++++## Project Reference File Review ++++ ++++When present in `ProjectInstructions.zip`, the active project instruction directory, or `docs_build/dev/admin-notes/`, Codex must include these recognized project instruction/reference files in the Project Instructions read set: ++++ ++++- `Installs required.txt` ++++- `Table layout.txt` ++++ ++++Chat instructions may supplement Project Instructions but must not override approved governance without explicit OWNER approval. ++++ ++++## Conflict Handling ++++ ++++If a chat instruction conflicts with Project Instructions: ++++- Stop ++++- Do not continue the PR ++++- Produce the required ZIP artifact ++++- Document the conflict in summary.md ++++- Ask for OWNER direction ++++ ++++## Execution Mode Validation ++++ ++++When a request contains: ++++- Build PR ++++- Continue ++++- Follow Project Instructions ++++- Next PR ++++ ++++Codex must treat the request as Execution Mode. ++++ ++++Execution Mode means: ++++- Execute the requested work order ++++- Do not redesign the process ++++- Do not provide alternatives unless a Stop Gate condition exists ++++ ++++## Validation ++++ ++++Before completing the PR: ++++- Verify this addendum appears in the Project Instructions index ++++- Verify markdown is valid ++++- Verify all indexed addendums exist ++++- Verify the required ZIP artifact is produced +++diff --git a/docs_build/dev/ProjectInstructions/addendums/legacy_migration_policy.md b/docs_build/dev/ProjectInstructions/addendums/legacy_migration_policy.md +++new file mode 100644 +++index 000000000..5e43679f4 +++--- /dev/null ++++++ b/docs_build/dev/ProjectInstructions/addendums/legacy_migration_policy.md +++@@ -0,0 +1,33 @@ ++++# Legacy Migration Policy ++++ ++++## Purpose ++++ ++++Reduce technical debt incrementally during normal development. ++++ ++++## Migration Trigger ++++ ++++Migration review is required when any of these actions touch legacy files: ++++ ++++- File modified ++++- File renamed ++++- Bug fix ++++- Enhancement ++++- Test modification ++++ ++++## Migration Process ++++ ++++1. Review JS location. ++++2. Review CSS location. ++++3. Review test location. ++++4. Move touched files into canonical structure. ++++5. Update imports. ++++6. Update tests. ++++7. Remove legacy references. ++++ ++++## Rules ++++ ++++- Legacy files may only be deleted when no active references remain. ++++- Temporary bridge code must contain `TEMPORARY_MIGRATION` and a removal plan. ++++- No new scattered JS locations. ++++- No new scattered CSS locations. ++++- No new scattered test locations. +++diff --git a/docs_build/dev/ProjectInstructions/addendums/pr_workflow.md b/docs_build/dev/ProjectInstructions/addendums/pr_workflow.md +++index f8a4acb6e..abad0b789 100644 +++--- a/docs_build/dev/ProjectInstructions/addendums/pr_workflow.md ++++++ b/docs_build/dev/ProjectInstructions/addendums/pr_workflow.md +++@@ -26,6 +26,37 @@ Define the standard pull request workflow for Game Foundry Studio. +++ 15. Pull latest main before starting the next PR. +++ 16. Verify Main Verified and Closed gates. +++ ++++## Branch Lifecycle Governance ++++ ++++### START RULE ++++ ++++- Every team starts on `main`. ++++- `main` must be clean. ++++- `main...origin/main` must be `0 0`. ++++- `HEAD` SHA must match published EOD SHA. ++++- Only then create or switch to the PR branch. ++++- No commits are allowed on `main`. ++++ ++++### WORK RULE ++++ ++++- Codex must remain on the PR branch during implementation. ++++- Codex commits only to the PR branch. ++++- Codex pushes only the PR branch. ++++- HARD STOP if branch changes unexpectedly. ++++- HARD STOP before committing if current branch is `main`. ++++ ++++### END RULE ++++ ++++- After PR validation, push the PR branch. ++++- Merge PR into `main` only when approved. ++++- Checkout `main`. ++++- Run `git fetch origin`. ++++- Run `git pull --ff-only origin main`. ++++- Confirm current branch is `main`. ++++- Confirm worktree is clean. ++++- Confirm `main...origin/main` is `0 0`. ++++- Record `HEAD` SHA as new EOD baseline. ++++ +++ ## PR Lifecycle States +++ +++ Required state order: +++@@ -129,3 +160,40 @@ Stop only for: +++ - Merge conflict +++ - Validation failure +++ - OWNER decision ++++ ++++## EOD Main Lock ++++ ++++End of Day: ++++ ++++```text ++++git checkout main ++++git fetch origin ++++git pull --ff-only origin main ++++git status ++++git rev-list --left-right --count main...origin/main ++++``` ++++ ++++Required: ++++ ++++```text ++++On branch main ++++nothing to commit, working tree clean ++++0 0 ++++``` ++++ ++++## Next Day Start ++++ ++++```text ++++git checkout main ++++git fetch origin ++++git pull --ff-only origin main ++++git status ++++git rev-list --left-right --count main...origin/main ++++git rev-parse HEAD ++++``` ++++ ++++No team creates a PR branch until: ++++- Current branch: `main` ++++- Worktree: clean ++++- `main...origin/main`: `0 0` ++++- `HEAD` SHA matches published EOD SHA +++diff --git a/docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md b/docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md +++new file mode 100644 +++index 000000000..c41dc503d +++--- /dev/null ++++++ b/docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md +++@@ -0,0 +1,92 @@ ++++# Project Instructions Single Source And EOD Main Lock ++++ ++++Status: Approved ++++Owner: OWNER ++++ ++++## Active Source ++++ ++++`docs_build/dev/ProjectInstructions/` is the only active Project Instructions source for Game Foundry Studio. ++++ ++++Deprecated reference locations must not be used as active instruction sources: ++++- `docs_build/dev/PROJECT_INSTRUCTIONS.md` ++++- `project-instructions/` ++++- archived Project Instructions snapshots ++++- generated PR reports ++++ ++++If deprecated reference material conflicts with `docs_build/dev/ProjectInstructions/`, the active folder wins unless OWNER explicitly approves a newer governance change. ++++ ++++## End Of Day ++++ ++++```text ++++git checkout main ++++git fetch origin ++++git pull --ff-only origin main ++++git status ++++git rev-list --left-right --count main...origin/main ++++``` ++++ ++++Required: ++++ ++++```text ++++On branch main ++++nothing to commit, working tree clean ++++0 0 ++++``` ++++ ++++The EOD report must record the final `HEAD` SHA as the published EOD SHA. ++++ ++++## Next Day Start ++++ ++++```text ++++git checkout main ++++git fetch origin ++++git pull --ff-only origin main ++++git status ++++git rev-list --left-right --count main...origin/main ++++git rev-parse HEAD ++++``` ++++ ++++## Team Branch Creation Gate ++++ ++++No team creates a PR branch until: ++++- Current branch: `main` ++++- Worktree: clean ++++- `main...origin/main`: `0 0` ++++- `HEAD` SHA matches published EOD SHA ++++ ++++If any check fails, stop before branch creation and restore main to the published EOD state or request OWNER direction. ++++ ++++## Branch Lifecycle Governance ++++ ++++### START RULE ++++ ++++- Every team starts on `main`. ++++- `main` must be clean. ++++- `main...origin/main` must be `0 0`. ++++- `HEAD` SHA must match published EOD SHA. ++++- Only then create or switch to the PR branch. ++++- No commits are allowed on `main`. ++++ ++++### WORK RULE ++++ ++++- Codex must remain on the PR branch during implementation. ++++- Codex commits only to the PR branch. ++++- Codex pushes only the PR branch. ++++- HARD STOP if branch changes unexpectedly. ++++- HARD STOP before committing if current branch is `main`. ++++ ++++### END RULE ++++ ++++- After PR validation, push the PR branch. ++++- Merge PR into `main` only when approved. ++++- Checkout `main`. ++++- Run `git fetch origin`. ++++- Run `git pull --ff-only origin main`. ++++- Confirm current branch is `main`. ++++- Confirm worktree is clean. ++++- Confirm `main...origin/main` is `0 0`. ++++- Record `HEAD` SHA as new EOD baseline. ++++ ++++## Start Of Day Boundary ++++ ++++`docs_build/dev/start_of_day/` may point to `docs_build/dev/ProjectInstructions/`, but it must not become a second active Project Instructions source. +++diff --git a/docs_build/dev/ProjectInstructions/addendums/test_structure_standardization.md b/docs_build/dev/ProjectInstructions/addendums/test_structure_standardization.md +++new file mode 100644 +++index 000000000..997b16730 +++--- /dev/null ++++++ b/docs_build/dev/ProjectInstructions/addendums/test_structure_standardization.md +++@@ -0,0 +1,33 @@ ++++# Test Structure Standardization ++++ ++++## Purpose ++++ ++++Standardize testing locations and ensure independent tool validation. ++++ ++++## Canonical Test Structure ++++ ++++Tool tests: ++++- tests/toolbox/{tool-name}/ ++++ ++++Engine tests: ++++- tests/engine/{feature-name}/ ++++ ++++API tests: ++++- tests/api/{feature-name}/ ++++ ++++Server tests: ++++- tests/server/{feature-name}/ ++++ ++++Shared JavaScript tests: ++++- tests/js/shared/ ++++ ++++Regression tests: ++++- tests/regression/ ++++ ++++## Rules ++++ ++++- Every tool must be independently testable. ++++- Regression tests do not replace tool tests. ++++- Tool tests validate tool functionality. ++++- Regression tests validate platform behavior. ++++- New tests follow the canonical structure. +++diff --git a/docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md b/docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md +++index 9735b4bd4..f70440ad2 100644 +++--- a/docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md ++++++ b/docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md +++@@ -211,3 +211,72 @@ Commit/push during the day is allowed only on assigned team/OWNER/PR branches. +++ +++ Merge to main is EOD-only and owner-approved, unless the owner explicitly says: +++ "Merge this PR now." ++++ ++++## EOD Main Lock And Next Day Reset ++++ ++++End of Day: ++++ ++++```text ++++git checkout main ++++git fetch origin ++++git pull --ff-only origin main ++++git status ++++git rev-list --left-right --count main...origin/main ++++``` ++++ ++++Required: ++++ ++++```text ++++On branch main ++++nothing to commit, working tree clean ++++0 0 ++++``` ++++ ++++Next Day Start: ++++ ++++```text ++++git checkout main ++++git fetch origin ++++git pull --ff-only origin main ++++git status ++++git rev-list --left-right --count main...origin/main ++++git rev-parse HEAD ++++``` ++++ ++++Team rule: ++++No team creates a PR branch until: ++++- Current branch: `main` ++++- Worktree: clean ++++- `main...origin/main`: `0 0` ++++- `HEAD` SHA matches published EOD SHA ++++ ++++Active source rule: ++++Teams must use only `docs_build/dev/ProjectInstructions/` as the active Project Instructions source. ++++ ++++## Explicit Branch Lifecycle Governance ++++ ++++START RULE: ++++- Every team starts on `main`. ++++- `main` must be clean. ++++- `main...origin/main` must be `0 0`. ++++- `HEAD` SHA must match published EOD SHA. ++++- Only then create or switch to the PR branch. ++++- No commits are allowed on `main`. ++++ ++++WORK RULE: ++++- Codex must remain on the PR branch during implementation. ++++- Codex commits only to the PR branch. ++++- Codex pushes only the PR branch. ++++- HARD STOP if branch changes unexpectedly. ++++- HARD STOP before committing if current branch is `main`. ++++ ++++END RULE: ++++- After PR validation, push the PR branch. ++++- Merge PR into `main` only when approved. ++++- Checkout `main`. ++++- Run `git fetch origin`. ++++- Run `git pull --ff-only origin main`. ++++- Confirm current branch is `main`. ++++- Confirm worktree is clean. ++++- Confirm `main...origin/main` is `0 0`. ++++- Record `HEAD` SHA as new EOD baseline. +++diff --git a/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock.md b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock.md +++new file mode 100644 +++index 000000000..ed2f3e94a +++--- /dev/null ++++++ b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock.md +++@@ -0,0 +1,27 @@ ++++# PR_26177_OWNER_007-project-instructions-single-source-eod-lock ++++ ++++Date: 2026-06-26 ++++Scope: Project Instructions single-source, EOD main lock, and branch lifecycle governance ++++Status: PASS ++++ ++++## Summary ++++ ++++- Established docs_build/dev/ProjectInstructions/ as the only active Project Instructions source. ++++- Migrated legacy root project-instructions/addendums/ content into active docs_build/dev/ProjectInstructions/addendums/ files. ++++- Marked legacy docs_build/dev/PROJECT_INSTRUCTIONS.md and project-instructions/ material as deprecated reference only. ++++- Added EOD main lock, next-day reset, and team branch creation gate governance. ++++- Added explicit START RULE, WORK RULE, and END RULE branch lifecycle governance. ++++- Updated active team start and Codex workflow docs under docs_build/dev/ProjectInstructions/. ++++- No product/runtime, start_of_day, feature, or legacy SQLite file changes were made. ++++ ++++## Validation ++++ ++++- PASS: targeted grep found no active duplicate ProjectInstructions source-of-truth claim outside the active source. ++++- PASS: targeted grep confirmed EOD/Next Day governance appears in active governance docs. ++++- PASS: targeted grep confirmed START / WORK / END branch lifecycle governance appears in active governance docs. ++++- PASS: product/runtime and start_of_day changed-file check returned no files. ++++- PASS: git diff --check. ++++ ++++## Artifact ++++ ++++- tmp/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_delta.zip +++diff --git a/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_branch-validation.md b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_branch-validation.md +++new file mode 100644 +++index 000000000..b54d77ced +++--- /dev/null ++++++ b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_branch-validation.md +++@@ -0,0 +1,6 @@ ++++# PR_26177_OWNER_007-project-instructions-single-source-eod-lock Branch Validation ++++ ++++- PASS: Current branch is PR_26177_OWNER_007-project-instructions-single-source-eod-lock. ++++- PASS: Work remained on the PR branch during implementation. ++++- PASS: No commit was made on main. ++++- PASS: No .vscode/settings.json change is staged or included. +++diff --git a/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_manual-validation-notes.md b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_manual-validation-notes.md +++new file mode 100644 +++index 000000000..5d9f186fa +++--- /dev/null ++++++ b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_manual-validation-notes.md +++@@ -0,0 +1,9 @@ ++++# PR_26177_OWNER_007-project-instructions-single-source-eod-lock Manual Validation Notes ++++ ++++- Reviewed active ProjectInstructions branch lifecycle wording. ++++- Confirmed START RULE, WORK RULE, and END RULE are documented in active governance docs. ++++- Confirmed active source declarations live under docs_build/dev/ProjectInstructions/. ++++- Confirmed legacy locations remain deprecated reference material rather than active sources. ++++- Confirmed docs_build/dev/start_of_day/ was not modified. ++++- Confirmed no product/runtime files were modified. ++++- Confirmed ZIP artifact path: tmp/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_delta.zip. +++diff --git a/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_requirement-checklist.md b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_requirement-checklist.md +++new file mode 100644 +++index 000000000..c3c7e7c53 +++--- /dev/null ++++++ b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_requirement-checklist.md +++@@ -0,0 +1,20 @@ ++++# PR_26177_OWNER_007-project-instructions-single-source-eod-lock Requirement Checklist ++++ ++++- PASS: Audited repo for ProjectInstructions / project instructions duplicates. ++++- PASS: Active source is docs_build/dev/ProjectInstructions/. ++++- PASS: Legacy docs_build/dev/PROJECT_INSTRUCTIONS.md is marked deprecated. ++++- PASS: Legacy root project-instructions/ folder is marked deprecated. ++++- PASS: Legacy root addendums are migrated into the active addendum tree. ++++- PASS: Active team start/governance docs reference only docs_build/dev/ProjectInstructions/. ++++- PASS: Added EOD command sequence. ++++- PASS: Added required EOD output: On branch main, clean worktree, 0 0. ++++- PASS: Added Next Day Start command sequence. ++++- PASS: Added team branch creation rule requiring main, clean worktree, 0 0, and matching published EOD SHA. ++++- PASS: Added START RULE with main clean/synced/EOD SHA gate and no commits on main. ++++- PASS: Added WORK RULE requiring Codex to remain, commit, and push only on the PR branch. ++++- PASS: Added hard stops for unexpected branch changes and current branch main before commit. ++++- PASS: Added END RULE requiring PR branch push, merge to main, main checkout/fetch/pull, clean 0 0 confirmation, and EOD SHA recording. ++++- PASS: Did not modify start_of_day folders. ++++- PASS: Did not modify product/runtime files. ++++- PASS: Did not remove, move, or overwrite legacy SQLite files. ++++- PASS: Did not start feature work. +++diff --git a/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_validation-lane.md b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_validation-lane.md +++new file mode 100644 +++index 000000000..6e30ad6f6 +++--- /dev/null ++++++ b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_validation-lane.md +++@@ -0,0 +1,19 @@ ++++# PR_26177_OWNER_007-project-instructions-single-source-eod-lock Validation Lane ++++ ++++- PASS: duplicate-source grep returned no matches for old active source claims. ++++- PASS: EOD/Next Day governance grep returned active governance matches. ++++- PASS: branch lifecycle grep returned active START / WORK / END governance matches. ++++- PASS: product/runtime/start_of_day changed-file check returned no files. ++++- PASS: git diff --check. ++++ ++++Commands used: ++++ ++++~~~text ++++rg -n 'project-instructions/addendums|docs_build/dev/PROJECT_INSTRUCTIONS.md.*source of truth|Codex must always read `docs_build/dev/PROJECT_INSTRUCTIONS.md`|Read `docs_build/dev/PROJECT_INSTRUCTIONS.md`' docs_build/dev/ProjectInstructions docs_build/dev/PROJECT_INSTRUCTIONS.md project-instructions ++++rg -n 'START RULE|WORK RULE|END RULE|HARD STOP before committing|Codex commits only to the PR branch|Codex pushes only the PR branch|HEAD SHA recorded as new EOD baseline|No commits are allowed on `main`' docs_build/dev/ProjectInstructions ++++rg -n "End of Day:|Next Day Start:|HEAD.*published EOD SHA|only active Project Instructions source" docs_build/dev/ProjectInstructions ++++git diff --name-only -- src assets toolbox games api serverside package.json package-lock.json docs_build/dev/start_of_day ++++git diff --check ++++~~~ ++++ ++++Full product/runtime tests were not run because this PR changes governance documentation only. +++diff --git a/docs_build/dev/reports/codex_changed_files.txt b/docs_build/dev/reports/codex_changed_files.txt +++index 8e34972a1..85beb7824 100644 +++--- a/docs_build/dev/reports/codex_changed_files.txt ++++++ b/docs_build/dev/reports/codex_changed_files.txt +++@@ -1,14 +1,30 @@ +++-docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_branch-validation.md +++-docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_manual-validation-notes.md +++-docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_report.md +++-docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_requirement-checklist.md +++-docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_validation-lane.md ++++docs_build/dev/BUILD_PR.md ++++docs_build/dev/PLAN_PR.md ++++docs_build/dev/PROJECT_INSTRUCTIONS.md ++++docs_build/dev/ProjectInstructions/PROJECT_INSTRUCTIONS.md ++++docs_build/dev/ProjectInstructions/README.txt ++++docs_build/dev/ProjectInstructions/TEAM_START_COMMANDS.md ++++docs_build/dev/ProjectInstructions/addendums/assistant_execution_modes.md ++++docs_build/dev/ProjectInstructions/addendums/branch_lock_governance.md ++++docs_build/dev/ProjectInstructions/addendums/canonical_repository_structure.md ++++docs_build/dev/ProjectInstructions/addendums/codex_artifact_and_reporting_standard.md ++++docs_build/dev/ProjectInstructions/addendums/codex_project_instructions_startup.md ++++docs_build/dev/ProjectInstructions/addendums/legacy_migration_policy.md ++++docs_build/dev/ProjectInstructions/addendums/pr_workflow.md ++++docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md ++++docs_build/dev/ProjectInstructions/addendums/test_structure_standardization.md ++++docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md ++++docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock.md ++++docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_branch-validation.md ++++docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_manual-validation-notes.md ++++docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_requirement-checklist.md ++++docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_validation-lane.md +++ docs_build/dev/reports/codex_changed_files.txt +++ docs_build/dev/reports/codex_review.diff +++-src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs +++-src/dev-runtime/persistence/tool-repositories/game-journey-mock-repository.js +++-src/dev-runtime/server/local-api-router.mjs +++-tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs +++-tests/helpers/playwrightRepoServer.mjs +++-tests/playwright/tools/GameJourneyTool.spec.mjs +++-tests/playwright/tools/IdeaBoardTableNotes.spec.mjs ++++project-instructions/README.md ++++project-instructions/addendums/assistant-execution-modes.md ++++project-instructions/addendums/canonical-repository-structure.md ++++project-instructions/addendums/codex-artifact-and-reporting-standard.md ++++project-instructions/addendums/codex-project-instructions-startup.md ++++project-instructions/addendums/legacy-migration-policy.md ++++project-instructions/addendums/test-structure-standardization.md +++diff --git a/docs_build/dev/reports/codex_review.diff b/docs_build/dev/reports/codex_review.diff +++index f88731273..53132b823 100644 +++--- a/docs_build/dev/reports/codex_review.diff ++++++ b/docs_build/dev/reports/codex_review.diff +++@@ -1,465 +1,1168 @@ +++-diff --git a/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_branch-validation.md b/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_branch-validation.md +++-index c5ced6d1b..53bc243c2 100644 +++---- a/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_branch-validation.md +++-+++ b/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_branch-validation.md +++-@@ -17,3 +17,4 @@ Status: PASS +++- - PASS: Tests are limited to targeted Game Journey completion metrics regression coverage. +++- - PASS: Did not delete, move, overwrite, export, or migrate `tmp/local-api/game-journey-completion-metrics.sqlite`. +++- - PASS: Did not start Alfa Tags PRs. +++-+- PASS: Final audit removed active runtime JS/MJS SQLite and `tmp/local-api` references outside the migration-only utility. +++-diff --git a/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_manual-validation-notes.md b/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_manual-validation-notes.md +++-index 9a952fb7b..6dad6bb08 100644 +++---- a/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_manual-validation-notes.md +++-+++ b/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_manual-validation-notes.md +++-@@ -5,9 +5,10 @@ Status: PASS +++- ## Notes ++ - ++--export function classifyLegacyCompletionMetricRows({ existingRows = [], legacyRows = [] } = {}) { ++-- const existingByKey = new Map(existingRows.map((row) => [String(row.key || ""), row])); ++-- const existingByBucketKey = new Map(existingRows.map((row) => [String(row.bucketKey || ""), row])); ++-- const duplicates = []; ++-- const conflicts = []; ++-- const inserts = []; ++-- const timestampPatches = []; ++-- legacyRows.forEach((legacyRow) => { ++-- const existing = existingByKey.get(legacyRow.key) || existingByBucketKey.get(legacyRow.bucketKey); ++-- if (!existing) { ++-- inserts.push(legacyRow); ++-- return; ++-- } ++-- if (rowsMatch(legacyRow, existing)) { ++-- duplicates.push({ ++-- bucketKey: legacyRow.bucketKey, ++-- key: legacyRow.key, ++-- reason: "already present in Postgres with matching data", ++-- }); ++-- return; ++-- } ++-- const diffs = differingColumns(legacyRow, existing); ++-- if (diffs.every((column) => column === "createdAt" || column === "updatedAt")) { ++-- timestampPatches.push({ ++-- bucketKey: legacyRow.bucketKey, ++-- createdAt: legacyRow.createdAt, ++-- key: legacyRow.key, ++-- reason: "Postgres row matched legacy data except timestamps; preserving legacy createdAt/updatedAt.", ++-- updatedAt: legacyRow.updatedAt, ++-- }); ++-- return; ++-- } ++-- conflicts.push({ ++-- bucketKey: legacyRow.bucketKey, ++-- existingKey: String(existing.key || ""), ++-- key: legacyRow.key, ++-- reason: `Postgres already contains a different row for this key or bucketKey (${diffs.join(", ")} differ).`, ++-- }); ++-- }); ++-- return { conflicts, duplicates, inserts, timestampPatches }; ++--} +++- - Confirmed the repo-local `tmp/local-api/game-journey-completion-metrics.sqlite` file exists before validation. +++--- Confirmed active `createGameJourneyCompletionMetricsStore({ postgresClient })` no longer resolves that retired path by default. +++--- Confirmed active metrics load 14 Postgres-backed completion buckets while the retired file remains untouched. +++--- Confirmed explicit `legacyDbPath` protection remains covered by the existing migration/regression test file. +++-+- Confirmed active `createGameJourneyCompletionMetricsStore({ postgresClient })` exposes no `legacyDbPath`. +++-+- Confirmed active metrics snapshots expose no `legacySqlitePath`. +++-+- Confirmed active metrics load 14 DB-backed completion buckets while the retired file remains untouched. +++-+- Confirmed active runtime JS/MJS has no SQLite or `tmp/local-api` metrics references outside the migration-only utility. +++- - Confirmed the toolbox page renders neutral Creator-facing outage wording when active metrics are unavailable. +++- - Confirmed the toolbox page does not render the forbidden warning string, SQLite wording, `tmp/local-api`, or Postgres internals in the simulated outage lane. +++- - Confirmed no Alfa Tags PR work was started. +++-diff --git a/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_report.md b/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_report.md +++-index 1940890cf..777642b00 100644 +++---- a/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_report.md +++-+++ b/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_report.md +++-@@ -11,9 +11,10 @@ Recover the Game Journey completion metrics path so active Alfa and Owner work n +++- ## Implementation Summary ++ - ++--function spawnPythonExport({ legacyDbPath, pythonCommand }) { ++-- return new Promise((resolve, reject) => { ++-- const child = spawn(pythonCommand, ["-", legacyDbPath], { ++-- stdio: ["pipe", "pipe", "pipe"], ++-- windowsHide: true, ++-- }); ++-- let stdout = ""; ++-- let stderr = ""; ++-- child.stdout.setEncoding("utf8"); ++-- child.stderr.setEncoding("utf8"); ++-- child.stdout.on("data", (chunk) => { ++-- stdout += chunk; ++-- }); ++-- child.stderr.on("data", (chunk) => { ++-- stderr += chunk; ++-- }); ++-- child.once("error", reject); ++-- child.once("close", (code) => { ++-- if (code === 0) { ++-- resolve(stdout); ++-- return; ++-- } ++-- reject(new GameJourneyCompletionMetricsMigrationError( ++-- `Python SQLite export failed with exit code ${code}. ${stderr.trim()}`, ++-- { stderr: stderr.trim() }, ++-- )); ++-- }); ++-- child.stdin.end(PYTHON_SQLITE_EXPORT_SCRIPT); ++-- }); ++--} +++- - Removed active runtime defaulting to `tmp/local-api/game-journey-completion-metrics.sqlite` in `createGameJourneyCompletionMetricsStore`. +++--- Kept the explicit `legacyDbPath` guard intact for recovery/migration callers so legacy data is still protected from silent overwrite or deletion. +++-+- Removed active runtime `legacyDbPath` guard plumbing from the Game Journey metrics store, repository, Local API router, and Playwright test server helper. +++- - Updated `toolbox/tools-page-accordions.js` to render neutral Creator-safe progress outage wording instead of backend diagnostics. +++--- Added a store-level regression test proving a retired default SQLite-shaped file does not block active Postgres-backed metrics. +++-+- Added a store-level regression test proving a retired default SQLite-shaped file does not block or get touched by active DB-backed metrics. +++-+- Added a targeted guardrail test proving active runtime JS/MJS under `src`, `assets`, and `toolbox` has no SQLite or `tmp/local-api` metrics references, excluding the migration-only utility. +++- - Added a focused Playwright test proving the toolbox page does not render the forbidden warning, SQLite wording, local filesystem path, or Postgres internals when metrics are unavailable. ++ - ++--export async function readLegacyCompletionMetricsSqlite({ legacyDbPath, pythonCommand = "python" } = {}) { ++-- const resolvedPath = path.resolve(legacyDbPath || DEFAULT_GAME_JOURNEY_COMPLETION_METRICS_SQLITE_PATH); ++-- if (!existsSync(resolvedPath)) { ++-- throw new GameJourneyCompletionMetricsMigrationError(`Legacy SQLite file was not found: ${resolvedPath}.`); ++-- } ++-- const stdout = await spawnPythonExport({ legacyDbPath: resolvedPath, pythonCommand }); ++-- let exported; ++-- try { ++-- exported = JSON.parse(stdout); ++-- } catch (error) { ++-- throw new GameJourneyCompletionMetricsMigrationError( ++-- `Python SQLite export did not return valid JSON: ${error instanceof Error ? error.message : String(error)}.`, ++-- ); ++-- } ++-- validateLegacySchema(exported); ++-- const rows = (exported.rows || []).map(normalizeLegacyCompletionMetric); ++-- assertUniqueLegacyRows(rows); ++-- return { ++-- legacyDbPath: resolvedPath, ++-- rowCount: rows.length, ++-- rows, ++-- schema: exported.schema, ++-- }; ++--} +++- ## Reference Comparison +++-@@ -28,16 +29,20 @@ Recover the Game Journey completion metrics path so active Alfa and Owner work n +++- - PASS: `node --check` on modified source and test files. +++- - PASS: `node ./scripts/run-node-test-files.mjs tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs tests/dev-runtime/GameJourneyCompletionMetricsMigration.test.mjs`. +++- - PASS: `npx playwright test tests/playwright/tools/GameJourneyTool.spec.mjs --project=playwright --workers=1 --reporter=line -g "Game Journey Local API persists completion metrics to Postgres|Toolbox renders Creator-safe Game Journey progress outage copy"`. +++--- PASS: Direct proof against the actual existing `tmp/local-api/game-journey-completion-metrics.sqlite` file confirmed active Postgres metrics load 14 buckets and do not resolve a legacy path. +++--- PASS: Runtime source search found no `Game Journey completion metrics unavailable` string. +++--- PASS: Runtime source search found no active metrics-store default reference to `game-journey-completion-metrics.sqlite`, `GAMEFOUNDRY_GAME_JOURNEY_METRICS_DB_PATH`, or `defaultLegacySqlitePath`. +++-+- PASS: Direct proof against the actual existing `tmp/local-api/game-journey-completion-metrics.sqlite` file confirmed active DB metrics load 14 buckets, expose no legacy path fields, and do not touch the retired file. +++-+- PASS: Active runtime JS/MJS search found no SQLite, `.sqlite`, `better-sqlite`, `game-journey-completion-metrics.sqlite`, or `tmp/local-api` references outside the migration-only utility. +++-+- PASS: Runtime source search found no `Game Journey completion metrics unavailable` Creator-facing string. +++- - PASS: `git diff --check` reported no whitespace errors. Git emitted line-ending warnings only. ++ - ++--async function nextArchivePath({ archiveDir, legacyDbPath, now = new Date() }) { ++-- await fs.mkdir(archiveDir, { recursive: true }); ++-- const parsed = path.parse(legacyDbPath); ++-- const stamp = now.toISOString().replace(/[-:]/g, "").replace(/\.\d{3}Z$/, "Z"); ++-- for (let index = 0; index < 100; index += 1) { ++-- const suffix = index === 0 ? "" : `-${index + 1}`; ++-- const candidate = path.join(archiveDir, `${parsed.name}-${stamp}${suffix}${parsed.ext || ".sqlite"}`); ++-- if (!existsSync(candidate)) { ++-- return candidate; ++-- } ++-- } ++-- throw new GameJourneyCompletionMetricsMigrationError(`Could not allocate archive path in ${archiveDir}.`); ++--} +++- ## Files ++ - ++--export async function archiveLegacyCompletionMetricsSqlite({ archiveDir, legacyDbPath, now = new Date() } = {}) { ++-- const resolvedLegacyPath = path.resolve(legacyDbPath || DEFAULT_GAME_JOURNEY_COMPLETION_METRICS_SQLITE_PATH); ++-- const resolvedArchiveDir = path.resolve(archiveDir || DEFAULT_GAME_JOURNEY_COMPLETION_METRICS_ARCHIVE_DIR); ++-- if (!existsSync(resolvedLegacyPath)) { ++-- return { ++-- archived: false, ++-- archivePath: "", ++-- legacyDbPath: resolvedLegacyPath, ++-- message: "Legacy SQLite file was already absent.", ++-- }; ++-- } ++-- const archivePath = await nextArchivePath({ ++-- archiveDir: resolvedArchiveDir, ++-- legacyDbPath: resolvedLegacyPath, ++-- now, ++-- }); ++-- await fs.rename(resolvedLegacyPath, archivePath); ++-- return { ++-- archived: true, ++-- archivePath, ++-- legacyDbPath: resolvedLegacyPath, ++-- message: `Legacy SQLite file moved to ${archivePath}.`, ++-- }; ++--} +++- - `src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs` +++-+- `src/dev-runtime/persistence/tool-repositories/game-journey-mock-repository.js` +++-+- `src/dev-runtime/server/local-api-router.mjs` +++- - `tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs` +++-+- `tests/helpers/playwrightRepoServer.mjs` +++- - `tests/playwright/tools/GameJourneyTool.spec.mjs` +++-+- `tests/playwright/tools/IdeaBoardTableNotes.spec.mjs` +++- - `toolbox/tools-page-accordions.js` ++ - ++--export async function migrateLegacyCompletionMetricRowsToPostgres({ ++-- archiveDir, ++-- dryRun = false, ++-- env = process.env, ++-- legacyDbPath, ++-- now = new Date(), ++-- postgresClient = null, ++-- rows = [], ++--} = {}) { ++-- const legacyRows = rows.map(normalizeLegacyCompletionMetric); ++-- assertUniqueLegacyRows(legacyRows); ++-- const client = postgresClient || createPostgresConnectionClient({ env }); ++-- await client.query(GAME_JOURNEY_COMPLETION_METRICS_SCHEMA_SQL); ++-- const existingRows = await client.requestTable(GAME_JOURNEY_COMPLETION_METRICS_TABLE, { ++-- method: "GET", ++-- query: "select=*", ++-- }); ++-- const classified = classifyLegacyCompletionMetricRows({ ++-- existingRows: Array.isArray(existingRows) ? existingRows : [], ++-- legacyRows, ++-- }); ++-- if (classified.conflicts.length) { ++-- throw new GameJourneyCompletionMetricsMigrationError( ++-- `Game Journey completion metrics migration blocked by ${classified.conflicts.length} Postgres conflict(s). No data was moved.`, ++-- { conflicts: classified.conflicts }, ++-- ); ++-- } ++-- if (!dryRun && classified.inserts.length) { ++-- await client.requestTable(GAME_JOURNEY_COMPLETION_METRICS_TABLE, { ++-- body: classified.inserts, ++-- method: "POST", ++-- query: "on_conflict=key", ++-- }); ++-- } ++-- if (!dryRun) { ++-- for (const patch of classified.timestampPatches) { ++-- await client.requestTable(GAME_JOURNEY_COMPLETION_METRICS_TABLE, { ++-- body: { ++-- createdAt: patch.createdAt, ++-- updatedAt: patch.updatedAt, ++-- }, ++-- method: "PATCH", ++-- query: `bucketKey=eq.${encodeURIComponent(patch.bucketKey)}`, ++-- }); ++-- } ++-- } ++-- const archive = dryRun ++-- ? { ++-- archived: false, ++-- archivePath: "", ++-- legacyDbPath: path.resolve(legacyDbPath || DEFAULT_GAME_JOURNEY_COMPLETION_METRICS_SQLITE_PATH), ++-- message: "Dry run did not move the legacy SQLite file.", ++-- } ++-- : await archiveLegacyCompletionMetricsSqlite({ archiveDir, legacyDbPath, now }); ++-- return { ++-- archive, ++-- duplicateCount: classified.duplicates.length, ++-- duplicates: classified.duplicates, ++-- insertedCount: dryRun ? 0 : classified.inserts.length, ++-- legacyRowCount: legacyRows.length, ++-- status: dryRun ? "DRY_RUN" : "PASS", ++-- timestampPatchCount: dryRun ? 0 : classified.timestampPatches.length, ++-- timestampPatches: classified.timestampPatches, ++-- wouldInsertCount: classified.inserts.length, ++-- wouldPatchTimestampCount: classified.timestampPatches.length, ++-- }; ++--} +++- ## Artifact +++-diff --git a/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_requirement-checklist.md b/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_requirement-checklist.md +++-index 544b7057f..65a654b6d 100644 +++---- a/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_requirement-checklist.md +++-+++ b/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_requirement-checklist.md +++-@@ -11,12 +11,14 @@ Status: PASS +++- - PASS: Fixed only the Game Journey completion metrics regression. +++- - PASS: Did not delete, move, overwrite, export, or migrate `tmp/local-api/game-journey-completion-metrics.sqlite`. +++- - PASS: Stopped active runtime from defaulting to `tmp/local-api/game-journey-completion-metrics.sqlite`. +++-+- PASS: Removed active runtime `legacyDbPath` SQLite guard plumbing. +++- - PASS: Preserved Postgres-backed Game Journey completion metrics as the active path. +++- - PASS: Ensured `toolbox/tools-page-accordions.js` cannot render `Game Journey completion metrics unavailable:`. +++- - PASS: Creator-facing UI does not expose SQLite, local filesystem paths, migration/export language, or Postgres internals. +++- - PASS: Did not introduce silent fallback behavior; metrics outage remains visible with neutral wording. +++- - PASS: Added targeted regression tests. +++- - PASS: Proved the existing legacy SQLite file does not block active metrics. +++-+- PASS: Proved active runtime JS/MJS has no SQLite or `tmp/local-api` metrics references outside the migration-only utility. +++- - PASS: Proved the forbidden warning string is not rendered. +++- - PASS: Proved Game Journey metrics still load through the active DB/API path. +++- - PASS: Used targeted validation only. +++-diff --git a/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_validation-lane.md b/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_validation-lane.md +++-index fe5ba4768..47530c453 100644 +++---- a/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_validation-lane.md +++-+++ b/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_validation-lane.md +++-@@ -6,9 +6,13 @@ Status: PASS ++++diff --git a/docs_build/dev/BUILD_PR.md b/docs_build/dev/BUILD_PR.md ++++index 30700e9cd..50b1b27fa 100644 ++++--- a/docs_build/dev/BUILD_PR.md +++++++ b/docs_build/dev/BUILD_PR.md ++++@@ -1,66 +1,52 @@ ++++-# PR_26177_006-shared-time-foundation +++++# PR_26177_OWNER_007-project-instructions-single-source-eod-lock +++ +++- ```powershell +++- node --check src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs +++-+node --check src/dev-runtime/persistence/tool-repositories/game-journey-mock-repository.js +++-+node --check src/dev-runtime/server/local-api-router.mjs +++- node --check toolbox/tools-page-accordions.js +++- node --check tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs +++-+node --check tests/helpers/playwrightRepoServer.mjs +++- node --check tests/playwright/tools/GameJourneyTool.spec.mjs +++-+node --check tests/playwright/tools/IdeaBoardTableNotes.spec.mjs +++- ``` ++++ ## Purpose +++ +++- Result: PASS +++-@@ -17,7 +21,7 @@ Result: PASS +++- node ./scripts/run-node-test-files.mjs tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs tests/dev-runtime/GameJourneyCompletionMetricsMigration.test.mjs +++- ``` ++++-Add a small shared time foundation. +++++Make `docs_build/dev/ProjectInstructions/` the only active Project Instructions source and add EOD main lock plus next-day reset governance. +++ +++--Result: PASS, 2 targeted node test files passed +++-+Result: PASS, 2 targeted node test files passed. Includes active runtime JS/MJS SQLite reference guardrail. ++++ ## Source Of Truth +++ +++- ```powershell +++- npx playwright test tests/playwright/tools/GameJourneyTool.spec.mjs --project=playwright --workers=1 --reporter=line -g "Game Journey Local API persists completion metrics to Postgres|Toolbox renders Creator-safe Game Journey progress outage copy" +++-@@ -26,14 +30,14 @@ npx playwright test tests/playwright/tools/GameJourneyTool.spec.mjs --project=pl +++- Result: PASS, 2 passed ++++-This `BUILD_PR.md`, `PLAN_PR.md`, and the user request are the source of truth for `PR_26177_006-shared-time-foundation`. ++++- ++++-## Stack ++++- ++++-- Base branch: `PR_26177_005-shared-text-foundation` +++++This `BUILD_PR.md`, `PLAN_PR.md`, and the user request are the source of truth for `PR_26177_OWNER_007-project-instructions-single-source-eod-lock`. ++++ ++++ ## Exact Scope ++++ ++++-- Add `src/shared/time/` foundation. ++++-- Include duration formatting, timestamp helpers, debounce/throttle/sleep helpers where safe for shared runtime. ++++-- Add targeted tests for the shared time area. ++++-- No scheduler/runtime behavior changes. ++++-- Create required Codex reports under `docs_build/dev/reports/`. ++++-- Create repo-structured delta ZIP under `tmp/`. +++++- Audit repo for ProjectInstructions / project instructions duplicates. +++++- Establish `docs_build/dev/ProjectInstructions/` as the only active source. +++++- Mark all other ProjectInstructions-style sources changed by this PR as deprecated references. +++++- Update active team start/governance docs to reference only `docs_build/dev/ProjectInstructions/`. +++++- Add EOD main lock and next-day reset governance. +++++- Add required reports under `docs_build/dev/reports/`. ++++ ++++ ## Exact Targets ++++ ++++ - `docs_build/dev/PLAN_PR.md` ++++ - `docs_build/dev/BUILD_PR.md` ++++-- `src/shared/time/time.js` ++++-- `tests/shared/TimeFoundation.test.mjs` ++++-- `docs_build/dev/reports/PR_26177_006-shared-time-foundation.md` ++++-- `docs_build/dev/reports/PR_26177_006-shared-time-foundation_branch-validation.md` ++++-- `docs_build/dev/reports/PR_26177_006-shared-time-foundation_requirement-checklist.md` ++++-- `docs_build/dev/reports/PR_26177_006-shared-time-foundation_validation-lane.md` ++++-- `docs_build/dev/reports/PR_26177_006-shared-time-foundation_manual-validation-notes.md` +++++- `docs_build/dev/PROJECT_INSTRUCTIONS.md` +++++- `docs_build/dev/ProjectInstructions/README.txt` +++++- `docs_build/dev/ProjectInstructions/PROJECT_INSTRUCTIONS.md` +++++- `docs_build/dev/ProjectInstructions/TEAM_START_COMMANDS.md` +++++- `docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md` +++++- `docs_build/dev/ProjectInstructions/addendums/*.md` +++++- `project-instructions/README.md` +++++- `project-instructions/addendums/*.md` +++++- `docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock*.md` ++++ - `docs_build/dev/reports/codex_review.diff` ++++ - `docs_build/dev/reports/codex_changed_files.txt` ++++ ++++ ## Out Of Scope ++++ ++++-- No scheduler/runtime behavior changes. ++++-- No browser-owned product data. ++++-- No runtime UI changes. ++++-- No browser storage changes. ++++-- No API/database changes. ++++-- No `start_of_day` folder changes. ++++-- No unrelated cleanup. ++++-- No full samples smoke by default. +++++- No product/runtime changes. +++++- No feature work. +++++- No `start_of_day` changes. +++++- No legacy SQLite file changes. ++++ ++++ ## Validation ++++ ++++-Run exactly: +++++Run: +++ +++ ```powershell +++--node -e "import('node:fs').then(async fs=>{const [{createGameJourneyCompletionMetricsStore}, {createGameJourneyCompletionMetricsPostgresClientStub}] = await Promise.all([import('./src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs'), import('./tests/helpers/gameJourneyCompletionMetricsPostgresClientStub.mjs')]); const legacy='tmp/local-api/game-journey-completion-metrics.sqlite'; if(!fs.existsSync(legacy)) throw new Error('Expected existing legacy SQLite file for regression proof'); const store=createGameJourneyCompletionMetricsStore({postgresClient:createGameJourneyCompletionMetricsPostgresClientStub()}); const metrics=await store.listMetrics(); if(store.legacyDbPath) throw new Error('Active store resolved a legacy path'); if(metrics.length!==14) throw new Error('Expected 14 active metrics'); console.log('PASS active Postgres metrics ignore existing retired legacy SQLite file');})" +++-+node -e "import('node:fs').then(async fs=>{const [{createGameJourneyCompletionMetricsStore}, {createGameJourneyCompletionMetricsPostgresClientStub}] = await Promise.all([import('./src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs'), import('./tests/helpers/gameJourneyCompletionMetricsPostgresClientStub.mjs')]); const legacy='tmp/local-api/game-journey-completion-metrics.sqlite'; if(!fs.existsSync(legacy)) throw new Error('Expected existing retired local file for regression proof'); const before=fs.statSync(legacy).mtimeMs; const store=createGameJourneyCompletionMetricsStore({postgresClient:createGameJourneyCompletionMetricsPostgresClientStub()}); const metrics=await store.listMetrics(); const snapshot=await store.snapshot(); const after=fs.statSync(legacy).mtimeMs; if(Object.hasOwn(store, 'legacyDbPath')) throw new Error('Store exposes legacyDbPath'); if(Object.hasOwn(snapshot, 'legacySqlitePath')) throw new Error('Snapshot exposes legacySqlitePath'); if(metrics.length!==14) throw new Error('Expected 14 active metrics'); if(before!==after) throw new Error('Retired local file was touched'); console.log('PASS active DB metrics ignore and do not inspect retired local file');})" ++++-node ./scripts/run-node-test-files.mjs tests/shared/TimeFoundation.test.mjs ++++-node --check src/shared/time/time.js ++++-node --check tests/shared/TimeFoundation.test.mjs +++++rg -n 'project-instructions/addendums|docs_build/dev/PROJECT_INSTRUCTIONS.md.*source of truth|Codex must always read `docs_build/dev/PROJECT_INSTRUCTIONS.md`|Read `docs_build/dev/PROJECT_INSTRUCTIONS.md`' docs_build/dev/ProjectInstructions docs_build/dev/PROJECT_INSTRUCTIONS.md project-instructions +++++rg -n "End of Day:|Next Day Start:|HEAD.*published EOD SHA|only active Project Instructions source" docs_build/dev/ProjectInstructions +++++git diff --name-only -- src assets toolbox games api serverside package.json package-lock.json docs_build/dev/start_of_day ++++ git diff --check +++ ``` ++++- ++++-## Artifact ++++- ++++-Create repo-structured delta ZIP: ++++- ++++-```text ++++-tmp/PR_26177_006-shared-time-foundation_delta.zip ++++-``` ++++diff --git a/docs_build/dev/PLAN_PR.md b/docs_build/dev/PLAN_PR.md ++++index 907936aee..39fa03385 100644 ++++--- a/docs_build/dev/PLAN_PR.md +++++++ b/docs_build/dev/PLAN_PR.md ++++@@ -1,22 +1,28 @@ ++++-# PLAN_PR: PR_26177_006-shared-time-foundation +++++# PLAN_PR: PR_26177_OWNER_007-project-instructions-single-source-eod-lock +++ +++- Result: PASS ++++ ## Purpose +++ +++- ```powershell +++-+rg -n -i "sqlite|better-sqlite|game-journey-completion-metrics\.sqlite|tmp/local-api" src assets toolbox -g "*.js" -g "*.mjs" --glob "!src/dev-runtime/persistence/game-journey-completion-metrics-migration.mjs" +++- rg -n "Game Journey completion metrics unavailable" src assets toolbox --glob "!**/*.map" +++--rg -n "game-journey-completion-metrics\.sqlite|GAMEFOUNDRY_GAME_JOURNEY_METRICS_DB_PATH|defaultLegacySqlitePath" src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs toolbox/tools-page-accordions.js assets/toolbox/game-journey/js/index.js ++++-Add a small shared time foundation. +++++Make `docs_build/dev/ProjectInstructions/` the only active Project Instructions source and add EOD main lock plus next-day reset governance. ++++ ++++ ## Scope ++++ ++++-- Add `src/shared/time/` foundation. ++++-- Include duration formatting, timestamp helpers, sleep, debounce, and throttle helpers. ++++-- Add targeted tests. ++++-- No scheduler/runtime behavior changes. ++++-- No browser-owned product data. ++++-- No runtime UI changes. ++++-- No unrelated cleanup. +++++- Audit ProjectInstructions and project instructions duplicates. +++++- Mark legacy ProjectInstructions-style sources as deprecated reference material. +++++- Move active legacy addendums into `docs_build/dev/ProjectInstructions/addendums/`. +++++- Update active team start and governance docs to reference only `docs_build/dev/ProjectInstructions/`. +++++- Add EOD main lock, next-day reset, and team PR branch creation gate. +++++- Add required Codex reports under `docs_build/dev/reports/`. ++++ ++++-## Implementation Plan +++++## Out Of Scope ++++ ++++-1. Add `src/shared/time/time.js`. ++++-2. Add `tests/shared/TimeFoundation.test.mjs`. ++++-3. Validate duration, timestamp, sleep, debounce, and throttle helpers. ++++-4. Produce required Codex reports and repo-structured ZIP. +++++- No product/runtime changes. +++++- No feature work. +++++- No `start_of_day` changes. +++++- No legacy SQLite file changes. +++++ +++++## Validation Plan +++++ +++++1. Run targeted grep/search proving no active duplicate ProjectInstructions source remains. +++++2. Confirm EOD/Next Day rule appears in active governance docs. +++++3. Confirm no product/runtime files changed. +++++4. Run `git diff --check`. ++++diff --git a/docs_build/dev/PROJECT_INSTRUCTIONS.md b/docs_build/dev/PROJECT_INSTRUCTIONS.md ++++index af9e9e2db..c1136fdbe 100644 ++++--- a/docs_build/dev/PROJECT_INSTRUCTIONS.md +++++++ b/docs_build/dev/PROJECT_INSTRUCTIONS.md ++++@@ -1,5 +1,7 @@ ++++ # PROJECT INSTRUCTIONS ++++ +++++> Deprecated active-source notice: this file is preserved as historical reference only. The only active Project Instructions source is `docs_build/dev/ProjectInstructions/`. If this file conflicts with `docs_build/dev/ProjectInstructions/`, the active folder wins unless OWNER explicitly approves a newer governance change. +++++ ++++ You are working in a docs-first repo workflow. ++++ ++++ Workflow: ++++@@ -864,7 +866,7 @@ Controls must remain copy-friendly and human-readable. ++++ ++++ ### ChatGPT Workflow Governance Consistency ++++ ++++-ChatGPT repo workflow responses are governed by `docs_build/dev/PROJECT_INSTRUCTIONS.md` as the source of truth. +++++Deprecated note: this historical section no longer defines the active source of truth. ChatGPT repo workflow responses are governed by `docs_build/dev/ProjectInstructions/`. ++++ ++++ ChatGPT must not drift from the required response ordering. ++++ ++++@@ -1716,13 +1718,13 @@ Do not compact: ++++ ++++ Do not change JSON contracts or semantics while applying array formatting. ++++ ++++-## PROJECT INSTRUCTIONS LOCATION +++++## DEPRECATED PROJECT INSTRUCTIONS LOCATION ++++ ++++-PROJECT_INSTRUCTIONS.md lives at: +++++Historical PROJECT_INSTRUCTIONS.md is preserved at: ++++ ++++ `docs_build/dev/PROJECT_INSTRUCTIONS.md` ++++ ++++-Codex must always read `docs_build/dev/PROJECT_INSTRUCTIONS.md` from this path as the source of truth before executing repository workflow instructions. +++++This file is not the active source of truth. Codex must read `docs_build/dev/ProjectInstructions/README.txt` first and use `docs_build/dev/ProjectInstructions/` as the active Project Instructions source before executing repository workflow instructions. ++++ ++++ ## CODEX COMMAND FORMATTING RULE ++++ ++++@@ -2384,9 +2386,9 @@ Treat these files the same as existing instruction documents for read-set, revie ++++ Codex must run this gate before every PR execution and before any file changes. ++++ ++++ Required instruction reads: ++++-- Read `docs_build/dev/PROJECT_INSTRUCTIONS.md`. +++++- Read `docs_build/dev/ProjectInstructions/README.txt`. ++++ - Read `docs_build/dev/PROJECT_MULTI_PC.txt`. ++++-- Treat the newest applicable section in `PROJECT_INSTRUCTIONS.md` as authoritative when rules overlap. +++++- Treat the newest applicable section in `docs_build/dev/ProjectInstructions/` as authoritative when rules overlap. ++++ - Treat the current team ownership section in `PROJECT_MULTI_PC.txt` as authoritative for TEAM routing. ++++ ++++ Required pre-change report: ++++diff --git a/docs_build/dev/ProjectInstructions/PROJECT_INSTRUCTIONS.md b/docs_build/dev/ProjectInstructions/PROJECT_INSTRUCTIONS.md ++++index d2a84ecbe..99ddd0f42 100644 ++++--- a/docs_build/dev/ProjectInstructions/PROJECT_INSTRUCTIONS.md +++++++ b/docs_build/dev/ProjectInstructions/PROJECT_INSTRUCTIONS.md ++++@@ -4,6 +4,12 @@ Read `README.txt` first. ++++ ++++ This file is the root index for the append-first Project Instructions operating system under `docs_build/dev/ProjectInstructions/`. ++++ +++++## Active Source +++++ +++++`docs_build/dev/ProjectInstructions/` is the only active Project Instructions source. +++++ +++++Historical Project Instructions material outside this folder is deprecated reference material only and must not be used as an active source of governance. +++++ ++++ ## Purpose ++++ ++++ The Project Instructions operating system provides additive governance for: ++++@@ -20,7 +26,7 @@ The Project Instructions operating system provides additive governance for: ++++ ++++ ## Preservation ++++ ++++-Existing Project Instructions remain preserved in their current locations. This operating system adds structure without deleting or rewriting existing documentation. +++++Existing Project Instructions outside `docs_build/dev/ProjectInstructions/` remain preserved only as deprecated reference material. When guidance conflicts, active files under `docs_build/dev/ProjectInstructions/` win unless OWNER explicitly approves a newer governance change. ++++ ++++ ## Folders ++++ ++++@@ -41,6 +47,10 @@ Existing Project Instructions remain preserved in their current locations. This ++++ ++++ `docs_build/dev/ProjectInstructions/addendums/environment_configuration_standards.md` defines official `.env` file names, environment variable values, host/domain configuration, API URL configuration, R2 prefix configuration, and feature flag governance. ++++ +++++## Single Source and Main Lock Governance +++++ +++++`docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md` defines the single active Project Instructions source, EOD main lock, next-day reset, and team branch creation gate. +++++ ++++ ## Merge Control ++++ ++++ No PR in this operating system is merged without explicit owner approval. ++++diff --git a/docs_build/dev/ProjectInstructions/README.txt b/docs_build/dev/ProjectInstructions/README.txt ++++index a48becf05..631fd3918 100644 ++++--- a/docs_build/dev/ProjectInstructions/README.txt +++++++ b/docs_build/dev/ProjectInstructions/README.txt ++++@@ -1,10 +1,10 @@ ++++ Read this file first. ++++ ++++ Folder purpose: ++++-This folder is the append-first Project Instructions operating system for Game Foundry Studio. It organizes active governance, backlog, team assignment, deprecation, and history material without deleting or rewriting the existing Project Instructions files elsewhere in the repository. +++++This folder is the only active Project Instructions source for Game Foundry Studio. It organizes active governance, backlog, team assignment, deprecation, and history material under `docs_build/dev/ProjectInstructions/`. ++++ ++++ Preservation rules: ++++-Preserve all existing documentation. Add new files or append explicit references unless the owner explicitly approves deletion or rewrite. When a conflict appears, stop, explain the conflict, and request owner approval before changing existing instruction text. +++++Preserve historical Project Instructions material as deprecated reference only. Do not treat `docs_build/dev/PROJECT_INSTRUCTIONS.md`, `project-instructions/`, or archived snapshots as active instruction sources. When a conflict appears, `docs_build/dev/ProjectInstructions/` wins unless OWNER explicitly approves a newer governance change. ++++ ++++ Backlog workflow: ++++ Backlog work is tracked under backlog/. BACKLOG_MASTER.md is the planned source for backlog item status, notes, and references. Backlog item text is treated as immutable once created; status and notes may change under the governance addendums. ++++@@ -29,9 +29,9 @@ Do not rewrite history snapshots after creation unless the owner explicitly appr ++++ ++++ READ THIS FIRST ++++ ++++-1. Read Project Instructions before making changes. ++++-2. Project Instructions are append-only. ++++-3. Existing approved guidance may not be removed. +++++1. Read `docs_build/dev/ProjectInstructions/README.txt` before making changes. +++++2. Treat `docs_build/dev/ProjectInstructions/` as the only active Project Instructions source. +++++3. Historical Project Instructions files outside this folder are deprecated references only. ++++ 4. Team ownership must be respected. ++++ 5. BACKLOG_MASTER.md is the authoritative backlog. ++++ 6. Build Path status derives from backlog status. ++++@@ -42,12 +42,13 @@ READ THIS FIRST ++++ 11. Batch Governance Mode is the default for governance, documentation, and administrative work. ++++ ++++ Addendum index: ++++-- Canonical Repository Structure: project-instructions/addendums/canonical-repository-structure.md ++++-- Test Structure Standardization: project-instructions/addendums/test-structure-standardization.md ++++-- Legacy Migration Policy: project-instructions/addendums/legacy-migration-policy.md ++++-- Assistant Execution Modes: project-instructions/addendums/assistant-execution-modes.md ++++-- Codex Artifact and Reporting Standard: project-instructions/addendums/codex-artifact-and-reporting-standard.md ++++-- Codex Project Instructions Startup: project-instructions/addendums/codex-project-instructions-startup.md +++++- Single Source and EOD Main Lock: docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md +++++- Canonical Repository Structure: docs_build/dev/ProjectInstructions/addendums/canonical_repository_structure.md +++++- Test Structure Standardization: docs_build/dev/ProjectInstructions/addendums/test_structure_standardization.md +++++- Legacy Migration Policy: docs_build/dev/ProjectInstructions/addendums/legacy_migration_policy.md +++++- Assistant Execution Modes: docs_build/dev/ProjectInstructions/addendums/assistant_execution_modes.md +++++- Codex Artifact and Reporting Standard: docs_build/dev/ProjectInstructions/addendums/codex_artifact_and_reporting_standard.md +++++- Codex Project Instructions Startup: docs_build/dev/ProjectInstructions/addendums/codex_project_instructions_startup.md ++++ - Project Reference Files Governance: docs_build/dev/ProjectInstructions/addendums/project_reference_files.md ++++ - Environment Governance Model: docs_build/dev/ProjectInstructions/addendums/environment_governance_model.md ++++ - Environment Configuration Standards: docs_build/dev/ProjectInstructions/addendums/environment_configuration_standards.md ++++diff --git a/docs_build/dev/ProjectInstructions/TEAM_START_COMMANDS.md b/docs_build/dev/ProjectInstructions/TEAM_START_COMMANDS.md ++++index d0118f63a..c446a4b33 100644 ++++--- a/docs_build/dev/ProjectInstructions/TEAM_START_COMMANDS.md +++++++ b/docs_build/dev/ProjectInstructions/TEAM_START_COMMANDS.md ++++@@ -1,5 +1,16 @@ ++++ # TEAM_START_COMMANDS ++++ +++++## Required Main Reset Gate For Every Team +++++ +++++No team creates a PR branch until all checks pass: +++++ +++++- Current branch: `main` +++++- Worktree: clean +++++- `main...origin/main`: `0 0` +++++- `HEAD` SHA matches the published EOD SHA +++++ +++++Use `docs_build/dev/ProjectInstructions/` as the only active Project Instructions source. +++++ ++++ ## Start Team Alfa ++++ ++++ Ready-to-copy command: ++++@@ -123,4 +134,24 @@ Merge to main is EOD-only and owner-approved, unless the owner explicitly says: ++++ "Merge this PR now." ++++ ++++ Do not treat sequential PR completion as merge approval. +++++ +++++End of Day: +++++git checkout main +++++git fetch origin +++++git pull --ff-only origin main +++++git status +++++git rev-list --left-right --count main...origin/main +++++ +++++Required: +++++On branch main +++++nothing to commit, working tree clean +++++0 0 +++++ +++++Next Day Start: +++++git checkout main +++++git fetch origin +++++git pull --ff-only origin main +++++git status +++++git rev-list --left-right --count main...origin/main +++++git rev-parse HEAD +++ ``` ++++diff --git a/docs_build/dev/ProjectInstructions/addendums/branch_lock_governance.md b/docs_build/dev/ProjectInstructions/addendums/branch_lock_governance.md ++++index 518f8c943..d6c8e4cf7 100644 ++++--- a/docs_build/dev/ProjectInstructions/addendums/branch_lock_governance.md +++++++ b/docs_build/dev/ProjectInstructions/addendums/branch_lock_governance.md ++++@@ -23,6 +23,7 @@ Keep active work attached to the correct assigned team, branch, and OWNER decisi +++ +++- Result: PASS, no matches ++++ - Start from current `main`. ++++ - Pull latest `origin/main` before creating a work branch. +++++- Do not create a PR branch unless current branch is `main`, worktree is clean, `main...origin/main` is `0 0`, and `HEAD` SHA matches the published EOD SHA. ++++ - Keep work on the active branch until the PR is merged, the branch is retired, or OWNER says to return to `main`. ++++ - Do not commit directly to `main` unless OWNER explicitly approves. ++++ - Do not merge stale historical branches directly unless they are current, clean, still needed, and OWNER-approved. ++++@@ -54,3 +55,36 @@ Protected guidance includes: ++++ - Governance Phase 1 completion guidance ++++ ++++ If protected guidance must change, OWNER approval is required. +++++ +++++## End Of Day Main Lock +++++ +++++End of Day: +++++ +++++```text +++++git checkout main +++++git fetch origin +++++git pull --ff-only origin main +++++git status +++++git rev-list --left-right --count main...origin/main +++++``` +++++ +++++Required: +++++ +++++```text +++++On branch main +++++nothing to commit, working tree clean +++++0 0 +++++``` +++++ +++++Next Day Start: +++++ +++++```text +++++git checkout main +++++git fetch origin +++++git pull --ff-only origin main +++++git status +++++git rev-list --left-right --count main...origin/main +++++git rev-parse HEAD +++++``` +++++ +++++The next-day `HEAD` SHA must match the published EOD SHA before any team creates a PR branch. ++++diff --git a/docs_build/dev/ProjectInstructions/addendums/pr_workflow.md b/docs_build/dev/ProjectInstructions/addendums/pr_workflow.md ++++index f8a4acb6e..7c1cd8275 100644 ++++--- a/docs_build/dev/ProjectInstructions/addendums/pr_workflow.md +++++++ b/docs_build/dev/ProjectInstructions/addendums/pr_workflow.md ++++@@ -129,3 +129,40 @@ Stop only for: ++++ - Merge conflict ++++ - Validation failure ++++ - OWNER decision +++++ +++++## EOD Main Lock +++++ +++++End of Day: +++++ +++++```text +++++git checkout main +++++git fetch origin +++++git pull --ff-only origin main +++++git status +++++git rev-list --left-right --count main...origin/main +++++``` +++++ +++++Required: +++++ +++++```text +++++On branch main +++++nothing to commit, working tree clean +++++0 0 +++++``` +++++ +++++## Next Day Start +++++ +++++```text +++++git checkout main +++++git fetch origin +++++git pull --ff-only origin main +++++git status +++++git rev-list --left-right --count main...origin/main +++++git rev-parse HEAD +++++``` +++++ +++++No team creates a PR branch until: +++++- Current branch: `main` +++++- Worktree: clean +++++- `main...origin/main`: `0 0` +++++- `HEAD` SHA matches published EOD SHA ++++diff --git a/docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md b/docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md ++++index 9735b4bd4..9a104b4f9 100644 ++++--- a/docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md +++++++ b/docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md ++++@@ -211,3 +211,44 @@ Commit/push during the day is allowed only on assigned team/OWNER/PR branches. ++++ ++++ Merge to main is EOD-only and owner-approved, unless the owner explicitly says: ++++ "Merge this PR now." +++++ +++++## EOD Main Lock And Next Day Reset +++++ +++++End of Day: +++++ +++++```text +++++git checkout main +++++git fetch origin +++++git pull --ff-only origin main +++++git status +++++git rev-list --left-right --count main...origin/main +++++``` +++++ +++++Required: +++++ +++++```text +++++On branch main +++++nothing to commit, working tree clean +++++0 0 +++++``` +++++ +++++Next Day Start: +++++ +++++```text +++++git checkout main +++++git fetch origin +++++git pull --ff-only origin main +++++git status +++++git rev-list --left-right --count main...origin/main +++++git rev-parse HEAD +++++``` +++++ +++++Team rule: +++++No team creates a PR branch until: +++++- Current branch: `main` +++++- Worktree: clean +++++- `main...origin/main`: `0 0` +++++- `HEAD` SHA matches published EOD SHA +++++ +++++Active source rule: +++++Teams must use only `docs_build/dev/ProjectInstructions/` as the active Project Instructions source. +++ diff --git a/docs_build/dev/reports/codex_changed_files.txt b/docs_build/dev/reports/codex_changed_files.txt +++-index 585a10850..8e34972a1 100644 ++++index 8e34972a1..85beb7824 100644 +++ --- a/docs_build/dev/reports/codex_changed_files.txt +++ +++ b/docs_build/dev/reports/codex_changed_files.txt +++-@@ -6,6 +6,9 @@ docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recove ++++@@ -1,14 +1,30 @@ ++++-docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_branch-validation.md ++++-docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_manual-validation-notes.md ++++-docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_report.md ++++-docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_requirement-checklist.md ++++-docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_validation-lane.md +++++docs_build/dev/BUILD_PR.md +++++docs_build/dev/PLAN_PR.md +++++docs_build/dev/PROJECT_INSTRUCTIONS.md +++++docs_build/dev/ProjectInstructions/PROJECT_INSTRUCTIONS.md +++++docs_build/dev/ProjectInstructions/README.txt +++++docs_build/dev/ProjectInstructions/TEAM_START_COMMANDS.md +++++docs_build/dev/ProjectInstructions/addendums/assistant_execution_modes.md +++++docs_build/dev/ProjectInstructions/addendums/branch_lock_governance.md +++++docs_build/dev/ProjectInstructions/addendums/canonical_repository_structure.md +++++docs_build/dev/ProjectInstructions/addendums/codex_artifact_and_reporting_standard.md +++++docs_build/dev/ProjectInstructions/addendums/codex_project_instructions_startup.md +++++docs_build/dev/ProjectInstructions/addendums/legacy_migration_policy.md +++++docs_build/dev/ProjectInstructions/addendums/pr_workflow.md +++++docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md +++++docs_build/dev/ProjectInstructions/addendums/test_structure_standardization.md +++++docs_build/dev/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md +++++docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock.md +++++docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_branch-validation.md +++++docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_manual-validation-notes.md +++++docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_requirement-checklist.md +++++docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_validation-lane.md +++ docs_build/dev/reports/codex_changed_files.txt +++ docs_build/dev/reports/codex_review.diff +++- src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs +++-+src/dev-runtime/persistence/tool-repositories/game-journey-mock-repository.js +++-+src/dev-runtime/server/local-api-router.mjs +++- tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs +++-+tests/helpers/playwrightRepoServer.mjs +++- tests/playwright/tools/GameJourneyTool.spec.mjs +++--toolbox/tools-page-accordions.js +++-+tests/playwright/tools/IdeaBoardTableNotes.spec.mjs +++-diff --git a/src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs b/src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs +++-index 6c202c8a2..eea6294e7 100644 +++---- a/src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs +++-+++ b/src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs +++-@@ -1,5 +1,3 @@ +++--import { existsSync } from "node:fs"; +++--import path from "node:path"; +++- import { createPostgresConnectionClient } from "./postgres-connection-client.mjs"; +++- import { SEED_DB_KEYS, makeSeedUlid } from "../seed/seed-db-keys.mjs"; ++ - ++--export async function migrateLegacyCompletionMetricsSqliteToPostgres({ ++-- archiveDir, ++-- dryRun = false, ++-- env = process.env, ++-- legacyDbPath, ++-- now = new Date(), ++-- postgresClient = null, ++-- pythonCommand = "python", ++--} = {}) { ++-- const exported = await readLegacyCompletionMetricsSqlite({ legacyDbPath, pythonCommand }); ++-- const result = await migrateLegacyCompletionMetricRowsToPostgres({ ++-- archiveDir, ++-- dryRun, ++-- env, ++-- legacyDbPath: exported.legacyDbPath, ++-- now, ++-- postgresClient, ++-- rows: exported.rows, ++-- }); ++-- return { ++-- ...result, ++-- legacyDbPath: exported.legacyDbPath, ++-- schemaObjectCount: exported.schema.objects.length, ++-- }; ++--} ++-diff --git a/tests/dev-runtime/GameJourneyCompletionMetricsMigration.test.mjs b/tests/dev-runtime/GameJourneyCompletionMetricsMigration.test.mjs ++-deleted file mode 100644 ++-index 6428e63e8..000000000 ++---- a/tests/dev-runtime/GameJourneyCompletionMetricsMigration.test.mjs ++-+++ /dev/null ++-@@ -1,194 +0,0 @@ ++--import assert from "node:assert/strict"; ++--import fs from "node:fs/promises"; ++--import os from "node:os"; ++--import path from "node:path"; ++--import test from "node:test"; ++--import { ++-- GAME_JOURNEY_COMPLETION_METRICS_TABLE, ++--} from "../../src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs"; ++--import { ++-- migrateLegacyCompletionMetricRowsToPostgres, ++--} from "../../src/dev-runtime/persistence/game-journey-completion-metrics-migration.mjs"; ++--import { createGameJourneyCompletionMetricsPostgresClientStub } from "../helpers/gameJourneyCompletionMetricsPostgresClientStub.mjs"; +++-@@ -59,24 +57,6 @@ function clone(value) { +++- return JSON.parse(JSON.stringify(value)); +++- } ++ - ++--const LEGACY_ROW = Object.freeze({ ++-- active: 1, ++-- bucketKey: "002-create", ++-- bucketName: "Create", ++-- bucketOrder: 2, ++-- canSkip: 0, ++-- completedCount: 3, ++-- createdAt: "2026-06-20T01:52:14.797Z", ++-- createdBy: "01K2GFSJ0Y0000000000000054", ++-- friendlyDescription: "Set up your game and crew", ++-- key: "01K2GFSJ0Y0000000000006002", ++-- plannedCount: 5, ++-- requiredForMvp: 1, ++-- status: "active", ++-- updatedAt: "2026-06-21T03:04:05.000Z", ++-- updatedBy: "01K2GFSJ0Y0000000000000054", ++--}); +++--function resolveLegacySqlitePath(legacyDbPath) { +++-- if (legacyDbPath === null || legacyDbPath === undefined) { +++-- return ""; +++-- } +++-- const value = String(legacyDbPath || "").trim(); +++-- if (!value) { +++-- return ""; +++-- } +++-- return path.resolve(value); +++--} +++-- +++--function assertNoUnmigratedLegacySqlite(legacyDbPath) { +++-- if (!legacyDbPath || !existsSync(legacyDbPath)) { +++-- return; +++-- } +++-- throw new Error(`Legacy Game Journey completion metrics SQLite data exists at ${legacyDbPath}. No data was removed or overwritten. Export or migrate that data into Postgres, then move the legacy file before using the Postgres metrics store.`); +++--} +++-- +++- function normalizeCount(value, fallback = 0) { +++- const parsed = Number(value); +++- if (!Number.isFinite(parsed)) { +++-@@ -158,7 +138,6 @@ function bucketSeedRow(bucket, now) { +++- export function createGameJourneyCompletionMetricsStore(options = {}) { +++- const env = options.env || process.env; +++- const bucketSeeds = Object.freeze((options.buckets || GAME_JOURNEY_COMPLETION_BUCKETS).map(clone)); +++-- const legacyDbPath = resolveLegacySqlitePath(options.legacyDbPath); +++- let postgresClient = options.postgresClient || null; +++- let readyPromise = null; ++ - ++--async function tempLegacyFile() { ++-- const directory = await fs.mkdtemp(path.join(os.tmpdir(), "gfs-game-journey-migration-")); ++-- const legacyDbPath = path.join(directory, "game-journey-completion-metrics.sqlite"); ++-- const archiveDir = path.join(directory, "legacy-migrated"); ++-- await fs.writeFile(legacyDbPath, "legacy sqlite placeholder"); ++-- return { archiveDir, directory, legacyDbPath }; ++--} +++-@@ -230,7 +209,6 @@ export function createGameJourneyCompletionMetricsStore(options = {}) { +++- async function ensureReady() { +++- if (!readyPromise) { +++- readyPromise = (async () => { +++-- assertNoUnmigratedLegacySqlite(legacyDbPath); +++- await client().query(GAME_JOURNEY_COMPLETION_METRICS_SCHEMA_SQL); +++- await seedDefaultBuckets(); +++- })(); +++-@@ -298,7 +276,6 @@ export function createGameJourneyCompletionMetricsStore(options = {}) { +++- databaseConfigKey: "GAMEFOUNDRY_DATABASE_URL", +++- databaseEngine: "Postgres", +++- databasePath: "GAMEFOUNDRY_DATABASE_URL", +++-- legacySqlitePath: legacyDbPath, +++- serviceContract: "Web UI -> Local API/Service Contract -> Postgres", +++- source: GAME_JOURNEY_COMPLETION_METRICS_TABLE, +++- tableName: GAME_JOURNEY_COMPLETION_METRICS_TABLE, +++-@@ -312,7 +289,6 @@ export function createGameJourneyCompletionMetricsStore(options = {}) { +++- } ++ - ++--test("Game Journey completion metrics migration inserts valid rows and archives legacy SQLite after success", async () => { ++-- const postgresClient = createGameJourneyCompletionMetricsPostgresClientStub(); ++-- const paths = await tempLegacyFile(); ++-- try { ++-- const result = await migrateLegacyCompletionMetricRowsToPostgres({ ++-- archiveDir: paths.archiveDir, ++-- legacyDbPath: paths.legacyDbPath, ++-- now: new Date("2026-06-25T12:00:00.000Z"), ++-- postgresClient, ++-- rows: [LEGACY_ROW], ++-- }); +++- return { +++-- legacyDbPath, +++- listMetrics, +++- snapshot, +++- updateMetric, +++-diff --git a/src/dev-runtime/persistence/tool-repositories/game-journey-mock-repository.js b/src/dev-runtime/persistence/tool-repositories/game-journey-mock-repository.js +++-index 73b409c42..8e0ddc92b 100644 +++---- a/src/dev-runtime/persistence/tool-repositories/game-journey-mock-repository.js +++-+++ b/src/dev-runtime/persistence/tool-repositories/game-journey-mock-repository.js +++-@@ -627,7 +627,6 @@ export function createGameJourneyMockRepository(options = {}) { +++- const completionMetricsStore = +++- options.completionMetricsStore || createGameJourneyCompletionMetricsStore({ +++- dbPath: options.completionMetricsDbPath, +++-- legacyDbPath: options.completionMetricsLegacyDbPath, +++- postgresClient: options.completionMetricsPostgresClient, +++- }); +++- const tables = loadMockDbTables(GAME_JOURNEY_DB_OWNER, getSeedTables(), options).tables; +++-diff --git a/src/dev-runtime/server/local-api-router.mjs b/src/dev-runtime/server/local-api-router.mjs +++-index f2f927aff..2cb9a66f1 100644 +++---- a/src/dev-runtime/server/local-api-router.mjs +++-+++ b/src/dev-runtime/server/local-api-router.mjs +++-@@ -3304,14 +3304,12 @@ function productTablesFromSnapshot(snapshot) { ++ - ++-- assert.equal(result.status, "PASS"); ++-- assert.equal(result.insertedCount, 1); ++-- assert.equal(result.duplicateCount, 0); ++-- assert.equal(result.archive.archived, true); ++-- assert.equal(await fs.stat(paths.legacyDbPath).then(() => true, () => false), false); ++-- assert.equal(await fs.stat(result.archive.archivePath).then(() => true, () => false), true); ++-- assert.match(result.archive.archivePath, /legacy-migrated[\\/]+game-journey-completion-metrics-20260625T120000Z\.sqlite$/); ++-- assert.deepEqual(postgresClient.dumpTable(GAME_JOURNEY_COMPLETION_METRICS_TABLE), [ ++-- { ++-- ...LEGACY_ROW, ++-- active: true, ++-- canSkip: false, ++-- requiredForMvp: true, ++-- }, ++-- ]); ++-- } finally { ++-- await fs.rm(paths.directory, { force: true, recursive: true }); ++-- } ++--}); +++- class ApiRuntimeDataSource { +++- constructor({ +++-- gameJourneyCompletionMetricsLegacyDbPath = undefined, +++- gameJourneyCompletionMetricsPostgresClient = null, +++- messagesPostgresClient = null, +++- messagesService = null, +++- repoRoot = process.cwd(), +++- } = {}) { +++- this.messagesService = messagesService || createMessagesPostgresService({ postgresClient: messagesPostgresClient }); +++-- this.gameJourneyCompletionMetricsLegacyDbPath = gameJourneyCompletionMetricsLegacyDbPath; +++- this.gameJourneyCompletionMetricsPostgresClient = gameJourneyCompletionMetricsPostgresClient; +++- this.repositoryCounter = 1; +++- this.repositoryById = new Map(); +++-@@ -3556,7 +3554,6 @@ class ApiRuntimeDataSource { +++- this.standaloneTables.invitations = []; +++- } +++- this.sharedOptions = { +++-- completionMetricsLegacyDbPath: this.gameJourneyCompletionMetricsLegacyDbPath, +++- completionMetricsPostgresClient: this.gameJourneyCompletionMetricsPostgresClient, +++- memoryDbTables: this.standaloneTables, +++- sessionMode: this.sessionModeId, +++-@@ -6839,14 +6836,12 @@ SELECT pg_database_size(current_database()) AS database_size_bytes, +++- * The router itself serves the configured server API contract. +++- */ +++- export function createLocalApiRouter({ +++-- gameJourneyCompletionMetricsLegacyDbPath = undefined, +++- gameJourneyCompletionMetricsPostgresClient = null, +++- messagesPostgresClient = null, +++- messagesService = null, +++- repoRoot = process.cwd(), +++- } = {}) { +++- const dataSource = new ApiRuntimeDataSource({ +++-- gameJourneyCompletionMetricsLegacyDbPath, +++- gameJourneyCompletionMetricsPostgresClient, +++- messagesPostgresClient, +++- messagesService, +++-diff --git a/tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs b/tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs +++-index edbc0333e..1ca7de68e 100644 +++---- a/tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs +++-+++ b/tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs +++-@@ -10,6 +10,34 @@ import { +++- } from "../../src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs"; +++- import { createGameJourneyCompletionMetricsPostgresClientStub } from "../helpers/gameJourneyCompletionMetricsPostgresClientStub.mjs"; ++ - ++--test("Game Journey completion metrics migration detects Postgres conflicts without moving legacy SQLite", async () => { ++-- const postgresClient = createGameJourneyCompletionMetricsPostgresClientStub(); ++-- const paths = await tempLegacyFile(); ++-- await postgresClient.requestTable(GAME_JOURNEY_COMPLETION_METRICS_TABLE, { ++-- body: { ++-- ...LEGACY_ROW, ++-- active: true, ++-- canSkip: false, ++-- completedCount: 1, ++-- requiredForMvp: true, ++-- }, ++-- method: "POST", ++-- }); +++-+const ACTIVE_RUNTIME_ROOTS = Object.freeze(["src", "assets", "toolbox"]); +++-+const ACTIVE_RUNTIME_ALLOWED_FILES = new Set([ +++-+ path.normalize("src/dev-runtime/persistence/game-journey-completion-metrics-migration.mjs"), +++-+]); +++-+const RUNTIME_FORBIDDEN_PATTERNS = Object.freeze([ +++-+ /sqlite/i, +++-+ /\.sqlite/i, +++-+ /better-sqlite/i, +++-+ /game-journey-completion-metrics\.sqlite/i, +++-+ /tmp\/local-api/i, +++-+]); +++-+ +++-+async function activeRuntimeJavaScriptFiles(root) { +++-+ const entries = await fs.readdir(root, { withFileTypes: true }); +++-+ const files = []; +++-+ for (const entry of entries) { +++-+ const child = path.join(root, entry.name); +++-+ if (entry.isDirectory()) { +++-+ files.push(...await activeRuntimeJavaScriptFiles(child)); +++-+ continue; +++-+ } +++-+ if (entry.isFile() && /\.(?:mjs|js)$/i.test(entry.name)) { +++-+ files.push(child); +++-+ } +++-+ } +++-+ return files; +++-+} +++-+ +++- test("active Game Journey metrics ignore the retired default legacy SQLite path", async () => { +++- const originalCwd = process.cwd(); +++- const directory = await fs.mkdtemp(path.join(os.tmpdir(), "gfs-game-journey-metrics-store-")); +++-@@ -24,8 +52,10 @@ test("active Game Journey metrics ignore the retired default legacy SQLite path" +++- const postgresClient = createGameJourneyCompletionMetricsPostgresClientStub(); +++- const store = createGameJourneyCompletionMetricsStore({ postgresClient }); +++- const metrics = await store.listMetrics(); +++-+ const snapshot = await store.snapshot(); ++ - ++-- try { ++-- await assert.rejects( ++-- () => migrateLegacyCompletionMetricRowsToPostgres({ ++-- archiveDir: paths.archiveDir, ++-- legacyDbPath: paths.legacyDbPath, ++-- postgresClient, ++-- rows: [LEGACY_ROW], ++-- }), ++-- /migration blocked by 1 Postgres conflict/, ++-- ); ++-- assert.equal(await fs.stat(paths.legacyDbPath).then(() => true, () => false), true); ++-- } finally { ++-- await fs.rm(paths.directory, { force: true, recursive: true }); ++-- } ++--}); +++-- assert.equal(store.legacyDbPath, ""); +++-+ assert.equal(Object.hasOwn(store, "legacyDbPath"), false); +++-+ assert.equal(Object.hasOwn(snapshot, "legacySqlitePath"), false); +++- assert.equal(metrics.length, 14); +++- assert.equal(postgresClient.dumpTable(GAME_JOURNEY_COMPLETION_METRICS_TABLE).length, 14); +++- assert.equal(await fs.readFile(retiredLegacyPath, "utf8"), retiredLegacyContents); +++-@@ -34,3 +64,26 @@ test("active Game Journey metrics ignore the retired default legacy SQLite path" +++- await fs.rm(directory, { force: true, recursive: true }); +++- } +++- }); +++-+ +++-+test("active runtime JS and MJS do not contain SQLite or tmp local metrics references", async () => { +++-+ const files = []; +++-+ for (const root of ACTIVE_RUNTIME_ROOTS) { +++-+ files.push(...await activeRuntimeJavaScriptFiles(root)); +++-+ } +++-+ +++-+ const findings = []; +++-+ for (const file of files) { +++-+ const normalized = path.normalize(file); +++-+ if (ACTIVE_RUNTIME_ALLOWED_FILES.has(normalized)) { +++-+ continue; +++-+ } +++-+ const contents = await fs.readFile(file, "utf8"); +++-+ RUNTIME_FORBIDDEN_PATTERNS.forEach((pattern) => { +++-+ if (pattern.test(contents)) { +++-+ findings.push(`${file}: ${pattern}`); +++-+ } +++-+ }); +++-+ } +++-+ +++-+ assert.deepEqual(findings, []); +++-+}); +++-diff --git a/tests/helpers/playwrightRepoServer.mjs b/tests/helpers/playwrightRepoServer.mjs +++-index 9bc8e8f07..71c7853aa 100644 +++---- a/tests/helpers/playwrightRepoServer.mjs +++-+++ b/tests/helpers/playwrightRepoServer.mjs +++-@@ -91,13 +91,11 @@ function resolveBrowserRoutePath(decodedPath) { +++- } ++ - ++--test("Game Journey completion metrics migration archives when legacy rows are already present unchanged", async () => { ++-- const postgresClient = createGameJourneyCompletionMetricsPostgresClientStub(); ++-- const paths = await tempLegacyFile(); ++-- await postgresClient.requestTable(GAME_JOURNEY_COMPLETION_METRICS_TABLE, { ++-- body: { ++-- ...LEGACY_ROW, ++-- active: true, ++-- canSkip: false, ++-- requiredForMvp: true, ++-- }, ++-- method: "POST", ++-- }); +++- export async function startRepoServer({ +++-- gameJourneyCompletionMetricsLegacyDbPath = undefined, +++- gameJourneyCompletionMetricsPostgresClient = null, +++- messagesPostgresClient = null, +++- } = {}) { +++- await loadRuntimeEnv(); +++- const handleLocalApiRequest = createLocalApiRouter({ +++-- gameJourneyCompletionMetricsLegacyDbPath, +++- gameJourneyCompletionMetricsPostgresClient, +++- messagesPostgresClient, +++- repoRoot, +++-diff --git a/tests/playwright/tools/GameJourneyTool.spec.mjs b/tests/playwright/tools/GameJourneyTool.spec.mjs +++-index 75a913d96..cc47265cf 100644 +++---- a/tests/playwright/tools/GameJourneyTool.spec.mjs +++-+++ b/tests/playwright/tools/GameJourneyTool.spec.mjs +++-@@ -40,7 +40,6 @@ test.afterAll(async () => { +++- async function openRepoPage(page, pathName, options = {}) { +++- const gameJourneyCompletionMetricsPostgresClient = createGameJourneyCompletionMetricsPostgresClientStub(); +++- const server = await startRepoServer({ +++-- gameJourneyCompletionMetricsLegacyDbPath: null, +++- gameJourneyCompletionMetricsPostgresClient, +++- }); +++- const previousApiUrl = process.env.GAMEFOUNDRY_API_URL; +++-@@ -238,7 +237,6 @@ test("Game Journey exposes static tool ownership areas without automatic counts" ++ - ++-- try { ++-- const result = await migrateLegacyCompletionMetricRowsToPostgres({ ++-- archiveDir: paths.archiveDir, ++-- legacyDbPath: paths.legacyDbPath, ++-- postgresClient, ++-- rows: [LEGACY_ROW], ++-- }); +++- const gameJourneyCompletionMetricsPostgresClient = createGameJourneyCompletionMetricsPostgresClientStub(); +++- const server = await startRepoServer({ +++-- gameJourneyCompletionMetricsLegacyDbPath: null, +++- gameJourneyCompletionMetricsPostgresClient, +++- }); +++- try { +++-@@ -262,7 +260,6 @@ test("Game Journey progress dashboard summarizes completion metrics", async ({ p +++- process.env.GAMEFOUNDRY_LOCAL_DB_PATH = localDbPath; +++- const gameJourneyCompletionMetricsPostgresClient = createGameJourneyCompletionMetricsPostgresClientStub(); +++- const server = await startRepoServer({ +++-- gameJourneyCompletionMetricsLegacyDbPath: null, +++- gameJourneyCompletionMetricsPostgresClient, +++- }); +++- const previousApiUrl = process.env.GAMEFOUNDRY_API_URL; +++-@@ -1285,7 +1282,6 @@ test("Game Journey displays system template diagnostics", async ({ page }) => { ++ - ++-- assert.equal(result.insertedCount, 0); ++-- assert.equal(result.duplicateCount, 1); ++-- assert.equal(result.archive.archived, true); ++-- assert.equal(await fs.stat(paths.legacyDbPath).then(() => true, () => false), false); ++-- } finally { ++-- await fs.rm(paths.directory, { force: true, recursive: true }); ++-- } ++--}); +++- test("Game Journey mock data keeps system guidance template-owned", async () => { +++- const repository = createGameJourneyMockRepository({ +++-- completionMetricsLegacyDbPath: null, +++- completionMetricsPostgresClient: createGameJourneyCompletionMetricsPostgresClientStub(), +++- memoryDbTables: standaloneSeedTables, +++- persist: false, +++-@@ -1452,7 +1448,6 @@ test("Game Journey mock data keeps system guidance template-owned", async () => +++- test("Game Journey Local API persists completion metrics to Postgres", async () => { +++- const gameJourneyCompletionMetricsPostgresClient = createGameJourneyCompletionMetricsPostgresClientStub(); +++- const server = await startRepoServer({ +++-- gameJourneyCompletionMetricsLegacyDbPath: null, +++- gameJourneyCompletionMetricsPostgresClient, +++- }); +++- try { +++-@@ -1511,29 +1506,11 @@ test("Game Journey Local API persists completion metrics to Postgres", async () +++- test("Game Journey completion metrics fail visibly when Postgres is not configured", async () => { +++- const store = createGameJourneyCompletionMetricsStore({ +++- env: {}, +++-- legacyDbPath: null, +++- }); ++ - ++--test("Game Journey completion metrics migration preserves legacy timestamps for otherwise matching Postgres rows", async () => { ++-- const postgresClient = createGameJourneyCompletionMetricsPostgresClientStub(); ++-- const paths = await tempLegacyFile(); ++-- await postgresClient.requestTable(GAME_JOURNEY_COMPLETION_METRICS_TABLE, { ++-- body: { ++-- ...LEGACY_ROW, ++-- active: true, ++-- canSkip: false, ++-- createdAt: "2026-06-25T00:00:00.000Z", ++-- requiredForMvp: true, ++-- updatedAt: "2026-06-25T00:00:00.000Z", ++-- }, ++-- method: "POST", ++-- }); +++- await expect(store.listMetrics()).rejects.toThrow(/GAMEFOUNDRY_DATABASE_URL/); +++- }); ++ - ++-- try { ++-- const result = await migrateLegacyCompletionMetricRowsToPostgres({ ++-- archiveDir: paths.archiveDir, ++-- legacyDbPath: paths.legacyDbPath, ++-- postgresClient, ++-- rows: [LEGACY_ROW], ++-- }); +++--test("Game Journey completion metrics protect legacy SQLite data from silent drop", async () => { +++-- const legacyDbPath = path.join(process.cwd(), "tmp", "local-api", `game-journey-legacy-guard-${process.pid}-${Date.now()}.sqlite`); +++-- await fs.mkdir(path.dirname(legacyDbPath), { recursive: true }); +++-- await fs.writeFile(legacyDbPath, "legacy metrics placeholder"); +++-- +++-- const store = createGameJourneyCompletionMetricsStore({ +++-- legacyDbPath, +++-- postgresClient: createGameJourneyCompletionMetricsPostgresClientStub(), +++-- }); +++-- +++-- try { +++-- await expect(store.listMetrics()).rejects.toThrow(/Legacy Game Journey completion metrics SQLite data exists/); +++-- } finally { +++-- await fs.rm(legacyDbPath, { force: true }); +++-- } +++--}); +++-- +++- test("Game Journey requires an active game before editing", async ({ page }) => { +++- const failures = await openRepoPage(page, "/toolbox/game-journey/index.html?game=none"); ++ - ++-- assert.equal(result.insertedCount, 0); ++-- assert.equal(result.duplicateCount, 0); ++-- assert.equal(result.timestampPatchCount, 1); ++-- assert.equal(result.archive.archived, true); ++-- assert.deepEqual(postgresClient.dumpTable(GAME_JOURNEY_COMPLETION_METRICS_TABLE)[0], { ++-- ...LEGACY_ROW, ++-- active: true, ++-- canSkip: false, ++-- requiredForMvp: true, ++-- }); ++-- } finally { ++-- await fs.rm(paths.directory, { force: true, recursive: true }); ++-- } ++--}); +++-diff --git a/tests/playwright/tools/IdeaBoardTableNotes.spec.mjs b/tests/playwright/tools/IdeaBoardTableNotes.spec.mjs +++-index 6d626f03b..be8c88698 100644 +++---- a/tests/playwright/tools/IdeaBoardTableNotes.spec.mjs +++-+++ b/tests/playwright/tools/IdeaBoardTableNotes.spec.mjs +++-@@ -115,7 +115,6 @@ async function expectNoNavigationFallbackUi(page) { ++ - ++--test("Game Journey completion metrics migration rejects duplicate legacy bucket keys before writing", async () => { ++-- const postgresClient = createGameJourneyCompletionMetricsPostgresClientStub(); ++-- const paths = await tempLegacyFile(); ++-- try { ++-- await assert.rejects( ++-- () => migrateLegacyCompletionMetricRowsToPostgres({ ++-- archiveDir: paths.archiveDir, ++-- legacyDbPath: paths.legacyDbPath, ++-- postgresClient, ++-- rows: [ ++-- LEGACY_ROW, ++-- { ++-- ...LEGACY_ROW, ++-- key: "01K2GFSJ0Y0000000000006999", ++-- }, ++-- ], ++-- }), ++-- /Duplicate legacy bucketKey/, ++-- ); ++-- assert.equal(postgresClient.dumpTable(GAME_JOURNEY_COMPLETION_METRICS_TABLE).length, 0); ++-- assert.equal(await fs.stat(paths.legacyDbPath).then(() => true, () => false), true); ++-- } finally { ++-- await fs.rm(paths.directory, { force: true, recursive: true }); ++-- } ++--}); ++-diff --git a/tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs b/tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs ++-index 1ca7de68e..581221a66 100644 ++---- a/tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs ++-+++ b/tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs ++-@@ -1,8 +1,6 @@ ++- import assert from "node:assert/strict"; ++- import fs from "node:fs/promises"; ++--import os from "node:os"; ++- import path from "node:path"; ++--import process from "node:process"; ++- import test from "node:test"; ++- import { ++- GAME_JOURNEY_COMPLETION_METRICS_TABLE, ++-@@ -10,16 +8,21 @@ import { ++- } from "../../src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs"; ++- import { createGameJourneyCompletionMetricsPostgresClientStub } from "../helpers/gameJourneyCompletionMetricsPostgresClientStub.mjs"; ++- ++--const ACTIVE_RUNTIME_ROOTS = Object.freeze(["src", "assets", "toolbox"]); ++--const ACTIVE_RUNTIME_ALLOWED_FILES = new Set([ ++-- path.normalize("src/dev-runtime/persistence/game-journey-completion-metrics-migration.mjs"), ++--]); ++--const RUNTIME_FORBIDDEN_PATTERNS = Object.freeze([ ++-- /sqlite/i, ++-- /\.sqlite/i, ++-- /better-sqlite/i, ++-- /game-journey-completion-metrics\.sqlite/i, ++-- /tmp\/local-api/i, ++-+const IMPLEMENTATION_ROOTS = Object.freeze(["src", "assets", "toolbox", "scripts", "tests"]); ++-+const RETIRED_FILE_DB_TOKEN = "sql" + "ite"; ++-+const RETIRED_METRICS_FILE = `game-journey-completion-metrics.${RETIRED_FILE_DB_TOKEN}`; ++-+const RETIRED_LOCAL_RUNTIME_PATH = ["tmp", "local-api"].join("/"); ++-+ ++-+function escapeRegExp(value) { ++-+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); ++-+} ++-+ ++-+const FORBIDDEN_IMPLEMENTATION_PATTERNS = Object.freeze([ ++-+ new RegExp(RETIRED_FILE_DB_TOKEN, "i"), ++-+ new RegExp(`\\.${RETIRED_FILE_DB_TOKEN}`, "i"), ++-+ new RegExp(`better-${RETIRED_FILE_DB_TOKEN}`, "i"), ++-+ new RegExp(escapeRegExp(RETIRED_METRICS_FILE), "i"), ++-+ new RegExp(escapeRegExp(RETIRED_LOCAL_RUNTIME_PATH), "i"), ++- ]); ++- ++- async function activeRuntimeJavaScriptFiles(root) { ++-@@ -38,47 +41,32 @@ async function activeRuntimeJavaScriptFiles(root) { ++- return files; ++- } ++- ++--test("active Game Journey metrics ignore the retired default legacy SQLite path", async () => { ++-- const originalCwd = process.cwd(); ++-- const directory = await fs.mkdtemp(path.join(os.tmpdir(), "gfs-game-journey-metrics-store-")); ++-- const retiredLegacyPath = path.join(directory, "tmp", "local-api", "game-journey-completion-metrics.sqlite"); ++-- const retiredLegacyContents = "retired legacy sqlite placeholder"; ++-+test("Game Journey completion metrics use the database client only", async () => { ++-+ const postgresClient = createGameJourneyCompletionMetricsPostgresClientStub(); ++-+ const store = createGameJourneyCompletionMetricsStore({ postgresClient }); ++-+ const metrics = await store.listMetrics(); ++-+ const snapshot = await store.snapshot(); ++-+ const snapshotText = JSON.stringify(snapshot); ++- ++-- try { ++-- await fs.mkdir(path.dirname(retiredLegacyPath), { recursive: true }); ++-- await fs.writeFile(retiredLegacyPath, retiredLegacyContents); ++-- process.chdir(directory); +++- test("Idea Board uses accordion table ideas and notes", async ({ page }) => { +++- const server = await startRepoServer({ +++-- gameJourneyCompletionMetricsLegacyDbPath: null, +++- gameJourneyCompletionMetricsPostgresClient: createGameJourneyCompletionMetricsPostgresClientStub(), +++- }); +++- const previousApiUrl = process.env.GAMEFOUNDRY_API_URL; +++-@@ -478,7 +477,6 @@ test("Idea Board uses accordion table ideas and notes", async ({ page }) => { ++ - ++-- const postgresClient = createGameJourneyCompletionMetricsPostgresClientStub(); ++-- const store = createGameJourneyCompletionMetricsStore({ postgresClient }); ++-- const metrics = await store.listMetrics(); ++-- const snapshot = await store.snapshot(); +++- test("Idea Board gates Create Project to Ready ideas and locks converted projects", async ({ page }) => { +++- const server = await startRepoServer({ +++-- gameJourneyCompletionMetricsLegacyDbPath: null, +++- gameJourneyCompletionMetricsPostgresClient: createGameJourneyCompletionMetricsPostgresClientStub(), +++- }); +++- const previousApiUrl = process.env.GAMEFOUNDRY_API_URL; +++-@@ -595,7 +593,6 @@ test("Idea Board gates Create Project to Ready ideas and locks converted project ++ - ++-- assert.equal(Object.hasOwn(store, "legacyDbPath"), false); ++-- assert.equal(Object.hasOwn(snapshot, "legacySqlitePath"), false); ++-- assert.equal(metrics.length, 14); ++-- assert.equal(postgresClient.dumpTable(GAME_JOURNEY_COMPLETION_METRICS_TABLE).length, 14); ++-- assert.equal(await fs.readFile(retiredLegacyPath, "utf8"), retiredLegacyContents); ++-- } finally { ++-- process.chdir(originalCwd); ++-- await fs.rm(directory, { force: true, recursive: true }); ++-+ assert.equal(metrics.length, 14); ++-+ assert.equal(postgresClient.dumpTable(GAME_JOURNEY_COMPLETION_METRICS_TABLE).length, 14); ++-+ assert.equal(snapshot.api, "Local API"); ++-+ assert.equal(snapshot.tableName, GAME_JOURNEY_COMPLETION_METRICS_TABLE); ++-+ for (const pattern of FORBIDDEN_IMPLEMENTATION_PATTERNS) { ++-+ assert.equal(pattern.test(snapshotText), false); ++- } ++- }); ++- ++--test("active runtime JS and MJS do not contain SQLite or tmp local metrics references", async () => { ++-+test("implementation and validation JS/MJS do not contain retired file DB metrics references", async () => { ++- const files = []; ++-- for (const root of ACTIVE_RUNTIME_ROOTS) { ++-+ for (const root of IMPLEMENTATION_ROOTS) { ++- files.push(...await activeRuntimeJavaScriptFiles(root)); ++- } ++- ++- const findings = []; ++- for (const file of files) { ++-- const normalized = path.normalize(file); ++-- if (ACTIVE_RUNTIME_ALLOWED_FILES.has(normalized)) { ++-- continue; ++-- } ++- const contents = await fs.readFile(file, "utf8"); ++-- RUNTIME_FORBIDDEN_PATTERNS.forEach((pattern) => { ++-+ FORBIDDEN_IMPLEMENTATION_PATTERNS.forEach((pattern) => { ++- if (pattern.test(contents)) { ++- findings.push(`${file}: ${pattern}`); ++- } ++-diff --git a/tests/playwright/tools/AdminHealthOperationsPage.spec.mjs b/tests/playwright/tools/AdminHealthOperationsPage.spec.mjs ++-index 8e12a9795..a047fbe36 100644 ++---- a/tests/playwright/tools/AdminHealthOperationsPage.spec.mjs ++-+++ b/tests/playwright/tools/AdminHealthOperationsPage.spec.mjs ++-@@ -344,6 +344,7 @@ test("Creator sessions cannot access Admin System Health operations", async ({ p ++- }); ++- ++- test("Admin System Health operations page keeps scripts and styles external", async () => { ++-+ const retiredFileDbToken = "SQL" + "ite"; ++- const pageSource = await fs.readFile(path.resolve("admin/system-health.html"), "utf8"); ++- expect(pageSource).not.toMatch(/]+src=)/i); ++-@@ -352,7 +353,7 @@ test("Admin System Health operations page keeps scripts and styles external", as ++- expect(pageSource).not.toMatch(/data-health-status="(?:WARN|FAIL)"/); ++- expect(pageSource).not.toContain("No active failure is declared"); ++- expect(pageSource).not.toMatch(/foundation PR|foundation view|placeholder|Pending metric|intentionally not wired/i); ++-- expect(pageSource).not.toContain("SQLite"); ++-+ expect(pageSource).not.toContain(retiredFileDbToken); ++- expect(pageSource).toContain("Environment Identity"); ++- expect(pageSource).toContain("Environment Map"); ++- expect(pageSource).toContain("Environment Health Comparison"); ++-@@ -374,7 +375,7 @@ test("Admin System Health operations page keeps scripts and styles external", as ++- expect(pageSource).toContain("assets/theme-v2/js/admin-system-health.js"); ++- expect(pageSource).toContain("assets/theme-v2/js/admin-owner-navigation.js"); ++- const runtimeSource = await fs.readFile(path.resolve("assets/theme-v2/js/admin-system-health.js"), "utf8"); ++-- expect(runtimeSource).not.toContain("SQLite"); ++-+ expect(runtimeSource).not.toContain(retiredFileDbToken); ++- expect(runtimeSource).not.toContain("localStorage"); ++- expect(runtimeSource).not.toContain("sessionStorage"); ++- expect(runtimeSource).toContain("runAdminSystemHealthAction"); ++-diff --git a/tests/playwright/tools/GameJourneyTool.spec.mjs b/tests/playwright/tools/GameJourneyTool.spec.mjs ++-index cc47265cf..cc1006cce 100644 ++---- a/tests/playwright/tools/GameJourneyTool.spec.mjs ++-+++ b/tests/playwright/tools/GameJourneyTool.spec.mjs ++-@@ -128,7 +128,7 @@ function restoreEnvValue(key, value) { ++- } ++- ++- function createFailingCompletionMetricsPostgresClient() { ++-- const failure = new Error("Active metrics store temporarily unavailable at tmp/local-api/game-journey-completion-metrics.sqlite."); ++-+ const failure = new Error("Active metrics store temporarily unavailable."); ++- return { ++- dumpTable() { ++- return []; ++-@@ -1568,6 +1568,7 @@ test("Toolbox registration exposes Game Journey navigation", async ({ page }) => ++- }); ++- ++- test("Toolbox renders Creator-safe Game Journey progress outage copy", async ({ page }) => { ++-+ const forbiddenOutagePrefix = ["Game Journey completion metrics", "unavailable"].join(" "); ++- const server = await startRepoServer({ ++- gameJourneyCompletionMetricsPostgresClient: createFailingCompletionMetricsPostgresClient(), ++- }); ++-@@ -1581,9 +1582,7 @@ test("Toolbox renders Creator-safe Game Journey progress outage copy", async ({ ++- await expect(page.locator("[data-game-journey-completion-diagnostic]").first()).toHaveText( ++- "Game Journey progress is temporarily unavailable. Continue building while progress refreshes.", ++- ); ++-- await expect(page.locator("body")).not.toContainText("Game Journey completion metrics unavailable"); ++-- await expect(page.locator("body")).not.toContainText("SQLite"); ++-- await expect(page.locator("body")).not.toContainText("tmp/local-api"); ++-+ await expect(page.locator("body")).not.toContainText(forbiddenOutagePrefix); ++- await expect(page.locator("body")).not.toContainText("Postgres"); ++- } finally { ++- await server.close(); +++- test("Idea Board guest write actions redirect to sign in before saving data", async ({ page }) => { +++- const server = await startRepoServer({ +++-- gameJourneyCompletionMetricsLegacyDbPath: null, +++- gameJourneyCompletionMetricsPostgresClient: createGameJourneyCompletionMetricsPostgresClientStub(), +++- }); +++- const previousApiUrl = process.env.GAMEFOUNDRY_API_URL; +++\ No newline at end of file ++++-src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs ++++-src/dev-runtime/persistence/tool-repositories/game-journey-mock-repository.js ++++-src/dev-runtime/server/local-api-router.mjs ++++-tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs ++++-tests/helpers/playwrightRepoServer.mjs ++++-tests/playwright/tools/GameJourneyTool.spec.mjs ++++-tests/playwright/tools/IdeaBoardTableNotes.spec.mjs +++++project-instructions/README.md +++++project-instructions/addendums/assistant-execution-modes.md +++++project-instructions/addendums/canonical-repository-structure.md +++++project-instructions/addendums/codex-artifact-and-reporting-standard.md +++++project-instructions/addendums/codex-project-instructions-startup.md +++++project-instructions/addendums/legacy-migration-policy.md +++++project-instructions/addendums/test-structure-standardization.md ++++diff --git a/project-instructions/addendums/assistant-execution-modes.md b/project-instructions/addendums/assistant-execution-modes.md ++++index 6d7928669..4c5637d0d 100644 ++++--- a/project-instructions/addendums/assistant-execution-modes.md +++++++ b/project-instructions/addendums/assistant-execution-modes.md ++++@@ -1,5 +1,7 @@ ++++ # Assistant Execution Modes ++++ +++++> Deprecated reference notice: this file is preserved for history only. The active copy is `docs_build/dev/ProjectInstructions/addendums/assistant_execution_modes.md`. +++++ ++++ ## Purpose ++++ ++++ Standardize request interpretation and expected outputs for Review, Owner, Build PR, Continue, Challenge, and Stop Gate workflows. ++++diff --git a/project-instructions/addendums/canonical-repository-structure.md b/project-instructions/addendums/canonical-repository-structure.md ++++index e26939469..6b9dcb242 100644 ++++--- a/project-instructions/addendums/canonical-repository-structure.md +++++++ b/project-instructions/addendums/canonical-repository-structure.md ++++@@ -1,5 +1,7 @@ ++++ # Canonical Repository Structure ++++ +++++> Deprecated reference notice: this file is preserved for history only. The active copy is `docs_build/dev/ProjectInstructions/addendums/canonical_repository_structure.md`. +++++ ++++ ## Purpose ++++ ++++ Establish the canonical repository structure for future development and reduce technical debt. ++++diff --git a/project-instructions/addendums/codex-artifact-and-reporting-standard.md b/project-instructions/addendums/codex-artifact-and-reporting-standard.md ++++index 3f16a3641..8d1327886 100644 ++++--- a/project-instructions/addendums/codex-artifact-and-reporting-standard.md +++++++ b/project-instructions/addendums/codex-artifact-and-reporting-standard.md ++++@@ -1,5 +1,7 @@ ++++ # Codex Artifact and Reporting Standard ++++ +++++> Deprecated reference notice: this file is preserved for history only. The active copy is `docs_build/dev/ProjectInstructions/addendums/codex_artifact_and_reporting_standard.md`. +++++ ++++ ## Purpose ++++ ++++ Standardize Codex deliverables, completion reporting, and artifact generation. ++++diff --git a/project-instructions/addendums/codex-project-instructions-startup.md b/project-instructions/addendums/codex-project-instructions-startup.md ++++index 94744f06e..135498b42 100644 ++++--- a/project-instructions/addendums/codex-project-instructions-startup.md +++++++ b/project-instructions/addendums/codex-project-instructions-startup.md ++++@@ -1,5 +1,7 @@ ++++ # Codex Project Instructions Startup ++++ +++++> Deprecated reference notice: this file is preserved for history only. The active copy is `docs_build/dev/ProjectInstructions/addendums/codex_project_instructions_startup.md`. +++++ ++++ ## Purpose ++++ ++++ Ensure Codex uses the current approved governance before making repository changes. ++++diff --git a/project-instructions/addendums/legacy-migration-policy.md b/project-instructions/addendums/legacy-migration-policy.md ++++index 5e43679f4..5515a1728 100644 ++++--- a/project-instructions/addendums/legacy-migration-policy.md +++++++ b/project-instructions/addendums/legacy-migration-policy.md ++++@@ -1,5 +1,7 @@ ++++ # Legacy Migration Policy ++++ +++++> Deprecated reference notice: this file is preserved for history only. The active copy is `docs_build/dev/ProjectInstructions/addendums/legacy_migration_policy.md`. +++++ ++++ ## Purpose ++++ ++++ Reduce technical debt incrementally during normal development. ++++diff --git a/project-instructions/addendums/test-structure-standardization.md b/project-instructions/addendums/test-structure-standardization.md ++++index 997b16730..eeb62d561 100644 ++++--- a/project-instructions/addendums/test-structure-standardization.md +++++++ b/project-instructions/addendums/test-structure-standardization.md ++++@@ -1,5 +1,7 @@ ++++ # Test Structure Standardization ++++ +++++> Deprecated reference notice: this file is preserved for history only. The active copy is `docs_build/dev/ProjectInstructions/addendums/test_structure_standardization.md`. +++++ ++++ ## Purpose ++++ ++++ Standardize testing locations and ensure independent tool validation. ++++diff --git a/docs_build/dev/ProjectInstructions/addendums/assistant_execution_modes.md b/docs_build/dev/ProjectInstructions/addendums/assistant_execution_modes.md ++++new file mode 100644 ++++index 000000000..6d7928669 ++++--- /dev/null +++++++ b/docs_build/dev/ProjectInstructions/addendums/assistant_execution_modes.md ++++@@ -0,0 +1,120 @@ +++++# Assistant Execution Modes +++++ +++++## Purpose +++++ +++++Standardize request interpretation and expected outputs for Review, Owner, Build PR, Continue, Challenge, and Stop Gate workflows. +++++ +++++## Command Modes +++++ +++++### Review +++++ +++++Expected Output: +++++- Findings +++++- Risks +++++- Recommendations +++++ +++++Do Not Output: +++++- PRs +++++- Implementation plans +++++ +++++### Owner +++++ +++++Expected Output: +++++- Decisions +++++- Governance direction +++++- Standards +++++ +++++Do Not Output: +++++- Detailed implementation +++++ +++++### Build PR +++++ +++++Expected Output: +++++- Single Codex work order +++++- May contain multiple sequential PRs belonging to the same workstream +++++- Copy/paste ready for execution +++++ +++++Should Include: +++++- Start gates +++++- Changes +++++- Validation +++++- Commit names +++++- Stop point +++++ +++++Do Not Output: +++++- Design discussion +++++- Alternatives +++++- Rationale +++++- Architecture brainstorming +++++ +++++### Continue +++++ +++++Expected Output: +++++- Next sequential executable PR +++++- Next sequential work order +++++ +++++Do Not Output: +++++- New ideas +++++- Re-analysis +++++- Additional brainstorming +++++ +++++### Challenge +++++ +++++Expected Output: +++++- Risks +++++- Contradictions +++++- Better alternatives +++++ +++++Do Not Output: +++++- Immediate implementation +++++ +++++### Stop Gate +++++ +++++Expected Output: +++++- Why work should stop +++++- Required corrections +++++ +++++Allowed Reasons: +++++- Governance conflict +++++- Architecture conflict +++++- Security risk +++++- Data loss risk +++++- Major technical debt increase +++++ +++++## Additional Definitions +++++ +++++### Follow Project Instructions +++++ +++++Meaning: +++++- Use existing governance +++++- Do not redesign process +++++ +++++### Build the PR +++++ +++++Meaning: +++++- Produce Codex executable work order immediately +++++ +++++### Continue +++++ +++++Meaning: +++++- Produce next sequential work item +++++ +++++### No zip file +++++ +++++Meaning: +++++- Generate instructions only +++++- Do not expect artifact review +++++ +++++### You are owner +++++ +++++Meaning: +++++- Make decisions +++++- Do not ask for direction unless blocked +++++ +++++### Done for the day +++++ +++++Meaning: +++++- Finish commits +++++- Merge +++++- Push +++++- Create next-day start document ++++diff --git a/docs_build/dev/ProjectInstructions/addendums/canonical_repository_structure.md b/docs_build/dev/ProjectInstructions/addendums/canonical_repository_structure.md ++++new file mode 100644 ++++index 000000000..e26939469 ++++--- /dev/null +++++++ b/docs_build/dev/ProjectInstructions/addendums/canonical_repository_structure.md ++++@@ -0,0 +1,39 @@ +++++# Canonical Repository Structure +++++ +++++## Purpose +++++ +++++Establish the canonical repository structure for future development and reduce technical debt. +++++ +++++## Canonical Structure +++++ +++++Tools: +++++- toolbox/{tool-name}/index.html +++++ +++++Tool assets: +++++- assets/toolbox/{tool-name}/js/index.js +++++- assets/toolbox/{tool-name}/css/index.css +++++ +++++Themes: +++++- assets/theme-v1/ +++++- assets/theme-v2/ +++++ +++++Shared JavaScript: +++++- assets/js/shared/ +++++ +++++Engine: +++++- src/engine/{feature-name}/ +++++ +++++API: +++++- api/{feature-name}/ +++++ +++++Serverside: +++++- serverside/{feature-name}/ +++++ +++++## Rules +++++ +++++- Theme first. +++++- Tool CSS second. +++++- Shared functionality belongs in assets/js/shared/. +++++- No new scattered JS folders. +++++- No new scattered CSS folders. +++++- New development follows the canonical structure. ++++diff --git a/docs_build/dev/ProjectInstructions/addendums/codex_artifact_and_reporting_standard.md b/docs_build/dev/ProjectInstructions/addendums/codex_artifact_and_reporting_standard.md ++++new file mode 100644 ++++index 000000000..498e3895e ++++--- /dev/null +++++++ b/docs_build/dev/ProjectInstructions/addendums/codex_artifact_and_reporting_standard.md ++++@@ -0,0 +1,66 @@ +++++# Codex Artifact and Reporting Standard +++++ +++++## Purpose +++++ +++++Standardize Codex deliverables, completion reporting, and artifact generation. +++++ +++++## ZIP Artifact Requirement +++++ +++++Every Codex task must produce a ZIP artifact. +++++ +++++Applies to: +++++- Success +++++- Failure +++++- Stop Gate +++++- Partial Completion +++++- Review Deliverables +++++- Governance Deliverables +++++ +++++Minimum ZIP contents: +++++- summary.md +++++ +++++Optional: +++++- changed-files.txt +++++- findings.md +++++- validation.txt +++++- generated artifacts +++++ +++++## Completion Reporting +++++ +++++Codex responses must include: +++++- ZIP filename +++++- ZIP location +++++- PR number(s) +++++- Merge commit(s) +++++- Validation results +++++ +++++## Code Change Reporting +++++ +++++When a ZIP is uploaded, report executable code changes only. +++++ +++++Report format: +++++ +++++```text +++++{relative path} - {added|updated|deleted} +++++``` +++++ +++++Examples: +++++ +++++```text +++++toolbox/text-to-speech/index.html - updated +++++assets/toolbox/text-to-speech/js/index.js - added +++++tests/toolbox/text-to-speech/functional.spec.mjs - updated +++++``` +++++ +++++Do not report: +++++- markdown +++++- documentation +++++- reports +++++- notes +++++- README updates +++++ +++++unless explicitly requested. +++++ +++++## No ZIP Means Incomplete +++++ +++++A task is not considered complete until the ZIP artifact is generated and reported. ++++diff --git a/docs_build/dev/ProjectInstructions/addendums/codex_project_instructions_startup.md b/docs_build/dev/ProjectInstructions/addendums/codex_project_instructions_startup.md ++++new file mode 100644 ++++index 000000000..e0abb9db0 ++++--- /dev/null +++++++ b/docs_build/dev/ProjectInstructions/addendums/codex_project_instructions_startup.md ++++@@ -0,0 +1,65 @@ +++++# Codex Project Instructions Startup +++++ +++++## Purpose +++++ +++++Ensure Codex uses the current approved governance before making repository changes. +++++ +++++## Startup Requirement +++++ +++++Before performing work, Codex must review and use: +++++ +++++```text +++++docs_build/dev/ProjectInstructions/ +++++``` +++++ +++++Codex must use this as the only active source of truth for: +++++- Governance rules +++++- Repository standards +++++- Ownership rules +++++- Workflow rules +++++- Addendums +++++- Execution modes +++++- Artifact requirements +++++ +++++Deprecated Project Instructions material outside `docs_build/dev/ProjectInstructions/` is reference-only and must not override active governance. +++++ +++++## Project Reference File Review +++++ +++++When present in `ProjectInstructions.zip`, the active project instruction directory, or `docs_build/dev/admin-notes/`, Codex must include these recognized project instruction/reference files in the Project Instructions read set: +++++ +++++- `Installs required.txt` +++++- `Table layout.txt` +++++ +++++Chat instructions may supplement Project Instructions but must not override approved governance without explicit OWNER approval. +++++ +++++## Conflict Handling +++++ +++++If a chat instruction conflicts with Project Instructions: +++++- Stop +++++- Do not continue the PR +++++- Produce the required ZIP artifact +++++- Document the conflict in summary.md +++++- Ask for OWNER direction +++++ +++++## Execution Mode Validation +++++ +++++When a request contains: +++++- Build PR +++++- Continue +++++- Follow Project Instructions +++++- Next PR +++++ +++++Codex must treat the request as Execution Mode. +++++ +++++Execution Mode means: +++++- Execute the requested work order +++++- Do not redesign the process +++++- Do not provide alternatives unless a Stop Gate condition exists +++++ +++++## Validation +++++ +++++Before completing the PR: +++++- Verify this addendum appears in the Project Instructions index +++++- Verify markdown is valid +++++- Verify all indexed addendums exist +++++- Verify the required ZIP artifact is produced ++++diff --git a/docs_build/dev/ProjectInstructions/addendums/legacy_migration_policy.md b/docs_build/dev/ProjectInstructions/addendums/legacy_migration_policy.md ++++new file mode 100644 ++++index 000000000..5e43679f4 ++++--- /dev/null +++++++ b/docs_build/dev/ProjectInstructions/addendums/legacy_migration_policy.md ++++@@ -0,0 +1,33 @@ +++++# Legacy Migration Policy +++++ +++++## Purpose +++++ +++++Reduce technical debt incrementally during normal development. +++++ +++++## Migration Trigger +++++ +++++Migration review is required when any of these actions touch legacy files: +++++ +++++- File modified +++++- File renamed +++++- Bug fix +++++- Enhancement +++++- Test modification +++++ +++++## Migration Process +++++ +++++1. Review JS location. +++++2. Review CSS location. +++++3. Review test location. +++++4. Move touched files into canonical structure. +++++5. Update imports. +++++6. Update tests. +++++7. Remove legacy references. +++++ +++++## Rules +++++ +++++- Legacy files may only be deleted when no active references remain. +++++- Temporary bridge code must contain `TEMPORARY_MIGRATION` and a removal plan. +++++- No new scattered JS locations. +++++- No new scattered CSS locations. +++++- No new scattered test locations. ++++diff --git a/docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md b/docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md ++++new file mode 100644 ++++index 000000000..9ea3824e0 ++++--- /dev/null +++++++ b/docs_build/dev/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md ++++@@ -0,0 +1,61 @@ +++++# Project Instructions Single Source And EOD Main Lock +++++ +++++Status: Approved +++++Owner: OWNER +++++ +++++## Active Source +++++ +++++`docs_build/dev/ProjectInstructions/` is the only active Project Instructions source for Game Foundry Studio. +++++ +++++Deprecated reference locations must not be used as active instruction sources: +++++- `docs_build/dev/PROJECT_INSTRUCTIONS.md` +++++- `project-instructions/` +++++- archived Project Instructions snapshots +++++- generated PR reports +++++ +++++If deprecated reference material conflicts with `docs_build/dev/ProjectInstructions/`, the active folder wins unless OWNER explicitly approves a newer governance change. +++++ +++++## End Of Day +++++ +++++```text +++++git checkout main +++++git fetch origin +++++git pull --ff-only origin main +++++git status +++++git rev-list --left-right --count main...origin/main +++++``` +++++ +++++Required: +++++ +++++```text +++++On branch main +++++nothing to commit, working tree clean +++++0 0 +++++``` +++++ +++++The EOD report must record the final `HEAD` SHA as the published EOD SHA. +++++ +++++## Next Day Start +++++ +++++```text +++++git checkout main +++++git fetch origin +++++git pull --ff-only origin main +++++git status +++++git rev-list --left-right --count main...origin/main +++++git rev-parse HEAD +++++``` +++++ +++++## Team Branch Creation Gate +++++ +++++No team creates a PR branch until: +++++- Current branch: `main` +++++- Worktree: clean +++++- `main...origin/main`: `0 0` +++++- `HEAD` SHA matches published EOD SHA +++++ +++++If any check fails, stop before branch creation and restore main to the published EOD state or request OWNER direction. +++++ +++++## Start Of Day Boundary +++++ +++++`docs_build/dev/start_of_day/` may point to `docs_build/dev/ProjectInstructions/`, but it must not become a second active Project Instructions source. ++++diff --git a/docs_build/dev/ProjectInstructions/addendums/test_structure_standardization.md b/docs_build/dev/ProjectInstructions/addendums/test_structure_standardization.md ++++new file mode 100644 ++++index 000000000..997b16730 ++++--- /dev/null +++++++ b/docs_build/dev/ProjectInstructions/addendums/test_structure_standardization.md ++++@@ -0,0 +1,33 @@ +++++# Test Structure Standardization +++++ +++++## Purpose +++++ +++++Standardize testing locations and ensure independent tool validation. +++++ +++++## Canonical Test Structure +++++ +++++Tool tests: +++++- tests/toolbox/{tool-name}/ +++++ +++++Engine tests: +++++- tests/engine/{feature-name}/ +++++ +++++API tests: +++++- tests/api/{feature-name}/ +++++ +++++Server tests: +++++- tests/server/{feature-name}/ +++++ +++++Shared JavaScript tests: +++++- tests/js/shared/ +++++ +++++Regression tests: +++++- tests/regression/ +++++ +++++## Rules +++++ +++++- Every tool must be independently testable. +++++- Regression tests do not replace tool tests. +++++- Tool tests validate tool functionality. +++++- Regression tests validate platform behavior. +++++- New tests follow the canonical structure. ++++diff --git a/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock.md b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock.md ++++new file mode 100644 ++++index 000000000..5c7927f17 ++++--- /dev/null +++++++ b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock.md ++++@@ -0,0 +1,25 @@ +++++# PR_26177_OWNER_007-project-instructions-single-source-eod-lock +++++ +++++Date: 2026-06-26 +++++Scope: Project Instructions single-source and EOD main lock governance +++++Status: PASS +++++ +++++## Summary +++++ +++++- Established `docs_build/dev/ProjectInstructions/` as the only active Project Instructions source. +++++- Migrated legacy root `project-instructions/addendums/` content into active `docs_build/dev/ProjectInstructions/addendums/` files. +++++- Marked legacy `docs_build/dev/PROJECT_INSTRUCTIONS.md` and `project-instructions/` material as deprecated reference only. +++++- Added EOD main lock, next-day reset, and team branch creation gate governance. +++++- Updated active team start and governance docs to reference only `docs_build/dev/ProjectInstructions/`. +++++- No product/runtime, `start_of_day`, feature, or legacy SQLite file changes were made. +++++ +++++## Validation +++++ +++++- PASS: targeted grep found no active duplicate ProjectInstructions source-of-truth claim outside the active source. +++++- PASS: targeted grep confirmed EOD/Next Day governance appears in active governance docs. +++++- PASS: product/runtime and `start_of_day` changed-file check returned no files. +++++- PASS: `git diff --check`. +++++ +++++## Artifact +++++ +++++- `tmp/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_delta.zip` ++++diff --git a/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_branch-validation.md b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_branch-validation.md ++++new file mode 100644 ++++index 000000000..17e0bfc39 ++++--- /dev/null +++++++ b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_branch-validation.md ++++@@ -0,0 +1,7 @@ +++++# PR_26177_OWNER_007-project-instructions-single-source-eod-lock Branch Validation +++++ +++++- PASS: Started from `main`. +++++- PASS: Start gate confirmed worktree clean before branch creation. +++++- PASS: Start gate confirmed `main...origin/main` was `0 0` before branch creation. +++++- PASS: Current branch is `PR_26177_OWNER_007-project-instructions-single-source-eod-lock`. +++++- PASS: No `.vscode/settings.json` change is staged or included. ++++diff --git a/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_manual-validation-notes.md b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_manual-validation-notes.md ++++new file mode 100644 ++++index 000000000..10cbb4170 ++++--- /dev/null +++++++ b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_manual-validation-notes.md ++++@@ -0,0 +1,8 @@ +++++# PR_26177_OWNER_007-project-instructions-single-source-eod-lock Manual Validation Notes +++++ +++++- Reviewed ProjectInstructions path and text references. +++++- Confirmed active source declarations live under `docs_build/dev/ProjectInstructions/`. +++++- Confirmed legacy locations are preserved as deprecated reference material rather than active sources. +++++- Confirmed `docs_build/dev/start_of_day/` was not modified. +++++- Confirmed no product/runtime files were modified. +++++- Confirmed ZIP artifact path: `tmp/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_delta.zip`. ++++diff --git a/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_requirement-checklist.md b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_requirement-checklist.md ++++new file mode 100644 ++++index 000000000..99ab45345 ++++--- /dev/null +++++++ b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_requirement-checklist.md ++++@@ -0,0 +1,16 @@ +++++# PR_26177_OWNER_007-project-instructions-single-source-eod-lock Requirement Checklist +++++ +++++- PASS: Audited repo for ProjectInstructions / project instructions duplicates. +++++- PASS: Active source is `docs_build/dev/ProjectInstructions/`. +++++- PASS: Legacy `docs_build/dev/PROJECT_INSTRUCTIONS.md` is marked deprecated. +++++- PASS: Legacy root `project-instructions/` folder is marked deprecated. +++++- PASS: Legacy root addendums are migrated into the active addendum tree. +++++- PASS: Active team start/governance docs reference only `docs_build/dev/ProjectInstructions/`. +++++- PASS: Added EOD command sequence. +++++- PASS: Added required EOD output: `On branch main`, clean worktree, `0 0`. +++++- PASS: Added Next Day Start command sequence. +++++- PASS: Added team branch creation rule requiring main, clean worktree, `0 0`, and matching published EOD SHA. +++++- PASS: Did not modify `start_of_day` folders. +++++- PASS: Did not modify product/runtime files. +++++- PASS: Did not remove, move, or overwrite legacy SQLite files. +++++- PASS: Did not start feature work. ++++diff --git a/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_validation-lane.md b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_validation-lane.md ++++new file mode 100644 ++++index 000000000..8a1b82360 ++++--- /dev/null +++++++ b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_validation-lane.md ++++@@ -0,0 +1,17 @@ +++++# PR_26177_OWNER_007-project-instructions-single-source-eod-lock Validation Lane +++++ +++++- PASS: duplicate-source grep returned no matches for old active source claims. +++++- PASS: EOD/Next Day governance grep returned active governance matches. +++++- PASS: product/runtime/start_of_day changed-file check returned no files. +++++- PASS: git diff --check. +++++ +++++Commands used: +++++ +++++~~~text +++++rg -n 'project-instructions/addendums|docs_build/dev/PROJECT_INSTRUCTIONS.md.*source of truth|Codex must always read `docs_build/dev/PROJECT_INSTRUCTIONS.md`|Read `docs_build/dev/PROJECT_INSTRUCTIONS.md`' docs_build/dev/ProjectInstructions docs_build/dev/PROJECT_INSTRUCTIONS.md project-instructions +++++rg -n "End of Day:|Next Day Start:|HEAD.*published EOD SHA|only active Project Instructions source" docs_build/dev/ProjectInstructions +++++git diff --name-only -- src assets toolbox games api serverside package.json package-lock.json docs_build/dev/start_of_day +++++git diff --check +++++~~~ +++++ +++++Full product/runtime tests were not run because this PR changes governance documentation only. ++++diff --git a/project-instructions/README.md b/project-instructions/README.md ++++new file mode 100644 ++++index 000000000..af401852e ++++--- /dev/null +++++++ b/project-instructions/README.md ++++@@ -0,0 +1,11 @@ +++++# Deprecated Project Instructions Reference +++++ +++++This folder is preserved as historical reference only. +++++ +++++The only active Project Instructions source is: +++++ +++++```text +++++docs_build/dev/ProjectInstructions/ +++++``` +++++ +++++Do not use files under `project-instructions/` as active governance. If a file here conflicts with `docs_build/dev/ProjectInstructions/`, the active folder wins unless OWNER explicitly approves a newer governance change. +++diff --git a/project-instructions/README.md b/project-instructions/README.md +++new file mode 100644 +++index 000000000..af401852e +++--- /dev/null ++++++ b/project-instructions/README.md +++@@ -0,0 +1,11 @@ ++++# Deprecated Project Instructions Reference ++++ ++++This folder is preserved as historical reference only. ++++ ++++The only active Project Instructions source is: ++++ ++++```text ++++docs_build/dev/ProjectInstructions/ ++++``` ++++ ++++Do not use files under `project-instructions/` as active governance. If a file here conflicts with `docs_build/dev/ProjectInstructions/`, the active folder wins unless OWNER explicitly approves a newer governance change. +++diff --git a/project-instructions/addendums/assistant-execution-modes.md b/project-instructions/addendums/assistant-execution-modes.md +++index 6d7928669..4c5637d0d 100644 +++--- a/project-instructions/addendums/assistant-execution-modes.md ++++++ b/project-instructions/addendums/assistant-execution-modes.md +++@@ -1,5 +1,7 @@ +++ # Assistant Execution Modes +++ ++++> Deprecated reference notice: this file is preserved for history only. The active copy is `docs_build/dev/ProjectInstructions/addendums/assistant_execution_modes.md`. ++++ +++ ## Purpose +++ +++ Standardize request interpretation and expected outputs for Review, Owner, Build PR, Continue, Challenge, and Stop Gate workflows. +++diff --git a/project-instructions/addendums/canonical-repository-structure.md b/project-instructions/addendums/canonical-repository-structure.md +++index e26939469..6b9dcb242 100644 +++--- a/project-instructions/addendums/canonical-repository-structure.md ++++++ b/project-instructions/addendums/canonical-repository-structure.md +++@@ -1,5 +1,7 @@ +++ # Canonical Repository Structure +++ ++++> Deprecated reference notice: this file is preserved for history only. The active copy is `docs_build/dev/ProjectInstructions/addendums/canonical_repository_structure.md`. ++++ +++ ## Purpose +++ +++ Establish the canonical repository structure for future development and reduce technical debt. +++diff --git a/project-instructions/addendums/codex-artifact-and-reporting-standard.md b/project-instructions/addendums/codex-artifact-and-reporting-standard.md +++index 3f16a3641..8d1327886 100644 +++--- a/project-instructions/addendums/codex-artifact-and-reporting-standard.md ++++++ b/project-instructions/addendums/codex-artifact-and-reporting-standard.md +++@@ -1,5 +1,7 @@ +++ # Codex Artifact and Reporting Standard +++ ++++> Deprecated reference notice: this file is preserved for history only. The active copy is `docs_build/dev/ProjectInstructions/addendums/codex_artifact_and_reporting_standard.md`. ++++ +++ ## Purpose +++ +++ Standardize Codex deliverables, completion reporting, and artifact generation. +++diff --git a/project-instructions/addendums/codex-project-instructions-startup.md b/project-instructions/addendums/codex-project-instructions-startup.md +++index 94744f06e..135498b42 100644 +++--- a/project-instructions/addendums/codex-project-instructions-startup.md ++++++ b/project-instructions/addendums/codex-project-instructions-startup.md +++@@ -1,5 +1,7 @@ +++ # Codex Project Instructions Startup +++ ++++> Deprecated reference notice: this file is preserved for history only. The active copy is `docs_build/dev/ProjectInstructions/addendums/codex_project_instructions_startup.md`. ++++ +++ ## Purpose +++ +++ Ensure Codex uses the current approved governance before making repository changes. +++diff --git a/project-instructions/addendums/legacy-migration-policy.md b/project-instructions/addendums/legacy-migration-policy.md +++index 5e43679f4..5515a1728 100644 +++--- a/project-instructions/addendums/legacy-migration-policy.md ++++++ b/project-instructions/addendums/legacy-migration-policy.md +++@@ -1,5 +1,7 @@ +++ # Legacy Migration Policy +++ ++++> Deprecated reference notice: this file is preserved for history only. The active copy is `docs_build/dev/ProjectInstructions/addendums/legacy_migration_policy.md`. ++++ +++ ## Purpose +++ +++ Reduce technical debt incrementally during normal development. +++diff --git a/project-instructions/addendums/test-structure-standardization.md b/project-instructions/addendums/test-structure-standardization.md +++index 997b16730..eeb62d561 100644 +++--- a/project-instructions/addendums/test-structure-standardization.md ++++++ b/project-instructions/addendums/test-structure-standardization.md +++@@ -1,5 +1,7 @@ +++ # Test Structure Standardization +++ ++++> Deprecated reference notice: this file is preserved for history only. The active copy is `docs_build/dev/ProjectInstructions/addendums/test_structure_standardization.md`. ++++ +++ ## Purpose +++ +++ Standardize testing locations and ensure independent tool validation. ++diff --git a/docs_build/dev/reports/coverage_changed_js_guardrail.txt b/docs_build/dev/reports/coverage_changed_js_guardrail.txt ++index 7b1c51f19..01a698376 100644 ++--- a/docs_build/dev/reports/coverage_changed_js_guardrail.txt +++++ b/docs_build/dev/reports/coverage_changed_js_guardrail.txt ++@@ -6,7 +6,9 @@ Missing changed runtime JS files are WARN, not FAIL. ++ Source: Playwright/Chromium built-in V8 coverage from the active Playwright run. ++ ++ Changed runtime JS files considered: ++-(100%) none changed - no changed runtime JS files +++(0%) src/dev-runtime/persistence/game-journey-completion-metrics-migration.mjs - WARNING: changed runtime JS file was not collected by Playwright V8 coverage; advisory only +++(0%) src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs - WARNING: changed runtime JS file was not collected by Playwright V8 coverage; advisory only ++ ++ Guardrail warnings: ++-(100%) none changed - no changed runtime JS files +++(0%) src/dev-runtime/persistence/game-journey-completion-metrics-migration.mjs - WARNING: changed runtime JS file missing from coverage; advisory only +++(0%) src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs - WARNING: changed runtime JS file missing from coverage; advisory only ++diff --git a/docs_build/dev/reports/playwright_v8_coverage_report.txt b/docs_build/dev/reports/playwright_v8_coverage_report.txt ++index f2363d3bf..da369bcdb 100644 ++--- a/docs_build/dev/reports/playwright_v8_coverage_report.txt +++++ b/docs_build/dev/reports/playwright_v8_coverage_report.txt ++@@ -17,7 +17,8 @@ Exercised tool entry points detected: ++ (72%) Theme V2 Shared JS - exercised 4 runtime JS files + +- - Removed active runtime defaulting to `tmp/local-api/game-journey-completion-metrics.sqlite` in `createGameJourneyCompletionMetricsStore`. +--- Kept the explicit `legacyDbPath` guard intact for recovery/migration callers so legacy data is still protected from silent overwrite or deletion. +-+- Removed active runtime `legacyDbPath` guard plumbing from the Game Journey metrics store, repository, Local API router, and Playwright test server helper. +- - Updated `toolbox/tools-page-accordions.js` to render neutral Creator-safe progress outage wording instead of backend diagnostics. +--- Added a store-level regression test proving a retired default SQLite-shaped file does not block active Postgres-backed metrics. +-+- Added a store-level regression test proving a retired default SQLite-shaped file does not block or get touched by active DB-backed metrics. +-+- Added a targeted guardrail test proving active runtime JS/MJS under `src`, `assets`, and `toolbox` has no SQLite or `tmp/local-api` metrics references, excluding the migration-only utility. +- - Added a focused Playwright test proving the toolbox page does not render the forbidden warning, SQLite wording, local filesystem path, or Postgres internals when metrics are unavailable. +- +- ## Reference Comparison +-@@ -28,16 +29,20 @@ Recover the Game Journey completion metrics path so active Alfa and Owner work n +- - PASS: `node --check` on modified source and test files. +- - PASS: `node ./scripts/run-node-test-files.mjs tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs tests/dev-runtime/GameJourneyCompletionMetricsMigration.test.mjs`. +- - PASS: `npx playwright test tests/playwright/tools/GameJourneyTool.spec.mjs --project=playwright --workers=1 --reporter=line -g "Game Journey Local API persists completion metrics to Postgres|Toolbox renders Creator-safe Game Journey progress outage copy"`. +--- PASS: Direct proof against the actual existing `tmp/local-api/game-journey-completion-metrics.sqlite` file confirmed active Postgres metrics load 14 buckets and do not resolve a legacy path. +--- PASS: Runtime source search found no `Game Journey completion metrics unavailable` string. +--- PASS: Runtime source search found no active metrics-store default reference to `game-journey-completion-metrics.sqlite`, `GAMEFOUNDRY_GAME_JOURNEY_METRICS_DB_PATH`, or `defaultLegacySqlitePath`. +-+- PASS: Direct proof against the actual existing `tmp/local-api/game-journey-completion-metrics.sqlite` file confirmed active DB metrics load 14 buckets, expose no legacy path fields, and do not touch the retired file. +-+- PASS: Active runtime JS/MJS search found no SQLite, `.sqlite`, `better-sqlite`, `game-journey-completion-metrics.sqlite`, or `tmp/local-api` references outside the migration-only utility. +-+- PASS: Runtime source search found no `Game Journey completion metrics unavailable` Creator-facing string. +- - PASS: `git diff --check` reported no whitespace errors. Git emitted line-ending warnings only. ++ Changed runtime JS files covered: ++-(100%) none changed - no changed runtime JS files +++(0%) src/dev-runtime/persistence/game-journey-completion-metrics-migration.mjs - WARNING: changed runtime JS file was not collected by Playwright V8 coverage; advisory only +++(0%) src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs - WARNING: changed runtime JS file was not collected by Playwright V8 coverage; advisory only + +- ## Files ++ Files with executed line/function counts where available: ++ (36%) src/shared/toolbox/tool-metadata-inventory.js - executed lines 2041/2041; executed functions 12/33 ++@@ -33,10 +34,11 @@ Files with executed line/function counts where available: ++ (100%) assets/js/shared/game-journey-api-client.js - executed lines 19/19; executed functions 2/2 + +- - `src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs` +-+- `src/dev-runtime/persistence/tool-repositories/game-journey-mock-repository.js` +-+- `src/dev-runtime/server/local-api-router.mjs` +- - `tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs` +-+- `tests/helpers/playwrightRepoServer.mjs` +- - `tests/playwright/tools/GameJourneyTool.spec.mjs` +-+- `tests/playwright/tools/IdeaBoardTableNotes.spec.mjs` +- - `toolbox/tools-page-accordions.js` ++ Uncovered or low-coverage changed JS files: ++-(100%) none changed - no changed runtime JS files +++(0%) src/dev-runtime/persistence/game-journey-completion-metrics-migration.mjs - WARNING: uncovered changed runtime JS file; advisory only +++(0%) src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs - WARNING: uncovered changed runtime JS file; advisory only + +- ## Artifact +-diff --git a/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_requirement-checklist.md b/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_requirement-checklist.md +-index 544b7057f..65a654b6d 100644 +---- a/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_requirement-checklist.md +-+++ b/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_requirement-checklist.md +-@@ -11,12 +11,14 @@ Status: PASS +- - PASS: Fixed only the Game Journey completion metrics regression. +- - PASS: Did not delete, move, overwrite, export, or migrate `tmp/local-api/game-journey-completion-metrics.sqlite`. +- - PASS: Stopped active runtime from defaulting to `tmp/local-api/game-journey-completion-metrics.sqlite`. +-+- PASS: Removed active runtime `legacyDbPath` SQLite guard plumbing. +- - PASS: Preserved Postgres-backed Game Journey completion metrics as the active path. +- - PASS: Ensured `toolbox/tools-page-accordions.js` cannot render `Game Journey completion metrics unavailable:`. +- - PASS: Creator-facing UI does not expose SQLite, local filesystem paths, migration/export language, or Postgres internals. +- - PASS: Did not introduce silent fallback behavior; metrics outage remains visible with neutral wording. +- - PASS: Added targeted regression tests. +- - PASS: Proved the existing legacy SQLite file does not block active metrics. +-+- PASS: Proved active runtime JS/MJS has no SQLite or `tmp/local-api` metrics references outside the migration-only utility. +- - PASS: Proved the forbidden warning string is not rendered. +- - PASS: Proved Game Journey metrics still load through the active DB/API path. +- - PASS: Used targeted validation only. +-diff --git a/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_validation-lane.md b/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_validation-lane.md +-index fe5ba4768..47530c453 100644 +---- a/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_validation-lane.md +-+++ b/docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recovery_validation-lane.md +-@@ -6,9 +6,13 @@ Status: PASS ++ Changed JS files considered: ++-(0%) scripts/validate-browser-env-agnostic.mjs - changed JS file not collected as browser runtime coverage ++-(0%) tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs - changed JS file not collected as browser runtime coverage ++-(0%) tests/playwright/tools/AdminHealthOperationsPage.spec.mjs - changed JS file not collected as browser runtime coverage ++-(0%) tests/playwright/tools/GameJourneyTool.spec.mjs - changed JS file not collected as browser runtime coverage +++(0%) scripts/migrate-game-journey-completion-metrics-sqlite-to-postgres.mjs - changed JS file not collected as browser runtime coverage +++(0%) src/dev-runtime/persistence/game-journey-completion-metrics-migration.mjs - changed JS file not collected as browser runtime coverage +++(0%) src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs - changed JS file not collected as browser runtime coverage +++(0%) tests/dev-runtime/GameJourneyCompletionMetricsMigration.test.mjs - changed JS file not collected as browser runtime coverage ++diff --git a/project-instructions/README.md b/project-instructions/README.md +new file mode 100644 -+index 000000000..997b16730 ++index 000000000..af401852e +--- /dev/null -++++ b/docs_build/dev/ProjectInstructions/addendums/test_structure_standardization.md -+@@ -0,0 +1,33 @@ -++# Test Structure Standardization -++ -++## Purpose -++ -++Standardize testing locations and ensure independent tool validation. -++ -++## Canonical Test Structure -++ -++Tool tests: -++- tests/toolbox/{tool-name}/ -++ -++Engine tests: -++- tests/engine/{feature-name}/ -++ -++API tests: -++- tests/api/{feature-name}/ -++ -++Server tests: -++- tests/server/{feature-name}/ -++ -++Shared JavaScript tests: -++- tests/js/shared/ -++ -++Regression tests: -++- tests/regression/ -++ -++## Rules +++++ b/project-instructions/README.md ++@@ -0,0 +1,11 @@ +++# Deprecated Project Instructions Reference ++ -++- Every tool must be independently testable. -++- Regression tests do not replace tool tests. -++- Tool tests validate tool functionality. -++- Regression tests validate platform behavior. -++- New tests follow the canonical structure. -+diff --git a/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock.md b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock.md -+new file mode 100644 -+index 000000000..5c7927f17 -+--- /dev/null -++++ b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock.md -+@@ -0,0 +1,25 @@ -++# PR_26177_OWNER_007-project-instructions-single-source-eod-lock +++This folder is preserved as historical reference only. ++ -++Date: 2026-06-26 -++Scope: Project Instructions single-source and EOD main lock governance -++Status: PASS +++The only active Project Instructions source is: ++ -++## Summary +++```text +++docs_build/dev/ProjectInstructions/ +++``` ++ -++- Established `docs_build/dev/ProjectInstructions/` as the only active Project Instructions source. -++- Migrated legacy root `project-instructions/addendums/` content into active `docs_build/dev/ProjectInstructions/addendums/` files. -++- Marked legacy `docs_build/dev/PROJECT_INSTRUCTIONS.md` and `project-instructions/` material as deprecated reference only. -++- Added EOD main lock, next-day reset, and team branch creation gate governance. -++- Updated active team start and governance docs to reference only `docs_build/dev/ProjectInstructions/`. -++- No product/runtime, `start_of_day`, feature, or legacy SQLite file changes were made. +++Do not use files under `project-instructions/` as active governance. If a file here conflicts with `docs_build/dev/ProjectInstructions/`, the active folder wins unless OWNER explicitly approves a newer governance change. ++diff --git a/project-instructions/addendums/assistant-execution-modes.md b/project-instructions/addendums/assistant-execution-modes.md ++index 6d7928669..4c5637d0d 100644 ++--- a/project-instructions/addendums/assistant-execution-modes.md +++++ b/project-instructions/addendums/assistant-execution-modes.md ++@@ -1,5 +1,7 @@ ++ # Assistant Execution Modes + +- ```powershell +- node --check src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs +-+node --check src/dev-runtime/persistence/tool-repositories/game-journey-mock-repository.js +-+node --check src/dev-runtime/server/local-api-router.mjs +- node --check toolbox/tools-page-accordions.js +- node --check tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs +-+node --check tests/helpers/playwrightRepoServer.mjs +- node --check tests/playwright/tools/GameJourneyTool.spec.mjs +-+node --check tests/playwright/tools/IdeaBoardTableNotes.spec.mjs +- ``` +++> Deprecated reference notice: this file is preserved for history only. The active copy is `docs_build/dev/ProjectInstructions/addendums/assistant_execution_modes.md`. ++ -++## Validation ++ ## Purpose + +- Result: PASS +-@@ -17,7 +21,7 @@ Result: PASS +- node ./scripts/run-node-test-files.mjs tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs tests/dev-runtime/GameJourneyCompletionMetricsMigration.test.mjs +- ``` ++ Standardize request interpretation and expected outputs for Review, Owner, Build PR, Continue, Challenge, and Stop Gate workflows. ++diff --git a/project-instructions/addendums/canonical-repository-structure.md b/project-instructions/addendums/canonical-repository-structure.md ++index e26939469..6b9dcb242 100644 ++--- a/project-instructions/addendums/canonical-repository-structure.md +++++ b/project-instructions/addendums/canonical-repository-structure.md ++@@ -1,5 +1,7 @@ ++ # Canonical Repository Structure + +--Result: PASS, 2 targeted node test files passed +-+Result: PASS, 2 targeted node test files passed. Includes active runtime JS/MJS SQLite reference guardrail. +++> Deprecated reference notice: this file is preserved for history only. The active copy is `docs_build/dev/ProjectInstructions/addendums/canonical_repository_structure.md`. ++ -++- PASS: targeted grep found no active duplicate ProjectInstructions source-of-truth claim outside the active source. -++- PASS: targeted grep confirmed EOD/Next Day governance appears in active governance docs. -++- PASS: product/runtime and `start_of_day` changed-file check returned no files. -++- PASS: `git diff --check`. ++ ## Purpose + +- ```powershell +- npx playwright test tests/playwright/tools/GameJourneyTool.spec.mjs --project=playwright --workers=1 --reporter=line -g "Game Journey Local API persists completion metrics to Postgres|Toolbox renders Creator-safe Game Journey progress outage copy" +-@@ -26,14 +30,14 @@ npx playwright test tests/playwright/tools/GameJourneyTool.spec.mjs --project=pl +- Result: PASS, 2 passed ++ Establish the canonical repository structure for future development and reduce technical debt. ++diff --git a/project-instructions/addendums/codex-artifact-and-reporting-standard.md b/project-instructions/addendums/codex-artifact-and-reporting-standard.md ++index 3f16a3641..8d1327886 100644 ++--- a/project-instructions/addendums/codex-artifact-and-reporting-standard.md +++++ b/project-instructions/addendums/codex-artifact-and-reporting-standard.md ++@@ -1,5 +1,7 @@ ++ # Codex Artifact and Reporting Standard + +- ```powershell +--node -e "import('node:fs').then(async fs=>{const [{createGameJourneyCompletionMetricsStore}, {createGameJourneyCompletionMetricsPostgresClientStub}] = await Promise.all([import('./src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs'), import('./tests/helpers/gameJourneyCompletionMetricsPostgresClientStub.mjs')]); const legacy='tmp/local-api/game-journey-completion-metrics.sqlite'; if(!fs.existsSync(legacy)) throw new Error('Expected existing legacy SQLite file for regression proof'); const store=createGameJourneyCompletionMetricsStore({postgresClient:createGameJourneyCompletionMetricsPostgresClientStub()}); const metrics=await store.listMetrics(); if(store.legacyDbPath) throw new Error('Active store resolved a legacy path'); if(metrics.length!==14) throw new Error('Expected 14 active metrics'); console.log('PASS active Postgres metrics ignore existing retired legacy SQLite file');})" +-+node -e "import('node:fs').then(async fs=>{const [{createGameJourneyCompletionMetricsStore}, {createGameJourneyCompletionMetricsPostgresClientStub}] = await Promise.all([import('./src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs'), import('./tests/helpers/gameJourneyCompletionMetricsPostgresClientStub.mjs')]); const legacy='tmp/local-api/game-journey-completion-metrics.sqlite'; if(!fs.existsSync(legacy)) throw new Error('Expected existing retired local file for regression proof'); const before=fs.statSync(legacy).mtimeMs; const store=createGameJourneyCompletionMetricsStore({postgresClient:createGameJourneyCompletionMetricsPostgresClientStub()}); const metrics=await store.listMetrics(); const snapshot=await store.snapshot(); const after=fs.statSync(legacy).mtimeMs; if(Object.hasOwn(store, 'legacyDbPath')) throw new Error('Store exposes legacyDbPath'); if(Object.hasOwn(snapshot, 'legacySqlitePath')) throw new Error('Snapshot exposes legacySqlitePath'); if(metrics.length!==14) throw new Error('Expected 14 active metrics'); if(before!==after) throw new Error('Retired local file was touched'); console.log('PASS active DB metrics ignore and do not inspect retired local file');})" +- ``` +++> Deprecated reference notice: this file is preserved for history only. The active copy is `docs_build/dev/ProjectInstructions/addendums/codex_artifact_and_reporting_standard.md`. ++ -++## Artifact ++ ## Purpose + +- Result: PASS ++ Standardize Codex deliverables, completion reporting, and artifact generation. ++diff --git a/project-instructions/addendums/codex-project-instructions-startup.md b/project-instructions/addendums/codex-project-instructions-startup.md ++index 94744f06e..135498b42 100644 ++--- a/project-instructions/addendums/codex-project-instructions-startup.md +++++ b/project-instructions/addendums/codex-project-instructions-startup.md ++@@ -1,5 +1,7 @@ ++ # Codex Project Instructions Startup + +- ```powershell +-+rg -n -i "sqlite|better-sqlite|game-journey-completion-metrics\.sqlite|tmp/local-api" src assets toolbox -g "*.js" -g "*.mjs" --glob "!src/dev-runtime/persistence/game-journey-completion-metrics-migration.mjs" +- rg -n "Game Journey completion metrics unavailable" src assets toolbox --glob "!**/*.map" +--rg -n "game-journey-completion-metrics\.sqlite|GAMEFOUNDRY_GAME_JOURNEY_METRICS_DB_PATH|defaultLegacySqlitePath" src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs toolbox/tools-page-accordions.js assets/toolbox/game-journey/js/index.js +- ``` +++> Deprecated reference notice: this file is preserved for history only. The active copy is `docs_build/dev/ProjectInstructions/addendums/codex_project_instructions_startup.md`. ++ -++- `tmp/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_delta.zip` -+diff --git a/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_branch-validation.md b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_branch-validation.md -+new file mode 100644 -+index 000000000..17e0bfc39 -+--- /dev/null -++++ b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_branch-validation.md -+@@ -0,0 +1,7 @@ -++# PR_26177_OWNER_007-project-instructions-single-source-eod-lock Branch Validation ++ ## Purpose + +- Result: PASS, no matches +-diff --git a/docs_build/dev/reports/codex_changed_files.txt b/docs_build/dev/reports/codex_changed_files.txt +-index 585a10850..8e34972a1 100644 +---- a/docs_build/dev/reports/codex_changed_files.txt +-+++ b/docs_build/dev/reports/codex_changed_files.txt +-@@ -6,6 +6,9 @@ docs_build/dev/reports/PR_26177_OWNER_057-game-journey-metrics-regression-recove +- docs_build/dev/reports/codex_changed_files.txt +- docs_build/dev/reports/codex_review.diff +- src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs +-+src/dev-runtime/persistence/tool-repositories/game-journey-mock-repository.js +-+src/dev-runtime/server/local-api-router.mjs +- tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs +-+tests/helpers/playwrightRepoServer.mjs +- tests/playwright/tools/GameJourneyTool.spec.mjs +--toolbox/tools-page-accordions.js +-+tests/playwright/tools/IdeaBoardTableNotes.spec.mjs +-diff --git a/src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs b/src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs +-index 6c202c8a2..eea6294e7 100644 +---- a/src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs +-+++ b/src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs +-@@ -1,5 +1,3 @@ +--import { existsSync } from "node:fs"; +--import path from "node:path"; +- import { createPostgresConnectionClient } from "./postgres-connection-client.mjs"; +- import { SEED_DB_KEYS, makeSeedUlid } from "../seed/seed-db-keys.mjs"; +- +-@@ -59,24 +57,6 @@ function clone(value) { +- return JSON.parse(JSON.stringify(value)); ++ Ensure Codex uses the current approved governance before making repository changes. ++diff --git a/project-instructions/addendums/legacy-migration-policy.md b/project-instructions/addendums/legacy-migration-policy.md ++index 5e43679f4..5515a1728 100644 ++--- a/project-instructions/addendums/legacy-migration-policy.md +++++ b/project-instructions/addendums/legacy-migration-policy.md ++@@ -1,5 +1,7 @@ ++ # Legacy Migration Policy ++ +++> Deprecated reference notice: this file is preserved for history only. The active copy is `docs_build/dev/ProjectInstructions/addendums/legacy_migration_policy.md`. ++ -++- PASS: Started from `main`. -++- PASS: Start gate confirmed worktree clean before branch creation. -++- PASS: Start gate confirmed `main...origin/main` was `0 0` before branch creation. -++- PASS: Current branch is `PR_26177_OWNER_007-project-instructions-single-source-eod-lock`. -++- PASS: No `.vscode/settings.json` change is staged or included. -+diff --git a/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_manual-validation-notes.md b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_manual-validation-notes.md -+new file mode 100644 -+index 000000000..10cbb4170 -+--- /dev/null -++++ b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_manual-validation-notes.md -+@@ -0,0 +1,8 @@ -++# PR_26177_OWNER_007-project-instructions-single-source-eod-lock Manual Validation Notes ++ ## Purpose ++ ++ Reduce technical debt incrementally during normal development. ++diff --git a/project-instructions/addendums/test-structure-standardization.md b/project-instructions/addendums/test-structure-standardization.md ++index 997b16730..eeb62d561 100644 ++--- a/project-instructions/addendums/test-structure-standardization.md +++++ b/project-instructions/addendums/test-structure-standardization.md ++@@ -1,5 +1,7 @@ ++ # Test Structure Standardization ++ +++> Deprecated reference notice: this file is preserved for history only. The active copy is `docs_build/dev/ProjectInstructions/addendums/test_structure_standardization.md`. ++ -++- Reviewed ProjectInstructions path and text references. -++- Confirmed active source declarations live under `docs_build/dev/ProjectInstructions/`. -++- Confirmed legacy locations are preserved as deprecated reference material rather than active sources. -++- Confirmed `docs_build/dev/start_of_day/` was not modified. -++- Confirmed no product/runtime files were modified. -++- Confirmed ZIP artifact path: `tmp/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_delta.zip`. -+diff --git a/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_requirement-checklist.md b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_requirement-checklist.md ++ ## Purpose ++ ++ Standardize testing locations and ensure independent tool validation. ++diff --git a/scripts/migrate-game-journey-completion-metrics-sqlite-to-postgres.mjs b/scripts/migrate-game-journey-completion-metrics-sqlite-to-postgres.mjs +new file mode 100644 -+index 000000000..99ab45345 ++index 000000000..bb3c19985 +--- /dev/null -++++ b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_requirement-checklist.md -+@@ -0,0 +1,16 @@ -++# PR_26177_OWNER_007-project-instructions-single-source-eod-lock Requirement Checklist -++ -++- PASS: Audited repo for ProjectInstructions / project instructions duplicates. -++- PASS: Active source is `docs_build/dev/ProjectInstructions/`. -++- PASS: Legacy `docs_build/dev/PROJECT_INSTRUCTIONS.md` is marked deprecated. -++- PASS: Legacy root `project-instructions/` folder is marked deprecated. -++- PASS: Legacy root addendums are migrated into the active addendum tree. -++- PASS: Active team start/governance docs reference only `docs_build/dev/ProjectInstructions/`. -++- PASS: Added EOD command sequence. -++- PASS: Added required EOD output: `On branch main`, clean worktree, `0 0`. -++- PASS: Added Next Day Start command sequence. -++- PASS: Added team branch creation rule requiring main, clean worktree, `0 0`, and matching published EOD SHA. -++- PASS: Did not modify `start_of_day` folders. -++- PASS: Did not modify product/runtime files. -++- PASS: Did not remove, move, or overwrite legacy SQLite files. -++- PASS: Did not start feature work. -+diff --git a/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_validation-lane.md b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_validation-lane.md +++++ b/scripts/migrate-game-journey-completion-metrics-sqlite-to-postgres.mjs ++@@ -0,0 +1,156 @@ +++import fs from "node:fs"; +++import path from "node:path"; +++import process from "node:process"; +++import { +++ DEFAULT_GAME_JOURNEY_COMPLETION_METRICS_ARCHIVE_DIR, +++ DEFAULT_GAME_JOURNEY_COMPLETION_METRICS_SQLITE_PATH, +++ migrateLegacyCompletionMetricsSqliteToPostgres, +++ readLegacyCompletionMetricsSqlite, +++} from "../src/dev-runtime/persistence/game-journey-completion-metrics-migration.mjs"; +++ +++const ENV_FILE = ".env"; +++ +++function parseEnvValue(value) { +++ const trimmed = value.trim(); +++ const quote = trimmed[0]; +++ if ((quote === "\"" || quote === "'") && trimmed.endsWith(quote)) { +++ return trimmed.slice(1, -1); +++ } +++ const commentIndex = trimmed.indexOf(" #"); +++ return commentIndex === -1 ? trimmed : trimmed.slice(0, commentIndex).trim(); +++} +++ +++function loadRuntimeEnv() { +++ const envPath = path.resolve(process.cwd(), ENV_FILE); +++ if (!fs.existsSync(envPath)) { +++ return { +++ loaded: false, +++ loadedKeys: [], +++ path: envPath, +++ }; +++ } +++ const loadedKeys = []; +++ fs.readFileSync(envPath, "utf8").split(/\r?\n/u).forEach((line) => { +++ const trimmed = line.trim(); +++ if (!trimmed || trimmed.startsWith("#")) { +++ return; +++ } +++ const normalized = trimmed.startsWith("export ") ? trimmed.slice(7).trim() : trimmed; +++ const separatorIndex = normalized.indexOf("="); +++ if (separatorIndex <= 0) { +++ return; +++ } +++ const key = normalized.slice(0, separatorIndex).trim(); +++ if (!/^[A-Za-z_][A-Za-z0-9_]*$/u.test(key) || process.env[key] !== undefined) { +++ return; +++ } +++ process.env[key] = parseEnvValue(normalized.slice(separatorIndex + 1)); +++ loadedKeys.push(key); +++ }); +++ return { +++ loaded: true, +++ loadedKeys: loadedKeys.sort(), +++ path: envPath, +++ }; +++} +++ +++function parseArgs(argv) { +++ const options = { +++ archiveDir: DEFAULT_GAME_JOURNEY_COMPLETION_METRICS_ARCHIVE_DIR, +++ dryRun: false, +++ inspectOnly: false, +++ legacyDbPath: DEFAULT_GAME_JOURNEY_COMPLETION_METRICS_SQLITE_PATH, +++ pythonCommand: "python", +++ }; +++ for (let index = 0; index < argv.length; index += 1) { +++ const arg = argv[index]; +++ if (arg === "--dry-run") { +++ options.dryRun = true; +++ continue; +++ } +++ if (arg === "--inspect-only") { +++ options.inspectOnly = true; +++ continue; +++ } +++ if (arg === "--legacy-db") { +++ options.legacyDbPath = path.resolve(argv[index + 1] || ""); +++ index += 1; +++ continue; +++ } +++ if (arg === "--archive-dir") { +++ options.archiveDir = path.resolve(argv[index + 1] || ""); +++ index += 1; +++ continue; +++ } +++ if (arg === "--python") { +++ options.pythonCommand = argv[index + 1] || "python"; +++ index += 1; +++ continue; +++ } +++ throw new Error(`Unknown argument: ${arg}`); +++ } +++ return options; +++} +++ +++function printSummary(summary) { +++ Object.entries(summary).forEach(([key, value]) => { +++ console.log(`${key}: ${value}`); +++ }); +++} +++ +++async function main() { +++ const options = parseArgs(process.argv.slice(2)); +++ const envLoad = loadRuntimeEnv(); +++ const exported = await readLegacyCompletionMetricsSqlite({ +++ legacyDbPath: options.legacyDbPath, +++ pythonCommand: options.pythonCommand, +++ }); +++ printSummary({ +++ "Legacy SQLite": exported.legacyDbPath, +++ "Schema objects": exported.schema.objects.length, +++ "Valid rows": exported.rowCount, +++ }); +++ if (options.inspectOnly) { +++ console.log("PASS: inspect-only completed; no Postgres writes or file moves were attempted."); +++ return; +++ } +++ if (!String(process.env.GAMEFOUNDRY_DATABASE_URL || "").trim()) { +++ console.error("BLOCKED: GAMEFOUNDRY_DATABASE_URL is missing; migration did not run and the legacy SQLite file was not moved."); +++ console.error("Run after configuring Postgres, for example:"); +++ console.error(" node --use-system-ca scripts/migrate-game-journey-completion-metrics-sqlite-to-postgres.mjs"); +++ process.exitCode = 2; +++ return; +++ } +++ if (!String(process.env.GAMEFOUNDRY_DATABASE_SSL || "").trim()) { +++ console.error("BLOCKED: GAMEFOUNDRY_DATABASE_SSL is missing; migration did not run and the legacy SQLite file was not moved."); +++ console.error("Set GAMEFOUNDRY_DATABASE_SSL=disable for local Postgres or require for TLS Postgres."); +++ process.exitCode = 2; +++ return; +++ } +++ const result = await migrateLegacyCompletionMetricsSqliteToPostgres({ +++ archiveDir: options.archiveDir, +++ dryRun: options.dryRun, +++ env: process.env, +++ legacyDbPath: exported.legacyDbPath, +++ pythonCommand: options.pythonCommand, +++ }); +++ printSummary({ +++ "Env file": envLoad.loaded ? `${envLoad.path} (${envLoad.loadedKeys.length} key(s) loaded)` : "not found", +++ "Legacy rows": result.legacyRowCount, +++ "Rows inserted": result.insertedCount, +++ "Rows already present": result.duplicateCount, +++ "Rows timestamp-patched": result.timestampPatchCount, +++ "Rows that would insert": result.wouldInsertCount, +++ "Rows that would patch timestamps": result.wouldPatchTimestampCount, +++ "Archive": result.archive.archived ? result.archive.archivePath : result.archive.message, +++ "Status": result.status, +++ }); +++} +++ +++main().catch((error) => { +++ console.error(error instanceof Error ? error.message : String(error || "Unknown migration failure.")); +++ if (error?.details?.conflicts) { +++ console.error(JSON.stringify({ conflicts: error.details.conflicts }, null, 2)); +++ } +++ process.exitCode = 1; +++}); ++diff --git a/scripts/validate-browser-env-agnostic.mjs b/scripts/validate-browser-env-agnostic.mjs ++index 277366d84..53a165d48 100644 ++--- a/scripts/validate-browser-env-agnostic.mjs +++++ b/scripts/validate-browser-env-agnostic.mjs ++@@ -30,32 +30,12 @@ const excludedSegments = new Set([ ++ "tmp", ++ ]); ++ ++-const retiredFileDbToken = "SQL" + "ite"; ++-const retiredDbConstructorToken = "Database" + "Sync"; ++-const providerLeakPattern = new RegExp([ ++- "local-db", ++- retiredFileDbToken, ++- "Supabase", ++- "GAMEFOUNDRY_", ++- "process\\.env", ++-].join("|"), "i"); ++-const routerRetiredStoragePattern = new RegExp([ ++- `node:${retiredFileDbToken}`, ++- retiredDbConstructorToken, ++- "createRequire", ++- "GAMEFOUNDRY_AUTH_PROVIDER", ++- "GAMEFOUNDRY_DB_PROVIDER", ++- "parts\\[1\\] === \"local-db\"", ++- "parts\\[1\\] === \"mock-db\"", ++- "mock-db-state", ++- "deprecatedDatabaseEndpointError", ++-].join("|"), "i"); ++ const deploymentTermPattern = /\b(?:DEV|UAT|PROD|Prod|Production|production|Development|development)\b|process\.env|GAMEFOUNDRY_[A-Z0-9_]*(?:ENV|ENVIRONMENT|STAGE|PROVIDER|MODE)[A-Z0-9_]*/; ++ const deploymentBranchDecisionPattern = /^\s*(?:if|else\s+if|switch|while|for)\s*\([^)]*(?:GAMEFOUNDRY_(?:ENV|DEPLOYMENT_ENV|STAGE|MODE)|NODE_ENV|process\.env\.(?:GAMEFOUNDRY_ENV|GAMEFOUNDRY_DEPLOYMENT_ENV|NODE_ENV)|\.env\.(?:local|uat|prod)|deployment|environment|stage)[^)]*(?:DEV|UAT|PROD|dev|development|uat|prod|production)[^)]*\)/i; ++ const deploymentCasePattern = /^\s*case\s+["'`](?:dev|development|uat|prod|production)["'`]\s*:/i; ++ const deploymentTernaryDecisionPattern = /(?:GAMEFOUNDRY_(?:ENV|DEPLOYMENT_ENV|STAGE|MODE)|NODE_ENV|process\.env|deployment|environment|stage)[^?\r\n]*\?[^:\r\n]*(?:DEV|UAT|PROD|dev|development|uat|prod|production)/i; ++-const accountDependencyPattern = new RegExp(`\\b(?:Local(?: DB| API)?|${retiredFileDbToken}|Supabase|provider|localhost|DEV|UAT|PROD|Prod)\\b|data-local-db-|local-db-page-data\\.js`, "i"); ++-const userFacingImplementationPattern = new RegExp(`\\b(?:DEV|UAT|PROD|Local DB|Local API|${retiredFileDbToken}|Supabase|provider)\\b`, "i"); +++const accountDependencyPattern = /\b(?:Local(?: DB| API)?|SQLite|Supabase|provider|localhost|DEV|UAT|PROD|Prod)\b|data-local-db-|local-db-page-data\.js/i; +++const userFacingImplementationPattern = /\b(?:DEV|UAT|PROD|Local DB|Local API|SQLite|Supabase|provider)\b/i; ++ const accountBrowserFiles = new Set([ ++ "assets/theme-v2/js/account-auth-actions.js", ++ "assets/theme-v2/js/account-auth-service.js", ++@@ -306,7 +286,7 @@ async function validateAccountServiceContract() { ++ const accountService = await readRequiredRepoFile("assets/theme-v2/js/account-auth-service.js", findings, "Account auth service module is missing"); ++ requireSnippet(accountService, "assets/theme-v2/js/account-auth-service.js", "fetchServerApi(`/auth/${path}`", findings, "Account auth service must own configured /api/auth requests."); ++ requireSnippet(accountService, "assets/theme-v2/js/account-auth-service.js", "fetchServerApi(\"/session/current\"", findings, "Account auth service must own configured /api/session/current requests."); ++- rejectPattern(accountService, "assets/theme-v2/js/account-auth-service.js", providerLeakPattern, findings, "Account auth service must not expose provider or environment implementation details."); +++ rejectPattern(accountService, "assets/theme-v2/js/account-auth-service.js", /local-db|SQLite|Supabase|provider|GAMEFOUNDRY_|process\.env/i, findings, "Account auth service must not expose provider or environment implementation details."); ++ ++ return findings; + } ++@@ -315,18 +295,18 @@ async function validateProductServiceContract() { ++ const findings = []; ++ const registryClient = await readRequiredRepoFile("toolbox/tool-registry-api-client.js", findings, "Toolbox registry client is missing"); ++ requireSnippet(registryClient, "toolbox/tool-registry-api-client.js", "safeRequestServerApi(\"/toolbox/registry/snapshot\")", findings, "Toolbox registry must read through the server API service contract."); ++- rejectPattern(registryClient, "toolbox/tool-registry-api-client.js", providerLeakPattern, findings, "Toolbox registry client must not expose provider/environment implementation details."); +++ rejectPattern(registryClient, "toolbox/tool-registry-api-client.js", /local-db|SQLite|Supabase|GAMEFOUNDRY_|process\.env/i, findings, "Toolbox registry client must not expose provider/environment implementation details."); + +--function resolveLegacySqlitePath(legacyDbPath) { +-- if (legacyDbPath === null || legacyDbPath === undefined) { +-- return ""; +-- } +-- const value = String(legacyDbPath || "").trim(); +-- if (!value) { +-- return ""; +-- } +-- return path.resolve(value); +--} +-- +--function assertNoUnmigratedLegacySqlite(legacyDbPath) { +-- if (!legacyDbPath || !existsSync(legacyDbPath)) { +-- return; +-- } +-- throw new Error(`Legacy Game Journey completion metrics SQLite data exists at ${legacyDbPath}. No data was removed or overwritten. Export or migrate that data into Postgres, then move the legacy file before using the Postgres metrics store.`); +--} +-- +- function normalizeCount(value, fallback = 0) { +- const parsed = Number(value); +- if (!Number.isFinite(parsed)) { +-@@ -158,7 +138,6 @@ function bucketSeedRow(bucket, now) { +- export function createGameJourneyCompletionMetricsStore(options = {}) { +- const env = options.env || process.env; +- const bucketSeeds = Object.freeze((options.buckets || GAME_JOURNEY_COMPLETION_BUCKETS).map(clone)); +-- const legacyDbPath = resolveLegacySqlitePath(options.legacyDbPath); +- let postgresClient = options.postgresClient || null; +- let readyPromise = null; +- +-@@ -230,7 +209,6 @@ export function createGameJourneyCompletionMetricsStore(options = {}) { +- async function ensureReady() { +- if (!readyPromise) { +- readyPromise = (async () => { +-- assertNoUnmigratedLegacySqlite(legacyDbPath); +- await client().query(GAME_JOURNEY_COMPLETION_METRICS_SCHEMA_SQL); +- await seedDefaultBuckets(); +- })(); +-@@ -298,7 +276,6 @@ export function createGameJourneyCompletionMetricsStore(options = {}) { +- databaseConfigKey: "GAMEFOUNDRY_DATABASE_URL", +- databaseEngine: "Postgres", +- databasePath: "GAMEFOUNDRY_DATABASE_URL", +-- legacySqlitePath: legacyDbPath, +- serviceContract: "Web UI -> Local API/Service Contract -> Postgres", +- source: GAME_JOURNEY_COMPLETION_METRICS_TABLE, +- tableName: GAME_JOURNEY_COMPLETION_METRICS_TABLE, +-@@ -312,7 +289,6 @@ export function createGameJourneyCompletionMetricsStore(options = {}) { ++ const votesClient = await readRequiredRepoFile("src/api/toolbox-votes-api-client.js", findings, "Toolbox votes API client is missing"); ++ requireSnippet(votesClient, "src/api/toolbox-votes-api-client.js", "safeRequestServerApi(\"/toolbox/votes/snapshot\")", findings, "Toolbox votes must read through the server API service contract."); ++ requireSnippet(votesClient, "src/api/toolbox-votes-api-client.js", "safeRequestServerApi(\"/toolbox/votes/cast\"", findings, "Toolbox votes must write through the server API service contract."); ++- rejectPattern(votesClient, "src/api/toolbox-votes-api-client.js", providerLeakPattern, findings, "Toolbox votes client must not expose provider/environment implementation details."); +++ rejectPattern(votesClient, "src/api/toolbox-votes-api-client.js", /local-db|SQLite|Supabase|GAMEFOUNDRY_|process\.env/i, findings, "Toolbox votes client must not expose provider/environment implementation details."); ++ ++ for (const filePath of productApiClientFiles) { ++ const contents = await readRequiredRepoFile(filePath, findings, "Product API client is missing"); ++ requireSnippet(contents, filePath, "createServerRepositoryClient", findings, "Product API client must use the server repository contract."); ++ requireSnippet(contents, filePath, "readServerToolConstants", findings, "Product API client must read server-owned constants."); ++- rejectPattern(contents, filePath, providerLeakPattern, findings, "Product API client must not expose provider/environment implementation details."); +++ rejectPattern(contents, filePath, /local-db|SQLite|Supabase|GAMEFOUNDRY_|process\.env/i, findings, "Product API client must not expose provider/environment implementation details."); + } + +- return { +-- legacyDbPath, +- listMetrics, +- snapshot, +- updateMetric, +-diff --git a/src/dev-runtime/persistence/tool-repositories/game-journey-mock-repository.js b/src/dev-runtime/persistence/tool-repositories/game-journey-mock-repository.js +-index 73b409c42..8e0ddc92b 100644 +---- a/src/dev-runtime/persistence/tool-repositories/game-journey-mock-repository.js +-+++ b/src/dev-runtime/persistence/tool-repositories/game-journey-mock-repository.js +-@@ -627,7 +627,6 @@ export function createGameJourneyMockRepository(options = {}) { +- const completionMetricsStore = +- options.completionMetricsStore || createGameJourneyCompletionMetricsStore({ +- dbPath: options.completionMetricsDbPath, +-- legacyDbPath: options.completionMetricsLegacyDbPath, +- postgresClient: options.completionMetricsPostgresClient, +- }); +- const tables = loadMockDbTables(GAME_JOURNEY_DB_OWNER, getSeedTables(), options).tables; +-diff --git a/src/dev-runtime/server/local-api-router.mjs b/src/dev-runtime/server/local-api-router.mjs +-index f2f927aff..2cb9a66f1 100644 +---- a/src/dev-runtime/server/local-api-router.mjs +-+++ b/src/dev-runtime/server/local-api-router.mjs +-@@ -3304,14 +3304,12 @@ function productTablesFromSnapshot(snapshot) { +- +- class ApiRuntimeDataSource { +- constructor({ +-- gameJourneyCompletionMetricsLegacyDbPath = undefined, +- gameJourneyCompletionMetricsPostgresClient = null, +- messagesPostgresClient = null, +- messagesService = null, +- repoRoot = process.cwd(), +- } = {}) { +- this.messagesService = messagesService || createMessagesPostgresService({ postgresClient: messagesPostgresClient }); +-- this.gameJourneyCompletionMetricsLegacyDbPath = gameJourneyCompletionMetricsLegacyDbPath; +- this.gameJourneyCompletionMetricsPostgresClient = gameJourneyCompletionMetricsPostgresClient; +- this.repositoryCounter = 1; +- this.repositoryById = new Map(); +-@@ -3556,7 +3554,6 @@ class ApiRuntimeDataSource { +- this.standaloneTables.invitations = []; +- } +- this.sharedOptions = { +-- completionMetricsLegacyDbPath: this.gameJourneyCompletionMetricsLegacyDbPath, +- completionMetricsPostgresClient: this.gameJourneyCompletionMetricsPostgresClient, +- memoryDbTables: this.standaloneTables, +- sessionMode: this.sessionModeId, +-@@ -6839,14 +6836,12 @@ SELECT pg_database_size(current_database()) AS database_size_bytes, +- * The router itself serves the configured server API contract. +- */ +- export function createLocalApiRouter({ +-- gameJourneyCompletionMetricsLegacyDbPath = undefined, +- gameJourneyCompletionMetricsPostgresClient = null, +- messagesPostgresClient = null, +- messagesService = null, +- repoRoot = process.cwd(), +- } = {}) { +- const dataSource = new ApiRuntimeDataSource({ +-- gameJourneyCompletionMetricsLegacyDbPath, +- gameJourneyCompletionMetricsPostgresClient, +- messagesPostgresClient, +- messagesService, ++ const router = await readRequiredRepoFile("src/dev-runtime/server/local-api-router.mjs", findings, "Local API router is missing"); ++@@ -337,7 +317,7 @@ async function validateProductServiceContract() { ++ requireSnippet(router, "src/dev-runtime/server/local-api-router.mjs", "this.assertProductDatabaseProvider(`Creating ${toolId} repository`);", findings, "Repository creation must assert the server-owned product-data contract."); ++ requireSnippet(router, "src/dev-runtime/server/local-api-router.mjs", "this.assertProductDatabaseProvider(`Calling repository method ${methodName}`);", findings, "Repository method calls must assert the server-owned product-data contract."); ++ rejectPattern(router, "src/dev-runtime/server/local-api-router.mjs", /selectedDatabaseProviderId|selectedAuthProvider|selectedProvidersCanServeRuntime/, findings, "Runtime router must not contain active provider-selection helpers."); ++- rejectPattern(router, "src/dev-runtime/server/local-api-router.mjs", routerRetiredStoragePattern, findings, "Runtime router must not contain retired file-DB startup/opening code, provider-selection environment variables, or retired local-db/mock-db routes."); +++ rejectPattern(router, "src/dev-runtime/server/local-api-router.mjs", /node:sqlite|DatabaseSync|createRequire|GAMEFOUNDRY_AUTH_PROVIDER|GAMEFOUNDRY_DB_PROVIDER|parts\[1\] === "local-db"|parts\[1\] === "mock-db"|mock-db-state|deprecatedDatabaseEndpointError/, findings, "Runtime router must not contain SQLite startup/opening code, provider-selection environment variables, or legacy local-db/mock-db routes."); ++ ++ const startup = await readRequiredRepoFile("scripts/start-local-api-server.mjs", findings, "Local API startup script is missing"); ++ rejectPattern(startup, "scripts/start-local-api-server.mjs", /GAMEFOUNDRY_AUTH_PROVIDER|GAMEFOUNDRY_DB_PROVIDER|auth provider|product data provider|provider selection/i, findings, "Local API startup must describe configured connections without provider-selection environment variables."); ++@@ -406,7 +386,7 @@ const report = [ ++ "## User-Facing Implementation Wording Findings", ++ formatRecords(userFacingUiFindings), ++ "", ++- "## Deprecated Local DB Technical Debt", +++ "## Deprecated SQLite/Local DB Technical Debt", ++ formatTechnicalDebt(deprecatedLocalDbDebt), ++ "", ++ "## Non-Branching Deployment Mentions Reviewed", ++diff --git a/src/dev-runtime/persistence/game-journey-completion-metrics-migration.mjs b/src/dev-runtime/persistence/game-journey-completion-metrics-migration.mjs +new file mode 100644 -+index 000000000..8a1b82360 ++index 000000000..e53bee7fe +--- /dev/null -++++ b/docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock_validation-lane.md -+@@ -0,0 +1,17 @@ -++# PR_26177_OWNER_007-project-instructions-single-source-eod-lock Validation Lane -++ -++- PASS: duplicate-source grep returned no matches for old active source claims. -++- PASS: EOD/Next Day governance grep returned active governance matches. -++- PASS: product/runtime/start_of_day changed-file check returned no files. -++- PASS: git diff --check. -++ -++Commands used: -++ -++~~~text -++rg -n 'project-instructions/addendums|docs_build/dev/PROJECT_INSTRUCTIONS.md.*source of truth|Codex must always read `docs_build/dev/PROJECT_INSTRUCTIONS.md`|Read `docs_build/dev/PROJECT_INSTRUCTIONS.md`' docs_build/dev/ProjectInstructions docs_build/dev/PROJECT_INSTRUCTIONS.md project-instructions -++rg -n "End of Day:|Next Day Start:|HEAD.*published EOD SHA|only active Project Instructions source" docs_build/dev/ProjectInstructions -++git diff --name-only -- src assets toolbox games api serverside package.json package-lock.json docs_build/dev/start_of_day -++git diff --check -++~~~ -++ -++Full product/runtime tests were not run because this PR changes governance documentation only. -+diff --git a/project-instructions/README.md b/project-instructions/README.md +++++ b/src/dev-runtime/persistence/game-journey-completion-metrics-migration.mjs ++@@ -0,0 +1,433 @@ +++import fs from "node:fs/promises"; +++import { existsSync } from "node:fs"; +++import path from "node:path"; +++import { spawn } from "node:child_process"; +++import process from "node:process"; +++import { +++ GAME_JOURNEY_COMPLETION_METRICS_SCHEMA_SQL, +++ GAME_JOURNEY_COMPLETION_METRICS_TABLE, +++} from "./game-journey-completion-metrics-store.mjs"; +++import { createPostgresConnectionClient } from "./postgres-connection-client.mjs"; +++ +++export const DEFAULT_GAME_JOURNEY_COMPLETION_METRICS_SQLITE_PATH = path.join( +++ process.cwd(), +++ "tmp", +++ "local-api", +++ "game-journey-completion-metrics.sqlite", +++); +++export const DEFAULT_GAME_JOURNEY_COMPLETION_METRICS_ARCHIVE_DIR = path.join( +++ process.cwd(), +++ "tmp", +++ "local-api", +++ "legacy-migrated", +++); +++ +++const LEGACY_TABLE = GAME_JOURNEY_COMPLETION_METRICS_TABLE; +++const EXPECTED_COLUMNS = Object.freeze([ +++ "key", +++ "bucketKey", +++ "bucketOrder", +++ "bucketName", +++ "friendlyDescription", +++ "requiredForMvp", +++ "canSkip", +++ "plannedCount", +++ "completedCount", +++ "active", +++ "status", +++ "createdAt", +++ "updatedAt", +++ "createdBy", +++ "updatedBy", +++]); +++ +++const PYTHON_SQLITE_EXPORT_SCRIPT = String.raw` +++import json +++import sqlite3 +++import sys +++ +++db_path = sys.argv[1] +++connection = sqlite3.connect(db_path) +++connection.row_factory = sqlite3.Row +++try: +++ schema_objects = [ +++ dict(row) +++ for row in connection.execute( +++ "SELECT name, type, sql FROM sqlite_master WHERE type IN ('table', 'index', 'trigger', 'view') ORDER BY type, name" +++ ).fetchall() +++ ] +++ columns = [ +++ dict(row) +++ for row in connection.execute("PRAGMA table_info(game_journey_completion_metrics)").fetchall() +++ ] +++ rows = [ +++ dict(row) +++ for row in connection.execute( +++ 'SELECT * FROM "game_journey_completion_metrics" ORDER BY "bucketOrder", "bucketKey"' +++ ).fetchall() +++ ] +++ print(json.dumps({ +++ "schema": { +++ "columns": columns, +++ "objects": schema_objects, +++ }, +++ "rows": rows, +++ })) +++finally: +++ connection.close() +++`; +++ +++export class GameJourneyCompletionMetricsMigrationError extends Error { +++ constructor(message, details = {}) { +++ super(message); +++ this.name = "GameJourneyCompletionMetricsMigrationError"; +++ this.details = details; +++ } +++} +++ +++function asText(value) { +++ return String(value ?? "").trim(); +++} +++ +++function normalizeCount(value, label) { +++ const parsed = Number(value); +++ if (!Number.isFinite(parsed) || parsed < 0) { +++ throw new GameJourneyCompletionMetricsMigrationError(`Invalid legacy ${label}: ${value}.`); +++ } +++ return Math.trunc(parsed); +++} +++ +++function normalizeBoolean(value, label) { +++ if (value === true || value === 1 || value === "1" || value === "true" || value === "active") { +++ return true; +++ } +++ if (value === false || value === 0 || value === "0" || value === "false" || value === "inactive") { +++ return false; +++ } +++ throw new GameJourneyCompletionMetricsMigrationError(`Invalid legacy ${label}: ${value}.`); +++} +++ +++function requireText(row, key) { +++ const value = asText(row?.[key]); +++ if (!value) { +++ throw new GameJourneyCompletionMetricsMigrationError(`Legacy row is missing required ${key}.`); +++ } +++ return value; +++} +++ +++function normalizeStatus(row, active) { +++ const status = asText(row?.status) || (active ? "active" : "inactive"); +++ if (!["active", "inactive"].includes(status)) { +++ throw new GameJourneyCompletionMetricsMigrationError(`Invalid legacy status: ${status}.`); +++ } +++ return status; +++} +++ +++export function normalizeLegacyCompletionMetric(row) { +++ const plannedCount = normalizeCount(row?.plannedCount, "plannedCount"); +++ const completedCount = normalizeCount(row?.completedCount, "completedCount"); +++ if (completedCount > plannedCount) { +++ throw new GameJourneyCompletionMetricsMigrationError( +++ `Legacy completedCount ${completedCount} exceeds plannedCount ${plannedCount} for ${asText(row?.bucketKey) || "(missing bucketKey)"}.`, +++ ); +++ } +++ const active = normalizeBoolean(row?.active, "active"); +++ return { +++ active, +++ bucketKey: requireText(row, "bucketKey"), +++ bucketName: requireText(row, "bucketName"), +++ bucketOrder: normalizeCount(row?.bucketOrder, "bucketOrder"), +++ canSkip: normalizeBoolean(row?.canSkip, "canSkip"), +++ completedCount, +++ createdAt: requireText(row, "createdAt"), +++ createdBy: requireText(row, "createdBy"), +++ friendlyDescription: requireText(row, "friendlyDescription"), +++ key: requireText(row, "key"), +++ plannedCount, +++ requiredForMvp: normalizeBoolean(row?.requiredForMvp, "requiredForMvp"), +++ status: normalizeStatus(row, active), +++ updatedAt: requireText(row, "updatedAt"), +++ updatedBy: requireText(row, "updatedBy"), +++ }; +++} +++ +++function validateLegacySchema(exported) { +++ const table = exported?.schema?.objects?.find((object) => object.type === "table" && object.name === LEGACY_TABLE); +++ if (!table) { +++ throw new GameJourneyCompletionMetricsMigrationError(`Legacy SQLite file does not contain ${LEGACY_TABLE}.`); +++ } +++ const columns = new Set((exported?.schema?.columns || []).map((column) => String(column.name || ""))); +++ const missingColumns = EXPECTED_COLUMNS.filter((column) => !columns.has(column)); +++ if (missingColumns.length) { +++ throw new GameJourneyCompletionMetricsMigrationError( +++ `Legacy SQLite ${LEGACY_TABLE} is missing required columns: ${missingColumns.join(", ")}.`, +++ { missingColumns }, +++ ); +++ } +++} +++ +++function assertUniqueLegacyRows(rows) { +++ const seenKeys = new Set(); +++ const seenBucketKeys = new Set(); +++ rows.forEach((row) => { +++ if (seenKeys.has(row.key)) { +++ throw new GameJourneyCompletionMetricsMigrationError(`Duplicate legacy key detected before migration: ${row.key}.`); +++ } +++ if (seenBucketKeys.has(row.bucketKey)) { +++ throw new GameJourneyCompletionMetricsMigrationError(`Duplicate legacy bucketKey detected before migration: ${row.bucketKey}.`); +++ } +++ seenKeys.add(row.key); +++ seenBucketKeys.add(row.bucketKey); +++ }); +++} +++ +++function comparableRow(row) { +++ const normalized = normalizeLegacyCompletionMetric(row); +++ return EXPECTED_COLUMNS.reduce((record, key) => { +++ record[key] = normalized[key]; +++ return record; +++ }, {}); +++} +++ +++function rowsMatch(left, right) { +++ const normalizedLeft = comparableRow(left); +++ const normalizedRight = comparableRow(right); +++ return EXPECTED_COLUMNS.every((key) => normalizedLeft[key] === normalizedRight[key]); +++} +++ +++function differingColumns(left, right) { +++ const normalizedLeft = comparableRow(left); +++ const normalizedRight = comparableRow(right); +++ return EXPECTED_COLUMNS.filter((key) => normalizedLeft[key] !== normalizedRight[key]); +++} +++ +++export function classifyLegacyCompletionMetricRows({ existingRows = [], legacyRows = [] } = {}) { +++ const existingByKey = new Map(existingRows.map((row) => [String(row.key || ""), row])); +++ const existingByBucketKey = new Map(existingRows.map((row) => [String(row.bucketKey || ""), row])); +++ const duplicates = []; +++ const conflicts = []; +++ const inserts = []; +++ const timestampPatches = []; +++ legacyRows.forEach((legacyRow) => { +++ const existing = existingByKey.get(legacyRow.key) || existingByBucketKey.get(legacyRow.bucketKey); +++ if (!existing) { +++ inserts.push(legacyRow); +++ return; +++ } +++ if (rowsMatch(legacyRow, existing)) { +++ duplicates.push({ +++ bucketKey: legacyRow.bucketKey, +++ key: legacyRow.key, +++ reason: "already present in Postgres with matching data", +++ }); +++ return; +++ } +++ const diffs = differingColumns(legacyRow, existing); +++ if (diffs.every((column) => column === "createdAt" || column === "updatedAt")) { +++ timestampPatches.push({ +++ bucketKey: legacyRow.bucketKey, +++ createdAt: legacyRow.createdAt, +++ key: legacyRow.key, +++ reason: "Postgres row matched legacy data except timestamps; preserving legacy createdAt/updatedAt.", +++ updatedAt: legacyRow.updatedAt, +++ }); +++ return; +++ } +++ conflicts.push({ +++ bucketKey: legacyRow.bucketKey, +++ existingKey: String(existing.key || ""), +++ key: legacyRow.key, +++ reason: `Postgres already contains a different row for this key or bucketKey (${diffs.join(", ")} differ).`, +++ }); +++ }); +++ return { conflicts, duplicates, inserts, timestampPatches }; +++} +++ +++function spawnPythonExport({ legacyDbPath, pythonCommand }) { +++ return new Promise((resolve, reject) => { +++ const child = spawn(pythonCommand, ["-", legacyDbPath], { +++ stdio: ["pipe", "pipe", "pipe"], +++ windowsHide: true, +++ }); +++ let stdout = ""; +++ let stderr = ""; +++ child.stdout.setEncoding("utf8"); +++ child.stderr.setEncoding("utf8"); +++ child.stdout.on("data", (chunk) => { +++ stdout += chunk; +++ }); +++ child.stderr.on("data", (chunk) => { +++ stderr += chunk; +++ }); +++ child.once("error", reject); +++ child.once("close", (code) => { +++ if (code === 0) { +++ resolve(stdout); +++ return; +++ } +++ reject(new GameJourneyCompletionMetricsMigrationError( +++ `Python SQLite export failed with exit code ${code}. ${stderr.trim()}`, +++ { stderr: stderr.trim() }, +++ )); +++ }); +++ child.stdin.end(PYTHON_SQLITE_EXPORT_SCRIPT); +++ }); +++} +++ +++export async function readLegacyCompletionMetricsSqlite({ legacyDbPath, pythonCommand = "python" } = {}) { +++ const resolvedPath = path.resolve(legacyDbPath || DEFAULT_GAME_JOURNEY_COMPLETION_METRICS_SQLITE_PATH); +++ if (!existsSync(resolvedPath)) { +++ throw new GameJourneyCompletionMetricsMigrationError(`Legacy SQLite file was not found: ${resolvedPath}.`); +++ } +++ const stdout = await spawnPythonExport({ legacyDbPath: resolvedPath, pythonCommand }); +++ let exported; +++ try { +++ exported = JSON.parse(stdout); +++ } catch (error) { +++ throw new GameJourneyCompletionMetricsMigrationError( +++ `Python SQLite export did not return valid JSON: ${error instanceof Error ? error.message : String(error)}.`, +++ ); +++ } +++ validateLegacySchema(exported); +++ const rows = (exported.rows || []).map(normalizeLegacyCompletionMetric); +++ assertUniqueLegacyRows(rows); +++ return { +++ legacyDbPath: resolvedPath, +++ rowCount: rows.length, +++ rows, +++ schema: exported.schema, +++ }; +++} +++ +++async function nextArchivePath({ archiveDir, legacyDbPath, now = new Date() }) { +++ await fs.mkdir(archiveDir, { recursive: true }); +++ const parsed = path.parse(legacyDbPath); +++ const stamp = now.toISOString().replace(/[-:]/g, "").replace(/\.\d{3}Z$/, "Z"); +++ for (let index = 0; index < 100; index += 1) { +++ const suffix = index === 0 ? "" : `-${index + 1}`; +++ const candidate = path.join(archiveDir, `${parsed.name}-${stamp}${suffix}${parsed.ext || ".sqlite"}`); +++ if (!existsSync(candidate)) { +++ return candidate; +++ } +++ } +++ throw new GameJourneyCompletionMetricsMigrationError(`Could not allocate archive path in ${archiveDir}.`); +++} +++ +++export async function archiveLegacyCompletionMetricsSqlite({ archiveDir, legacyDbPath, now = new Date() } = {}) { +++ const resolvedLegacyPath = path.resolve(legacyDbPath || DEFAULT_GAME_JOURNEY_COMPLETION_METRICS_SQLITE_PATH); +++ const resolvedArchiveDir = path.resolve(archiveDir || DEFAULT_GAME_JOURNEY_COMPLETION_METRICS_ARCHIVE_DIR); +++ if (!existsSync(resolvedLegacyPath)) { +++ return { +++ archived: false, +++ archivePath: "", +++ legacyDbPath: resolvedLegacyPath, +++ message: "Legacy SQLite file was already absent.", +++ }; +++ } +++ const archivePath = await nextArchivePath({ +++ archiveDir: resolvedArchiveDir, +++ legacyDbPath: resolvedLegacyPath, +++ now, +++ }); +++ await fs.rename(resolvedLegacyPath, archivePath); +++ return { +++ archived: true, +++ archivePath, +++ legacyDbPath: resolvedLegacyPath, +++ message: `Legacy SQLite file moved to ${archivePath}.`, +++ }; +++} +++ +++export async function migrateLegacyCompletionMetricRowsToPostgres({ +++ archiveDir, +++ dryRun = false, +++ env = process.env, +++ legacyDbPath, +++ now = new Date(), +++ postgresClient = null, +++ rows = [], +++} = {}) { +++ const legacyRows = rows.map(normalizeLegacyCompletionMetric); +++ assertUniqueLegacyRows(legacyRows); +++ const client = postgresClient || createPostgresConnectionClient({ env }); +++ await client.query(GAME_JOURNEY_COMPLETION_METRICS_SCHEMA_SQL); +++ const existingRows = await client.requestTable(GAME_JOURNEY_COMPLETION_METRICS_TABLE, { +++ method: "GET", +++ query: "select=*", +++ }); +++ const classified = classifyLegacyCompletionMetricRows({ +++ existingRows: Array.isArray(existingRows) ? existingRows : [], +++ legacyRows, +++ }); +++ if (classified.conflicts.length) { +++ throw new GameJourneyCompletionMetricsMigrationError( +++ `Game Journey completion metrics migration blocked by ${classified.conflicts.length} Postgres conflict(s). No data was moved.`, +++ { conflicts: classified.conflicts }, +++ ); +++ } +++ if (!dryRun && classified.inserts.length) { +++ await client.requestTable(GAME_JOURNEY_COMPLETION_METRICS_TABLE, { +++ body: classified.inserts, +++ method: "POST", +++ query: "on_conflict=key", +++ }); +++ } +++ if (!dryRun) { +++ for (const patch of classified.timestampPatches) { +++ await client.requestTable(GAME_JOURNEY_COMPLETION_METRICS_TABLE, { +++ body: { +++ createdAt: patch.createdAt, +++ updatedAt: patch.updatedAt, +++ }, +++ method: "PATCH", +++ query: `bucketKey=eq.${encodeURIComponent(patch.bucketKey)}`, +++ }); +++ } +++ } +++ const archive = dryRun +++ ? { +++ archived: false, +++ archivePath: "", +++ legacyDbPath: path.resolve(legacyDbPath || DEFAULT_GAME_JOURNEY_COMPLETION_METRICS_SQLITE_PATH), +++ message: "Dry run did not move the legacy SQLite file.", +++ } +++ : await archiveLegacyCompletionMetricsSqlite({ archiveDir, legacyDbPath, now }); +++ return { +++ archive, +++ duplicateCount: classified.duplicates.length, +++ duplicates: classified.duplicates, +++ insertedCount: dryRun ? 0 : classified.inserts.length, +++ legacyRowCount: legacyRows.length, +++ status: dryRun ? "DRY_RUN" : "PASS", +++ timestampPatchCount: dryRun ? 0 : classified.timestampPatches.length, +++ timestampPatches: classified.timestampPatches, +++ wouldInsertCount: classified.inserts.length, +++ wouldPatchTimestampCount: classified.timestampPatches.length, +++ }; +++} +++ +++export async function migrateLegacyCompletionMetricsSqliteToPostgres({ +++ archiveDir, +++ dryRun = false, +++ env = process.env, +++ legacyDbPath, +++ now = new Date(), +++ postgresClient = null, +++ pythonCommand = "python", +++} = {}) { +++ const exported = await readLegacyCompletionMetricsSqlite({ legacyDbPath, pythonCommand }); +++ const result = await migrateLegacyCompletionMetricRowsToPostgres({ +++ archiveDir, +++ dryRun, +++ env, +++ legacyDbPath: exported.legacyDbPath, +++ now, +++ postgresClient, +++ rows: exported.rows, +++ }); +++ return { +++ ...result, +++ legacyDbPath: exported.legacyDbPath, +++ schemaObjectCount: exported.schema.objects.length, +++ }; +++} ++diff --git a/tests/dev-runtime/GameJourneyCompletionMetricsMigration.test.mjs b/tests/dev-runtime/GameJourneyCompletionMetricsMigration.test.mjs +new file mode 100644 -+index 000000000..af401852e ++index 000000000..6428e63e8 +--- /dev/null -++++ b/project-instructions/README.md -+@@ -0,0 +1,11 @@ -++# Deprecated Project Instructions Reference -++ -++This folder is preserved as historical reference only. -++ -++The only active Project Instructions source is: -++ -++```text -++docs_build/dev/ProjectInstructions/ -++``` +++++ b/tests/dev-runtime/GameJourneyCompletionMetricsMigration.test.mjs ++@@ -0,0 +1,194 @@ +++import assert from "node:assert/strict"; +++import fs from "node:fs/promises"; +++import os from "node:os"; +++import path from "node:path"; +++import test from "node:test"; +++import { +++ GAME_JOURNEY_COMPLETION_METRICS_TABLE, +++} from "../../src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs"; +++import { +++ migrateLegacyCompletionMetricRowsToPostgres, +++} from "../../src/dev-runtime/persistence/game-journey-completion-metrics-migration.mjs"; +++import { createGameJourneyCompletionMetricsPostgresClientStub } from "../helpers/gameJourneyCompletionMetricsPostgresClientStub.mjs"; +++ +++const LEGACY_ROW = Object.freeze({ +++ active: 1, +++ bucketKey: "002-create", +++ bucketName: "Create", +++ bucketOrder: 2, +++ canSkip: 0, +++ completedCount: 3, +++ createdAt: "2026-06-20T01:52:14.797Z", +++ createdBy: "01K2GFSJ0Y0000000000000054", +++ friendlyDescription: "Set up your game and crew", +++ key: "01K2GFSJ0Y0000000000006002", +++ plannedCount: 5, +++ requiredForMvp: 1, +++ status: "active", +++ updatedAt: "2026-06-21T03:04:05.000Z", +++ updatedBy: "01K2GFSJ0Y0000000000000054", +++}); +++ +++async function tempLegacyFile() { +++ const directory = await fs.mkdtemp(path.join(os.tmpdir(), "gfs-game-journey-migration-")); +++ const legacyDbPath = path.join(directory, "game-journey-completion-metrics.sqlite"); +++ const archiveDir = path.join(directory, "legacy-migrated"); +++ await fs.writeFile(legacyDbPath, "legacy sqlite placeholder"); +++ return { archiveDir, directory, legacyDbPath }; +++} +++ +++test("Game Journey completion metrics migration inserts valid rows and archives legacy SQLite after success", async () => { +++ const postgresClient = createGameJourneyCompletionMetricsPostgresClientStub(); +++ const paths = await tempLegacyFile(); +++ try { +++ const result = await migrateLegacyCompletionMetricRowsToPostgres({ +++ archiveDir: paths.archiveDir, +++ legacyDbPath: paths.legacyDbPath, +++ now: new Date("2026-06-25T12:00:00.000Z"), +++ postgresClient, +++ rows: [LEGACY_ROW], +++ }); +++ +++ assert.equal(result.status, "PASS"); +++ assert.equal(result.insertedCount, 1); +++ assert.equal(result.duplicateCount, 0); +++ assert.equal(result.archive.archived, true); +++ assert.equal(await fs.stat(paths.legacyDbPath).then(() => true, () => false), false); +++ assert.equal(await fs.stat(result.archive.archivePath).then(() => true, () => false), true); +++ assert.match(result.archive.archivePath, /legacy-migrated[\\/]+game-journey-completion-metrics-20260625T120000Z\.sqlite$/); +++ assert.deepEqual(postgresClient.dumpTable(GAME_JOURNEY_COMPLETION_METRICS_TABLE), [ +++ { +++ ...LEGACY_ROW, +++ active: true, +++ canSkip: false, +++ requiredForMvp: true, +++ }, +++ ]); +++ } finally { +++ await fs.rm(paths.directory, { force: true, recursive: true }); +++ } +++}); +++ +++test("Game Journey completion metrics migration detects Postgres conflicts without moving legacy SQLite", async () => { +++ const postgresClient = createGameJourneyCompletionMetricsPostgresClientStub(); +++ const paths = await tempLegacyFile(); +++ await postgresClient.requestTable(GAME_JOURNEY_COMPLETION_METRICS_TABLE, { +++ body: { +++ ...LEGACY_ROW, +++ active: true, +++ canSkip: false, +++ completedCount: 1, +++ requiredForMvp: true, +++ }, +++ method: "POST", +++ }); +++ +++ try { +++ await assert.rejects( +++ () => migrateLegacyCompletionMetricRowsToPostgres({ +++ archiveDir: paths.archiveDir, +++ legacyDbPath: paths.legacyDbPath, +++ postgresClient, +++ rows: [LEGACY_ROW], +++ }), +++ /migration blocked by 1 Postgres conflict/, +++ ); +++ assert.equal(await fs.stat(paths.legacyDbPath).then(() => true, () => false), true); +++ } finally { +++ await fs.rm(paths.directory, { force: true, recursive: true }); +++ } +++}); +++ +++test("Game Journey completion metrics migration archives when legacy rows are already present unchanged", async () => { +++ const postgresClient = createGameJourneyCompletionMetricsPostgresClientStub(); +++ const paths = await tempLegacyFile(); +++ await postgresClient.requestTable(GAME_JOURNEY_COMPLETION_METRICS_TABLE, { +++ body: { +++ ...LEGACY_ROW, +++ active: true, +++ canSkip: false, +++ requiredForMvp: true, +++ }, +++ method: "POST", +++ }); +++ +++ try { +++ const result = await migrateLegacyCompletionMetricRowsToPostgres({ +++ archiveDir: paths.archiveDir, +++ legacyDbPath: paths.legacyDbPath, +++ postgresClient, +++ rows: [LEGACY_ROW], +++ }); +++ +++ assert.equal(result.insertedCount, 0); +++ assert.equal(result.duplicateCount, 1); +++ assert.equal(result.archive.archived, true); +++ assert.equal(await fs.stat(paths.legacyDbPath).then(() => true, () => false), false); +++ } finally { +++ await fs.rm(paths.directory, { force: true, recursive: true }); +++ } +++}); +++ +++test("Game Journey completion metrics migration preserves legacy timestamps for otherwise matching Postgres rows", async () => { +++ const postgresClient = createGameJourneyCompletionMetricsPostgresClientStub(); +++ const paths = await tempLegacyFile(); +++ await postgresClient.requestTable(GAME_JOURNEY_COMPLETION_METRICS_TABLE, { +++ body: { +++ ...LEGACY_ROW, +++ active: true, +++ canSkip: false, +++ createdAt: "2026-06-25T00:00:00.000Z", +++ requiredForMvp: true, +++ updatedAt: "2026-06-25T00:00:00.000Z", +++ }, +++ method: "POST", +++ }); +++ +++ try { +++ const result = await migrateLegacyCompletionMetricRowsToPostgres({ +++ archiveDir: paths.archiveDir, +++ legacyDbPath: paths.legacyDbPath, +++ postgresClient, +++ rows: [LEGACY_ROW], +++ }); +++ +++ assert.equal(result.insertedCount, 0); +++ assert.equal(result.duplicateCount, 0); +++ assert.equal(result.timestampPatchCount, 1); +++ assert.equal(result.archive.archived, true); +++ assert.deepEqual(postgresClient.dumpTable(GAME_JOURNEY_COMPLETION_METRICS_TABLE)[0], { +++ ...LEGACY_ROW, +++ active: true, +++ canSkip: false, +++ requiredForMvp: true, +++ }); +++ } finally { +++ await fs.rm(paths.directory, { force: true, recursive: true }); +++ } +++}); +++ +++test("Game Journey completion metrics migration rejects duplicate legacy bucket keys before writing", async () => { +++ const postgresClient = createGameJourneyCompletionMetricsPostgresClientStub(); +++ const paths = await tempLegacyFile(); +++ try { +++ await assert.rejects( +++ () => migrateLegacyCompletionMetricRowsToPostgres({ +++ archiveDir: paths.archiveDir, +++ legacyDbPath: paths.legacyDbPath, +++ postgresClient, +++ rows: [ +++ LEGACY_ROW, +++ { +++ ...LEGACY_ROW, +++ key: "01K2GFSJ0Y0000000000006999", +++ }, +++ ], +++ }), +++ /Duplicate legacy bucketKey/, +++ ); +++ assert.equal(postgresClient.dumpTable(GAME_JOURNEY_COMPLETION_METRICS_TABLE).length, 0); +++ assert.equal(await fs.stat(paths.legacyDbPath).then(() => true, () => false), true); +++ } finally { +++ await fs.rm(paths.directory, { force: true, recursive: true }); +++ } +++}); + diff --git a/tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs b/tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs +-index edbc0333e..1ca7de68e 100644 ++index 581221a66..1ca7de68e 100644 + --- a/tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs + +++ b/tests/dev-runtime/GameJourneyCompletionMetricsStore.test.mjs +-@@ -10,6 +10,34 @@ import { ++@@ -1,6 +1,8 @@ ++ import assert from "node:assert/strict"; ++ import fs from "node:fs/promises"; +++import os from "node:os"; ++ import path from "node:path"; +++import process from "node:process"; ++ import test from "node:test"; ++ import { ++ GAME_JOURNEY_COMPLETION_METRICS_TABLE, ++@@ -8,21 +10,16 @@ import { + } from "../../src/dev-runtime/persistence/game-journey-completion-metrics-store.mjs"; + import { createGameJourneyCompletionMetricsPostgresClientStub } from "../helpers/gameJourneyCompletionMetricsPostgresClientStub.mjs"; + ++-const IMPLEMENTATION_ROOTS = Object.freeze(["src", "assets", "toolbox", "scripts", "tests"]); ++-const RETIRED_FILE_DB_TOKEN = "sql" + "ite"; ++-const RETIRED_METRICS_FILE = `game-journey-completion-metrics.${RETIRED_FILE_DB_TOKEN}`; ++-const RETIRED_LOCAL_RUNTIME_PATH = ["tmp", "local-api"].join("/"); ++- ++-function escapeRegExp(value) { ++- return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); ++-} ++- ++-const FORBIDDEN_IMPLEMENTATION_PATTERNS = Object.freeze([ ++- new RegExp(RETIRED_FILE_DB_TOKEN, "i"), ++- new RegExp(`\\.${RETIRED_FILE_DB_TOKEN}`, "i"), ++- new RegExp(`better-${RETIRED_FILE_DB_TOKEN}`, "i"), ++- new RegExp(escapeRegExp(RETIRED_METRICS_FILE), "i"), ++- new RegExp(escapeRegExp(RETIRED_LOCAL_RUNTIME_PATH), "i"), + +const ACTIVE_RUNTIME_ROOTS = Object.freeze(["src", "assets", "toolbox"]); + +const ACTIVE_RUNTIME_ALLOWED_FILES = new Set([ + + path.normalize("src/dev-runtime/persistence/game-journey-completion-metrics-migration.mjs"), +@@ -283,183 +7226,131 @@ index edbc0333e..1ca7de68e 100644 + + /better-sqlite/i, + + /game-journey-completion-metrics\.sqlite/i, + + /tmp\/local-api/i, +-+]); +-+ +-+async function activeRuntimeJavaScriptFiles(root) { +-+ const entries = await fs.readdir(root, { withFileTypes: true }); +-+ const files = []; +-+ for (const entry of entries) { +-+ const child = path.join(root, entry.name); +-+ if (entry.isDirectory()) { +-+ files.push(...await activeRuntimeJavaScriptFiles(child)); +-+ continue; +-+ } +-+ if (entry.isFile() && /\.(?:mjs|js)$/i.test(entry.name)) { +-+ files.push(child); +-+ } +-+ } +-+ return files; +-+} ++ ]); ++ ++ async function activeRuntimeJavaScriptFiles(root) { ++@@ -41,32 +38,47 @@ async function activeRuntimeJavaScriptFiles(root) { ++ return files; ++ } ++ ++-test("Game Journey completion metrics use the database client only", async () => { ++- const postgresClient = createGameJourneyCompletionMetricsPostgresClientStub(); ++- const store = createGameJourneyCompletionMetricsStore({ postgresClient }); ++- const metrics = await store.listMetrics(); ++- const snapshot = await store.snapshot(); ++- const snapshotText = JSON.stringify(snapshot); +++test("active Game Journey metrics ignore the retired default legacy SQLite path", async () => { +++ const originalCwd = process.cwd(); +++ const directory = await fs.mkdtemp(path.join(os.tmpdir(), "gfs-game-journey-metrics-store-")); +++ const retiredLegacyPath = path.join(directory, "tmp", "local-api", "game-journey-completion-metrics.sqlite"); +++ const retiredLegacyContents = "retired legacy sqlite placeholder"; ++ ++- assert.equal(metrics.length, 14); ++- assert.equal(postgresClient.dumpTable(GAME_JOURNEY_COMPLETION_METRICS_TABLE).length, 14); ++- assert.equal(snapshot.api, "Local API"); ++- assert.equal(snapshot.tableName, GAME_JOURNEY_COMPLETION_METRICS_TABLE); ++- for (const pattern of FORBIDDEN_IMPLEMENTATION_PATTERNS) { ++- assert.equal(pattern.test(snapshotText), false); +++ try { +++ await fs.mkdir(path.dirname(retiredLegacyPath), { recursive: true }); +++ await fs.writeFile(retiredLegacyPath, retiredLegacyContents); +++ process.chdir(directory); + + +- test("active Game Journey metrics ignore the retired default legacy SQLite path", async () => { +- const originalCwd = process.cwd(); +- const directory = await fs.mkdtemp(path.join(os.tmpdir(), "gfs-game-journey-metrics-store-")); +-@@ -24,8 +52,10 @@ test("active Game Journey metrics ignore the retired default legacy SQLite path" +- const postgresClient = createGameJourneyCompletionMetricsPostgresClientStub(); +- const store = createGameJourneyCompletionMetricsStore({ postgresClient }); +- const metrics = await store.listMetrics(); +++ const postgresClient = createGameJourneyCompletionMetricsPostgresClientStub(); +++ const store = createGameJourneyCompletionMetricsStore({ postgresClient }); +++ const metrics = await store.listMetrics(); + + const snapshot = await store.snapshot(); +- +-- assert.equal(store.legacyDbPath, ""); ++ -++Do not use files under `project-instructions/` as active governance. If a file here conflicts with `docs_build/dev/ProjectInstructions/`, the active folder wins unless OWNER explicitly approves a newer governance change. + + assert.equal(Object.hasOwn(store, "legacyDbPath"), false); + + assert.equal(Object.hasOwn(snapshot, "legacySqlitePath"), false); +- assert.equal(metrics.length, 14); +- assert.equal(postgresClient.dumpTable(GAME_JOURNEY_COMPLETION_METRICS_TABLE).length, 14); +- assert.equal(await fs.readFile(retiredLegacyPath, "utf8"), retiredLegacyContents); +-@@ -34,3 +64,26 @@ test("active Game Journey metrics ignore the retired default legacy SQLite path" +- await fs.rm(directory, { force: true, recursive: true }); +++ assert.equal(metrics.length, 14); +++ assert.equal(postgresClient.dumpTable(GAME_JOURNEY_COMPLETION_METRICS_TABLE).length, 14); +++ assert.equal(await fs.readFile(retiredLegacyPath, "utf8"), retiredLegacyContents); +++ } finally { +++ process.chdir(originalCwd); +++ await fs.rm(directory, { force: true, recursive: true }); + } + }); +-+ ++ ++-test("implementation and validation JS/MJS do not contain retired file DB metrics references", async () => { + +test("active runtime JS and MJS do not contain SQLite or tmp local metrics references", async () => { +-+ const files = []; ++ const files = []; ++- for (const root of IMPLEMENTATION_ROOTS) { + + for (const root of ACTIVE_RUNTIME_ROOTS) { +-+ files.push(...await activeRuntimeJavaScriptFiles(root)); +-+ } +-+ +-+ const findings = []; +-+ for (const file of files) { ++ files.push(...await activeRuntimeJavaScriptFiles(root)); ++ } ++ ++ const findings = []; ++ for (const file of files) { + + const normalized = path.normalize(file); + + if (ACTIVE_RUNTIME_ALLOWED_FILES.has(normalized)) { + + continue; + + } +-+ const contents = await fs.readFile(file, "utf8"); ++ const contents = await fs.readFile(file, "utf8"); ++- FORBIDDEN_IMPLEMENTATION_PATTERNS.forEach((pattern) => { + + RUNTIME_FORBIDDEN_PATTERNS.forEach((pattern) => { +-+ if (pattern.test(contents)) { +-+ findings.push(`${file}: ${pattern}`); +-+ } +-+ }); +-+ } +-+ +-+ assert.deepEqual(findings, []); +-+}); +-diff --git a/tests/helpers/playwrightRepoServer.mjs b/tests/helpers/playwrightRepoServer.mjs +-index 9bc8e8f07..71c7853aa 100644 +---- a/tests/helpers/playwrightRepoServer.mjs +-+++ b/tests/helpers/playwrightRepoServer.mjs +-@@ -91,13 +91,11 @@ function resolveBrowserRoutePath(decodedPath) { +- } ++ if (pattern.test(contents)) { ++ findings.push(`${file}: ${pattern}`); ++ } ++diff --git a/tests/playwright/tools/AdminHealthOperationsPage.spec.mjs b/tests/playwright/tools/AdminHealthOperationsPage.spec.mjs ++index a047fbe36..8e12a9795 100644 ++--- a/tests/playwright/tools/AdminHealthOperationsPage.spec.mjs +++++ b/tests/playwright/tools/AdminHealthOperationsPage.spec.mjs ++@@ -344,7 +344,6 @@ test("Creator sessions cannot access Admin System Health operations", async ({ p ++ }); + +- export async function startRepoServer({ +-- gameJourneyCompletionMetricsLegacyDbPath = undefined, +- gameJourneyCompletionMetricsPostgresClient = null, +- messagesPostgresClient = null, +- } = {}) { +- await loadRuntimeEnv(); +- const handleLocalApiRequest = createLocalApiRouter({ +-- gameJourneyCompletionMetricsLegacyDbPath, +- gameJourneyCompletionMetricsPostgresClient, +- messagesPostgresClient, +- repoRoot, ++ test("Admin System Health operations page keeps scripts and styles external", async () => { ++- const retiredFileDbToken = "SQL" + "ite"; ++ const pageSource = await fs.readFile(path.resolve("admin/system-health.html"), "utf8"); ++ expect(pageSource).not.toMatch(/]+src=)/i); ++@@ -353,7 +352,7 @@ test("Admin System Health operations page keeps scripts and styles external", as ++ expect(pageSource).not.toMatch(/data-health-status="(?:WARN|FAIL)"/); ++ expect(pageSource).not.toContain("No active failure is declared"); ++ expect(pageSource).not.toMatch(/foundation PR|foundation view|placeholder|Pending metric|intentionally not wired/i); ++- expect(pageSource).not.toContain(retiredFileDbToken); +++ expect(pageSource).not.toContain("SQLite"); ++ expect(pageSource).toContain("Environment Identity"); ++ expect(pageSource).toContain("Environment Map"); ++ expect(pageSource).toContain("Environment Health Comparison"); ++@@ -375,7 +374,7 @@ test("Admin System Health operations page keeps scripts and styles external", as ++ expect(pageSource).toContain("assets/theme-v2/js/admin-system-health.js"); ++ expect(pageSource).toContain("assets/theme-v2/js/admin-owner-navigation.js"); ++ const runtimeSource = await fs.readFile(path.resolve("assets/theme-v2/js/admin-system-health.js"), "utf8"); ++- expect(runtimeSource).not.toContain(retiredFileDbToken); +++ expect(runtimeSource).not.toContain("SQLite"); ++ expect(runtimeSource).not.toContain("localStorage"); ++ expect(runtimeSource).not.toContain("sessionStorage"); ++ expect(runtimeSource).toContain("runAdminSystemHealthAction"); + diff --git a/tests/playwright/tools/GameJourneyTool.spec.mjs b/tests/playwright/tools/GameJourneyTool.spec.mjs +-index 75a913d96..cc47265cf 100644 ++index cc1006cce..cc47265cf 100644 + --- a/tests/playwright/tools/GameJourneyTool.spec.mjs + +++ b/tests/playwright/tools/GameJourneyTool.spec.mjs +-@@ -40,7 +40,6 @@ test.afterAll(async () => { +- async function openRepoPage(page, pathName, options = {}) { +- const gameJourneyCompletionMetricsPostgresClient = createGameJourneyCompletionMetricsPostgresClientStub(); +- const server = await startRepoServer({ +-- gameJourneyCompletionMetricsLegacyDbPath: null, +- gameJourneyCompletionMetricsPostgresClient, +- }); +- const previousApiUrl = process.env.GAMEFOUNDRY_API_URL; +-@@ -238,7 +237,6 @@ test("Game Journey exposes static tool ownership areas without automatic counts" +- +- const gameJourneyCompletionMetricsPostgresClient = createGameJourneyCompletionMetricsPostgresClientStub(); +- const server = await startRepoServer({ +-- gameJourneyCompletionMetricsLegacyDbPath: null, +- gameJourneyCompletionMetricsPostgresClient, +- }); +- try { +-@@ -262,7 +260,6 @@ test("Game Journey progress dashboard summarizes completion metrics", async ({ p +- process.env.GAMEFOUNDRY_LOCAL_DB_PATH = localDbPath; +- const gameJourneyCompletionMetricsPostgresClient = createGameJourneyCompletionMetricsPostgresClientStub(); +- const server = await startRepoServer({ +-- gameJourneyCompletionMetricsLegacyDbPath: null, +- gameJourneyCompletionMetricsPostgresClient, +- }); +- const previousApiUrl = process.env.GAMEFOUNDRY_API_URL; +-@@ -1285,7 +1282,6 @@ test("Game Journey displays system template diagnostics", async ({ page }) => { +- +- test("Game Journey mock data keeps system guidance template-owned", async () => { +- const repository = createGameJourneyMockRepository({ +-- completionMetricsLegacyDbPath: null, +- completionMetricsPostgresClient: createGameJourneyCompletionMetricsPostgresClientStub(), +- memoryDbTables: standaloneSeedTables, +- persist: false, +-@@ -1452,7 +1448,6 @@ test("Game Journey mock data keeps system guidance template-owned", async () => +- test("Game Journey Local API persists completion metrics to Postgres", async () => { +- const gameJourneyCompletionMetricsPostgresClient = createGameJourneyCompletionMetricsPostgresClientStub(); +- const server = await startRepoServer({ +-- gameJourneyCompletionMetricsLegacyDbPath: null, +- gameJourneyCompletionMetricsPostgresClient, +- }); +- try { +-@@ -1511,29 +1506,11 @@ test("Game Journey Local API persists completion metrics to Postgres", async () +- test("Game Journey completion metrics fail visibly when Postgres is not configured", async () => { +- const store = createGameJourneyCompletionMetricsStore({ +- env: {}, +-- legacyDbPath: null, +- }); ++@@ -128,7 +128,7 @@ function restoreEnvValue(key, value) { ++ } + +- await expect(store.listMetrics()).rejects.toThrow(/GAMEFOUNDRY_DATABASE_URL/); ++ function createFailingCompletionMetricsPostgresClient() { ++- const failure = new Error("Active metrics store temporarily unavailable."); +++ const failure = new Error("Active metrics store temporarily unavailable at tmp/local-api/game-journey-completion-metrics.sqlite."); ++ return { ++ dumpTable() { ++ return []; ++@@ -1568,7 +1568,6 @@ test("Toolbox registration exposes Game Journey navigation", async ({ page }) => + }); + +--test("Game Journey completion metrics protect legacy SQLite data from silent drop", async () => { +-- const legacyDbPath = path.join(process.cwd(), "tmp", "local-api", `game-journey-legacy-guard-${process.pid}-${Date.now()}.sqlite`); +-- await fs.mkdir(path.dirname(legacyDbPath), { recursive: true }); +-- await fs.writeFile(legacyDbPath, "legacy metrics placeholder"); +-- +-- const store = createGameJourneyCompletionMetricsStore({ +-- legacyDbPath, +-- postgresClient: createGameJourneyCompletionMetricsPostgresClientStub(), +-- }); +-- +-- try { +-- await expect(store.listMetrics()).rejects.toThrow(/Legacy Game Journey completion metrics SQLite data exists/); +-- } finally { +-- await fs.rm(legacyDbPath, { force: true }); +-- } +--}); +-- +- test("Game Journey requires an active game before editing", async ({ page }) => { +- const failures = await openRepoPage(page, "/toolbox/game-journey/index.html?game=none"); +- +-diff --git a/tests/playwright/tools/IdeaBoardTableNotes.spec.mjs b/tests/playwright/tools/IdeaBoardTableNotes.spec.mjs +-index 6d626f03b..be8c88698 100644 +---- a/tests/playwright/tools/IdeaBoardTableNotes.spec.mjs +-+++ b/tests/playwright/tools/IdeaBoardTableNotes.spec.mjs +-@@ -115,7 +115,6 @@ async function expectNoNavigationFallbackUi(page) { +- +- test("Idea Board uses accordion table ideas and notes", async ({ page }) => { +- const server = await startRepoServer({ +-- gameJourneyCompletionMetricsLegacyDbPath: null, +- gameJourneyCompletionMetricsPostgresClient: createGameJourneyCompletionMetricsPostgresClientStub(), +- }); +- const previousApiUrl = process.env.GAMEFOUNDRY_API_URL; +-@@ -478,7 +477,6 @@ test("Idea Board uses accordion table ideas and notes", async ({ page }) => { +- +- test("Idea Board gates Create Project to Ready ideas and locks converted projects", async ({ page }) => { +- const server = await startRepoServer({ +-- gameJourneyCompletionMetricsLegacyDbPath: null, +- gameJourneyCompletionMetricsPostgresClient: createGameJourneyCompletionMetricsPostgresClientStub(), +- }); +- const previousApiUrl = process.env.GAMEFOUNDRY_API_URL; +-@@ -595,7 +593,6 @@ test("Idea Board gates Create Project to Ready ideas and locks converted project +- +- test("Idea Board guest write actions redirect to sign in before saving data", async ({ page }) => { ++ test("Toolbox renders Creator-safe Game Journey progress outage copy", async ({ page }) => { ++- const forbiddenOutagePrefix = ["Game Journey completion metrics", "unavailable"].join(" "); + const server = await startRepoServer({ +-- gameJourneyCompletionMetricsLegacyDbPath: null, +- gameJourneyCompletionMetricsPostgresClient: createGameJourneyCompletionMetricsPostgresClientStub(), ++ gameJourneyCompletionMetricsPostgresClient: createFailingCompletionMetricsPostgresClient(), + }); +- const previousApiUrl = process.env.GAMEFOUNDRY_API_URL; +\ No newline at end of file ++@@ -1582,7 +1581,9 @@ test("Toolbox renders Creator-safe Game Journey progress outage copy", async ({ ++ await expect(page.locator("[data-game-journey-completion-diagnostic]").first()).toHaveText( ++ "Game Journey progress is temporarily unavailable. Continue building while progress refreshes.", ++ ); ++- await expect(page.locator("body")).not.toContainText(forbiddenOutagePrefix); +++ await expect(page.locator("body")).not.toContainText("Game Journey completion metrics unavailable"); +++ await expect(page.locator("body")).not.toContainText("SQLite"); +++ await expect(page.locator("body")).not.toContainText("tmp/local-api"); ++ await expect(page.locator("body")).not.toContainText("Postgres"); ++ } finally { ++ await server.close(); diff --git a/project-instructions/README.md b/project-instructions/README.md new file mode 100644 index 000000000..af401852e From a5f5d2eb1411cda3c20034772d47c25d0f53cae1 Mon Sep 17 00:00:00 2001 From: Alfa Team Date: Fri, 26 Jun 2026 13:30:23 -0400 Subject: [PATCH 4/9] Clean ProjectInstructions dev root --- docs_build/dev/BUILD_PR.md | 30 +- ...NDALONE_SAMPLE_GENERIC_FAILURE_CLOSEOUT.md | 64 - docs_build/dev/NEXT_RESTART.md | 67 - docs_build/dev/PLAN_PR.md | 11 +- ...NDALONE_SAMPLE_GENERIC_FAILURE_CLOSEOUT.md | 64 - docs_build/dev/PROJECT_INSTRUCTIONS.md | 2432 ---- docs_build/dev/PROJECT_MULTI_PC.txt | 563 - docs_build/dev/ProjectInstructions/README.txt | 4 +- ...ect_instructions_single_source_eod_lock.md | 4 +- docs_build/dev/codex_commands.md | 37 - docs_build/dev/codex_rules.md | 1 - docs_build/dev/commit_comment.txt | 5 - ...ect-instructions-single-source-eod-lock.md | 39 +- ...ingle-source-eod-lock_branch-validation.md | 13 +- ...source-eod-lock_manual-validation-notes.md | 19 +- ...e-source-eod-lock_requirement-checklist.md | 40 +- ...-single-source-eod-lock_validation-lane.md | 31 +- .../dev/reports/codex_changed_files.txt | 88 +- docs_build/dev/reports/codex_review.diff | 11896 +++++----------- docs_build/dev/restart_notes_11_105.md | 16 - docs_build/dev/restart_notes_11_110.md | 7 - docs_build/dev/restart_notes_11_111.md | 12 - docs_build/dev/restart_notes_11_112.md | 16 - docs_build/dev/restart_notes_11_116.md | 7 - docs_build/dev/restart_notes_11_118.md | 9 - docs_build/dev/restart_notes_11_119.md | 11 - docs_build/dev/restart_notes_11_120.md | 11 - docs_build/dev/restart_notes_11_121.md | 9 - docs_build/dev/restart_notes_11_122.md | 7 - docs_build/dev/restart_notes_11_123.md | 10 - 30 files changed, 3899 insertions(+), 11624 deletions(-) delete mode 100644 docs_build/dev/BUILD_PR_LEVEL_10_6B_STANDALONE_SAMPLE_GENERIC_FAILURE_CLOSEOUT.md delete mode 100644 docs_build/dev/NEXT_RESTART.md delete mode 100644 docs_build/dev/PLAN_PR_LEVEL_10_6B_STANDALONE_SAMPLE_GENERIC_FAILURE_CLOSEOUT.md delete mode 100644 docs_build/dev/PROJECT_INSTRUCTIONS.md delete mode 100644 docs_build/dev/PROJECT_MULTI_PC.txt delete mode 100644 docs_build/dev/codex_commands.md delete mode 100644 docs_build/dev/codex_rules.md delete mode 100644 docs_build/dev/commit_comment.txt delete mode 100644 docs_build/dev/restart_notes_11_105.md delete mode 100644 docs_build/dev/restart_notes_11_110.md delete mode 100644 docs_build/dev/restart_notes_11_111.md delete mode 100644 docs_build/dev/restart_notes_11_112.md delete mode 100644 docs_build/dev/restart_notes_11_116.md delete mode 100644 docs_build/dev/restart_notes_11_118.md delete mode 100644 docs_build/dev/restart_notes_11_119.md delete mode 100644 docs_build/dev/restart_notes_11_120.md delete mode 100644 docs_build/dev/restart_notes_11_121.md delete mode 100644 docs_build/dev/restart_notes_11_122.md delete mode 100644 docs_build/dev/restart_notes_11_123.md diff --git a/docs_build/dev/BUILD_PR.md b/docs_build/dev/BUILD_PR.md index c375aee47..9852d7780 100644 --- a/docs_build/dev/BUILD_PR.md +++ b/docs_build/dev/BUILD_PR.md @@ -12,7 +12,9 @@ This `BUILD_PR.md`, `PLAN_PR.md`, and the user request are the source of truth f - Audit repo for ProjectInstructions / project instructions duplicates. - Establish `docs_build/dev/ProjectInstructions/` as the only active source. -- Mark all other ProjectInstructions-style sources changed by this PR as deprecated references. +- Remove duplicate active instruction files from `docs_build/dev/` root. +- Remove stale one-off PR/restart files from `docs_build/dev/` root. +- Keep preserved historical ProjectInstructions material reference-only. - Update active team start/governance docs to reference only `docs_build/dev/ProjectInstructions/`. - Add EOD main lock, next-day reset governance, and canonical START / WORK / END branch lifecycle rules. - Add required reports under `docs_build/dev/reports/`. @@ -21,7 +23,6 @@ This `BUILD_PR.md`, `PLAN_PR.md`, and the user request are the source of truth f - `docs_build/dev/PLAN_PR.md` - `docs_build/dev/BUILD_PR.md` -- `docs_build/dev/PROJECT_INSTRUCTIONS.md` - `docs_build/dev/ProjectInstructions/README.txt` - `docs_build/dev/ProjectInstructions/PROJECT_INSTRUCTIONS.md` - `docs_build/dev/ProjectInstructions/TEAM_START_COMMANDS.md` @@ -29,6 +30,26 @@ This `BUILD_PR.md`, `PLAN_PR.md`, and the user request are the source of truth f - `docs_build/dev/ProjectInstructions/addendums/*.md` - `project-instructions/README.md` - `project-instructions/addendums/*.md` +- `docs_build/dev/PROJECT_INSTRUCTIONS.md` (delete) +- `docs_build/dev/PROJECT_MULTI_PC.txt` (delete) +- `docs_build/dev/BUILD_PR_LEVEL_10_6B_STANDALONE_SAMPLE_GENERIC_FAILURE_CLOSEOUT.md` (delete) +- `docs_build/dev/PLAN_PR_LEVEL_10_6B_STANDALONE_SAMPLE_GENERIC_FAILURE_CLOSEOUT.md` (delete) +- `docs_build/dev/codex_commands.md` (delete) +- `docs_build/dev/codex_rules.md` (delete) +- `docs_build/dev/commit_comment.txt` (delete) +- `docs_build/dev/next_command.txt` (delete if present) +- `docs_build/dev/NEXT_RESTART.md` (delete) +- `docs_build/dev/restart_notes_11_105.md` (delete) +- `docs_build/dev/restart_notes_11_110.md` (delete) +- `docs_build/dev/restart_notes_11_111.md` (delete) +- `docs_build/dev/restart_notes_11_112.md` (delete) +- `docs_build/dev/restart_notes_11_116.md` (delete) +- `docs_build/dev/restart_notes_11_118.md` (delete) +- `docs_build/dev/restart_notes_11_119.md` (delete) +- `docs_build/dev/restart_notes_11_120.md` (delete) +- `docs_build/dev/restart_notes_11_121.md` (delete) +- `docs_build/dev/restart_notes_11_122.md` (delete) +- `docs_build/dev/restart_notes_11_123.md` (delete) - `docs_build/dev/reports/PR_26177_OWNER_007-project-instructions-single-source-eod-lock*.md` - `docs_build/dev/reports/codex_review.diff` - `docs_build/dev/reports/codex_changed_files.txt` @@ -45,7 +66,10 @@ This `BUILD_PR.md`, `PLAN_PR.md`, and the user request are the source of truth f Run: ```powershell -rg -n 'project-instructions/addendums|docs_build/dev/PROJECT_INSTRUCTIONS.md.*source of truth|Codex must always read `docs_build/dev/PROJECT_INSTRUCTIONS.md`|Read `docs_build/dev/PROJECT_INSTRUCTIONS.md`' docs_build/dev/ProjectInstructions docs_build/dev/PROJECT_INSTRUCTIONS.md project-instructions +Test-Path docs_build/dev/PROJECT_INSTRUCTIONS.md +Test-Path docs_build/dev/PROJECT_MULTI_PC.txt +rg -n 'only active Project Instructions source|docs_build/dev/ProjectInstructions/' docs_build/dev/ProjectInstructions +rg -n 'docs_build/dev/PROJECT_INSTRUCTIONS.md.*source of truth|Codex must always read `docs_build/dev/PROJECT_INSTRUCTIONS.md`|Read `docs_build/dev/PROJECT_INSTRUCTIONS.md`' docs_build/dev/ProjectInstructions project-instructions rg -n "Branch Lifecycle \\(Canonical\\)|Every PR follows exactly three phases|^START$|^WORK$|^END$|Mandatory Hard Stops|tomorrow's official baseline|No commits on main|Never checkout main|Only after ALL four pass" docs_build/dev/ProjectInstructions git diff --name-only -- src assets toolbox games api serverside package.json package-lock.json docs_build/dev/start_of_day git diff --check diff --git a/docs_build/dev/BUILD_PR_LEVEL_10_6B_STANDALONE_SAMPLE_GENERIC_FAILURE_CLOSEOUT.md b/docs_build/dev/BUILD_PR_LEVEL_10_6B_STANDALONE_SAMPLE_GENERIC_FAILURE_CLOSEOUT.md deleted file mode 100644 index 3c6e356d5..000000000 --- a/docs_build/dev/BUILD_PR_LEVEL_10_6B_STANDALONE_SAMPLE_GENERIC_FAILURE_CLOSEOUT.md +++ /dev/null @@ -1,64 +0,0 @@ -# BUILD_PR: LEVEL_10_6B_STANDALONE_SAMPLE_GENERIC_FAILURE_CLOSEOUT - -## One-pass Codex build instruction -Implement the smallest valid changes needed to close remaining generic standalone sample/tool data-flow failures. - -Use the existing failing report as the source of truth: - -```text -docs_build/dev/reports/level_10_6_standalone_tool_data_flow_report.md -``` - -Focus only on failures where a sample launches but the tool does not receive or bind the payload correctly. - -## Implementation boundaries -Codex may edit only files needed for standalone sample contract stability, typically: - -- affected `samples/phase-*/*` sample files -- affected `toolbox/*` tool entrypoints or adapters -- affected manifest/contract files already used by these samples -- the standalone data-flow test only if it currently reports a false generic failure without weakening coverage -- docs_build/dev reports for the new result - -Codex must not implement unrelated features. - -## Contract checks per tool -For every changed failing area, verify: - -1. Sample declares explicit payload/manifest input. -2. Schema or normalized contract accepts the payload shape. -3. Tool receives the payload from the standalone launch path. -4. Tool renders safe empty state only when the input is truly absent. -5. Tool does not auto-load hidden defaults, demo assets, or hardcoded paths. -6. Test report captures the corrected behavior. - -## Required validation commands -Run these from repo root: - -```powershell -npm run test:launch-smoke:games -npm run test:sample-standalone:data-flow -``` - -## Required output files -Update or create: - -```text -docs_build/dev/reports/level_10_6b_standalone_generic_failure_closeout_report.md -docs_build/dev/reports/level_10_6b_tool_contract_matrix.md -``` - -The closeout report must include: - -- before generic failure count -- after generic failure count -- list of tools fixed -- list of tools still failing, if any -- exact validation commands run -- whether game launch smoke still passes - -## Done criteria -- `npm run test:launch-smoke:games` passes. -- `npm run test:sample-standalone:data-flow` passes or materially reduces generic failures with a precise remaining list. -- No silent fallback data or hardcoded asset path was added. -- Roadmap status is advanced only through real validation-backed progress. diff --git a/docs_build/dev/NEXT_RESTART.md b/docs_build/dev/NEXT_RESTART.md deleted file mode 100644 index e44fe0fc4..000000000 --- a/docs_build/dev/NEXT_RESTART.md +++ /dev/null @@ -1,67 +0,0 @@ -# RESTART — PR 11.188 Palette Manager Tool v2 - -## Open repo - -```powershell -cd C:\Users\davidq\Documents\GitHub\HTML-JavaScript-Gaming -code . -``` - -## Sync - -```powershell -git status -git pull -``` - -## Active PR - -```text -BUILD_PR_LEVEL_11_188_PALETTE_MANAGER_REVERSE_ENGINEER_AND_REBUILD -``` - -## Locked Direction - -```text -Tool v2 lane only -Palette Manager first -No schema changes -No sample changes -No game changes -No Workspace Manager v1 wiring -No legacy tool patching -No toolbox/shared usage for new v2 code -No fallback/default data -``` - -## Visible Name - -```text -Palette Manager -``` - -Do not show: - -```text -Palette Browser / Manager -Palette Manager v2 -Palette Browser v2 -``` - -## Required Header Rule - -Use the header pattern from: - -```text -/index.html -``` - -Include an accordion to hide/show the header/details section. - -## Next Execution - -Run the Codex command in: - -```text -docs_build/dev/codex_commands.md -``` diff --git a/docs_build/dev/PLAN_PR.md b/docs_build/dev/PLAN_PR.md index 0e5d6a50e..56df3b956 100644 --- a/docs_build/dev/PLAN_PR.md +++ b/docs_build/dev/PLAN_PR.md @@ -7,7 +7,9 @@ Make `docs_build/dev/ProjectInstructions/` the only active Project Instructions ## Scope - Audit ProjectInstructions and project instructions duplicates. -- Mark legacy ProjectInstructions-style sources as deprecated reference material. +- Delete duplicate active instruction files from `docs_build/dev/` root. +- Delete stale one-off PR/restart files from `docs_build/dev/` root. +- Preserve historical ProjectInstructions-style sources only as deprecated reference material. - Move active legacy addendums into `docs_build/dev/ProjectInstructions/addendums/`. - Update active team start and governance docs to reference only `docs_build/dev/ProjectInstructions/`. - Add EOD main lock, next-day reset, team PR branch creation gate, and canonical START / WORK / END branch lifecycle rules. @@ -23,6 +25,7 @@ Make `docs_build/dev/ProjectInstructions/` the only active Project Instructions ## Validation Plan 1. Run targeted grep/search proving no active duplicate ProjectInstructions source remains. -2. Confirm EOD/Next Day and canonical START / WORK / END branch lifecycle rules appear in active governance docs. -3. Confirm no product/runtime files changed. -4. Run `git diff --check`. +2. Confirm duplicate active root instruction files and stale one-off root files are absent. +3. Confirm EOD/Next Day and canonical START / WORK / END branch lifecycle rules appear in active governance docs. +4. Confirm no product/runtime files changed. +5. Run `git diff --check`. diff --git a/docs_build/dev/PLAN_PR_LEVEL_10_6B_STANDALONE_SAMPLE_GENERIC_FAILURE_CLOSEOUT.md b/docs_build/dev/PLAN_PR_LEVEL_10_6B_STANDALONE_SAMPLE_GENERIC_FAILURE_CLOSEOUT.md deleted file mode 100644 index f4a0ebc2c..000000000 --- a/docs_build/dev/PLAN_PR_LEVEL_10_6B_STANDALONE_SAMPLE_GENERIC_FAILURE_CLOSEOUT.md +++ /dev/null @@ -1,64 +0,0 @@ -# PLAN_PR: LEVEL_10_6B_STANDALONE_SAMPLE_GENERIC_FAILURE_CLOSEOUT - -## Purpose -Close the remaining generic failure signals in the standalone sample/tool data-flow contract test without adding new tools, schemas, or features. - -## Roadmap phase -Phase 10 = TOOL + SAMPLE CONTRACT STABILITY - -## Scope -Fix only standalone sample contract failures reported by: - -```powershell -npm run test:sample-standalone:data-flow -``` - -Target failing areas from the prior report: - -- Asset Browser / Import Hub -- Asset Pipeline Tool -- Parallax Scene Studio -- Performance Profiler -- Physics Sandbox -- Replay Visualizer -- Palette binding -- State Inspector JSON input -- Tile Model Converter -- Tilemap Studio -- Vector Asset Studio -- Vector Map Editor - -## Required rule -Every fix must preserve this contract chain: - -```text -sample -> schema -> normalized input -> tool -> UI/state -``` - -## Hard constraints -- Do not add silent fallback data. -- Do not add hardcoded asset paths. -- Do not hide failures by weakening assertions. -- Do not add new schemas unless an existing documented schema is missing from the sample contract path. -- Do not make repo-wide formatting or unrelated cleanup changes. -- Do not modify `start_of_day` folders. - -## Debug priority -For each failure, answer this first: - -```text -Did the tool receive the payload? -``` - -Then check: - -- payload shape -- binding slot -- manifest path -- stale route/path -- required field mismatch -- JSON validity -- UI state update after payload ingest - -## Expected result -The PR is complete when the standalone data-flow test report shows fewer generic failure signals than before, with all changed tools receiving explicit sample payloads through the documented contract path. diff --git a/docs_build/dev/PROJECT_INSTRUCTIONS.md b/docs_build/dev/PROJECT_INSTRUCTIONS.md deleted file mode 100644 index c1136fdbe..000000000 --- a/docs_build/dev/PROJECT_INSTRUCTIONS.md +++ /dev/null @@ -1,2432 +0,0 @@ -# PROJECT INSTRUCTIONS - -> Deprecated active-source notice: this file is preserved as historical reference only. The only active Project Instructions source is `docs_build/dev/ProjectInstructions/`. If this file conflicts with `docs_build/dev/ProjectInstructions/`, the active folder wins unless OWNER explicitly approves a newer governance change. - -You are working in a docs-first repo workflow. - -Workflow: -PLAN_PR → BUILD_PR → APPLY_PR - -PR lifecycle gate: -PR Open → Plan → Build → Validation → Approved → Merged → Main Verified → Closed - -The PLAN_PR → BUILD_PR → APPLY_PR workflow remains preserved. PR Open is the first lifecycle status for active work, Plan happens after PR Open on the same PR branch, and Closed is the final repository-state gate. - -# WORKFLOW & EXECUTION - -## PR NAMING STANDARD - -PR names MUST follow: - -`PR___<###>-` - -Where: -- `YY` = year (2 digit) -- `JJJ` = Julian day (001-365) -- `TEAM` = required team ownership token from `docs_build/dev/PROJECT_MULTI_PC.txt` -- `###` = sequence for the day (001+) - -Example: -- `PR_26171_ALPHA_065-message-studio-parent-child-table-foundation` -- `PR_26171_BETA_069-message-tts-profile-contract-alignment` -- `PR_26171_GAMMA_071-main-merge-conflict-recovery` - -Branch names MUST mirror PR ownership: - -`pr/--<###>-` - -Branch examples: -- `pr/26171-ALPHA-065-message-studio-parent-child-table-foundation` -- `pr/26171-BETA-069-message-tts-profile-contract-alignment` -- `pr/26171-GAMMA-071-main-merge-conflict-recovery` - -Rules: -- Must be unique per day -- Must be sortable -- `TEAM` is required -- `TEAM` ownership comes from `docs_build/dev/PROJECT_MULTI_PC.txt` -- Team ownership is independent of machine, workspace, laptop, desktop, or environment -- Description must be short and hyphenated -- Do NOT reuse old `PR_11_*` format for new PRs -- Existing PC/LAPTOP, desktop/laptop, workspace, environment, or machine-parity examples are historical only -- Future PR reports, recovery reports, validation reports, and manual validation notes must include TEAM ownership - -## PR LIFECYCLE STATE GATE - -Required state order: - -1. PR Open -2. Plan -3. Build -4. Validation -5. Approved -6. Merged -7. Main Verified -8. Closed - -Definitions: -- PR Open is the first active lifecycle state. -- PR Open means the tracked PR identity and source branch have been created and named before Plan begins. -- Plan happens after PR Open on the same PR branch. -- Build, validation, reports, ZIP packaging, and closeout stay tied to that same PR identity and source branch. -- No BUILD_PR may proceed without a PR name and active branch/PR identity unless it is explicitly marked `PLAN_ONLY`. -- Build means scoped implementation, audit, report, validation, governance, or cleanup work is in progress for that PR identity. -- Validation means requested checks, required report creation, manual validation notes, and ZIP packaging are being completed. -- Approved means the owner or required reviewer has approved the PR outcome for merge. -- Merged means the PR has merged and changes have been pushed. -- Main Verified means Codex is back on `main`, `main` includes the merge commit or recorded final commit, the worktree is clean, local/origin sync is `0/0`, and no untracked files remain. -- Closed means every Closed gate below is PASS. - -Closed is valid only when all are PASS: -- PR merged and changes pushed. -- Current branch is `main`. -- `main` includes the merge commit or recorded final commit. -- Worktree clean. -- Local/origin sync is `0/0`. -- No untracked files. -- Branch disposition recorded as `retained`. -- Required reports exist. -- Required repo-structured ZIP under `tmp/` exists. -- Backlog updated. -- Tool state updated when applicable. - -Hard stop: -- A team must not begin another PR if its previous PR is not Closed. -- Exception is allowed only for explicitly documented stacked PR chains. - -Required final closeout output: - -```text -FINAL REPOSITORY STATE: -- Branch -- Worktree -- Local/origin sync -- PR number/name -- PR status -- Merge/final commit -- Branch disposition -- Backlog update status -- Tool state update status -- ZIP path -- Closeout PASS/FAIL -``` - -## CHATGPT EXECUTION ROLE - -ChatGPT no longer creates PLAN_PR, BUILD_PR, APPLY_PR docs, ZIP bundles, or implementation code. - -ChatGPT repo workflow response formatting is governed by `OUTPUT RULES` and the newest explicit ChatGPT workflow sections below. - -ChatGPT must not: -- create ZIP files -- reference ZIP delivery -- produce PLAN/BUILD/APPLY docs -- write implementation code unless explicitly requested - -## CODEX EXECUTION ROLE - -Codex creates: -- PLAN_PR docs -- BUILD_PR docs -- APPLY_PR docs when needed -- repo-structured ZIP bundles -- implementation changes -- Playwright/test updates when required -- review artifacts for ChatGPT code review - -Codex must place detailed content in: -- `docs_build/pr/*` -- `docs_build/dev/codex_commands.md` -- `docs_build/dev/commit_comment.txt` -- `docs_build/dev/reports/*` - -## USER ROLE - -User: -- runs Codex -- validates results -- commits approved changes -- uploads deltas/reports when ChatGPT review is needed - -## RULES - -- One PR purpose only -- Smallest scoped valid change -- BUILD must be one-pass executable -- No vague wording -- No repo-wide scanning unless required -- Do not expand scope beyond the PR -- Do not modify `start_of_day` folders unless requested - -## MAIN BRANCH EXECUTION GUARD - -Before any BUILD execution, Codex must verify the current git branch. - -Rules: -- The required execution branch is: - - `main` -- If the current branch is not `main`: - - HARD STOP. - - Do not create code changes. - - Do not create implementation PRs. - - Do not create ZIP artifacts. - - Do not continue execution. -- Codex must report: - - current branch - - expected branch (`main`) - - local branches found -- Codex may continue only after the user explicitly returns to `main`. - -Exception: -- Explicit branch-audit or branch-comparison PRs may inspect non-main branches but must not perform implementation work on them. - -Required report output: -- Current branch -- Branch validation PASS/FAIL - -## SLIDER VALUE VISIBILITY REQUIREMENT - -All user-adjustable slider controls must display their current value while being adjusted. - -Rules: -- Value display must update live during drag/input. -- Creators must not need to release the slider to see the value. -- Value display must remain visible at all times. -- Value display must not rely solely on browser-native tooltips. -- Sliders should prefer: - - Label + Slider + Current Value -- Example: - - `Contrast [------^------] 40%` - - `Saturation [------^------] 75%` - - `Hue Shift [------^------] +15°` -- Units should be displayed when meaningful: - - `%` - - degrees - - pixels - - milliseconds - - volume - - opacity -- Floating thumb tooltips are optional. -- Persistent visible values are required. -- Applies to: - - Toolbox tools - - Game Hub controls - - Account/Admin pages - - Theme V2 controls - - Future tools and pages - -## SLIDER RESET BEHAVIOR REQUIREMENT - -All user-adjustable sliders must support reset-to-default behavior. - -Rules: -- Double-clicking a slider resets it to its default value. -- Reset must occur immediately. -- Reset value must be visible through the live value display. -- Creators must not need a separate reset button for individual sliders. -- Tool-specific Reset buttons may still exist for resetting multiple controls. -- Slider tooltips/help text should identify the default value when practical. -- Applies to: - - Toolbox tools - - Game Hub controls - - Account/Admin pages - - Theme V2 controls - - Future tools and pages - -## RULE PRECEDENCE - -Newer appended sections override earlier overlapping rules. - -When rules overlap, use the most specific current section as authoritative. - -Conflicting workflow instructions must resolve to the newest explicit section. - -Future governance additions should extend existing sections instead of duplicating overlapping guidance. - -## GOVERNANCE CLOSEOUT - -Docs-only PRs should prefer bundling with related docs/workflow cleanup when safe. - -Stabilization/recovery lane rules supersede older generalized workflow assumptions. - -Engine/tool/integration boundaries are authoritative for validation routing. - -Hidden validation expansion is prohibited. - -Workflow and testing language must not assume implicit persisted workspace, toolState, `localStorage`, `sessionStorage`, sample, or runtime state. - -Required validation lane names are: -- contract -- runtime -- integration -- engine -- samples -- recovery/UAT - -## PROJECT INSTRUCTIONS STABILITY AND MAINTENANCE MODE - -`PROJECT_INSTRUCTIONS.md` is now considered architecturally stabilized. - -Future additions should prefer targeted amendments instead of broad workflow rewrites. - -New rules should extend existing authoritative sections whenever possible. - -Avoid introducing parallel governance systems or duplicate rule sets. - -Anti-drift governance: -- avoid capability drift across `src/`, deprecated `archive/v1-v2/tools/`, deprecated `archive/v1-v2/games/`, deprecated `archive/v1-v2/samples/`, and `toolbox/` -- avoid workflow drift across overlapping sections -- avoid validation drift between engine, tool, and integration lanes -- avoid UI/UX drift from Workspace V2 ecosystem contracts - -Stabilization intent: -- governance exists to reduce monolith growth, hidden coupling, and duplicated runtime behavior -- reusable/shared capability should converge into `src/` -- first-class tools should converge toward shared Workspace V2 lifecycle behavior -- targeted validation is the preferred operational mode - -Future guidance: -- future governance PRs should remain small and execution-backed -- implementation, runtime, and tool work should now take priority over additional governance expansion unless a real gap is discovered -- governance additions should solve demonstrated operational problems rather than hypothetical future issues - -## NAVIGATION, LIST, AND TOOLBOX MODEL GOVERNANCE - -Navigation menus, submenus, nested submenus, and user-facing lists must be alphabetically sorted when they are presented as browseable choices. - -Primary top-level header navigation is an explicit product IA exception and must remain: -- Games -- Toolbox -- Marketplace -- Learn -- Account -- Admin - -Allowed intentional-order exceptions: -- primary top-level header navigation -- Toolbox groups and tiles when they are presented as creator workflow surfaces -- workflow paths -- Build Path -- dependency paths -- Game Progress -- Launch Progress -- guided creator steps - -Every intentional-order exception must be documented in the PR report that introduces or preserves it. - -### Workflow Ordering Governance - -When a surface represents a creator workflow, items are ordered by the likely next action, not alphabetically. -Workflow ordering is an approved exception to alphabetical ordering. -This applies to Toolbox, Game Hub, Create, Publish, Progress, and future guided workflows. - -Rules: -- Order follows how users naturally work: - - Select -> Create -> Review - - Left -> Right - - Top -> Bottom -- The next tile should represent the most likely next creator action. -- Tile ordering should minimize navigation decisions. - -Create group order: -1. Game Hub -2. Game Crew -3. Game Configuration -4. Tags - -Team planning distinction: -- Studio Team is the account-level roster. -- Game Crew is the game-level assignment surface. -- Current Toolbox implementation focus is Game Crew. -- Creator functionality that previously lived in Account/Team planning should be planned through Create/Game Crew when it is game-specific. - -Toolbox status values are: -- Ready -- Wireframe -- Under Construction -- Planned -- Hidden -- Deprecated - -Toolbox progress foundation fields are: -- `requiredForTestable` -- `requiredForPublish` -- `requires` -- `status` -- `progressChecklist` - -Progress and Build Path views remain wireframe-only until a later implementation PR explicitly introduces a declared registry/data source and runtime behavior. - -Game Hub is the next first real Toolbox rebuild target. Its contract owns: -- Project Identity -- Project Status -- Project Progress -- Launch Progress - -Do not implement Game Hub runtime behavior, persistence, database behavior, authentication, or save/load flows before the rebuild PR explicitly scopes those capabilities. - -## TOOL STATUS GOVERNANCE - -The authoritative tool status values are: -- `planned` -- `wireframe` -- `beta` -- `complete` -- `deprecated` - -Status definitions: -- `planned`: Not designed yet. No meaningful UI. No ownership defined. -- `wireframe`: Tool exists. User can understand workflow. Data ownership is defined. Not functionally usable. -- `beta`: Functionally usable. Can be used in a real game. May still contain incomplete workflows, placeholder data, UI cleanup issues, unused fields, missing validation, or incomplete code review. -- `complete`: Functionally usable. Code reviewed. Dead code removed. Invalid fields removed. UI cleaned up. No known placeholder data. No known invalid controls. Ready for long-term support. -- `deprecated`: Tool remains supported but is not recommended for new workflows. Must remain deprecated before removal. - -UAT rule: -- A tool required for the current MVP game path must be `beta` or `complete` before UAT. -- `complete` is not required for MVP UAT, but `beta` is the minimum usable state. - -## TARGETED MSJ VALIDATION GOVERNANCE - -Every tool, page, or `src/` change must declare its impacted MSJ/test lane. - -Run only the affected MSJ/test lane by default. - -Do not run the full suite for small scoped changes unless one of these shared surfaces changes: -- shared runtime behavior -- shared parser behavior -- shared DB behavior -- shared Theme V2 behavior -- cross-tool integration behavior - -If a shared source file changes, name the affected dependent lanes and run only those targeted lanes unless the dependency impact proves broader validation is required. - -Reports must state: -- impacted lane -- skipped lanes -- why skipped lanes were safe to skip -- when the full suite is required - -## SHARED MOCK DB ADAPTER CONTRACT - -All current app and tool mock data must flow through the shared DB adapter under `src/engine/persistence`. - -Tools must not maintain isolated page-local DB snapshots for data that should be visible to the Mock DB viewer or to another current tool. - -The active browser mock implementation is the Mock adapter. UAT and production persistence must swap through the same module-level contract by deployment configuration rather than by changing tool UI code. - -The Mock DB viewer must render live adapter state and table schemas, including empty tables with headers. It must not render hardcoded table dumps, hardcoded row counts, or copied static JSON snapshots. - -Audit ownership is users-only: every shared table record uses `key`, `createdAt`, `updatedAt`, `createdBy`, and `updatedBy`; the ownership fields reference `users.key`. Roles are modeled with `roles` and `user_roles`. - -## DB-BACKED PRODUCT DATA SSOT GOVERNANCE - -Web UI must access product data only through API or service contracts backed by DB adapters. - -Allowed production flow: -- Web UI -> API/Service Contract -> Server DB - -Allowed dev/UAT/test flow: -- Web UI -> API/Service Contract -> DB Adapter -- The DB Adapter may be MEM DB, Local DB, Test DB, or Server DB. - -Prohibited product-data ownership: -- page-local product data arrays -- page-local metadata registries -- hardcoded product counts -- duplicated status, group, path, or order data -- duplicated lookup maps that compete with DB-backed metadata -- browser storage as the product source of truth -- UI-only vote, order, or status state -- direct DB-shaped product data embedded in HTML or browser JavaScript pages - -Toolbox and Admin tool metadata must use a shared DB-backed tool metadata source for `toolKey`, `toolName`, `group`, `path`, `order`, and `status`. Browser pages may render metadata returned by the API/service contract, but they must not own a separate runtime copy of that metadata. - -## DATABASE DIRECTION - -Postgres is the authoritative active runtime database. - -SQLite is deprecated/retired and is not an active runtime database for Local (VS Code), DEV, IST, UAT, or PROD. - -Rules: -- New database work must target Postgres. -- Local (VS Code) API -> Postgres is the required direction. -- New PRs must not introduce SQLite persistence. -- Do not add new SQLite services. -- Do not add new SQLite DDL. -- Do not add new SQLite seed data. -- Do not add new SQLite runtime persistence. -- Legacy SQLite references may remain only as documented technical debt when they already exist. -- Browser code must not own product data or generate authoritative persistence keys. - -## DEV RUNTIME BOUNDARY - -All mock/dev-only runtime implementation must live under `src/dev-runtime/`. - -Required dev-runtime folders: -- `src/dev-runtime/auth/` -- `src/dev-runtime/persistence/` -- `src/dev-runtime/admin/` -- `src/dev-runtime/testing/` -- `src/dev-runtime/guest-seeds/` - -Rules: -- UAT/PROD must never import, bundle, or deploy `src/dev-runtime/`. -- Active tools must use declared runtime contracts and must not import `src/dev-runtime/` directly. -- Dev-only adapters may be exposed through existing dev/runtime contract shims only when the deployment boundary keeps `src/dev-runtime/` out of UAT/PROD bundles. -- No fallback auth, session, user, admin, or system user data is allowed. -- Local session state must resolve selected users and roles from persisted Memory DB `users`, `roles`, and `user_roles` records. -- Missing users or roles must fail visibly with actionable diagnostics. - -## ENVIRONMENT CONFIGURATION GOVERNANCE - -Runtime startup loads `.env` only. - -Official environment model: -- `Local (VS Code)` -- `DEV` -- `IST` -- `UAT` -- `PROD` - -Promotion order: -- `Local (VS Code) -> DEV -> IST -> UAT -> PROD` - -Environment invariance rule: -- The deployable artifact is identical across every environment. -- Only `.env` values and environment-managed secret values differ between environments. -- Application code, runtime code, API/service code, database runtime scripts, migrations, and bundles must not fork by environment name. - -Shared API/service contract: -- One shared API/service contract is required across Local (VS Code), DEV, IST, UAT, and PROD. -- Browser/UI/runtime code must consume the same contract in every environment. -- Environment-specific URLs, endpoints, keys, buckets, and prefixes are `.env` or environment-managed secret/config values only. -- Do not create environment-specific API/service contracts. -- Do not split Local API and Public API contracts. Local and shared environments use the same API/service contract; URLs may differ by `.env` only. - -Required services in every environment: -- Supabase Auth -- Supabase Postgres -- Cloudflare R2 - -Guest seed data rule: -- All environments receive approved guest seed data for all tools. -- Guest seed data is shared environment setup data, not an environment-specific behavior fork. -- Guest seed data must be applied through the shared data/service contract and must not require per-environment application code. - -Required Cloudflare R2 top-level prefixes: -- Local (VS Code): `/local/` -- DEV: `/dev/` -- IST: `/ist/` -- UAT: `/uat/` -- PROD: `/prod/` - -Derived R2 paths for projects, backups, exports, or future storage lanes must stay under the matching top-level prefix for the active environment. - -Only `.env.example` is committed to the repository. - -Real `.env` files are user/environment-owned and must live outside the repo clone or be injected by deployment. - -Official external environment file names when a copy-source file is used outside the repo clone: -- `.env.local` -- `.env.dev` -- `.env.ist` -- `.env.uat` -- `.env.prod` - -Example external layout: -- `/env/local/.env` -- `/env/dev/.env` -- `/env/ist/.env` -- `/env/uat/.env` -- `/env/prod/.env` -- `/GFS/` repo clone - -The app/runtime reads `.env` values supplied by the target environment. It must not require real `.env` files to be committed inside the repo clone. - -`.env.prd` is legacy technical debt only. New environment governance uses `.env.prod` for external PROD copy-source naming and the `PROD` environment name. - -Allowed `GAMEFOUNDRY_ENVIRONMENT` values: -- `local` -- `dev` -- `ist` -- `uat` -- `prod` - -`GAMEFOUNDRY_ENVIRONMENT_LABEL` is display-only and must not drive runtime behavior, API/service selection, database selection, storage selection, or feature behavior. - -Valid environment stages are: -- `Local (VS Code)` -- `DEV` -- `IST` -- `UAT` -- `PROD` - -Manual deployment-target flow: -1. Copy the selected `.env.` file to `.env`. -2. Run validation. -3. Apply DDL/DML migrations. -4. Start runtime. - -Runtime environment parameters are prohibited. - -Do not introduce runtime parameters such as: -- `--env` -- `--environment` -- `ENVIRONMENT=LOCAL` -- `ENVIRONMENT=DEV` -- `ENVIRONMENT=UAT` -- `ENVIRONMENT=PROD` - -`Local (VS Code)`, `DEV`, `IST`, `UAT`, and `PROD` are environment stages, not application behaviors. - -Application code, runtime code, API/service code, and DB runtime scripts must not branch behavior by deployment target name. - -Host/domain configuration: -- Local (VS Code) uses `127.0.0.1` hostnames. -- DEV, IST, UAT, and PROD use configured `*.gamefoundrystudio.com` hostnames. -- Host/domain differences are configuration values only and must not create separate deployable artifacts or environment-specific code. - -Feature flag governance: -- Feature flags must not create permanent environment-specific behavior. -- Feature flags may be used only for staged rollout, testing, or emergency mitigation. -- Feature flags must be removed, promoted to normal behavior, or documented as active temporary controls when the rollout, test, or mitigation ends. - -## RUNTIME SCRIPT NAMING GOVERNANCE - -Active runtime script names should describe capability rather than vendor/provider. - -Preferred runtime naming nouns are: -- `auth` -- `database` -- `storage` -- `telemetry` -- `api` - -Avoid provider or vendor names in future active runtime script names. - -When an active script is renamed, a temporary compatibility wrapper may remain only when needed for command continuity. - -Compatibility wrappers must log: - -`Deprecated script name. Use .` - -## ARCHIVED V1/V2 REFERENCE MATERIAL - -Deprecated V1/V2 reference material lives under: - -- `archive/v1-v2/tools/` -- `archive/v1-v2/games/` -- `archive/v1-v2/samples/` - -Rules: -- Archive material is retained for reference and traceability, not active app ownership. -- Active app navigation must not point users into `archive/v1-v2/`. -- Active validation must not run tests against `archive/v1-v2/` unless a later PR explicitly reclassifies a target. -- New toolbox, game, sample, engine, and Theme V2 work must not use archived material as the implementation source of truth. -- Cleanup and governance docs should refer to archived V1/V2 reference material through `archive/v1-v2/`. - -## GAMEFOUNDRYSTUDIO NORTH STAR - -GameFoundryStudio should present as an open-web creator destination where players and makers can move fluidly between creator tools, playable games, marketplace assets, tutorials, cloud saves, and community discovery. - -The product guidance phrase is: - -`Build · Play · Share` - -Use that phrase as a compact IA and copywriting anchor: -- Build: tools and creation flow, including asset creation, prototypes, systems, and publishing preparation. -- Play: games and discovery, including playable games, arcade browsing, testing, and saves. -- Share: public game pages, share links, creator profiles, marketplace assets, tutorials/community, ratings, and future publish/export flows. - -## GAMEFOUNDRYSTUDIO THEME V2 GOVERNANCE - -`assets/theme-v2` is the only approved styling surface for public/root GameFoundryStudio page work as bounded below. - -V1/legacy CSS is deprecated and out of play. - -### Theme Surface Boundary - -`assets/theme-v2/css` owns public/root GameFoundryStudio page styling: -- root Home -- Company pages -- Tools index -- public/root tool pages -- marketing/content surfaces -- placeholder Admin/Account pages until DB/login implementation - -`src/engine/theme` owns engine/runtime first-class tool shell styling: -- runtime tool shell -- engine-facing first-class tools -- reusable runtime UI foundations - -Rules: -- Do not deprecate `src/engine/theme` at this time. -- Do not duplicate behavior between the two surfaces. -- Do not create competing `.tool-shell` implementations. -- If both public/root tools and runtime first-class tools need the same behavior, document the shared shell contract first. -- Shared behavior must be promoted intentionally rather than patched independently in both places. -- Collapse/rail behavior currently belongs only to the public/root `.tool-workspace` shell unless a later PR explicitly promotes it to shared runtime shell behavior. - -### Theme V2 Only CSS Rule - -- Theme V2 is the only active styling system for public/root GameFoundryStudio page work. -- V1/legacy CSS is deprecated and out of play. -- V1/legacy CSS must not be used as a source. -- V1/legacy CSS must not be copied. -- V1/legacy CSS must not be ported. -- V1/legacy CSS must not be compared as the desired target. -- V1/legacy CSS must not be extended. -- V1/legacy CSS must not be reintroduced through aliases, duplicate selectors, wrapper selectors, compatibility classes, or fallback imports. -- New CSS must be authored directly in Theme V2 only when approved as reusable Theme V2 design-system styling. -- Pages not migrated to Theme V2 may temporarily retain their existing references until their migration PR. -- Pages that have migrated to Theme V2 must not reference V1/legacy CSS. -- Migration means replacing the page with Theme V2 usage, not copying V1 styles into Theme V2. - -If Theme V2 lacks a needed pattern: -1. Document the design-system gap. -2. Request approval. -3. Implement the reusable pattern directly in Theme V2. -4. Do not solve it by using V1. - -Rules: -- Do not extend deprecated CSS. -- Do not create new CSS files outside `assets/theme-v2/css`. -- No page-local CSS. -- No tool-local CSS. -- No inline style attributes. -- No `