diff --git a/dev/build/ProjectInstructions/PROJECT_INSTRUCTIONS.md b/dev/build/ProjectInstructions/PROJECT_INSTRUCTIONS.md index 22611dd52..8ca721dc7 100644 --- a/dev/build/ProjectInstructions/PROJECT_INSTRUCTIONS.md +++ b/dev/build/ProjectInstructions/PROJECT_INSTRUCTIONS.md @@ -117,7 +117,7 @@ Rules: ## Current Version/Date -- Project Instructions Version: 2026.06.28.002 +- Project Instructions Version: 2026.06.28.003 - Date: 2026-06-28 - Owner: OWNER @@ -202,6 +202,8 @@ That file owns Start of Day, PLAN_PR, BUILD_PR, APPLY_PR, and invalid command be - Team ownership: `dev/build/ProjectInstructions/team_assignments/team_ownership.md` - Team assignments: `dev/build/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md` - Backlog: `dev/build/ProjectInstructions/backlog/BACKLOG_MASTER.md` +- Team backlog/startup assignment standard: `dev/build/ProjectInstructions/addendums/team_backlog_sod_eod_standard.md` +- Tool Votes/Admin Owner priority signal source: `admin/tool-votes.html` - Database docs: `dev/build/database/` - Runtime/API standards: `dev/build/ProjectInstructions/standards/` - Runtime/API governance: `dev/build/ProjectInstructions/addendums/environment_governance_model.md` diff --git a/dev/build/ProjectInstructions/PROJECT_INSTRUCTIONS_VERSION.md b/dev/build/ProjectInstructions/PROJECT_INSTRUCTIONS_VERSION.md index 1fda3a7a5..56ae2b21e 100644 --- a/dev/build/ProjectInstructions/PROJECT_INSTRUCTIONS_VERSION.md +++ b/dev/build/ProjectInstructions/PROJECT_INSTRUCTIONS_VERSION.md @@ -1,6 +1,6 @@ # Project Instructions Version -Current Project Instructions Version: 2026.06.28.002 +Current Project Instructions Version: 2026.06.28.003 Last Updated: 2026-06-28 @@ -10,6 +10,7 @@ Last Updated: 2026-06-28 - Project Instructions versions are repository-owned and increment independently of PR numbers. - Added dedicated branching policy document. - Startup validation now verifies the branching policy document was loaded instead of duplicating policy text. +- Added backlog startup assignment policy requiring `BACKLOG_MASTER.md` and Tool Votes/Admin Owner priority signal review during team startup. - Codex must read this version file and the latest repository copy of `PROJECT_INSTRUCTIONS.md` before performing work. - Codex must discard previously remembered Project Instructions and treat the repository copy as authoritative. - Codex must validate canonical report and ZIP paths, branching model, and legacy path avoidance before work proceeds. diff --git a/dev/build/ProjectInstructions/TEAM_START_COMMANDS.md b/dev/build/ProjectInstructions/TEAM_START_COMMANDS.md index 90f244e8e..1beb81812 100644 --- a/dev/build/ProjectInstructions/TEAM_START_COMMANDS.md +++ b/dev/build/ProjectInstructions/TEAM_START_COMMANDS.md @@ -23,6 +23,13 @@ Non-Owner team PRs use Stacked PR workstreams by default. A non-Owner team PR ma Use `dev/build/ProjectInstructions/` as the only active Project Instructions source. Read `dev/build/ProjectInstructions/addendums/team_backlog_sod_eod_standard.md` before implementation. +Read `dev/build/ProjectInstructions/backlog/BACKLOG_MASTER.md` during startup. + +`BACKLOG_MASTER.md` is the authoritative source for assigned product work. `admin/tool-votes.html` is the Tool Votes/Admin Owner priority signal source for tool demand and Owner/Admin review; it informs backlog priority but does not replace the backlog. + +Team startup must display the Team Assignment table defined in `dev/build/ProjectInstructions/addendums/team_backlog_sod_eod_standard.md`. + +Codex must not invent work from conversation memory when `BACKLOG_MASTER.md` has a matching product area. Branch Lifecycle (Canonical): - Follow `dev/build/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md` for START / WORK / END lifecycle, branch gates, mandatory hard stops, and EOD main lock. @@ -45,10 +52,12 @@ Ready-to-copy command: OWNER override approved: Start Alfa from the ProjectInstructions release gate. Read dev/build/ProjectInstructions/PROJECT_INSTRUCTIONS.md first. +Read dev/build/ProjectInstructions/addendums/team_backlog_sod_eod_standard.md. Read dev/build/ProjectInstructions/backlog/BACKLOG_MASTER.md. Read dev/build/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md. Pull one [ ] item for Alfa from BACKLOG_MASTER.md. +Report the Team Assignment table before implementation. Stop if Alfa already has an active branch. Stop if Alfa already has an active assignment. Stop if no [ ] Alfa backlog item is available. @@ -67,10 +76,12 @@ Ready-to-copy command: OWNER override approved: Start Bravo from the ProjectInstructions release gate. Read dev/build/ProjectInstructions/PROJECT_INSTRUCTIONS.md first. +Read dev/build/ProjectInstructions/addendums/team_backlog_sod_eod_standard.md. Read dev/build/ProjectInstructions/backlog/BACKLOG_MASTER.md. Read dev/build/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md. Pull one [ ] item for Bravo from BACKLOG_MASTER.md. +Report the Team Assignment table before implementation. Stop if Bravo already has an active branch. Stop if Bravo already has an active assignment. Stop if no [ ] Bravo backlog item is available. @@ -89,10 +100,12 @@ Ready-to-copy command: OWNER override approved: Start Charlie from the ProjectInstructions release gate. Read dev/build/ProjectInstructions/PROJECT_INSTRUCTIONS.md first. +Read dev/build/ProjectInstructions/addendums/team_backlog_sod_eod_standard.md. Read dev/build/ProjectInstructions/backlog/BACKLOG_MASTER.md. Read dev/build/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md. Pull one [ ] item for Charlie from BACKLOG_MASTER.md. +Report the Team Assignment table before implementation. Stop if Charlie already has an active branch. Stop if Charlie already has an active assignment. Stop if no [ ] Charlie backlog item is available. @@ -111,11 +124,13 @@ Ready-to-copy command: OWNER override approved: Start Delta from the ProjectInstructions release gate. Read dev/build/ProjectInstructions/PROJECT_INSTRUCTIONS.md first. +Read dev/build/ProjectInstructions/addendums/team_backlog_sod_eod_standard.md. Read dev/build/ProjectInstructions/backlog/BACKLOG_MASTER.md. Read dev/build/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md. Read dev/build/ProjectInstructions/team_assignments/team_ownership.md. Pull one [ ] item for Delta from BACKLOG_MASTER.md. +Report the Team Assignment table before implementation. Stop if Delta already has an active branch. Stop if Delta already has an active assignment. Stop if no [ ] Delta backlog item is available. @@ -135,10 +150,12 @@ Ready-to-copy command: OWNER override approved: Start Golf from the ProjectInstructions release gate. Read dev/build/ProjectInstructions/PROJECT_INSTRUCTIONS.md first. +Read dev/build/ProjectInstructions/addendums/team_backlog_sod_eod_standard.md. Read dev/build/ProjectInstructions/backlog/BACKLOG_MASTER.md. Read dev/build/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md. Read dev/build/ProjectInstructions/team_assignments/team_ownership.md. +Report the Team Assignment table before implementation. Stop if Golf already has an active branch. Stop if Golf already has an active assignment. Stop if OWNER has not explicitly assigned Golf work. diff --git a/dev/build/ProjectInstructions/addendums/team_backlog_sod_eod_standard.md b/dev/build/ProjectInstructions/addendums/team_backlog_sod_eod_standard.md index 1e6a04a87..f75f69870 100644 --- a/dev/build/ProjectInstructions/addendums/team_backlog_sod_eod_standard.md +++ b/dev/build/ProjectInstructions/addendums/team_backlog_sod_eod_standard.md @@ -26,20 +26,40 @@ Historical snapshots, archived references, and non-team phrases such as `Alfa/Be ## Team Backlog Ownership +Authoritative assigned product work source: + +```text +dev/build/ProjectInstructions/backlog/BACKLOG_MASTER.md +``` + +Tool demand and Owner/Admin priority signal source: + +```text +admin/tool-votes.html +``` + +The Tool Votes/Admin Owner planning surface informs backlog priority, Owner/Admin review, tool demand, and reprioritization. It does not replace `BACKLOG_MASTER.md` as the authoritative assigned-work source. + Every active team owns an active backlog when it has assigned work. Each backlog item must track: - name - description +- product area +- status - current completion percentage +- active PR, when one exists +- next milestone - remaining work - blocking dependencies - owning team +- source or reference Completion percentages are updated: - at SOD +- when work changes status - after every accepted PR - at EOD @@ -47,8 +67,45 @@ The backlog is the authoritative source for determining the next logical PRs. If the backlog and a generated report conflict, the backlog wins unless OWNER explicitly approves a newer governance decision. +Codex must not invent assigned product work from conversation memory when `BACKLOG_MASTER.md` has a matching product area. + +Teams must update backlog status and percent complete when work changes status. + +Owner must update backlog status, completion percentage, and Tool Votes/Admin Owner status when assigning, reprioritizing, completing, or deferring work. + When the Product Owner provides a completed PR ZIP, ChatGPT must review that ZIP, update the active team backlog and completion percentages, and recommend the next logical PRs needed to keep moving toward a Product Owner testable outcome. +## Team Assignment Startup Review + +During startup, each team must: + +1. Read `dev/build/ProjectInstructions/backlog/BACKLOG_MASTER.md`. +2. Locate its assigned team section and assigned product areas. +3. Read the Tool Votes/Admin Owner priority signal source at `admin/tool-votes.html` when the work involves tool demand, tool ordering, or Owner/Admin prioritization. +4. Display assignments as a table grouped by Team, then Product Area. +5. Include Team, Product Area, Status, Percent Complete, Active PR, Next Milestone, and Source / Reference for every assignment row. + +Required startup output: + +```text +Team Assignment +=============== + +Source ............ dev/build/ProjectInstructions/backlog/BACKLOG_MASTER.md +Priority Source ... admin/tool-votes.html +Team .............. +Status ............ PASS + +Assignments +----------- + +| Team | Product Area | Status | Complete | Active PR | Next Milestone | Source | +|------|--------------|--------|----------|-----------|----------------|--------| +| Alfa | Objects Manager | Active | 45% | PR_26179_ALFA_011 | Properties | BACKLOG_MASTER.md | +``` + +If the task is not represented in `BACKLOG_MASTER.md` or the Tool Votes/Admin Owner planning source, Codex must flag the missing representation and ask OWNER whether to add or update the backlog before continuing. + ## Start Of Day Team Briefing When a team is assigned, ChatGPT/Codex must provide this briefing before implementation begins: @@ -65,6 +122,18 @@ When a team is assigned, ChatGPT/Codex must provide this briefing before impleme This briefing is required before implementation begins. +The briefing must include the Team Assignment startup output defined above. + +## Startup Hard Stops + +STOP before implementation when: + +- `dev/build/ProjectInstructions/backlog/BACKLOG_MASTER.md` cannot be found. +- the assigned team cannot be found in the backlog, unless OWNER explicitly provided a one-off task. +- the requested product-area task is not represented in the backlog or Tool Votes/Admin Owner planning source, until OWNER confirms whether to update the backlog. + +If `admin/tool-votes.html` cannot be found, document the missing priority signal source and recommend `admin/tool-votes.html` as the canonical path instead of inventing a replacement. + ## End Of Day Team Summary At EOD, ChatGPT/Codex must provide: diff --git a/dev/build/ProjectInstructions/addendums/team_start_and_release.md b/dev/build/ProjectInstructions/addendums/team_start_and_release.md index 3c660f598..021f2d0be 100644 --- a/dev/build/ProjectInstructions/addendums/team_start_and_release.md +++ b/dev/build/ProjectInstructions/addendums/team_start_and_release.md @@ -19,11 +19,13 @@ Before a team starts, validate: - `main...origin/main` is `0 0` - `HEAD` SHA matches published EOD SHA - active assignment is selected or confirmed by OWNER +- `dev/build/ProjectInstructions/backlog/BACKLOG_MASTER.md` is loaded as the authoritative assigned-work source +- `admin/tool-votes.html` is located as the Tool Votes/Admin Owner priority signal source - assigned team uses the canonical Owner plus military team-name set - work remains with the assigned team until complete or OWNER reassignment - the team's previous PR is Closed, unless OWNER documented an explicit stacked PR chain -Before implementation begins, ChatGPT/Codex must provide the SOD briefing defined in `dev/build/ProjectInstructions/addendums/team_backlog_sod_eod_standard.md`. +Before implementation begins, ChatGPT/Codex must provide the SOD briefing and Team Assignment table defined in `dev/build/ProjectInstructions/addendums/team_backlog_sod_eod_standard.md`. ## Current Four-Team Start Set @@ -63,17 +65,19 @@ Clarification: For backlog-driven work: 1. Read `dev/build/ProjectInstructions/backlog/BACKLOG_MASTER.md`. -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. 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. +2. Locate the assigned team section and product areas. +3. Locate `admin/tool-votes.html` as the Tool Votes/Admin Owner priority signal source when tool demand or Owner/Admin prioritization is relevant. +4. Select only the OWNER-approved backlog item. +5. Use the approved status model from `status_model.md`. +6. Confirm the previous PR for the team is Closed, unless this is an explicitly documented stacked PR chain. +7. Follow the canonical START phase in `project_instructions_single_source_eod_lock.md`. +8. Create or use the approved team branch and PR identity only after START passes. +9. Mark lifecycle state as PR Open. +10. Plan on the same PR branch. +11. Build on the same PR branch. +12. Record active work in the active team registry when required. +13. Open or update a draft PR during active WORK. +14. Merge only through OWNER-approved PR workflow and canonical END. ## Team Command Examples diff --git a/dev/build/ProjectInstructions/backlog/BACKLOG_MASTER.md b/dev/build/ProjectInstructions/backlog/BACKLOG_MASTER.md index a7d317ed2..3c47c2a1b 100644 --- a/dev/build/ProjectInstructions/backlog/BACKLOG_MASTER.md +++ b/dev/build/ProjectInstructions/backlog/BACKLOG_MASTER.md @@ -4,16 +4,29 @@ Canonical backlog tracking owner: `dev/build/ProjectInstructions/addendums/team_backlog_sod_eod_standard.md`. +This file is the authoritative source for assigned product work. + +This document is updated as work status changes, including Owner assignment, reprioritization, completion, deferral, accepted PRs, SOD review, and EOD review. + +`BACKLOG_MASTER.md` is now the canonical team/product-area assignment and status source. Future backlog changes must update this structure directly. + +Each product area must include status and percent complete. + Every active team owns an active backlog when it has assigned work. Backlog entries in this file follow the canonical field list, including: - Name - Description +- Product area +- Status - Current completion percentage +- Active PR, when one exists +- Next milestone - Remaining work - Blocking dependencies - Owning team +- Source or reference Completion percentages are updated at SOD, after every accepted PR, and at EOD. @@ -181,6 +194,29 @@ The backlog is the authoritative source for determining the next logical PRs. - OWNER merge approval and EOD merge governance verified. - Team ownership governance verified through the authoritative ownership map. +- [x] Alfa - Team-aware local dev bootstrap runtime complete + + Notes: + - Completion reference: PR #250 / `PR_26171_ALFA_009-team-aware-bootstrap`. + - `npm run dev:bootstrap` is the primary team-aware local bootstrap command. + - `npm run dev:local-api` remains as the legacy API alias. + - `npm run dev:api` supports API-only startup. + - `npm run dev:web` supports web-only startup. + - `dev/bootstrap/start-dev.mjs` owns bootstrap orchestration. + - `dev/bootstrap/team-port-config.mjs` owns team port resolution. + - Team-aware `--team` runtime support is implemented. + - Bootstrap orchestration, browser launch reporting, and port resolution are implemented. + - Verified command: `npm run dev:bootstrap -- --team bravo`. + - Observed verified output includes: + - `GameFoundry team-aware dev bootstrap` + - `Mode: bootstrap` + - `Team: bravo` + - `Web URL: http://127.0.0.1:5520` + - `API URL: http://127.0.0.1:5521/api` + - `Browser launch: http://127.0.0.1:5520/index.html` + - `Supported teams: owner, alfa, bravo, charlie, delta, echo, foxtrot, golf, hotel` + - Do not assign team-aware dev bootstrap, `dev:bootstrap`, team-port config, browser launch, bootstrap orchestration, or port resolution as remaining backlog work unless OWNER opens a new enhancement request. + - [x] OWNER - Repository hygiene governance complete Notes: @@ -195,11 +231,10 @@ The backlog is the authoritative source for determining the next logical PRs. Status: CANCELLED / NOT DOING Items removed from backlog: -- Multi-port workspace framework - Alfa/Beta/User isolation framework -- Runtime port management initiative Replacement governance: +- Multi-port workspace framework and runtime port management are no longer cancelled/not doing; they are implemented by the team-aware local dev bootstrap runtime item above. - System Health remains one page per deployed environment. - Each deployment actively checks only itself. - Environment Summary, Database Health, Storage Health, Runtime Health, and Health Check History are Charlie System Health ownership. diff --git a/dev/build/ProjectInstructions/bootstrap/codex_start_of_day_bootstrap.md b/dev/build/ProjectInstructions/bootstrap/codex_start_of_day_bootstrap.md index f2eb2787d..c6b440fd5 100644 --- a/dev/build/ProjectInstructions/bootstrap/codex_start_of_day_bootstrap.md +++ b/dev/build/ProjectInstructions/bootstrap/codex_start_of_day_bootstrap.md @@ -29,6 +29,8 @@ The bootstrap loads: - Canonical Repository Structure - Team instructions - Team backlog +- `dev/build/ProjectInstructions/backlog/BACKLOG_MASTER.md` assignment source +- `admin/tool-votes.html` Tool Votes/Admin Owner priority signal source - Current team status - Current branch - Worktree status @@ -148,6 +150,31 @@ Additional Documents Loaded: Next Recommended PR: ``` +Start-of-Day bootstrap must also include the Team Assignment section defined by: + +```text +dev/build/ProjectInstructions/addendums/team_backlog_sod_eod_standard.md +``` + +Required assignment output: + +```text +Team Assignment +=============== + +Source ............ dev/build/ProjectInstructions/backlog/BACKLOG_MASTER.md +Priority Source ... admin/tool-votes.html +Team .............. +Status ............ PASS + +Assignments +----------- + +| Team | Product Area | Status | Complete | Active PR | Next Milestone | Source | +|------|--------------|--------|----------|-----------|----------------|--------| +| Alfa | Objects Manager | Active | 45% | PR_26179_ALFA_011 | Properties | BACKLOG_MASTER.md | +``` + ## Loading Rules Only `PROJECT_INSTRUCTIONS.md` is requested directly. diff --git a/dev/build/ProjectInstructions/standards/CODEX_WORKFLOW_COMMANDS.md b/dev/build/ProjectInstructions/standards/CODEX_WORKFLOW_COMMANDS.md index c2021eef3..728f5e86b 100644 --- a/dev/build/ProjectInstructions/standards/CODEX_WORKFLOW_COMMANDS.md +++ b/dev/build/ProjectInstructions/standards/CODEX_WORKFLOW_COMMANDS.md @@ -61,10 +61,19 @@ Start of Day reports: - current branch - worktree status - latest main status +- backlog assignment source +- Tool Votes/Admin Owner priority signal source +- Team Assignment table grouped by Team, then Product Area - active PR, if any - recommended next action - blockers +The Team Assignment table and backlog hard stops are defined in: + +```text +dev/build/ProjectInstructions/addendums/team_backlog_sod_eod_standard.md +``` + Start of Day may recommend the next execution phase, but it must not execute that phase. Start of Day must satisfy the Codex Completion Contract in `dev/build/ProjectInstructions/addendums/codex_artifact_and_reporting_standard.md`. Because Start of Day is read-only discovery, its ZIP outcome is review-only unless another outcome is explicitly documented. diff --git a/dev/reports/PR_26180_OWNER_003-backlog-startup-assignment-policy_branch-validation.md b/dev/reports/PR_26180_OWNER_003-backlog-startup-assignment-policy_branch-validation.md new file mode 100644 index 000000000..dff7c5ede --- /dev/null +++ b/dev/reports/PR_26180_OWNER_003-backlog-startup-assignment-policy_branch-validation.md @@ -0,0 +1,13 @@ +# PR_26180_OWNER_003 Branch Validation + +| Gate | Result | Evidence | +|---|---|---| +| Project Instructions version loaded | PASS | `2026.06.28.003` | +| Repository Project Instructions source | PASS | Loaded from `dev/build/ProjectInstructions/` | +| Cached memory discarded | PASS | Repository instructions used as authority | +| Branching policy loaded | PASS | `dev/build/ProjectInstructions/PROJECT_BRANCHING_POLICY.md` | +| Batch Governance Mode loaded | PASS | `dev/build/ProjectInstructions/addendums/batch_governance_mode.md` | +| Current branch | PASS | `PR_26180_OWNER_003-backlog-startup-assignment-policy` | +| Owner independent PR model | PASS | Branch created from synchronized `main` | +| Worktree before edits | PASS | Clean before PR edits | +| Scope | PASS | Governance/documentation only | diff --git a/dev/reports/PR_26180_OWNER_003-backlog-startup-assignment-policy_manual-validation-notes.md b/dev/reports/PR_26180_OWNER_003-backlog-startup-assignment-policy_manual-validation-notes.md new file mode 100644 index 000000000..f40b1c3ea --- /dev/null +++ b/dev/reports/PR_26180_OWNER_003-backlog-startup-assignment-policy_manual-validation-notes.md @@ -0,0 +1,14 @@ +# PR_26180_OWNER_003 Manual Validation Notes + +- Confirmed `dev/build/ProjectInstructions/backlog/BACKLOG_MASTER.md` exists and is referenced as the authoritative assigned-work source. +- Confirmed `admin/tool-votes.html` exists and is referenced only as the Tool Votes/Admin Owner priority signal source. +- Confirmed the required Team Assignment startup output section appears in active startup governance. +- Confirmed Project Instructions version is updated to `2026.06.28.003`. +- Confirmed rebase onto current `origin/main`; conflict resolution touched generated report artifacts only. +- Confirmed second rebase onto current `origin/main` after Bravo Messages merged; conflict resolution again touched generated report artifacts only. +- Confirmed `BACKLOG_MASTER.md` now treats team-aware local dev bootstrap runtime as implemented, not remaining work. +- Confirmed correction used OWNER-provided verification for `npm run dev:bootstrap -- --team bravo`. +- Confirmed future-normalization wording was replaced with current-state canonical backlog language. +- Confirmed Tool Votes UI/page files were not modified. +- Confirmed this PR does not implement Tile, Tool Votes, runtime, API, database, or UI behavior. +- Playwright was not run because this is governance/documentation-only and no runtime or UI files changed. diff --git a/dev/reports/PR_26180_OWNER_003-backlog-startup-assignment-policy_report.md b/dev/reports/PR_26180_OWNER_003-backlog-startup-assignment-policy_report.md new file mode 100644 index 000000000..5c5e0100e --- /dev/null +++ b/dev/reports/PR_26180_OWNER_003-backlog-startup-assignment-policy_report.md @@ -0,0 +1,105 @@ +# PR_26180_OWNER_003 Backlog Startup Assignment Policy Report + +## Executive Summary + +PASS: This PR updates Project Instructions so team startup must load `BACKLOG_MASTER.md`, report assigned product work by team/product area, and treat Admin Tool Votes as the priority signal source for tool demand and Owner/Admin review. + +The change is governance/documentation only. No runtime, UI, API, database, or tool implementation files were modified. + +Project Instructions version was bumped to `2026.06.28.003`. + +## Scope Decision + +Updated active Project Instructions and the backlog header only. + +`admin/tool-votes.html` was identified as the current Tool Votes/Admin Owner priority signal source. It was not modified because this PR is governance-only and the user explicitly prohibited UI/tool implementation changes. + +## Source Discovery + +| Source | Path | Status | +|---|---|---| +| Authoritative backlog | `dev/build/ProjectInstructions/backlog/BACKLOG_MASTER.md` | Found | +| Team backlog/SOD/EOD standard | `dev/build/ProjectInstructions/addendums/team_backlog_sod_eod_standard.md` | Updated | +| Start of Day bootstrap architecture | `dev/build/ProjectInstructions/bootstrap/codex_start_of_day_bootstrap.md` | Updated | +| Codex workflow commands | `dev/build/ProjectInstructions/standards/CODEX_WORKFLOW_COMMANDS.md` | Updated | +| Team start commands | `dev/build/ProjectInstructions/TEAM_START_COMMANDS.md` | Updated | +| Tool Votes/Admin Owner priority signal | `admin/tool-votes.html` | Found, not modified | + +## Changes + +- Added `BACKLOG_MASTER.md` as the authoritative assigned product work source in active startup/team governance. +- Added `admin/tool-votes.html` as the Tool Votes/Admin Owner priority signal source. +- Added the required Team Assignment startup output table. +- Added hard-stop behavior for missing backlog, missing assigned team, missing product-area representation, and missing Tool Votes priority source. +- Updated `BACKLOG_MASTER.md` header to state assigned-work ownership, status update expectations, current Team/Product Area status-source ownership, and required product-area status/percent complete. +- Corrected `BACKLOG_MASTER.md` to mark team-aware local dev bootstrap runtime as complete, including `dev:bootstrap`, `team-port-config.mjs`, `--team` support, bootstrap orchestration, browser launch reporting, and port resolution. +- Updated Start of Day command/bootstrap docs to require the Team Assignment section. +- Added top-level `PROJECT_INSTRUCTIONS.md` pointers for the team backlog/startup assignment standard and Tool Votes priority source. + +## Bootstrap Status Correction + +Team-aware dev bootstrap is implemented and must not be assigned as remaining backlog work. + +Owner-provided verification: + +```text +npm run dev:bootstrap -- --team bravo +GameFoundry team-aware dev bootstrap +Mode: bootstrap +Team: bravo +Web URL: http://127.0.0.1:5520 +API URL: http://127.0.0.1:5521/api +Browser launch: http://127.0.0.1:5520/index.html +Supported teams: owner, alfa, bravo, charlie, delta, echo, foxtrot, golf, hotel +Legacy API alias remains: npm run dev:local-api +``` + +Corrected implemented items: + +- `npm run dev:bootstrap` +- `dev/bootstrap/team-port-config.mjs` +- team-aware `--team` runtime support +- bootstrap orchestration +- browser launch reporting +- port resolution +- legacy `npm run dev:local-api` alias + +## Backlog Canonical Structure Correction + +`BACKLOG_MASTER.md` now states: + +```text +BACKLOG_MASTER.md is now the canonical team/product-area assignment and status source. Future backlog changes must update this structure directly. +``` + +This removes wording that implied team/product-area backlog normalization was a future activity. + +## Rebase Notes + +- Rebased onto current `origin/main` after Owner 035 merged. +- Rebased again onto current `origin/main` after Bravo Messages merged. +- Merge conflicts were limited to generated report artifacts: `dev/reports/codex_changed_files.txt` and `dev/reports/codex_review.diff`. +- Owner 035 runtime/API/auth files and Bravo Messages runtime/UI/API files from `main` were preserved unchanged. +- Owner 003 remains governance/documentation-only. + +## Owner Recommendation + +Use `dev/build/ProjectInstructions/backlog/BACKLOG_MASTER.md` as the required assigned-work source during startup and use `admin/tool-votes.html` as the priority signal source for tool demand. When either source is missing or does not represent the requested work, Codex must stop and ask OWNER whether to update the backlog before proceeding. + +## Validation + +| Check | Result | +|---|---| +| Branch validation | PASS | +| `git diff --check` | PASS | +| `npm run validate:canonical-structure` | PASS | +| Runtime/UI/API/DB implementation files changed | PASS - none changed | +| Bootstrap/runtime implementation recreated | PASS - not recreated; backlog status only | + +## Artifact + +Repo-structured outcome ZIP: + +```text +dev/workspace/zips/PR_26180_OWNER_003-backlog-startup-assignment-policy_delta.zip +``` diff --git a/dev/reports/PR_26180_OWNER_003-backlog-startup-assignment-policy_requirement-checklist.md b/dev/reports/PR_26180_OWNER_003-backlog-startup-assignment-policy_requirement-checklist.md new file mode 100644 index 000000000..276735921 --- /dev/null +++ b/dev/reports/PR_26180_OWNER_003-backlog-startup-assignment-policy_requirement-checklist.md @@ -0,0 +1,29 @@ +# PR_26180_OWNER_003 Requirement Checklist + +| Requirement | Result | Notes | +|---|---|---| +| Locate authoritative backlog | PASS | `dev/build/ProjectInstructions/backlog/BACKLOG_MASTER.md` exists and was updated. | +| Locate Tool Votes/Admin Owner planning source | PASS | `admin/tool-votes.html` identified as the active priority signal surface. | +| State backlog is authoritative assigned-work source | PASS | Added to backlog/startup governance. | +| State Tool Votes/Admin Owner is priority signal source | PASS | Added with path `admin/tool-votes.html`. | +| Teams must read backlog during startup | PASS | Added to team backlog standard and team start commands. | +| Teams must locate assigned team/product areas | PASS | Added to Team Assignment Startup Review. | +| Startup table grouped by Team/Product Area | PASS | Required output table added. | +| Assignment rows include all requested fields | PASS | Team, Product Area, Status, Complete, Active PR, Next Milestone, Source included. | +| Teams update backlog status/percent complete on status change | PASS | Added to team backlog standard. | +| Owner updates backlog and Tool Votes/Admin Owner status | PASS | Added to team backlog standard. | +| Codex must not invent work from conversation memory | PASS | Added hard rule. | +| Add required startup output section | PASS | Added to team backlog standard and bootstrap. | +| Add missing backlog hard stop | PASS | Added. | +| Add missing assigned team hard stop | PASS | Added with Owner one-off exception. | +| Add missing task representation hard stop | PASS | Added. | +| Add missing Tool Votes source behavior | PASS | Added recommendation behavior. | +| Update BACKLOG_MASTER header if needed | PASS | Updated. | +| Update Tool Votes page header if needed | PASS | Not needed; UI/tool page left untouched due governance-only scope. | +| Preserve startup validation, branching policy, ZIP/report contract, canonical paths, Batch Governance Mode, and no legacy paths | PASS | No conflicting edits made. | +| Bump Project Instructions version | PASS | `PROJECT_INSTRUCTIONS_VERSION.md` and `PROJECT_INSTRUCTIONS.md` now use `2026.06.28.003`. | +| Mark bootstrap/team-aware dev runtime as implemented | PASS | `BACKLOG_MASTER.md` now records team-aware local dev bootstrap as complete. | +| Do not recreate bootstrap work | PASS | No runtime/bootstrap source files were modified. | +| Do not assign bootstrap as remaining work | PASS | Backlog notes explicitly prohibit assigning `dev:bootstrap`, team-port config, browser launch, bootstrap orchestration, or port resolution as remaining backlog work unless OWNER opens a new enhancement. | +| Remove future-normalization wording | PASS | `BACKLOG_MASTER.md` now uses current-state canonical team/product-area assignment and status language. | +| No runtime/UI/API/database/tool implementation changes | PASS | Only Project Instructions and reports changed. | diff --git a/dev/reports/PR_26180_OWNER_003-backlog-startup-assignment-policy_validation-report.md b/dev/reports/PR_26180_OWNER_003-backlog-startup-assignment-policy_validation-report.md new file mode 100644 index 000000000..2ff76a6c2 --- /dev/null +++ b/dev/reports/PR_26180_OWNER_003-backlog-startup-assignment-policy_validation-report.md @@ -0,0 +1,39 @@ +# PR_26180_OWNER_003 Validation Report + +## Validation Commands + +| Command | Result | +|---|---| +| `git diff --check` | PASS | +| `npm run validate:canonical-structure` | PASS | + +## Canonical Structure Output + +```text +Canonical repository structure guardrail: PASS +Blocking violations: 0 +Approved legacy exceptions: 500 +``` + +## Scope Validation + +Changed files are limited to: + +- `dev/build/ProjectInstructions/PROJECT_INSTRUCTIONS.md` +- `dev/build/ProjectInstructions/PROJECT_INSTRUCTIONS_VERSION.md` +- `dev/build/ProjectInstructions/TEAM_START_COMMANDS.md` +- `dev/build/ProjectInstructions/addendums/team_backlog_sod_eod_standard.md` +- `dev/build/ProjectInstructions/addendums/team_start_and_release.md` +- `dev/build/ProjectInstructions/backlog/BACKLOG_MASTER.md` +- `dev/build/ProjectInstructions/bootstrap/codex_start_of_day_bootstrap.md` +- `dev/build/ProjectInstructions/standards/CODEX_WORKFLOW_COMMANDS.md` +- `dev/reports/*` + +No runtime, UI, API, database, or tool implementation files were changed. + +## Bootstrap Status Correction Validation + +- `BACKLOG_MASTER.md` marks team-aware local dev bootstrap runtime as complete. +- `dev:bootstrap`, `team-port-config.mjs`, `--team` runtime support, bootstrap orchestration, browser launch reporting, and port resolution are not listed as remaining backlog work. +- `BACKLOG_MASTER.md` no longer implies team/product-area backlog normalization is a future activity. +- No `dev/bootstrap/`, `package.json`, runtime, UI, API, or database files were modified by this correction. diff --git a/dev/reports/codex_changed_files.txt b/dev/reports/codex_changed_files.txt index bc37b31a4..1d5194e5c 100644 --- a/dev/reports/codex_changed_files.txt +++ b/dev/reports/codex_changed_files.txt @@ -1,10 +1,37 @@ -dev/build/database/ddl/messages.sql -dev/reports/PR_26180_BRAVO_002-complete-messages-creator-tool.md -dev/reports/codex_changed_files.txt -dev/reports/codex_review.diff -dev/tests/dev-runtime/MessagesPublishValidation.test.mjs -dev/tests/helpers/playwrightRepoServer.mjs -dev/tests/playwright/tools/MessagesTool.spec.mjs -src/dev-runtime/messages/messages-postgres-service.mjs -toolbox/messages/index.html -toolbox/messages/messages.js +# git diff --name-status merge-base(origin/main, HEAD)..working-tree +M dev/build/ProjectInstructions/PROJECT_INSTRUCTIONS.md +M dev/build/ProjectInstructions/PROJECT_INSTRUCTIONS_VERSION.md +M dev/build/ProjectInstructions/TEAM_START_COMMANDS.md +M dev/build/ProjectInstructions/addendums/team_backlog_sod_eod_standard.md +M dev/build/ProjectInstructions/addendums/team_start_and_release.md +M dev/build/ProjectInstructions/backlog/BACKLOG_MASTER.md +M dev/build/ProjectInstructions/bootstrap/codex_start_of_day_bootstrap.md +M dev/build/ProjectInstructions/standards/CODEX_WORKFLOW_COMMANDS.md +A dev/reports/PR_26180_OWNER_003-backlog-startup-assignment-policy_branch-validation.md +A dev/reports/PR_26180_OWNER_003-backlog-startup-assignment-policy_manual-validation-notes.md +A dev/reports/PR_26180_OWNER_003-backlog-startup-assignment-policy_report.md +A dev/reports/PR_26180_OWNER_003-backlog-startup-assignment-policy_requirement-checklist.md +A dev/reports/PR_26180_OWNER_003-backlog-startup-assignment-policy_validation-report.md +M dev/reports/codex_changed_files.txt +M dev/reports/codex_review.diff + +# git diff --stat merge-base(origin/main, HEAD)..working-tree +.../ProjectInstructions/PROJECT_INSTRUCTIONS.md | 4 +- + .../PROJECT_INSTRUCTIONS_VERSION.md | 3 +- + .../ProjectInstructions/TEAM_START_COMMANDS.md | 17 + + .../addendums/team_backlog_sod_eod_standard.md | 69 + + .../addendums/team_start_and_release.md | 28 +- + .../ProjectInstructions/backlog/BACKLOG_MASTER.md | 39 +- + .../bootstrap/codex_start_of_day_bootstrap.md | 27 + + .../standards/CODEX_WORKFLOW_COMMANDS.md | 9 + + ...-startup-assignment-policy_branch-validation.md | 13 + + ...up-assignment-policy_manual-validation-notes.md | 14 + + ...003-backlog-startup-assignment-policy_report.md | 105 ++ + ...rtup-assignment-policy_requirement-checklist.md | 29 + + ...-startup-assignment-policy_validation-report.md | 39 + + dev/reports/codex_changed_files.txt | 47 +- + dev/reports/codex_review.diff | 1555 +++++++++----------- + 15 files changed, 1105 insertions(+), 893 deletions(-) + +# merge-base +8c332fc82aeeed6508170363f04e04beaf67db28 diff --git a/dev/reports/codex_review.diff b/dev/reports/codex_review.diff index e19f5ecc6..aca321fc3 100644 --- a/dev/reports/codex_review.diff +++ b/dev/reports/codex_review.diff @@ -1,893 +1,714 @@ -diff --git a/dev/build/database/ddl/messages.sql b/dev/build/database/ddl/messages.sql -index ca7127905..2999e73fe 100644 ---- a/dev/build/database/ddl/messages.sql -+++ b/dev/build/database/ddl/messages.sql -@@ -72,6 +72,9 @@ CREATE TABLE IF NOT EXISTS messages_records ( - "emotionProfileKey" text NOT NULL REFERENCES messages_emotion_profiles(key), - "voiceProfileKey" text NOT NULL REFERENCES messages_tts_profiles(key), - "messageText" text NOT NULL, -+ "speaker" text NOT NULL DEFAULT '', -+ "trigger" text NOT NULL DEFAULT '', -+ "typewriterSpeed" numeric NOT NULL DEFAULT 30, - "notes" text NOT NULL DEFAULT '', - "active" boolean NOT NULL DEFAULT true, - "createdAt" timestamptz NOT NULL DEFAULT now(), -@@ -106,6 +109,10 @@ CREATE TABLE IF NOT EXISTS messages_event_actions ( - "updatedBy" text NOT NULL REFERENCES users(key) - ); - -+ALTER TABLE messages_records ADD COLUMN IF NOT EXISTS "speaker" text NOT NULL DEFAULT ''; -+ALTER TABLE messages_records ADD COLUMN IF NOT EXISTS "trigger" text NOT NULL DEFAULT ''; -+ALTER TABLE messages_records ADD COLUMN IF NOT EXISTS "typewriterSpeed" numeric NOT NULL DEFAULT 30; -+ - CREATE INDEX IF NOT EXISTS idx_messages_records_categorykey ON messages_records ("categoryKey"); - CREATE INDEX IF NOT EXISTS idx_messages_records_emotionprofilekey ON messages_records ("emotionProfileKey"); - CREATE INDEX IF NOT EXISTS idx_messages_records_voiceprofilekey ON messages_records ("voiceProfileKey"); -diff --git a/dev/reports/PR_26180_BRAVO_002-complete-messages-creator-tool.md b/dev/reports/PR_26180_BRAVO_002-complete-messages-creator-tool.md +diff --git a/dev/build/ProjectInstructions/PROJECT_INSTRUCTIONS.md b/dev/build/ProjectInstructions/PROJECT_INSTRUCTIONS.md +index 22611dd52..8ca721dc7 100644 +--- a/dev/build/ProjectInstructions/PROJECT_INSTRUCTIONS.md ++++ b/dev/build/ProjectInstructions/PROJECT_INSTRUCTIONS.md +@@ -117,7 +117,7 @@ Rules: + + ## Current Version/Date + +-- Project Instructions Version: 2026.06.28.002 ++- Project Instructions Version: 2026.06.28.003 + - Date: 2026-06-28 + - Owner: OWNER + +@@ -202,6 +202,8 @@ That file owns Start of Day, PLAN_PR, BUILD_PR, APPLY_PR, and invalid command be + - Team ownership: `dev/build/ProjectInstructions/team_assignments/team_ownership.md` + - Team assignments: `dev/build/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md` + - Backlog: `dev/build/ProjectInstructions/backlog/BACKLOG_MASTER.md` ++- Team backlog/startup assignment standard: `dev/build/ProjectInstructions/addendums/team_backlog_sod_eod_standard.md` ++- Tool Votes/Admin Owner priority signal source: `admin/tool-votes.html` + - Database docs: `dev/build/database/` + - Runtime/API standards: `dev/build/ProjectInstructions/standards/` + - Runtime/API governance: `dev/build/ProjectInstructions/addendums/environment_governance_model.md` +diff --git a/dev/build/ProjectInstructions/PROJECT_INSTRUCTIONS_VERSION.md b/dev/build/ProjectInstructions/PROJECT_INSTRUCTIONS_VERSION.md +index 1fda3a7a5..56ae2b21e 100644 +--- a/dev/build/ProjectInstructions/PROJECT_INSTRUCTIONS_VERSION.md ++++ b/dev/build/ProjectInstructions/PROJECT_INSTRUCTIONS_VERSION.md +@@ -1,6 +1,6 @@ + # Project Instructions Version + +-Current Project Instructions Version: 2026.06.28.002 ++Current Project Instructions Version: 2026.06.28.003 + + Last Updated: 2026-06-28 + +@@ -10,6 +10,7 @@ Last Updated: 2026-06-28 + - Project Instructions versions are repository-owned and increment independently of PR numbers. + - Added dedicated branching policy document. + - Startup validation now verifies the branching policy document was loaded instead of duplicating policy text. ++- Added backlog startup assignment policy requiring `BACKLOG_MASTER.md` and Tool Votes/Admin Owner priority signal review during team startup. + - Codex must read this version file and the latest repository copy of `PROJECT_INSTRUCTIONS.md` before performing work. + - Codex must discard previously remembered Project Instructions and treat the repository copy as authoritative. + - Codex must validate canonical report and ZIP paths, branching model, and legacy path avoidance before work proceeds. +diff --git a/dev/build/ProjectInstructions/TEAM_START_COMMANDS.md b/dev/build/ProjectInstructions/TEAM_START_COMMANDS.md +index 90f244e8e..1beb81812 100644 +--- a/dev/build/ProjectInstructions/TEAM_START_COMMANDS.md ++++ b/dev/build/ProjectInstructions/TEAM_START_COMMANDS.md +@@ -23,6 +23,13 @@ Non-Owner team PRs use Stacked PR workstreams by default. A non-Owner team PR ma + + Use `dev/build/ProjectInstructions/` as the only active Project Instructions source. + Read `dev/build/ProjectInstructions/addendums/team_backlog_sod_eod_standard.md` before implementation. ++Read `dev/build/ProjectInstructions/backlog/BACKLOG_MASTER.md` during startup. ++ ++`BACKLOG_MASTER.md` is the authoritative source for assigned product work. `admin/tool-votes.html` is the Tool Votes/Admin Owner priority signal source for tool demand and Owner/Admin review; it informs backlog priority but does not replace the backlog. ++ ++Team startup must display the Team Assignment table defined in `dev/build/ProjectInstructions/addendums/team_backlog_sod_eod_standard.md`. ++ ++Codex must not invent work from conversation memory when `BACKLOG_MASTER.md` has a matching product area. + + Branch Lifecycle (Canonical): + - Follow `dev/build/ProjectInstructions/addendums/project_instructions_single_source_eod_lock.md` for START / WORK / END lifecycle, branch gates, mandatory hard stops, and EOD main lock. +@@ -45,10 +52,12 @@ Ready-to-copy command: + OWNER override approved: Start Alfa from the ProjectInstructions release gate. + + Read dev/build/ProjectInstructions/PROJECT_INSTRUCTIONS.md first. ++Read dev/build/ProjectInstructions/addendums/team_backlog_sod_eod_standard.md. + Read dev/build/ProjectInstructions/backlog/BACKLOG_MASTER.md. + Read dev/build/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md. + + Pull one [ ] item for Alfa from BACKLOG_MASTER.md. ++Report the Team Assignment table before implementation. + Stop if Alfa already has an active branch. + Stop if Alfa already has an active assignment. + Stop if no [ ] Alfa backlog item is available. +@@ -67,10 +76,12 @@ Ready-to-copy command: + OWNER override approved: Start Bravo from the ProjectInstructions release gate. + + Read dev/build/ProjectInstructions/PROJECT_INSTRUCTIONS.md first. ++Read dev/build/ProjectInstructions/addendums/team_backlog_sod_eod_standard.md. + Read dev/build/ProjectInstructions/backlog/BACKLOG_MASTER.md. + Read dev/build/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md. + + Pull one [ ] item for Bravo from BACKLOG_MASTER.md. ++Report the Team Assignment table before implementation. + Stop if Bravo already has an active branch. + Stop if Bravo already has an active assignment. + Stop if no [ ] Bravo backlog item is available. +@@ -89,10 +100,12 @@ Ready-to-copy command: + OWNER override approved: Start Charlie from the ProjectInstructions release gate. + + Read dev/build/ProjectInstructions/PROJECT_INSTRUCTIONS.md first. ++Read dev/build/ProjectInstructions/addendums/team_backlog_sod_eod_standard.md. + Read dev/build/ProjectInstructions/backlog/BACKLOG_MASTER.md. + Read dev/build/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md. + + Pull one [ ] item for Charlie from BACKLOG_MASTER.md. ++Report the Team Assignment table before implementation. + Stop if Charlie already has an active branch. + Stop if Charlie already has an active assignment. + Stop if no [ ] Charlie backlog item is available. +@@ -111,11 +124,13 @@ Ready-to-copy command: + OWNER override approved: Start Delta from the ProjectInstructions release gate. + + Read dev/build/ProjectInstructions/PROJECT_INSTRUCTIONS.md first. ++Read dev/build/ProjectInstructions/addendums/team_backlog_sod_eod_standard.md. + Read dev/build/ProjectInstructions/backlog/BACKLOG_MASTER.md. + Read dev/build/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md. + Read dev/build/ProjectInstructions/team_assignments/team_ownership.md. + + Pull one [ ] item for Delta from BACKLOG_MASTER.md. ++Report the Team Assignment table before implementation. + Stop if Delta already has an active branch. + Stop if Delta already has an active assignment. + Stop if no [ ] Delta backlog item is available. +@@ -135,10 +150,12 @@ Ready-to-copy command: + OWNER override approved: Start Golf from the ProjectInstructions release gate. + + Read dev/build/ProjectInstructions/PROJECT_INSTRUCTIONS.md first. ++Read dev/build/ProjectInstructions/addendums/team_backlog_sod_eod_standard.md. + Read dev/build/ProjectInstructions/backlog/BACKLOG_MASTER.md. + Read dev/build/ProjectInstructions/team_assignments/TEAM_ASSIGNMENTS.md. + Read dev/build/ProjectInstructions/team_assignments/team_ownership.md. + ++Report the Team Assignment table before implementation. + Stop if Golf already has an active branch. + Stop if Golf already has an active assignment. + Stop if OWNER has not explicitly assigned Golf work. +diff --git a/dev/build/ProjectInstructions/addendums/team_backlog_sod_eod_standard.md b/dev/build/ProjectInstructions/addendums/team_backlog_sod_eod_standard.md +index 1e6a04a87..f75f69870 100644 +--- a/dev/build/ProjectInstructions/addendums/team_backlog_sod_eod_standard.md ++++ b/dev/build/ProjectInstructions/addendums/team_backlog_sod_eod_standard.md +@@ -26,20 +26,40 @@ Historical snapshots, archived references, and non-team phrases such as `Alfa/Be + + ## Team Backlog Ownership + ++Authoritative assigned product work source: ++ ++```text ++dev/build/ProjectInstructions/backlog/BACKLOG_MASTER.md ++``` ++ ++Tool demand and Owner/Admin priority signal source: ++ ++```text ++admin/tool-votes.html ++``` ++ ++The Tool Votes/Admin Owner planning surface informs backlog priority, Owner/Admin review, tool demand, and reprioritization. It does not replace `BACKLOG_MASTER.md` as the authoritative assigned-work source. ++ + Every active team owns an active backlog when it has assigned work. + + Each backlog item must track: + + - name + - description ++- product area ++- status + - current completion percentage ++- active PR, when one exists ++- next milestone + - remaining work + - blocking dependencies + - owning team ++- source or reference + + Completion percentages are updated: + + - at SOD ++- when work changes status + - after every accepted PR + - at EOD + +@@ -47,8 +67,45 @@ The backlog is the authoritative source for determining the next logical PRs. + + If the backlog and a generated report conflict, the backlog wins unless OWNER explicitly approves a newer governance decision. + ++Codex must not invent assigned product work from conversation memory when `BACKLOG_MASTER.md` has a matching product area. ++ ++Teams must update backlog status and percent complete when work changes status. ++ ++Owner must update backlog status, completion percentage, and Tool Votes/Admin Owner status when assigning, reprioritizing, completing, or deferring work. ++ + When the Product Owner provides a completed PR ZIP, ChatGPT must review that ZIP, update the active team backlog and completion percentages, and recommend the next logical PRs needed to keep moving toward a Product Owner testable outcome. + ++## Team Assignment Startup Review ++ ++During startup, each team must: ++ ++1. Read `dev/build/ProjectInstructions/backlog/BACKLOG_MASTER.md`. ++2. Locate its assigned team section and assigned product areas. ++3. Read the Tool Votes/Admin Owner priority signal source at `admin/tool-votes.html` when the work involves tool demand, tool ordering, or Owner/Admin prioritization. ++4. Display assignments as a table grouped by Team, then Product Area. ++5. Include Team, Product Area, Status, Percent Complete, Active PR, Next Milestone, and Source / Reference for every assignment row. ++ ++Required startup output: ++ ++```text ++Team Assignment ++=============== ++ ++Source ............ dev/build/ProjectInstructions/backlog/BACKLOG_MASTER.md ++Priority Source ... admin/tool-votes.html ++Team .............. ++Status ............ PASS ++ ++Assignments ++----------- ++ ++| Team | Product Area | Status | Complete | Active PR | Next Milestone | Source | ++|------|--------------|--------|----------|-----------|----------------|--------| ++| Alfa | Objects Manager | Active | 45% | PR_26179_ALFA_011 | Properties | BACKLOG_MASTER.md | ++``` ++ ++If the task is not represented in `BACKLOG_MASTER.md` or the Tool Votes/Admin Owner planning source, Codex must flag the missing representation and ask OWNER whether to add or update the backlog before continuing. ++ + ## Start Of Day Team Briefing + + When a team is assigned, ChatGPT/Codex must provide this briefing before implementation begins: +@@ -65,6 +122,18 @@ When a team is assigned, ChatGPT/Codex must provide this briefing before impleme + + This briefing is required before implementation begins. + ++The briefing must include the Team Assignment startup output defined above. ++ ++## Startup Hard Stops ++ ++STOP before implementation when: ++ ++- `dev/build/ProjectInstructions/backlog/BACKLOG_MASTER.md` cannot be found. ++- the assigned team cannot be found in the backlog, unless OWNER explicitly provided a one-off task. ++- the requested product-area task is not represented in the backlog or Tool Votes/Admin Owner planning source, until OWNER confirms whether to update the backlog. ++ ++If `admin/tool-votes.html` cannot be found, document the missing priority signal source and recommend `admin/tool-votes.html` as the canonical path instead of inventing a replacement. ++ + ## End Of Day Team Summary + + At EOD, ChatGPT/Codex must provide: +diff --git a/dev/build/ProjectInstructions/addendums/team_start_and_release.md b/dev/build/ProjectInstructions/addendums/team_start_and_release.md +index 3c660f598..021f2d0be 100644 +--- a/dev/build/ProjectInstructions/addendums/team_start_and_release.md ++++ b/dev/build/ProjectInstructions/addendums/team_start_and_release.md +@@ -19,11 +19,13 @@ Before a team starts, validate: + - `main...origin/main` is `0 0` + - `HEAD` SHA matches published EOD SHA + - active assignment is selected or confirmed by OWNER ++- `dev/build/ProjectInstructions/backlog/BACKLOG_MASTER.md` is loaded as the authoritative assigned-work source ++- `admin/tool-votes.html` is located as the Tool Votes/Admin Owner priority signal source + - assigned team uses the canonical Owner plus military team-name set + - work remains with the assigned team until complete or OWNER reassignment + - the team's previous PR is Closed, unless OWNER documented an explicit stacked PR chain + +-Before implementation begins, ChatGPT/Codex must provide the SOD briefing defined in `dev/build/ProjectInstructions/addendums/team_backlog_sod_eod_standard.md`. ++Before implementation begins, ChatGPT/Codex must provide the SOD briefing and Team Assignment table defined in `dev/build/ProjectInstructions/addendums/team_backlog_sod_eod_standard.md`. + + ## Current Four-Team Start Set + +@@ -63,17 +65,19 @@ Clarification: + For backlog-driven work: + + 1. Read `dev/build/ProjectInstructions/backlog/BACKLOG_MASTER.md`. +-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. 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. ++2. Locate the assigned team section and product areas. ++3. Locate `admin/tool-votes.html` as the Tool Votes/Admin Owner priority signal source when tool demand or Owner/Admin prioritization is relevant. ++4. Select only the OWNER-approved backlog item. ++5. Use the approved status model from `status_model.md`. ++6. Confirm the previous PR for the team is Closed, unless this is an explicitly documented stacked PR chain. ++7. Follow the canonical START phase in `project_instructions_single_source_eod_lock.md`. ++8. Create or use the approved team branch and PR identity only after START passes. ++9. Mark lifecycle state as PR Open. ++10. Plan on the same PR branch. ++11. Build on the same PR branch. ++12. Record active work in the active team registry when required. ++13. Open or update a draft PR during active WORK. ++14. Merge only through OWNER-approved PR workflow and canonical END. + + ## Team Command Examples + +diff --git a/dev/build/ProjectInstructions/backlog/BACKLOG_MASTER.md b/dev/build/ProjectInstructions/backlog/BACKLOG_MASTER.md +index a7d317ed2..3c47c2a1b 100644 +--- a/dev/build/ProjectInstructions/backlog/BACKLOG_MASTER.md ++++ b/dev/build/ProjectInstructions/backlog/BACKLOG_MASTER.md +@@ -4,16 +4,29 @@ + + Canonical backlog tracking owner: `dev/build/ProjectInstructions/addendums/team_backlog_sod_eod_standard.md`. + ++This file is the authoritative source for assigned product work. ++ ++This document is updated as work status changes, including Owner assignment, reprioritization, completion, deferral, accepted PRs, SOD review, and EOD review. ++ ++`BACKLOG_MASTER.md` is now the canonical team/product-area assignment and status source. Future backlog changes must update this structure directly. ++ ++Each product area must include status and percent complete. ++ + Every active team owns an active backlog when it has assigned work. + + Backlog entries in this file follow the canonical field list, including: + + - Name + - Description ++- Product area ++- Status + - Current completion percentage ++- Active PR, when one exists ++- Next milestone + - Remaining work + - Blocking dependencies + - Owning team ++- Source or reference + + Completion percentages are updated at SOD, after every accepted PR, and at EOD. + +@@ -181,6 +194,29 @@ The backlog is the authoritative source for determining the next logical PRs. + - OWNER merge approval and EOD merge governance verified. + - Team ownership governance verified through the authoritative ownership map. + ++- [x] Alfa - Team-aware local dev bootstrap runtime complete ++ ++ Notes: ++ - Completion reference: PR #250 / `PR_26171_ALFA_009-team-aware-bootstrap`. ++ - `npm run dev:bootstrap` is the primary team-aware local bootstrap command. ++ - `npm run dev:local-api` remains as the legacy API alias. ++ - `npm run dev:api` supports API-only startup. ++ - `npm run dev:web` supports web-only startup. ++ - `dev/bootstrap/start-dev.mjs` owns bootstrap orchestration. ++ - `dev/bootstrap/team-port-config.mjs` owns team port resolution. ++ - Team-aware `--team` runtime support is implemented. ++ - Bootstrap orchestration, browser launch reporting, and port resolution are implemented. ++ - Verified command: `npm run dev:bootstrap -- --team bravo`. ++ - Observed verified output includes: ++ - `GameFoundry team-aware dev bootstrap` ++ - `Mode: bootstrap` ++ - `Team: bravo` ++ - `Web URL: http://127.0.0.1:5520` ++ - `API URL: http://127.0.0.1:5521/api` ++ - `Browser launch: http://127.0.0.1:5520/index.html` ++ - `Supported teams: owner, alfa, bravo, charlie, delta, echo, foxtrot, golf, hotel` ++ - Do not assign team-aware dev bootstrap, `dev:bootstrap`, team-port config, browser launch, bootstrap orchestration, or port resolution as remaining backlog work unless OWNER opens a new enhancement request. ++ + - [x] OWNER - Repository hygiene governance complete + + Notes: +@@ -195,11 +231,10 @@ The backlog is the authoritative source for determining the next logical PRs. + Status: CANCELLED / NOT DOING + + Items removed from backlog: +-- Multi-port workspace framework + - Alfa/Beta/User isolation framework +-- Runtime port management initiative + + Replacement governance: ++- Multi-port workspace framework and runtime port management are no longer cancelled/not doing; they are implemented by the team-aware local dev bootstrap runtime item above. + - System Health remains one page per deployed environment. + - Each deployment actively checks only itself. + - Environment Summary, Database Health, Storage Health, Runtime Health, and Health Check History are Charlie System Health ownership. +diff --git a/dev/build/ProjectInstructions/bootstrap/codex_start_of_day_bootstrap.md b/dev/build/ProjectInstructions/bootstrap/codex_start_of_day_bootstrap.md +index f2eb2787d..c6b440fd5 100644 +--- a/dev/build/ProjectInstructions/bootstrap/codex_start_of_day_bootstrap.md ++++ b/dev/build/ProjectInstructions/bootstrap/codex_start_of_day_bootstrap.md +@@ -29,6 +29,8 @@ The bootstrap loads: + - Canonical Repository Structure + - Team instructions + - Team backlog ++- `dev/build/ProjectInstructions/backlog/BACKLOG_MASTER.md` assignment source ++- `admin/tool-votes.html` Tool Votes/Admin Owner priority signal source + - Current team status + - Current branch + - Worktree status +@@ -148,6 +150,31 @@ Additional Documents Loaded: + Next Recommended PR: + ``` + ++Start-of-Day bootstrap must also include the Team Assignment section defined by: ++ ++```text ++dev/build/ProjectInstructions/addendums/team_backlog_sod_eod_standard.md ++``` ++ ++Required assignment output: ++ ++```text ++Team Assignment ++=============== ++ ++Source ............ dev/build/ProjectInstructions/backlog/BACKLOG_MASTER.md ++Priority Source ... admin/tool-votes.html ++Team .............. ++Status ............ PASS ++ ++Assignments ++----------- ++ ++| Team | Product Area | Status | Complete | Active PR | Next Milestone | Source | ++|------|--------------|--------|----------|-----------|----------------|--------| ++| Alfa | Objects Manager | Active | 45% | PR_26179_ALFA_011 | Properties | BACKLOG_MASTER.md | ++``` ++ + ## Loading Rules + + Only `PROJECT_INSTRUCTIONS.md` is requested directly. +diff --git a/dev/build/ProjectInstructions/standards/CODEX_WORKFLOW_COMMANDS.md b/dev/build/ProjectInstructions/standards/CODEX_WORKFLOW_COMMANDS.md +index c2021eef3..728f5e86b 100644 +--- a/dev/build/ProjectInstructions/standards/CODEX_WORKFLOW_COMMANDS.md ++++ b/dev/build/ProjectInstructions/standards/CODEX_WORKFLOW_COMMANDS.md +@@ -61,10 +61,19 @@ Start of Day reports: + - current branch + - worktree status + - latest main status ++- backlog assignment source ++- Tool Votes/Admin Owner priority signal source ++- Team Assignment table grouped by Team, then Product Area + - active PR, if any + - recommended next action + - blockers + ++The Team Assignment table and backlog hard stops are defined in: ++ ++```text ++dev/build/ProjectInstructions/addendums/team_backlog_sod_eod_standard.md ++``` ++ + Start of Day may recommend the next execution phase, but it must not execute that phase. + + Start of Day must satisfy the Codex Completion Contract in `dev/build/ProjectInstructions/addendums/codex_artifact_and_reporting_standard.md`. Because Start of Day is read-only discovery, its ZIP outcome is review-only unless another outcome is explicitly documented. +diff --git a/dev/reports/PR_26180_OWNER_003-backlog-startup-assignment-policy_branch-validation.md b/dev/reports/PR_26180_OWNER_003-backlog-startup-assignment-policy_branch-validation.md new file mode 100644 -index 000000000..5e6ec07bb +index 000000000..dff7c5ede --- /dev/null -+++ b/dev/reports/PR_26180_BRAVO_002-complete-messages-creator-tool.md -@@ -0,0 +1,129 @@ -+# PR_26180_BRAVO_002-complete-messages-creator-tool -+ -+## Branch Validation -+ -+PASS - Current branch is `PR_26180_BRAVO_002-complete-messages-creator-tool`. -+PASS - Scoped PR_002 Messages Creator Tool changes were preserved. -+PASS - Artifact paths use `dev/reports` and `dev/workspace/zips`. -+PASS - `dev/build/database/seed/guest/game-crew.json` was not modified. -+PASS - `dev/tests/dev-runtime/DbSeedIntegrity.test.mjs` was not modified for Game Crew. -+PASS - PR_003+ Game Crew cleanup was not started from this dirty branch. -+PASS - Branch was refreshed with current `origin/main` to restore PR mergeability. -+ -+## Product Owner Testable Outcome -+ -+After applying this PR, the Product Owner can test the API-backed Message Studio MVP workflow: -+ -+- Create, edit, save, archive, and delete Messages. -+- Use creator-facing `Speaker`, `Text`, `Trigger`, `Typewriter Speed`, and `TTS Profile` fields. -+- Preview Message and sentence playback through existing Text To Speech behavior. -+- Add sentences with emotions scoped by the selected TTS Profile. -+- Confirm guest browsing is allowed while guest saves redirect to `account/sign-in.html`. -+- Confirm referenced Messages cannot be deleted while they have sentence usage. -+ -+This PR is not part of the Game Crew cleanup batch. Previous dependency: none for PR_002. Next dependency: resolve the separate Game Crew guest seed ownership cleanup before running full seed integrity as a required gate. -+ -+## Requirement Checklist -+ -+PASS - Preserve current PR_002 Messages Creator Tool changes. -+PASS - Do not modify guest `game-crew` seed files. -+PASS - Do not modify `DbSeedIntegrity` for Game Crew in this PR. -+PASS - Do not run or plan PR_003+ from this dirty branch. -+PASS - Document Game Crew seed integrity failure as unrelated/out-of-scope. -+PASS - Run only in-scope Messages validation and impacted Playwright. -+PASS - Produce PR_002 artifacts. -+PASS - Browser-owned product data was not introduced. -+PASS - No silent JSON fallback was introduced. -+PASS - No MEM DB/local-mem was introduced. -+PASS - No unrelated cleanup. -+ -+## Changed File Inventory -+ -+- `dev/build/database/ddl/messages.sql` -+- `dev/tests/dev-runtime/MessagesPublishValidation.test.mjs` -+- `dev/tests/helpers/playwrightRepoServer.mjs` -+- `dev/tests/playwright/tools/MessagesTool.spec.mjs` -+- `src/dev-runtime/messages/messages-postgres-service.mjs` -+- `toolbox/messages/index.html` -+- `toolbox/messages/messages.js` -+- `dev/reports/codex_changed_files.txt` -+- `dev/reports/codex_review.diff` -+- `dev/reports/PR_26180_BRAVO_002-complete-messages-creator-tool.md` -+ -+## DB/API Inventory -+ -+- `messages_records` DDL includes `speaker`, `trigger`, and `typewriterSpeed`. -+- Messages Postgres service normalizes, validates, serializes, creates, and updates `speaker`, `trigger`, and `typewriterSpeed`. -+- `typewriterSpeed` must be a number of 0 or greater. -+- Messages write resources require authenticated API actors. -+- Existing Text To Speech profile and Emotion Profile service contracts remain API-backed. -+- Guest writes redirect to `account/sign-in.html` through the existing account route. -+ -+## Validation Lane Report -+ -+PASS - Scoped Node/API Messages validation: -+ -+```powershell -+node --test dev/tests/tools/Text2SpeechShell.test.mjs dev/tests/tools/MessagesPlaybackSource.test.mjs dev/tests/dev-runtime/MessagesPublishValidation.test.mjs -+``` ++++ b/dev/reports/PR_26180_OWNER_003-backlog-startup-assignment-policy_branch-validation.md +@@ -0,0 +1,13 @@ ++# PR_26180_OWNER_003 Branch Validation ++ ++| Gate | Result | Evidence | ++|---|---|---| ++| Project Instructions version loaded | PASS | `2026.06.28.003` | ++| Repository Project Instructions source | PASS | Loaded from `dev/build/ProjectInstructions/` | ++| Cached memory discarded | PASS | Repository instructions used as authority | ++| Branching policy loaded | PASS | `dev/build/ProjectInstructions/PROJECT_BRANCHING_POLICY.md` | ++| Batch Governance Mode loaded | PASS | `dev/build/ProjectInstructions/addendums/batch_governance_mode.md` | ++| Current branch | PASS | `PR_26180_OWNER_003-backlog-startup-assignment-policy` | ++| Owner independent PR model | PASS | Branch created from synchronized `main` | ++| Worktree before edits | PASS | Clean before PR edits | ++| Scope | PASS | Governance/documentation only | +diff --git a/dev/reports/PR_26180_OWNER_003-backlog-startup-assignment-policy_manual-validation-notes.md b/dev/reports/PR_26180_OWNER_003-backlog-startup-assignment-policy_manual-validation-notes.md +new file mode 100644 +index 000000000..f40b1c3ea +--- /dev/null ++++ b/dev/reports/PR_26180_OWNER_003-backlog-startup-assignment-policy_manual-validation-notes.md +@@ -0,0 +1,14 @@ ++# PR_26180_OWNER_003 Manual Validation Notes ++ ++- Confirmed `dev/build/ProjectInstructions/backlog/BACKLOG_MASTER.md` exists and is referenced as the authoritative assigned-work source. ++- Confirmed `admin/tool-votes.html` exists and is referenced only as the Tool Votes/Admin Owner priority signal source. ++- Confirmed the required Team Assignment startup output section appears in active startup governance. ++- Confirmed Project Instructions version is updated to `2026.06.28.003`. ++- Confirmed rebase onto current `origin/main`; conflict resolution touched generated report artifacts only. ++- Confirmed second rebase onto current `origin/main` after Bravo Messages merged; conflict resolution again touched generated report artifacts only. ++- Confirmed `BACKLOG_MASTER.md` now treats team-aware local dev bootstrap runtime as implemented, not remaining work. ++- Confirmed correction used OWNER-provided verification for `npm run dev:bootstrap -- --team bravo`. ++- Confirmed future-normalization wording was replaced with current-state canonical backlog language. ++- Confirmed Tool Votes UI/page files were not modified. ++- Confirmed this PR does not implement Tile, Tool Votes, runtime, API, database, or UI behavior. ++- Playwright was not run because this is governance/documentation-only and no runtime or UI files changed. +diff --git a/dev/reports/PR_26180_OWNER_003-backlog-startup-assignment-policy_report.md b/dev/reports/PR_26180_OWNER_003-backlog-startup-assignment-policy_report.md +new file mode 100644 +index 000000000..5c5e0100e +--- /dev/null ++++ b/dev/reports/PR_26180_OWNER_003-backlog-startup-assignment-policy_report.md +@@ -0,0 +1,105 @@ ++# PR_26180_OWNER_003 Backlog Startup Assignment Policy Report ++ ++## Executive Summary ++ ++PASS: This PR updates Project Instructions so team startup must load `BACKLOG_MASTER.md`, report assigned product work by team/product area, and treat Admin Tool Votes as the priority signal source for tool demand and Owner/Admin review. ++ ++The change is governance/documentation only. No runtime, UI, API, database, or tool implementation files were modified. ++ ++Project Instructions version was bumped to `2026.06.28.003`. ++ ++## Scope Decision ++ ++Updated active Project Instructions and the backlog header only. ++ ++`admin/tool-votes.html` was identified as the current Tool Votes/Admin Owner priority signal source. It was not modified because this PR is governance-only and the user explicitly prohibited UI/tool implementation changes. ++ ++## Source Discovery ++ ++| Source | Path | Status | ++|---|---|---| ++| Authoritative backlog | `dev/build/ProjectInstructions/backlog/BACKLOG_MASTER.md` | Found | ++| Team backlog/SOD/EOD standard | `dev/build/ProjectInstructions/addendums/team_backlog_sod_eod_standard.md` | Updated | ++| Start of Day bootstrap architecture | `dev/build/ProjectInstructions/bootstrap/codex_start_of_day_bootstrap.md` | Updated | ++| Codex workflow commands | `dev/build/ProjectInstructions/standards/CODEX_WORKFLOW_COMMANDS.md` | Updated | ++| Team start commands | `dev/build/ProjectInstructions/TEAM_START_COMMANDS.md` | Updated | ++| Tool Votes/Admin Owner priority signal | `admin/tool-votes.html` | Found, not modified | ++ ++## Changes + -+Result: PASS, 21/21 tests. ++- Added `BACKLOG_MASTER.md` as the authoritative assigned product work source in active startup/team governance. ++- Added `admin/tool-votes.html` as the Tool Votes/Admin Owner priority signal source. ++- Added the required Team Assignment startup output table. ++- Added hard-stop behavior for missing backlog, missing assigned team, missing product-area representation, and missing Tool Votes priority source. ++- Updated `BACKLOG_MASTER.md` header to state assigned-work ownership, status update expectations, current Team/Product Area status-source ownership, and required product-area status/percent complete. ++- Corrected `BACKLOG_MASTER.md` to mark team-aware local dev bootstrap runtime as complete, including `dev:bootstrap`, `team-port-config.mjs`, `--team` support, bootstrap orchestration, browser launch reporting, and port resolution. ++- Updated Start of Day command/bootstrap docs to require the Team Assignment section. ++- Added top-level `PROJECT_INSTRUCTIONS.md` pointers for the team backlog/startup assignment standard and Tool Votes priority source. + -+PASS - Messages Playwright validation: ++## Bootstrap Status Correction + -+```powershell -+npx playwright test --config dev/workspace/tmp/pr_26180_bravo_002.playwright.headless.config.cjs dev/tests/playwright/tools/MessagesTool.spec.mjs --project=playwright ++Team-aware dev bootstrap is implemented and must not be assigned as remaining backlog work. ++ ++Owner-provided verification: ++ ++```text ++npm run dev:bootstrap -- --team bravo ++GameFoundry team-aware dev bootstrap ++Mode: bootstrap ++Team: bravo ++Web URL: http://127.0.0.1:5520 ++API URL: http://127.0.0.1:5521/api ++Browser launch: http://127.0.0.1:5520/index.html ++Supported teams: owner, alfa, bravo, charlie, delta, echo, foxtrot, golf, hotel ++Legacy API alias remains: npm run dev:local-api +``` + -+Result: PASS, 6/6 tests. ++Corrected implemented items: ++ ++- `npm run dev:bootstrap` ++- `dev/bootstrap/team-port-config.mjs` ++- team-aware `--team` runtime support ++- bootstrap orchestration ++- browser launch reporting ++- port resolution ++- legacy `npm run dev:local-api` alias ++ ++## Backlog Canonical Structure Correction + -+PASS - Text To Speech Playwright validation: ++`BACKLOG_MASTER.md` now states: + -+```powershell -+npx playwright test --config dev/workspace/tmp/pr_26180_bravo_002.playwright.headless.config.cjs dev/tests/playwright/tools/TextToSpeechFunctional.spec.mjs --project=playwright ++```text ++BACKLOG_MASTER.md is now the canonical team/product-area assignment and status source. Future backlog changes must update this structure directly. +``` + -+Result: PASS, 4/4 tests. ++This removes wording that implied team/product-area backlog normalization was a future activity. + -+INFO - A temporary ignored Playwright config under `dev/workspace/tmp` was used to run the repo's `playwright` project headlessly in this environment. The product/test delta does not depend on that generated file. ++## Rebase Notes + -+## Playwright Impacted Assessment ++- Rebased onto current `origin/main` after Owner 035 merged. ++- Rebased again onto current `origin/main` after Bravo Messages merged. ++- Merge conflicts were limited to generated report artifacts: `dev/reports/codex_changed_files.txt` and `dev/reports/codex_review.diff`. ++- Owner 035 runtime/API/auth files and Bravo Messages runtime/UI/API files from `main` were preserved unchanged. ++- Owner 003 remains governance/documentation-only. + -+PASS - `dev/tests/playwright/tools/MessagesTool.spec.mjs` validates: ++## Owner Recommendation + -+- table-first Message Studio structure -+- Speaker, Text, Trigger, Typewriter Speed fields -+- TTS Profile selection -+- API-backed profile consumption -+- sentence emotion filtering by selected profile -+- referenced Message delete protection -+- guest save redirect -+- Creator-safe load failures ++Use `dev/build/ProjectInstructions/backlog/BACKLOG_MASTER.md` as the required assigned-work source during startup and use `admin/tool-votes.html` as the priority signal source for tool demand. When either source is missing or does not represent the requested work, Codex must stop and ask OWNER whether to update the backlog before proceeding. + -+PASS - `dev/tests/playwright/tools/TextToSpeechFunctional.spec.mjs` validates existing Text To Speech behavior remains intact. ++## Validation + -+The Playwright repo helper was fixed so static files are served from the repository root instead of `dev/`. ++| Check | Result | ++|---|---| ++| Branch validation | PASS | ++| `git diff --check` | PASS | ++| `npm run validate:canonical-structure` | PASS | ++| Runtime/UI/API/DB implementation files changed | PASS - none changed | ++| Bootstrap/runtime implementation recreated | PASS - not recreated; backlog status only | + -+## Manual Validation Notes ++## Artifact + -+Recommended Product Owner manual validation: ++Repo-structured outcome ZIP: ++ ++```text ++dev/workspace/zips/PR_26180_OWNER_003-backlog-startup-assignment-policy_delta.zip ++``` +diff --git a/dev/reports/PR_26180_OWNER_003-backlog-startup-assignment-policy_requirement-checklist.md b/dev/reports/PR_26180_OWNER_003-backlog-startup-assignment-policy_requirement-checklist.md +new file mode 100644 +index 000000000..276735921 +--- /dev/null ++++ b/dev/reports/PR_26180_OWNER_003-backlog-startup-assignment-policy_requirement-checklist.md +@@ -0,0 +1,29 @@ ++# PR_26180_OWNER_003 Requirement Checklist ++ ++| Requirement | Result | Notes | ++|---|---|---| ++| Locate authoritative backlog | PASS | `dev/build/ProjectInstructions/backlog/BACKLOG_MASTER.md` exists and was updated. | ++| Locate Tool Votes/Admin Owner planning source | PASS | `admin/tool-votes.html` identified as the active priority signal surface. | ++| State backlog is authoritative assigned-work source | PASS | Added to backlog/startup governance. | ++| State Tool Votes/Admin Owner is priority signal source | PASS | Added with path `admin/tool-votes.html`. | ++| Teams must read backlog during startup | PASS | Added to team backlog standard and team start commands. | ++| Teams must locate assigned team/product areas | PASS | Added to Team Assignment Startup Review. | ++| Startup table grouped by Team/Product Area | PASS | Required output table added. | ++| Assignment rows include all requested fields | PASS | Team, Product Area, Status, Complete, Active PR, Next Milestone, Source included. | ++| Teams update backlog status/percent complete on status change | PASS | Added to team backlog standard. | ++| Owner updates backlog and Tool Votes/Admin Owner status | PASS | Added to team backlog standard. | ++| Codex must not invent work from conversation memory | PASS | Added hard rule. | ++| Add required startup output section | PASS | Added to team backlog standard and bootstrap. | ++| Add missing backlog hard stop | PASS | Added. | ++| Add missing assigned team hard stop | PASS | Added with Owner one-off exception. | ++| Add missing task representation hard stop | PASS | Added. | ++| Add missing Tool Votes source behavior | PASS | Added recommendation behavior. | ++| Update BACKLOG_MASTER header if needed | PASS | Updated. | ++| Update Tool Votes page header if needed | PASS | Not needed; UI/tool page left untouched due governance-only scope. | ++| Preserve startup validation, branching policy, ZIP/report contract, canonical paths, Batch Governance Mode, and no legacy paths | PASS | No conflicting edits made. | ++| Bump Project Instructions version | PASS | `PROJECT_INSTRUCTIONS_VERSION.md` and `PROJECT_INSTRUCTIONS.md` now use `2026.06.28.003`. | ++| Mark bootstrap/team-aware dev runtime as implemented | PASS | `BACKLOG_MASTER.md` now records team-aware local dev bootstrap as complete. | ++| Do not recreate bootstrap work | PASS | No runtime/bootstrap source files were modified. | ++| Do not assign bootstrap as remaining work | PASS | Backlog notes explicitly prohibit assigning `dev:bootstrap`, team-port config, browser launch, bootstrap orchestration, or port resolution as remaining backlog work unless OWNER opens a new enhancement. | ++| Remove future-normalization wording | PASS | `BACKLOG_MASTER.md` now uses current-state canonical team/product-area assignment and status language. | ++| No runtime/UI/API/database/tool implementation changes | PASS | Only Project Instructions and reports changed. | +diff --git a/dev/reports/PR_26180_OWNER_003-backlog-startup-assignment-policy_validation-report.md b/dev/reports/PR_26180_OWNER_003-backlog-startup-assignment-policy_validation-report.md +new file mode 100644 +index 000000000..2ff76a6c2 +--- /dev/null ++++ b/dev/reports/PR_26180_OWNER_003-backlog-startup-assignment-policy_validation-report.md +@@ -0,0 +1,39 @@ ++# PR_26180_OWNER_003 Validation Report ++ ++## Validation Commands ++ ++| Command | Result | ++|---|---| ++| `git diff --check` | PASS | ++| `npm run validate:canonical-structure` | PASS | ++ ++## Canonical Structure Output ++ ++```text ++Canonical repository structure guardrail: PASS ++Blocking violations: 0 ++Approved legacy exceptions: 500 ++``` + -+1. Open Message Studio as an authenticated Creator. -+2. Add a message with Speaker, Text, Trigger, Typewriter Speed, and TTS Profile. -+3. Save and reload to confirm API/Postgres persistence. -+4. Edit the same fields and confirm changes persist. -+5. Add a sentence with a profile-scoped emotion and confirm playback. -+6. Confirm guest can browse but Save redirects to `account/sign-in.html`. -+7. Confirm referenced Message Delete remains blocked. ++## Scope Validation + -+## Known Issues ++Changed files are limited to: + -+- Full `DbSeedIntegrity` remains blocked outside PR_002 because `dev/build/database/seed/guest/game-crew.json` publishes `game-crew` while canonical inventory expects Game Crew under `users`. -+- This PR intentionally does not clean up Game Crew guest seed JSON ownership. -+- The Game Crew cleanup should be planned from clean `main` as a separate batch after PR_002 is clean, committed, and opened. ++- `dev/build/ProjectInstructions/PROJECT_INSTRUCTIONS.md` ++- `dev/build/ProjectInstructions/PROJECT_INSTRUCTIONS_VERSION.md` ++- `dev/build/ProjectInstructions/TEAM_START_COMMANDS.md` ++- `dev/build/ProjectInstructions/addendums/team_backlog_sod_eod_standard.md` ++- `dev/build/ProjectInstructions/addendums/team_start_and_release.md` ++- `dev/build/ProjectInstructions/backlog/BACKLOG_MASTER.md` ++- `dev/build/ProjectInstructions/bootstrap/codex_start_of_day_bootstrap.md` ++- `dev/build/ProjectInstructions/standards/CODEX_WORKFLOW_COMMANDS.md` ++- `dev/reports/*` + -+## ZIP Outcome ++No runtime, UI, API, database, or tool implementation files were changed. + -+DELTA artifact: ++## Bootstrap Status Correction Validation + -+`dev/workspace/zips/PR_26180_BRAVO_002-complete-messages-creator-tool_delta.zip` ++- `BACKLOG_MASTER.md` marks team-aware local dev bootstrap runtime as complete. ++- `dev:bootstrap`, `team-port-config.mjs`, `--team` runtime support, bootstrap orchestration, browser launch reporting, and port resolution are not listed as remaining backlog work. ++- `BACKLOG_MASTER.md` no longer implies team/product-area backlog normalization is a future activity. ++- No `dev/bootstrap/`, `package.json`, runtime, UI, API, or database files were modified by this correction. diff --git a/dev/reports/codex_changed_files.txt b/dev/reports/codex_changed_files.txt -index 952a0ad68613d82b87fbe1153d77bdda99b517b7..bc37b31a4fecac5d0400b2370ad161ffed4f2b57 100644 -GIT binary patch -literal 431 -zcmZvY%~FFf5XbL*mn7JO)2rScJLvSvgk*s@35mN4rO)QUNAeX6jG$G|`~Ujw$J@Jw -zQPqRo-_06?6p=|C%W8jnb116&^6vCl6~$hd7?KADv6_TI -z&>T^4j9vzN6=0%;sWP4JTd-B*d@kXM|Ir|f4$jiLrdh5Gln3N70*9Vm0QK;-@;KDq -zQFqebWeOL2IcsHjp&!N$d;%nuyuO^#wH=q4=?QQI{3ZRCs2PE_qURZi5}3t6Xs+h0 -m{M+|Lio`7f3CcCjz+#&t>o{#H<@)>**>Ui@KeshgW|mJ*QKX6h - -literal 2004 -zcmd6oPfsH;48`9Sr2QyEVG$sXXyLF276eEft7#`KU0Mb@nL@uj@Uznq1r?Tm(pDoS -zPA0aW?HA|aeoreZ6f{vwW9Dm>%uyBVW1Xn2pW4=jcC?Fpq;vhzf$y(tQ(MYr+L?0I -z=v}Z=qaCo4>5_TsXF80{3G*=E>=cU~o6nqiq>A?OzU0;$JmcYfYN -z1uLv`Tw~q(Q$+`{&XFP2?B;Zn965N$F^idN1a_nMwG3^Gz?fzo$ULT-`j`2ozjTk2 -zuhb(m{MR#WV{A*OFFfzFJJBy^LgV%KGoMp*0$;(L@LR?VM`HSSAvp#^=~*@GV=!4a -zjYv6JiFl7-?|8kw?)?m_ePY<74g-&H?7qABem%YlG+nazT6WVrGI9JZ_*HV+UI=?j -z%#YQhBnr#l7(XM;XYXIuo2(DWOW*nQITqOqXGpE4CN)+4D4LR3hE$~F{xlJ`Jl-B- -PMwID9^7fS9=L~)XkUVLc - -diff --git a/dev/tests/dev-runtime/MessagesPublishValidation.test.mjs b/dev/tests/dev-runtime/MessagesPublishValidation.test.mjs -index 533dfa1f8..b8c4b2c2a 100644 ---- a/dev/tests/dev-runtime/MessagesPublishValidation.test.mjs -+++ b/dev/tests/dev-runtime/MessagesPublishValidation.test.mjs -@@ -612,3 +612,71 @@ test("Messages API requires sign-in for Text To Speech profile and emotion write - assert.equal(authenticated.ttsProfile.name, "Authenticated TTS Profile"); - service.close(); - }); -+ -+test("Messages API requires sign-in for Message and sentence writes", async () => { -+ const { service } = createServiceHarness(); -+ const voice = await createWorkingTtsProfile(service, { name: "Authenticated Message Profile" }); -+ const emotion = voice.emotionSettings.find((setting) => setting.emotionLabel === "Calm"); -+ assert.ok(emotion); -+ -+ const messagePayload = { -+ emotionProfileKey: emotion.key, -+ messageText: "Authenticated message text.", -+ name: "Authenticated Message", -+ speaker: "Guide", -+ trigger: "quest.start", -+ typewriterSpeed: 22, -+ voiceProfileKey: voice.key, -+ }; -+ -+ await assert.rejects( -+ () => handleMessagesApiContract({ -+ body: messagePayload, -+ method: "POST", -+ parts: ["messages"], -+ service, -+ }), -+ /Sign in required to save Messages through the API/, -+ ); -+ -+ const created = await handleMessagesApiContract({ -+ actorKey: "test-author", -+ body: messagePayload, -+ method: "POST", -+ parts: ["messages"], -+ service, -+ }); -+ assert.equal(created.message.name, "Authenticated Message"); -+ assert.equal(created.message.messageText, "Authenticated message text."); -+ assert.equal(created.message.speaker, "Guide"); -+ assert.equal(created.message.trigger, "quest.start"); -+ assert.equal(created.message.typewriterSpeed, 22); -+ -+ const segmentPayload = { -+ displayOrder: 1, -+ emotionProfileKey: emotion.key, -+ messageKey: created.message.key, -+ segmentText: "Authenticated sentence text.", -+ voiceProfileKey: voice.key, -+ }; -+ -+ await assert.rejects( -+ () => handleMessagesApiContract({ -+ body: segmentPayload, -+ method: "POST", -+ parts: ["segments"], -+ service, -+ }), -+ /Sign in required to save Messages through the API/, -+ ); -+ -+ const segment = await handleMessagesApiContract({ -+ actorKey: "test-author", -+ body: segmentPayload, -+ method: "POST", -+ parts: ["segments"], -+ service, -+ }); -+ assert.equal(segment.segment.segmentText, "Authenticated sentence text."); -+ service.close(); -+}); -diff --git a/dev/tests/playwright/tools/MessagesTool.spec.mjs b/dev/tests/playwright/tools/MessagesTool.spec.mjs -index 5bb31055d..3484467a8 100644 ---- a/dev/tests/playwright/tools/MessagesTool.spec.mjs -+++ b/dev/tests/playwright/tools/MessagesTool.spec.mjs -@@ -166,6 +166,14 @@ async function openMessagesPage(page, options = {}) { - if (options.seedMessageTtsProfile !== false) { - await ensureMessageTestTtsProfile(server); - } -+ if (options.authenticated === false) { -+ const session = await jsonRequest(`${server.baseUrl}/api/session/user`, { -+ body: JSON.stringify({ userKey: "" }), -+ method: "POST", -+ }); -+ expect(session.response.ok).toBe(true); -+ expect(session.payload.ok).toBe(true); -+ } - await workspaceV2CoverageReporter.start(page); - await page.goto(`${server.baseUrl}/tools/messages/index.html`, { waitUntil: "networkidle" }); - return failures; -@@ -179,6 +187,10 @@ async function closeMessagesRun(failures, page) { - async function addMessage(page, values) { - await page.getByRole("button", { name: "Add Message" }).click(); - await page.locator("[data-messages-row-editor='__new__'] [data-message-name]").fill(values.name); -+ await page.locator("[data-messages-row-editor='__new__'] [data-message-speaker]").fill(values.speaker || "Narrator"); -+ await page.locator("[data-messages-row-editor='__new__'] [data-message-text]").fill(values.text || `${values.name} message text.`); -+ await page.locator("[data-messages-row-editor='__new__'] [data-message-trigger]").fill(values.trigger || "manual"); -+ await page.locator("[data-messages-row-editor='__new__'] [data-message-typewriter-speed]").fill(String(values.typewriterSpeed ?? 30)); - await page.locator("[data-messages-row-editor='__new__'] [data-message-tts-profile]").selectOption({ label: values.ttsProfile }); - await page.locator("[data-messages-commit='__new__']").click(); - } -@@ -292,8 +304,9 @@ test("Message Studio uses the approved table-first Messages structure", async ({ - await expect(page.locator("[data-messages-publish-issues]")).toContainText("Run validation before publishing."); - await expect(page.locator("[data-messages-table]")).toContainText("No messages yet. Add your first message when you are ready."); - -- const expectedHeaders = ["Message", "TTS Profile", "Updated", "Actions"]; -- await expect(page.getByLabel("Messages").getByRole("columnheader")).toHaveText(expectedHeaders); -+ const expectedHeaders = ["Message", "Speaker", "Text", "Trigger", "Typewriter Speed", "TTS Profile", "Updated", "Actions"]; -+ const messagesTable = page.getByLabel("Messages"); -+ await expect(messagesTable.getByRole("columnheader")).toHaveText(expectedHeaders); - await expect(page.getByText("Reusable Assets", { exact: true })).toHaveCount(0); - await expect(page.getByRole("heading", { name: "Emotion Profiles" })).toHaveCount(0); - await expect(page.getByRole("heading", { name: "Voice Profiles" })).toHaveCount(0); -@@ -304,17 +317,21 @@ test("Message Studio uses the approved table-first Messages structure", async ({ - await expect(page.getByText("Message Parts", { exact: true })).toHaveCount(0); - await expect(page.getByRole("button", { name: "Add Emotion" })).toHaveCount(0); - await expect(page.getByRole("button", { name: "Add Voice" })).toHaveCount(0); -- await expect(page.getByRole("columnheader", { name: "Type" })).toHaveCount(0); -- await expect(page.getByRole("columnheader", { name: "Status" })).toHaveCount(0); -- await expect(page.getByRole("columnheader", { name: "Parts" })).toHaveCount(0); -- await expect(page.getByRole("columnheader", { name: "Emotion", exact: true })).toHaveCount(0); -- await expect(page.getByRole("columnheader", { name: "Voice", exact: true })).toHaveCount(0); -+ await expect(messagesTable.getByRole("columnheader", { exact: true, name: "Type" })).toHaveCount(0); -+ await expect(messagesTable.getByRole("columnheader", { exact: true, name: "Status" })).toHaveCount(0); -+ await expect(messagesTable.getByRole("columnheader", { exact: true, name: "Parts" })).toHaveCount(0); -+ await expect(messagesTable.getByRole("columnheader", { name: "Emotion", exact: true })).toHaveCount(0); -+ await expect(messagesTable.getByRole("columnheader", { name: "Voice", exact: true })).toHaveCount(0); - await expect(page.getByRole("button", { name: "Stop Playback" })).toHaveCount(0); - await expect(page.locator("[data-message-default-tts-profile], [data-segment-tts-profile]")).toHaveCount(0); - - await page.getByRole("button", { name: "Add Message" }).click(); - await expect(page.locator("[data-messages-row-editor='__new__']")).toBeVisible(); -- await expect(page.locator("[data-messages-row-editor='__new__'] td")).toHaveCount(4); -+ await expect(page.locator("[data-messages-row-editor='__new__'] td")).toHaveCount(8); -+ await expect(page.locator("[data-messages-row-editor='__new__'] [data-message-speaker]")).toBeVisible(); -+ await expect(page.locator("[data-messages-row-editor='__new__'] [data-message-text]")).toBeVisible(); -+ await expect(page.locator("[data-messages-row-editor='__new__'] [data-message-trigger]")).toBeVisible(); -+ await expect(page.locator("[data-messages-row-editor='__new__'] [data-message-typewriter-speed]")).toHaveValue("30"); - await expect(page.locator("[data-messages-row-editor='__new__'] [data-message-tts-profile]")).toBeVisible(); - await expect(page.locator("[data-messages-row-editor='__new__'] [data-message-tts-profile] option")).toHaveText([ - "Select TTS profile", -@@ -326,15 +343,24 @@ test("Message Studio uses the approved table-first Messages structure", async ({ - await page.locator("[data-messages-commit='__new__']").click(); - await expect(page.locator("[data-messages-validation-card]")).toBeVisible(); - await expect(page.locator("[data-messages-validation-errors]")).toContainText("Message is required."); -+ await expect(page.locator("[data-messages-validation-errors]")).toContainText("Message text is required."); - await expect(page.locator("[data-messages-validation-errors]")).toContainText("TTS Profile is required."); - await page.locator("[data-messages-cancel='__new__']").click(); - - await addMessage(page, { - name: "Bat Encounter", -+ speaker: "Scout", -+ text: "Bats are stirring in the rafters.", - ttsProfile: TEST_TTS_PROFILE_NAME, -+ trigger: "enter.cavern", -+ typewriterSpeed: 24, - }); - await expect(page.locator("[data-messages-log]")).toHaveText("Saved message Bat Encounter."); - const messageRow = page.locator("[data-messages-row]").filter({ hasText: "Bat Encounter" }); -+ await expect(messageRow).toContainText("Scout"); -+ await expect(messageRow).toContainText("Bats are stirring in the rafters."); -+ await expect(messageRow).toContainText("enter.cavern"); -+ await expect(messageRow).toContainText("24 cps"); - await expect(messageRow).toContainText(TEST_TTS_PROFILE_NAME); - await expect(messageRow.getByRole("button", { name: "Sentences" })).toBeVisible(); - await expect(messageRow.getByRole("button", { name: "Edit" })).toBeVisible(); -@@ -537,20 +563,37 @@ test("Message Studio uses the approved table-first Messages structure", async ({ - await expect(page.locator("[data-messages-row-editor]").getByRole("button", { name: "Save" })).toBeVisible(); - await expect(page.locator("[data-messages-row-editor]").getByRole("button", { name: "Cancel" })).toBeVisible(); - await page.locator("[data-messages-row-editor] [data-message-name]").fill("Temporary Message Edit"); -+ await page.locator("[data-messages-row-editor] [data-message-speaker]").fill("Temporary Speaker"); -+ await page.locator("[data-messages-row-editor] [data-message-text]").fill("Temporary text edit"); -+ await page.locator("[data-messages-row-editor] [data-message-trigger]").fill("temporary.trigger"); -+ await page.locator("[data-messages-row-editor] [data-message-typewriter-speed]").fill("99"); - await page.locator("[data-messages-row-editor] [data-messages-cancel]").click(); - await expect(page.locator("[data-messages-row]").filter({ hasText: "Bat Encounter" })).toBeVisible(); - await expect(page.locator("[data-messages-row]").filter({ hasText: "Temporary Message Edit" })).toHaveCount(0); -+ await expect(page.locator("[data-messages-row]").filter({ hasText: "Temporary Speaker" })).toHaveCount(0); - - await messageRow.getByRole("button", { name: "Edit" }).click(); - await page.locator("[data-messages-row-editor] [data-message-name]").fill("Bat Encounter Updated"); -+ await page.locator("[data-messages-row-editor] [data-message-speaker]").fill("Guide"); -+ await page.locator("[data-messages-row-editor] [data-message-text]").fill("Updated bats are dropping from the rafters."); -+ await page.locator("[data-messages-row-editor] [data-message-trigger]").fill("combat.bats.updated"); -+ await page.locator("[data-messages-row-editor] [data-message-typewriter-speed]").fill("18"); - await page.locator("[data-messages-row-editor] [data-messages-commit]").click(); - await expect(page.locator("[data-messages-log]")).toHaveText("Saved message Bat Encounter Updated."); - await expect(page.locator("[data-messages-row]").filter({ hasText: "Bat Encounter Updated" })).toContainText(TEST_TTS_PROFILE_NAME); -+ await expect(page.locator("[data-messages-row]").filter({ hasText: "Bat Encounter Updated" })).toContainText("Guide"); -+ await expect(page.locator("[data-messages-row]").filter({ hasText: "Bat Encounter Updated" })).toContainText("Updated bats are dropping from the rafters."); -+ await expect(page.locator("[data-messages-row]").filter({ hasText: "Bat Encounter Updated" })).toContainText("combat.bats.updated"); -+ await expect(page.locator("[data-messages-row]").filter({ hasText: "Bat Encounter Updated" })).toContainText("18 cps"); - - const updatedMessage = await createdMessage(failures.server, "Bat Encounter Updated"); - expect(updatedMessage).toEqual(expect.objectContaining({ - active: true, - categoryName: "Dialog", -+ messageText: "Updated bats are dropping from the rafters.", -+ speaker: "Guide", -+ trigger: "combat.bats.updated", -+ typewriterSpeed: 18, - voiceProfileName: TEST_TTS_PROFILE_NAME, - })); - expect(updatedMessage.key).toMatch(ULID_PATTERN); -@@ -614,6 +657,10 @@ test("Message Studio consumes active Local API Text To Speech profiles", async ( - await page.getByRole("button", { name: "Add Message" }).click(); - await expect(page.locator("[data-messages-row-editor='__new__'] [data-message-tts-profile]")).toContainText("Quest Profile Active"); - await page.locator("[data-messages-row-editor='__new__'] [data-message-name]").fill("Quest Profile Message"); -+ await page.locator("[data-messages-row-editor='__new__'] [data-message-speaker]").fill("Quest Giver"); -+ await page.locator("[data-messages-row-editor='__new__'] [data-message-text]").fill("The quest door opens."); -+ await page.locator("[data-messages-row-editor='__new__'] [data-message-trigger]").fill("quest.door"); -+ await page.locator("[data-messages-row-editor='__new__'] [data-message-typewriter-speed]").fill("28"); - await page.locator("[data-messages-row-editor='__new__'] [data-message-tts-profile]").selectOption({ label: "Quest Profile Active" }); - await page.locator("[data-messages-commit='__new__']").click(); - await expect(page.locator("[data-messages-log]")).toHaveText("Saved message Quest Profile Message."); -@@ -679,6 +726,10 @@ test("Message Studio loads Text To Speech profiles and filters sentence emotions - TEST_TTS_PROFILE_NAME, - ]); - await page.locator("[data-messages-row-editor='__new__'] [data-message-name]").fill("Profile Filter Test"); -+ await page.locator("[data-messages-row-editor='__new__'] [data-message-speaker]").fill("Narrator"); -+ await page.locator("[data-messages-row-editor='__new__'] [data-message-text]").fill("Urgent profile filter check."); -+ await page.locator("[data-messages-row-editor='__new__'] [data-message-trigger]").fill("profile.filter"); -+ await page.locator("[data-messages-row-editor='__new__'] [data-message-typewriter-speed]").fill("32"); - await page.locator("[data-messages-row-editor='__new__'] [data-message-tts-profile]").selectOption({ label: TEST_TTS_PROFILE_NAME }); - await page.locator("[data-messages-commit='__new__']").click(); - await expect(page.locator("[data-messages-log]")).toHaveText("Saved message Profile Filter Test."); -@@ -755,7 +806,7 @@ test("Message Studio disables Delete when a message is referenced", async ({ pag - - await page.reload({ waitUntil: "networkidle" }); - const messageRow = page.locator("[data-messages-row]").filter({ hasText: "Referenced Encounter" }); -- await messageRow.getByText("Referenced Encounter").click(); -+ await messageRow.getByRole("rowheader", { name: "Referenced Encounter" }).click(); - const deleteButton = messageRow.getByRole("button", { name: "Delete" }); - await expect(deleteButton).toBeDisabled(); - await expect(deleteButton).toHaveAttribute("title", "Delete disabled: this message has sentences."); -@@ -784,6 +835,29 @@ test("Message Studio disables Delete when a message is referenced", async ({ pag - } - }); - -+test("Message Studio guest message save redirects to sign in", async ({ page }) => { -+ const failures = await openMessagesPage(page, { authenticated: false }); -+ -+ try { -+ await page.getByRole("button", { name: "Add Message" }).click(); -+ await page.locator("[data-messages-row-editor='__new__'] [data-message-name]").fill("Guest Message"); -+ await page.locator("[data-messages-row-editor='__new__'] [data-message-speaker]").fill("Guest"); -+ await page.locator("[data-messages-row-editor='__new__'] [data-message-text]").fill("Guest save attempt."); -+ await page.locator("[data-messages-row-editor='__new__'] [data-message-trigger]").fill("guest.save"); -+ await page.locator("[data-messages-row-editor='__new__'] [data-message-typewriter-speed]").fill("20"); -+ await page.locator("[data-messages-row-editor='__new__'] [data-message-tts-profile]").selectOption({ label: TEST_TTS_PROFILE_NAME }); -+ await page.locator("[data-messages-commit='__new__']").click(); -+ await page.waitForURL(/\/account\/sign-in\.html$/); -+ await page.waitForLoadState("networkidle"); -+ -+ expect(failures.failedRequests.filter((request) => /^\d/.test(request) && !request.includes("/account/sign-in.html"))).toEqual([]); -+ expect(failures.pageErrors).toEqual([]); -+ expect(failures.consoleErrors).toEqual([]); -+ } finally { -+ await closeMessagesRun(failures, page); -+ } -+}); -+ - test("Message Studio shows Creator-safe load failures", async ({ page }) => { - const failures = await openMessagesPage(page, { apiUrl: "http://127.0.0.1:9/api" }); - -diff --git a/src/dev-runtime/messages/messages-postgres-service.mjs b/src/dev-runtime/messages/messages-postgres-service.mjs -index b56023c2a..481212e4f 100644 ---- a/src/dev-runtime/messages/messages-postgres-service.mjs -+++ b/src/dev-runtime/messages/messages-postgres-service.mjs -@@ -51,6 +51,15 @@ const SUPPORTED_TTS_SSML_LIKE_PRESETS = Object.freeze([ - const ACTIVE_PUBLISH_TTS_PROVIDER_KEYS = Object.freeze([ - "browser-speech", - ]); -+const DEFAULT_TYPEWRITER_SPEED = 30; -+const AUTHENTICATED_MESSAGES_WRITE_RESOURCES = Object.freeze([ -+ "categories", -+ "emotion-profiles", -+ "event-actions", -+ "messages", -+ "segments", -+ "tts-profiles", -+]); - const MESSAGE_EVENT_ACTION_TYPES = Object.freeze([ - Object.freeze({ key: "show-message", label: "Show Message", requiresMessage: true }), - Object.freeze({ key: "speak-message", label: "Speak Message", requiresMessage: true }), -@@ -125,6 +134,9 @@ CREATE TABLE IF NOT EXISTS messages_records ( - "emotionProfileKey" text NOT NULL REFERENCES messages_emotion_profiles(key), - "voiceProfileKey" text NOT NULL REFERENCES messages_tts_profiles(key), - "messageText" text NOT NULL, -+ "speaker" text NOT NULL DEFAULT '', -+ "trigger" text NOT NULL DEFAULT '', -+ "typewriterSpeed" numeric NOT NULL DEFAULT ${DEFAULT_TYPEWRITER_SPEED}, - "notes" text NOT NULL DEFAULT '', - "active" boolean NOT NULL DEFAULT true, - "createdAt" timestamptz NOT NULL DEFAULT now(), -@@ -160,6 +172,9 @@ CREATE TABLE IF NOT EXISTS messages_event_actions ( - ); - - ALTER TABLE messages_records ADD COLUMN IF NOT EXISTS "voiceProfileKey" text REFERENCES messages_tts_profiles(key); -+ALTER TABLE messages_records ADD COLUMN IF NOT EXISTS "speaker" text NOT NULL DEFAULT ''; -+ALTER TABLE messages_records ADD COLUMN IF NOT EXISTS "trigger" text NOT NULL DEFAULT ''; -+ALTER TABLE messages_records ADD COLUMN IF NOT EXISTS "typewriterSpeed" numeric NOT NULL DEFAULT ${DEFAULT_TYPEWRITER_SPEED}; - ALTER TABLE messages_segments ADD COLUMN IF NOT EXISTS "voiceProfileKey" text REFERENCES messages_tts_profiles(key); - - CREATE INDEX IF NOT EXISTS idx_messages_records_categorykey ON messages_records ("categoryKey"); -@@ -301,7 +316,14 @@ function normalizeActorKey(actorKey) { - - function messagesWriteRequiresAuthenticatedActor(resource, method) { - return String(method || "GET").toUpperCase() === "POST" -- && ["emotion-profiles", "tts-profiles"].includes(resource); -+ && AUTHENTICATED_MESSAGES_WRITE_RESOURCES.includes(resource); -+} -+ -+function messagesWriteAuthenticationMessage(resource) { -+ if (["emotion-profiles", "tts-profiles"].includes(resource)) { -+ return "Sign in required to save Text To Speech profiles and emotions."; -+ } -+ return "Sign in required to save Messages through the API."; - } - - function activeFromDatabase(value) { -@@ -340,6 +362,9 @@ function messageRecordFromRow(row, { categoryName = "", emotionProfileName = "", - messageText: row.messageText, - name: row.name, - notes: row.notes || "", -+ speaker: row.speaker || "", -+ trigger: row.trigger || "", -+ typewriterSpeed: normalizeNumber(row.typewriterSpeed, DEFAULT_TYPEWRITER_SPEED), - updatedAt: row.updatedAt, - updatedBy: row.updatedBy, - voiceProfileKey: row.voiceProfileKey || "", -@@ -1413,6 +1438,13 @@ export class MessagesPostgresService { - const emotionProfileKey = normalizeText(input.emotionProfileKey === undefined && existing ? existing.emotionProfileKey : input.emotionProfileKey).trim(); - const voiceProfileKey = normalizeText(input.voiceProfileKey === undefined && existing ? existing.voiceProfileKey : input.voiceProfileKey).trim(); - const messageText = input.messageText === undefined && existing ? existing.messageText : normalizeText(input.messageText); -+ const speaker = input.speaker === undefined && existing ? existing.speaker : normalizeText(input.speaker); -+ const trigger = input.trigger === undefined && existing ? existing.trigger : normalizeText(input.trigger); -+ const typewriterSpeed = normalizeEditableNumber( -+ input.typewriterSpeed === undefined && existing ? existing.typewriterSpeed : input.typewriterSpeed, -+ DEFAULT_TYPEWRITER_SPEED, -+ "Typewriter speed", -+ ); - if (!emotionProfileKey) { - throw httpError("Emotion profile is required."); - } -@@ -1422,6 +1454,9 @@ export class MessagesPostgresService { - if (!messageText.trim()) { - throw httpError("Message text is required."); - } -+ if (typewriterSpeed < 0) { -+ throw httpError("Typewriter speed must be 0 or greater."); -+ } - await this.assertActiveCategory(categoryKey); - await this.assertActiveEmotionProfile(emotionProfileKey); - await this.assertActiveVoiceProfile(voiceProfileKey); -@@ -1433,6 +1468,9 @@ export class MessagesPostgresService { - messageText, - name, - notes: input.notes === undefined && existing ? existing.notes : normalizeText(input.notes), -+ speaker, -+ trigger, -+ typewriterSpeed, - voiceProfileKey, - }; - } -@@ -1453,6 +1491,9 @@ export class MessagesPostgresService { - messageText: values.messageText, - name: values.name, - notes: values.notes, -+ speaker: values.speaker, -+ trigger: values.trigger, -+ typewriterSpeed: values.typewriterSpeed, - updatedAt: now, - updatedBy: actor, - voiceProfileKey: values.voiceProfileKey, -@@ -1470,6 +1511,9 @@ export class MessagesPostgresService { - messageText: values.messageText, - name: values.name, - notes: values.notes, -+ speaker: values.speaker, -+ trigger: values.trigger, -+ typewriterSpeed: values.typewriterSpeed, - updatedAt: timestamp(), - updatedBy: normalizeActorKey(actorKey), - voiceProfileKey: values.voiceProfileKey, -@@ -1815,6 +1859,17 @@ export class MessagesPostgresService { - targetType: "message", - }); - } -+ const typewriterSpeed = Number(message.typewriterSpeed); -+ if (!Number.isFinite(typewriterSpeed) || typewriterSpeed < 0) { -+ addIssue({ -+ code: "invalid-typewriter-speed", -+ field: "typewriterSpeed", -+ message: "Use a Typewriter Speed of 0 or greater before publishing.", -+ targetKey: message.key, -+ targetName, -+ targetType: "message", -+ }); -+ } - const validEmotion = validateEmotionReference(message, "message", targetName); - const validVoice = validateVoiceReference(message, "message", targetName); - if (validEmotion && validVoice) { -@@ -1931,7 +1986,7 @@ export async function handleMessagesApiContract({ - const key = parts[1] || ""; - const action = parts[2] || ""; - if (messagesWriteRequiresAuthenticatedActor(resource, normalizedMethod) && !normalizeText(actorKey).trim()) { -- throw httpError("Sign in required to save Text To Speech profiles and emotions.", 401); -+ throw httpError(messagesWriteAuthenticationMessage(resource), 401); - } - - if (resource === "publish-validation" && normalizedMethod === "GET" && !key) { -diff --git a/toolbox/messages/index.html b/toolbox/messages/index.html -index 252654778..c5c67802c 100644 ---- a/toolbox/messages/index.html -+++ b/toolbox/messages/index.html -@@ -70,13 +70,17 @@ - - - Message -+ Speaker -+ Text -+ Trigger -+ Typewriter Speed - TTS Profile - Updated - Actions - - - -- Loading message rows. -+ Loading message rows. - - - -@@ -96,8 +100,11 @@ - Selected Message -
-

Name: None

-+

Speaker: None

-

Emotion: None

-

Sentence: None

-+

Trigger: None

-+

Typewriter Speed: None

-

Status: None

-

Text:

-
No message selected.
-diff --git a/toolbox/messages/messages.js b/toolbox/messages/messages.js -index 8029abc2f..d4c6cd532 100644 ---- a/toolbox/messages/messages.js -+++ b/toolbox/messages/messages.js -@@ -11,9 +11,12 @@ import { - updateMessageSegment, - validatePublishConfiguration, - } from "./messages-api-client.js"; -+import { getSessionCurrent } from "../../src/api/session-api-client.js"; - - const NEW_ROW_KEY = "__new__"; --const MESSAGE_TABLE_COLSPAN = 4; -+const MESSAGE_TABLE_COLSPAN = 8; -+const SIGN_IN_ROUTE = "account/sign-in.html"; -+const TYPEWRITER_SPEED_DEFAULT = 30; - const TTS_PROVIDER_REGISTRY = Object.freeze({ - "azure": Object.freeze({ activeRuntime: false, label: "Azure", requiresConfig: true }), - "browser-speech": Object.freeze({ activeRuntime: true, label: "Browser Speech API", requiresConfig: false }), -@@ -35,9 +38,12 @@ const elements = { - referencedCount: document.querySelector("[data-messages-referenced-count]"), - selectedEmotion: document.querySelector("[data-messages-selected-emotion]"), - selectedName: document.querySelector("[data-messages-selected-name]"), -+ selectedSpeaker: document.querySelector("[data-messages-selected-speaker]"), - selectedSegment: document.querySelector("[data-messages-selected-segment]"), - selectedStatus: document.querySelector("[data-messages-selected-status]"), - selectedText: document.querySelector("[data-messages-selected-text]"), -+ selectedTrigger: document.querySelector("[data-messages-selected-trigger]"), -+ selectedTypewriterSpeed: document.querySelector("[data-messages-selected-typewriter-speed]"), - segmentCount: document.querySelector("[data-messages-segment-count]"), - speechStatus: document.querySelector("[data-messages-speech-status]"), - stopSpeech: document.querySelector("[data-messages-stop-speech]"), -@@ -190,6 +196,43 @@ function showCreatorSafeFailure(message) { - setText(elements.log, safeMessage); - } - -+function signInUrl() { -+ if (typeof document === "undefined" || typeof window === "undefined") { -+ return SIGN_IN_ROUTE; -+ } -+ return new URL(SIGN_IN_ROUTE, document.baseURI || window.location.href).href; -+} -+ -+function currentSessionState() { -+ try { -+ const session = getSessionCurrent(); -+ return { -+ apiAvailable: true, -+ authenticated: Boolean(session?.authenticated && session.userKey), -+ }; -+ } catch (error) { -+ console.warn("Message Studio could not verify the current session.", error instanceof Error ? error.message : String(error || "")); -+ return { -+ apiAvailable: false, -+ authenticated: false, -+ }; -+ } -+} -+ -+function requireAuthenticatedWrite(action) { -+ const sessionState = currentSessionState(); -+ if (!sessionState.apiAvailable) { -+ showCreatorSafeFailure("Session status could not be verified. Try again shortly."); -+ return false; -+ } -+ if (!sessionState.authenticated) { -+ setText(elements.log, `Sign in before ${action}.`); -+ window.location.href = signInUrl(); -+ return false; -+ } -+ return true; -+} -+ - function activeVoiceProfiles() { - return state.voiceProfiles.filter((profile) => profile.active); - } -@@ -278,6 +321,11 @@ function tagsForMessage(message) { - return message?.categoryName || "No tags"; - } - -+function formatTypewriterSpeed(value) { -+ const speed = Number(value); -+ return Number.isFinite(speed) ? `${speed} cps` : `${TYPEWRITER_SPEED_DEFAULT} cps`; -+} -+ - function formatUpdated(value) { - const date = new Date(value || ""); - if (Number.isNaN(date.getTime())) { -@@ -308,9 +356,12 @@ function renderSelectedMessage() { - const selected = selectedMessage(); - const segment = selectedSegment(); - setText(elements.selectedName, selected?.name || "None"); -+ setText(elements.selectedSpeaker, selected?.speaker || "None"); - setText(elements.selectedEmotion, segment?.emotionProfileName || selected?.emotionProfileName || "None"); - setText(elements.selectedSegment, segment ? `Sentence ${segment.displayOrder}` : selected ? `${messageReferenceCount(selected.key)} sentence${messageReferenceCount(selected.key) === 1 ? "" : "s"}` : "None"); - setText(elements.selectedStatus, selected ? `${selected.active === false ? "Archived" : "Active"} / ${isMessageReferenced(selected.key) ? "Referenced" : "Unreferenced"}` : "None"); -+ setText(elements.selectedTrigger, selected?.trigger || "None"); -+ setText(elements.selectedTypewriterSpeed, selected ? formatTypewriterSpeed(selected.typewriterSpeed) : "None"); - setText(elements.selectedText, segment?.segmentText || selected?.messageText || "No message selected."); - } - -@@ -652,6 +703,23 @@ function createMessageEditRow(message = null) { - const messageCell = document.createElement("td"); - messageCell.append(createInput(message?.name || "", "messageName", "Message")); - -+ const speakerCell = document.createElement("td"); -+ speakerCell.append(createInput(message?.speaker || "", "messageSpeaker", "Speaker")); -+ -+ const textCell = document.createElement("td"); -+ textCell.append(createTextarea(message?.messageText || "", "messageText", "Message text")); -+ -+ const triggerCell = document.createElement("td"); -+ triggerCell.append(createInput(message?.trigger || "", "messageTrigger", "Trigger")); -+ -+ const typewriterSpeedCell = document.createElement("td"); -+ typewriterSpeedCell.append(createNumberInput( -+ message?.typewriterSpeed ?? TYPEWRITER_SPEED_DEFAULT, -+ "messageTypewriterSpeed", -+ "Typewriter speed", -+ { min: 0, step: 1 }, -+ )); -+ - const profileCell = document.createElement("td"); - profileCell.append(createSelect( - message?.voiceProfileKey || "", -@@ -669,6 +737,10 @@ function createMessageEditRow(message = null) { - - row.append( - messageCell, -+ speakerCell, -+ textCell, -+ triggerCell, -+ typewriterSpeedCell, - profileCell, - createCell(message ? formatUpdated(message.updatedAt) : "New"), - actions, -@@ -838,6 +910,10 @@ function createMessageRow(message) { - - row.append( - createRowHeader(message.active === false ? `${message.name} (Archived)` : message.name), -+ createCell(message.speaker || "No speaker"), -+ createCell(message.messageText || "No text"), -+ createCell(message.trigger || "No trigger"), -+ createCell(formatTypewriterSpeed(message.typewriterSpeed)), - createCell(message.voiceProfileName || "No TTS profile"), - createCell(formatUpdated(message.updatedAt)), - actions, -@@ -887,14 +963,21 @@ function messageValues(key) { - const root = elements.table?.querySelector(`[data-messages-row-editor="${key}"]`); - const existing = state.messages.find((message) => message.key === key) || null; - const name = editorValue(root, "[data-message-name]"); -+ const messageText = editorValue(root, "[data-message-text]"); -+ const speaker = editorValue(root, "[data-message-speaker]"); -+ const trigger = editorValue(root, "[data-message-trigger]"); -+ const typewriterSpeed = editorValue(root, "[data-message-typewriter-speed]"); - const voiceProfileKey = editorValue(root, "[data-message-tts-profile]"); - const emotionProfileKey = profileEmotionKeyOrDefault(voiceProfileKey, existing?.emotionProfileKey || ""); - return { - active: existing ? existing.active : true, - emotionProfileKey, -- messageText: existing?.messageText || name, -+ messageText, - name, - notes: existing?.notes || "", -+ speaker, -+ trigger, -+ typewriterSpeed, - voiceProfileKey, - }; - } -@@ -904,6 +987,13 @@ function validateMessage(values) { - if (!values.name.trim()) { - errors.push("Message is required."); - } -+ if (!values.messageText.trim()) { -+ errors.push("Message text is required."); -+ } -+ const typewriterSpeed = Number(values.typewriterSpeed); -+ if (!Number.isFinite(typewriterSpeed) || typewriterSpeed < 0) { -+ errors.push("Typewriter speed must be 0 or greater."); -+ } - if (!values.voiceProfileKey) { - errors.push("TTS Profile is required."); - } -@@ -995,6 +1085,9 @@ async function reloadAfterChange(messageKey = state.selectedMessageKey) { - } - - async function commitMessage(key) { -+ if (!requireAuthenticatedWrite("saving Messages")) { -+ return; -+ } - const values = messageValues(key); - const errors = validateMessage(values); - if (errors.length) { -@@ -1004,9 +1097,13 @@ async function commitMessage(key) { - } - clearValidation(); - try { -+ const payload = { -+ ...values, -+ typewriterSpeed: Number(values.typewriterSpeed), -+ }; - const result = key === NEW_ROW_KEY -- ? createMessage(values) -- : updateMessage(key, values); -+ ? createMessage(payload) -+ : updateMessage(key, payload); - state.editingMessageKey = ""; - await reloadAfterChange(result.message.key); - setText(elements.log, `Saved message ${result.message.name}.`); -@@ -1016,6 +1113,9 @@ async function commitMessage(key) { - } - - async function deleteMessageRecord(key) { -+ if (!requireAuthenticatedWrite("deleting Messages")) { -+ return; -+ } - const message = state.messages.find((candidate) => candidate.key === key); - if (!message) { - return; -@@ -1042,6 +1142,9 @@ async function deleteMessageRecord(key) { - } - - async function archiveMessageRecord(key) { -+ if (!requireAuthenticatedWrite("updating Messages")) { -+ return; -+ } - const message = state.messages.find((candidate) => candidate.key === key); - if (!message) { - return; -@@ -1057,6 +1160,9 @@ async function archiveMessageRecord(key) { - } - - async function commitSegment(key) { -+ if (!requireAuthenticatedWrite("saving Message sentences")) { -+ return; -+ } - const values = segmentValues(key); - const errors = validateSegment(values); - if (errors.length) { -@@ -1085,6 +1191,9 @@ async function commitSegment(key) { - } - - async function deleteSegmentRecord(key) { -+ if (!requireAuthenticatedWrite("deleting Message sentences")) { -+ return; -+ } - const segment = state.segments.find((candidate) => candidate.key === key); - if (!segment) { - return; -@@ -1103,6 +1212,9 @@ async function deleteSegmentRecord(key) { - } - - async function archiveSegmentRecord(key) { -+ if (!requireAuthenticatedWrite("updating Message sentences")) { -+ return; -+ } - const segment = state.segments.find((candidate) => candidate.key === key); - if (!segment) { - return; +index bc37b31a4..266edf984 100644 +--- a/dev/reports/codex_changed_files.txt ++++ b/dev/reports/codex_changed_files.txt +@@ -1,10 +1,37 @@ +-dev/build/database/ddl/messages.sql +-dev/reports/PR_26180_BRAVO_002-complete-messages-creator-tool.md +-dev/reports/codex_changed_files.txt +-dev/reports/codex_review.diff +-dev/tests/dev-runtime/MessagesPublishValidation.test.mjs +-dev/tests/helpers/playwrightRepoServer.mjs +-dev/tests/playwright/tools/MessagesTool.spec.mjs +-src/dev-runtime/messages/messages-postgres-service.mjs +-toolbox/messages/index.html +-toolbox/messages/messages.js ++# git diff --name-status merge-base(origin/main, HEAD)..working-tree ++M dev/build/ProjectInstructions/PROJECT_INSTRUCTIONS.md ++M dev/build/ProjectInstructions/PROJECT_INSTRUCTIONS_VERSION.md ++M dev/build/ProjectInstructions/TEAM_START_COMMANDS.md ++M dev/build/ProjectInstructions/addendums/team_backlog_sod_eod_standard.md ++M dev/build/ProjectInstructions/addendums/team_start_and_release.md ++M dev/build/ProjectInstructions/backlog/BACKLOG_MASTER.md ++M dev/build/ProjectInstructions/bootstrap/codex_start_of_day_bootstrap.md ++M dev/build/ProjectInstructions/standards/CODEX_WORKFLOW_COMMANDS.md ++A dev/reports/PR_26180_OWNER_003-backlog-startup-assignment-policy_branch-validation.md ++A dev/reports/PR_26180_OWNER_003-backlog-startup-assignment-policy_manual-validation-notes.md ++A dev/reports/PR_26180_OWNER_003-backlog-startup-assignment-policy_report.md ++A dev/reports/PR_26180_OWNER_003-backlog-startup-assignment-policy_requirement-checklist.md ++A dev/reports/PR_26180_OWNER_003-backlog-startup-assignment-policy_validation-report.md ++M dev/reports/codex_changed_files.txt ++M dev/reports/codex_review.diff ++ ++# git diff --stat merge-base(origin/main, HEAD)..working-tree ++.../ProjectInstructions/PROJECT_INSTRUCTIONS.md | 4 +- ++ .../PROJECT_INSTRUCTIONS_VERSION.md | 3 +- ++ .../ProjectInstructions/TEAM_START_COMMANDS.md | 17 + ++ .../addendums/team_backlog_sod_eod_standard.md | 69 + ++ .../addendums/team_start_and_release.md | 28 +- ++ .../ProjectInstructions/backlog/BACKLOG_MASTER.md | 39 +- ++ .../bootstrap/codex_start_of_day_bootstrap.md | 27 + ++ .../standards/CODEX_WORKFLOW_COMMANDS.md | 9 + ++ ...-startup-assignment-policy_branch-validation.md | 13 + ++ ...up-assignment-policy_manual-validation-notes.md | 13 + ++ ...003-backlog-startup-assignment-policy_report.md | 104 ++ ++ ...rtup-assignment-policy_requirement-checklist.md | 29 + ++ ...-startup-assignment-policy_validation-report.md | 39 + ++ dev/reports/codex_changed_files.txt | 47 +- ++ dev/reports/codex_review.diff | 1553 +++++++++----------- ++ 15 files changed, 1101 insertions(+), 893 deletions(-) ++ ++# merge-base ++8c332fc82aeeed6508170363f04e04beaf67db28