53 KiB
Codex Game Studio Functionality Gap Pass Implementation Plan
For Hermes: Do not implement this plan until Merlin explicitly approves it. When approved, use subagent-driven-development skill to implement this plan task-by-task. Do not rewrite git history, push commits, or rename the package/repo unless Merlin explicitly asks.
Goal: Fill the five major functionality gaps versus the Claude Game Studio baseline while preserving the Codex-native architecture: role roster parity, project-specific role materialization, market/analytics workflows, studio orchestration, and richer studio workflow depth.
Architecture: Keep .codex/studio.json authoritative and AGENTS.md as the primary Codex instruction surface. Add richer Codex-native role packages and workflow specs rather than restoring legacy .gamestudio state, legacy agent aliases, or project_orchestrator.md. Keep the implementation file-backed, deterministic, package-friendly, and test-driven; telemetry, planner/next, hard ownership enforcement, and parallel orchestration remain future-only unless explicitly introduced by a later plan.
Tech Stack: TypeScript, NodeNext ESM, npm CLI package, Vitest, Codex CLI, file-backed JSON/Markdown project state.
Scope
This pass addresses the first five functionality gaps identified in the Claude Game Studio comparison:
- Agent roster parity: add missing specialized studio functions in Codex-native form.
- Project-specific agent materialization: generate project-aware role prompt files, not just generic prompt stubs.
- Market/analytics workflows: make market and analytics first-class renderable workflow prompts and role-owned inspection loops, not just templates selected by producer tasks. Workflow shortcut commands remain render-only in this pass; executable workflow lifecycle support is explicitly deferred.
- Studio orchestration: add a Codex-native orchestration role/workflow without restoring legacy
project_orchestrator.md. - Workflow depth: expand workflow files and CLI surfaces from thin prompt renderers into practical studio operating loops.
Non-Goals
- Do not restore legacy
.gamestudio/*state. - Do not make
project-config.jsonauthoritative again. - Do not add backwards-compatible legacy role aliases such as
producer_agentorqa_agent. - Do not generate
project_orchestrator.md. - Do not add interactive
menuorstartover. - Do not add database-backed task storage.
- Do not add parallel orchestration.
- Do not add
open-gamestudio next, telemetry, changed-file tracking, or hard output-ownership enforcement in this pass. - Do not eagerly generate full competitor reports during
init; full reports belong to the market workflow.
Design Decisions
Role IDs
Decision: use the expanded 16-role Codex-native superset and retain the existing narrative-designer role for compatibility and story/content coverage. This yields 17 total roles: the 16-role functionality-gap superset plus the retained current Codex-native narrative role.
Keep Codex-native role IDs, but expand coverage to preserve the upstream functional roles while avoiding a silent compatibility cut:
export const studioRoleIds = [
"studio-orchestrator",
"producer",
"market-analyst",
"data-scientist",
"creative-director",
"senior-game-designer",
"game-designer",
"narrative-designer",
"game-feel-designer",
"gameplay-programmer",
"engine-programmer",
"tools-programmer",
"senior-game-artist",
"technical-artist",
"ui-ux-designer",
"qa-playtester",
"release-manager"
] as const;
Rationale:
- This keeps existing Codex-native IDs where they already make sense.
- It adds explicit equivalents for upstream
master_orchestrator,market_analyst,data_scientist,game_feel_developer,sr_game_artist, andui_ux_agent. - It splits senior/implementation design coverage without restoring underscore legacy names.
- It retains the existing Codex-native
narrative-designerrole so current projects, tests, and story/content workflows do not lose a first-class owner. - It keeps existing
creative-director,engine-programmer,tools-programmer, andrelease-manageras Codex-native value-add roles.
Parity Crosswalk and Legacy Alias Cut
Decision: document functional parity as a role/function crosswalk, not as legacy role-ID compatibility. The implementation must reject representative legacy underscore aliases with clear guidance instead of silently accepting them.
| Upstream / baseline function | Codex-native owner(s) | Compatibility decision |
|---|---|---|
master_orchestrator / studio routing |
studio-orchestrator |
No master_orchestrator or project_orchestrator.md; use handoff workflow. |
producer_agent / production planning |
producer, studio-orchestrator |
No producer_agent alias; use producer. |
| market research / competitor analysis | market-analyst |
First-class renderable market-analysis workflow and market shortcut. |
| analytics / metrics / experiments | data-scientist |
First-class renderable analytics-setup workflow and analytics shortcut. |
| creative direction | creative-director |
Keep Codex-native hyphenated ID. |
| senior systems / economy / progression design | senior-game-designer |
New explicit senior design owner. |
| feature / acceptance design | game-designer |
Keep as implementation-level design owner. |
| story / world / content | narrative-designer |
Retained Codex-native compatibility role. |
| game feel / controls / juice | game-feel-designer |
New explicit feel owner. |
| gameplay implementation | gameplay-programmer |
Keep Codex-native hyphenated ID. |
| engine/platform implementation | engine-programmer |
Keep Codex-native value-add role. |
| internal tools/editor automation | tools-programmer |
Keep Codex-native value-add role. |
| senior art direction / asset quality bar | senior-game-artist |
New explicit senior art owner. |
| technical art / pipeline constraints | technical-artist |
Keep Codex-native value-add role. |
| UI/UX / onboarding / accessibility | ui-ux-designer |
New explicit UI/UX owner. |
qa_agent / playtest / QA review |
qa-playtester |
No qa_agent alias; use qa-playtester. |
| release / ship readiness | release-manager |
Keep Codex-native value-add role. |
Acceptance tests must verify the Codex-native role IDs exist and representative legacy aliases such as producer_agent, qa_agent, and master_orchestrator are not treated as valid StudioRoleId values.
Active Roles by Mode
Use functional parity with the upstream mode intent, adapted to Codex-native IDs:
always:
studio-orchestrator
producer
market-analyst
data-scientist
design:
creative-director
senior-game-designer
game-designer
narrative-designer
senior-game-artist
ui-ux-designer
prototype:
senior-game-designer
game-designer
game-feel-designer
gameplay-programmer
qa-playtester
development:
senior-game-designer
game-designer
game-feel-designer
gameplay-programmer
engine-programmer
tools-programmer
qa-playtester
senior-game-artist
technical-artist
ui-ux-designer
release-manager
Authoritative Studio State Contract
Decision: .codex/studio.json must distinguish the full available roster from mode-active roles. Keep roles as the full expanded role roster for discoverability, add an explicit activeRoles field for activeAgentsForMode(mode), and populate workflows from Object.keys(workflowRegistry) after the canonical registry exists.
Use this generated state contract or an equivalent typed shape:
export type StudioProjectState = {
// existing fields omitted
roles: StudioRoleId[]; // full available Codex-native roster
activeRoles: StudioRoleId[]; // mode-active roles from activeAgentsForMode(mode)
workflows: WorkflowId[]; // generated from workflowRegistry keys
};
statusProject should print activeRoles as active roles, not the full roster. Project validation must assert roles equals studioRoleIds, activeRoles equals activeAgentsForMode(studio.mode), and workflows equals the canonical workflow registry keys.
Project Prompt Materialization
Generated projects should contain project-aware prompt files:
projects/<slug>/
AGENTS.md
.codex/
studio.json
prompts/
studio-orchestrator.md
producer.md
market-analyst.md
data-scientist.md
creative-director.md
senior-game-designer.md
game-designer.md
narrative-designer.md
game-feel-designer.md
gameplay-programmer.md
engine-programmer.md
tools-programmer.md
senior-game-artist.md
technical-artist.md
ui-ux-designer.md
qa-playtester.md
release-manager.md
workflows/
vertical-slice.md
bugfix.md
playtest.md
market-analysis.md
analytics-setup.md
design-spec.md
game-feel-tuning.md
art-direction.md
ui-ux-review.md
production-milestone.md
handoff.md
review.md
ship-check.md
Only src/agents.ts owns generated project AGENTS.md. Project-specific prompt body generation may live in src/agents.ts or a new helper imported by it; do not put AGENTS.md body text in src/projects.ts.
Template Delivery for Workflow Prompts
Decision: keep package templates as the source of truth and inline only the selected template bodies into rendered workflow prompts. Do not rely on project-relative templates/... paths unless a future customization feature deliberately materializes project-local template overrides.
Use this contract:
- Project context files remain project-relative and listed as context files, for example
AGENTS.md,.codex/studio.json,.codex/workflows/<workflow>.md,documentation/design/gdd.md, andresources/market-research/market-overview.md. - Workflow templates are package assets selected by deterministic template IDs such as
market_analysis,analytics_setup,feature_spec, andhandoff. renderWorkflowPromptmust append a## Workflow Templatessection containing only the selected template IDs and bodies.- Each inlined template section must include both the template ID and package source path, for example:
## Workflow Templates
### Template: market_analysis
Source: package:templates/market_analysis_template.md
<template body>
Rationale:
- Generated projects do not need a copied
templates/directory, avoiding stale generated assets after package upgrades. - Codex receives the actual bounded template content, not a broken path string.
- Tests can assert exact template inclusion/exclusion without depending on global or installed-package filesystem layout.
- Package smoke still verifies templates are shipped via
npm pack --dry-run.
Workflow Phase Contract
Decision: workflow registry phases must use the existing Codex session phase vocabulary. Use "implement" for code-changing/build-style work instead of introducing a new "build" phase in this pass. Do not add "build" unless a later plan updates CodexStudioPhase, validation, defaults, prompt tests, and workflow tests together.
Canonical Workflow Registry
Decision: create one exported workflow registry as the source of truth for workflow identity, role routing, generated workflow file, prompt context files, selected template IDs, and optional user-facing CLI alias. Project generation, prompt rendering, validation, docs, and tests must consume this registry instead of maintaining parallel hand-written workflow lists.
Use this shape or an equivalent typed object in src/workflows.ts:
export type WorkflowDefinition = {
id: WorkflowId;
role: StudioRoleId;
phase: "plan" | "implement" | "review" | "ship";
objective: string;
file: `.codex/workflows/${string}.md`;
contextFiles: string[];
templateIds?: TemplateId[];
cliAlias?: string;
};
Workflow identity decisions:
reviewis a distinct workflow with its own.codex/workflows/review.md; it is not an alias forplaytest.bugfix,playtest,review,ship-check, andvertical-sliceremain renderable workflow IDs, but they do not receive new top-level shortcut commands in this pass unless already exposed by the current CLI.- User-facing shortcut commands are limited to practical studio loops:
market,analytics,design-spec,feel-review,art-direction,ui-review,milestone, andhandoff.
Workflow CLI Surface
Decision: shortcut workflow commands are prompt-rendering helpers in this pass. They render the selected workflow prompt for inspection and do not launch Codex. Actual Codex execution remains through open-gamestudio run <role>; lifecycle workflow execution can be added by a later plan.
Add explicit workflow commands where they materially improve usability:
open-gamestudio market --project projects/my-game --dry-run
open-gamestudio analytics --project projects/my-game --dry-run
open-gamestudio design-spec --project projects/my-game --dry-run
open-gamestudio feel-review --project projects/my-game --dry-run
open-gamestudio art-direction --project projects/my-game --dry-run
open-gamestudio ui-review --project projects/my-game --dry-run
open-gamestudio milestone --project projects/my-game --dry-run
open-gamestudio handoff --project projects/my-game --dry-run
For this pass, these commands only render workflow prompts for inspection; they do not launch Codex. Keep actual Codex execution on the existing open-gamestudio run <role> path. They must not introduce a planner, telemetry, ownership enforcement, or parallel orchestration.
Phase 0: Baseline Audit and Guardrails
Task 1: Add a parity-gap test scaffold
Objective: Create focused tests that encode the five gap areas before changing implementation.
Files:
- Create:
tests/functionality-gap-pass.test.ts - Modify later:
src/roles.ts,src/config.ts,src/agents.ts,src/projects.ts,src/workflows.ts,src/cli.ts,src/validation.ts
Step 1: Write failing tests for role roster coverage
Create tests/functionality-gap-pass.test.ts with imports that compile against current modules:
import { describe, expect, it } from "vitest";
import { studioRoleIds, rolePackages } from "../src/roles.js";
import { activeAgentsForMode } from "../src/config.js";
const requiredRoles = [
"studio-orchestrator",
"producer",
"market-analyst",
"data-scientist",
"creative-director",
"senior-game-designer",
"game-designer",
"narrative-designer",
"game-feel-designer",
"gameplay-programmer",
"engine-programmer",
"tools-programmer",
"senior-game-artist",
"technical-artist",
"ui-ux-designer",
"qa-playtester",
"release-manager"
] as const;
describe("functionality gap pass", () => {
it("exposes Codex-native roles for the full studio function set", () => {
expect(studioRoleIds).toEqual(requiredRoles);
for (const role of requiredRoles) {
expect(rolePackages[role].systemPrompt.length).toBeGreaterThan(80);
expect(rolePackages[role].expectedOutputs.length).toBeGreaterThanOrEqual(2);
expect(rolePackages[role].reviewChecklist.length).toBeGreaterThanOrEqual(2);
}
});
it("selects market, analytics, and orchestration roles in every project mode", () => {
for (const mode of ["design", "prototype", "development"] as const) {
expect(activeAgentsForMode(mode)).toEqual(expect.arrayContaining([
"studio-orchestrator",
"producer",
"market-analyst",
"data-scientist"
]));
}
});
});
Step 2: Run the test to verify failure
Run:
npm test -- tests/functionality-gap-pass.test.ts
Expected: FAIL because studio-orchestrator, market-analyst, data-scientist, senior-game-designer, game-feel-designer, senior-game-artist, and ui-ux-designer do not exist yet.
Step 3: Do not implement yet
Leave the test failing until Phase 1.
Phase 1: Agent Roster Parity
Task 2: Expand StudioRoleId and role packages
Objective: Add the missing Codex-native role packages with concrete prompts and review checklists while retaining the existing narrative-designer role.
Files:
- Modify:
src/roles.ts - Test:
tests/functionality-gap-pass.test.ts - Test:
tests/roles.test.ts
Step 1: Update studioRoleIds
Replace the current studioRoleIds list in src/roles.ts with the role list from the Design Decisions section.
Step 2: Replace rolePackages with complete package entries
Each package must have:
iddisplayNamesystemPromptof at least one substantial sentencecontextStrategy- at least two
expectedOutputs handoffTemplate- at least two
reviewChecklistitems
Use this behavior mapping:
"studio-orchestrator": "Route work between roles, maintain handoffs, protect scope, and identify the next bounded studio action without running hidden parallel work.",
"market-analyst": "Analyze audience, competitors, positioning, pricing, and market risks using project constraints and explicit assumptions.",
"data-scientist": "Define analytics events, success metrics, experiment plans, and evidence loops for design and production decisions.",
"senior-game-designer": "Own high-level systems, progression, economy, and design cohesion across feature slices.",
"narrative-designer": "Shape story, tone, world rules, character/content needs, and narrative consistency while respecting production constraints.",
"game-feel-designer": "Tune controls, feedback, pacing, animation timing, juice, and moment-to-moment player feel.",
"senior-game-artist": "Define art direction, asset style, visual constraints, production quality bars, and asset review notes.",
"ui-ux-designer": "Design interface flows, usability heuristics, HUD layout, onboarding, accessibility, and menu interactions."
Do not keep the old generic game-designer package as the only design role. Keep it as a mid/implementation designer focused on feature specs and acceptance criteria.
Step 3: Run focused tests
Run:
npm test -- tests/functionality-gap-pass.test.ts tests/roles.test.ts
Expected: role coverage tests pass or reveal tests that need legitimate updates for the expanded role set.
Task 3: Update active role selection by mode
Objective: Make generated projects include orchestration, market, and analytics roles by default while preserving mode-specific role intent.
Files:
- Modify:
src/config.ts - Test:
tests/functionality-gap-pass.test.ts - Test:
tests/project-workflow.test.ts
Step 1: Update activeAgentsForMode
Implement the active-role mapping from the Design Decisions section.
Step 2: Add assertions for mode-specific roles
Extend tests/functionality-gap-pass.test.ts:
it("selects mode-specific specialized roles", () => {
expect(activeAgentsForMode("design")).toEqual(expect.arrayContaining([
"creative-director",
"senior-game-designer",
"game-designer",
"narrative-designer",
"senior-game-artist",
"ui-ux-designer"
]));
expect(activeAgentsForMode("prototype")).toEqual(expect.arrayContaining([
"senior-game-designer",
"game-feel-designer",
"gameplay-programmer",
"qa-playtester"
]));
expect(activeAgentsForMode("development")).toEqual(expect.arrayContaining([
"game-feel-designer",
"engine-programmer",
"tools-programmer",
"technical-artist",
"ui-ux-designer",
"release-manager"
]));
});
Step 3: Run focused tests
Run:
npm test -- tests/functionality-gap-pass.test.ts tests/project-workflow.test.ts
Expected: PASS after project workflow expected role lists are updated.
Phase 2: Project-Specific Agent Materialization
Task 4: Add a project prompt rendering helper
Objective: Generate project-aware .codex/prompts/<role>.md files with project, engine, milestone, role, outputs, and handoff content.
Files:
- Modify:
src/agents.ts - Test:
tests/functionality-gap-pass.test.ts - Test:
tests/codex-context-files.test.ts
Step 1: Add tests for project-specific prompt content
Extend tests/functionality-gap-pass.test.ts with a temporary project init test. Use existing test fixture helpers if present; otherwise use mkdtempSync, tmpdir, and initProject directly.
Expected assertions:
expect(promptBody).toContain("Project: Test Studio Game");
expect(promptBody).toContain("Role: Market Analyst");
expect(promptBody).toContain("Engine:");
expect(promptBody).toContain("Current Milestone:");
expect(promptBody).toContain("Expected Outputs");
expect(promptBody).toContain("Handoff");
expect(promptBody).toContain("Competitors:");
Step 2: Implement renderProjectRolePrompt
Add a helper in src/agents.ts:
export function renderProjectRolePrompt(role: StudioRoleId, config: ProjectConfig, engines: EngineConfigRegistry): string {
const pkg = rolePackages[role];
const engine = engines[config.project.engine];
return [
`# ${pkg.displayName}`,
"",
`Project: ${config.project.name}`,
`Slug: ${config.project.slug}`,
`Role: ${pkg.displayName}`,
`Mode: ${config.project.mode}`,
`Engine: ${engine.display_name} ${config.project.engine_version}`,
`Current Milestone: ${config.project.mode === "design" ? "design" : config.project.mode === "development" ? "development" : "prototype"}`,
"",
"## Project Summary",
"",
config.project.concept,
"",
`Genre: ${config.project.genre}`,
`Platform: ${config.project.platform}`,
`Audience: ${config.project.audience}`,
`Monetization: ${config.project.monetization}`,
`Timeline: ${config.project.timeline}`,
`Competitors: ${config.project.competitors.join(", ") || "none configured"}`,
"",
"## Role Instructions",
"",
pkg.systemPrompt,
"",
"## Engine Context",
"",
...engine.codex_hints.map((hint) => `- ${hint}`),
"",
"## Expected Outputs",
"",
...pkg.expectedOutputs.map((item) => `- ${item}`),
"",
"## Review Checklist",
"",
...pkg.reviewChecklist.map((item) => `- ${item}`),
"",
"## Handoff",
"",
pkg.handoffTemplate,
""
].join("\n");
}
Adjust field names if engine config uses a different display name property. Preserve NodeNext .js imports.
Step 3: Update materialization
In materializeAgents, write all .codex/prompts/<role>.md files using renderProjectRolePrompt. Keep AGENTS.md generation in the same owner module.
Step 4: Remove duplicate generic prompt writer
src/projects.ts currently writes generic prompt files in writeCodexPromptAndWorkflowFiles. Move role-prompt writing out of that helper, or make it write workflows only. Avoid writing prompt files in two places.
Step 5: Run focused tests
Run:
npm test -- tests/functionality-gap-pass.test.ts tests/codex-context-files.test.ts tests/project-workflow.test.ts
Expected: PASS.
Task 5: Strengthen validation for project-specific prompts
Objective: Validation should reject prompt files that are generic stubs and require project-specific sections.
Files:
- Modify:
src/validation.ts - Test:
tests/validation.test.ts - Test:
tests/functionality-gap-pass.test.ts
Step 1: Add validation checks
In validateProject, for each role prompt require these sections/strings:
Project: <project name>Role:## Project Summary## Role Instructions## Expected Outputs## Handoff
Use the stable Task 13 validation ID scheme, for example:
codex.role.<role>.prompt.project-summary
codex.role.<role>.prompt.role-instructions
codex.role.<role>.prompt.handoff
Step 2: Add a failure fixture test
In tests/validation.test.ts, create a disposable generated project, overwrite one .codex/prompts/market-analyst.md with # Market Analyst\n, run validateProject, and assert at least one fail check for that prompt.
Step 3: Run validation tests
Run:
npm test -- tests/validation.test.ts tests/functionality-gap-pass.test.ts
Expected: PASS.
Phase 3: Market and Analytics as First-Class Renderable Workflows
Task 6: Add canonical workflow registry entries for market and analytics
Objective: Add market analysis and analytics setup to the canonical workflow registry while preserving renderable baseline workflows (vertical-slice, bugfix, playtest, distinct review, and ship-check), and immediately materialize/validate registry-backed workflow files before any shortcut CLI command is exposed.
Files:
- Modify:
src/workflows.ts - Modify:
src/projects.ts - Modify:
src/validation.ts - Modify:
src/templates.ts - Test:
tests/functionality-gap-pass.test.ts - Test:
tests/codex-prompts.test.ts - Test:
tests/project-workflow.test.ts - Test:
tests/validation.test.ts
Step 1: Update canonical workflow IDs
The canonical registry must expose these renderable workflow IDs at this point:
export type WorkflowId =
| "vertical-slice"
| "bugfix"
| "playtest"
| "market-analysis"
| "analytics-setup"
| "review"
| "ship-check";
review must point to .codex/workflows/review.md; do not map it to playtest.md.
Step 2: Add workflow registry entries
Map baseline and new entries in one registry. Existing vertical-slice behavior should be preserved; add explicit entries for bugfix, playtest, distinct review, ship-check, market-analysis, and analytics-setup if they do not already exist:
bugfix: {
role: "gameplay-programmer",
phase: "implement",
objective: "Investigate and fix a focused defect with reproduction steps, targeted changes, and verification notes."
},
playtest: {
role: "qa-playtester",
phase: "review",
objective: "Playtest the current build or slice, identify defects and friction, and recommend prioritized fixes."
},
review: {
role: "qa-playtester",
phase: "review",
objective: "Review project state, implementation quality, risks, and acceptance readiness as a distinct workflow from playtest."
},
"ship-check": {
role: "release-manager",
phase: "ship",
objective: "Check release readiness, risks, blockers, validation status, and ship/no-ship criteria."
},
"market-analysis": {
role: "market-analyst",
phase: "plan",
objective: "Create a competitor-aware market analysis with audience, positioning, monetization, risks, and recommended validation steps.",
templateIds: ["market_analysis"],
cliAlias: "market"
},
"analytics-setup": {
role: "data-scientist",
phase: "plan",
objective: "Define analytics events, success metrics, funnels, experiment questions, and implementation handoff notes.",
templateIds: ["analytics_setup"],
cliAlias: "analytics"
}
Update src/templates.ts role metadata so market_analysis is discoverable for market-analyst and analytics_setup is discoverable for data-scientist.
Step 3: Generate and validate registry workflow files
Before adding any CLI shortcut, update generated project materialization to write workflow files from the canonical registry for vertical-slice, bugfix, playtest, distinct review, ship-check, market-analysis, and analytics-setup. Also update .codex/studio.json.workflows to use the registry keys and update project validation to assert every workflowRegistry[id].file exists and every registry workflow renders.
Step 4: Include relevant package templates inline
Update renderWorkflowPrompt so:
market-analysisincludes a## Workflow Templatessection with template IDmarket_analysis, sourcepackage:templates/market_analysis_template.md, and the actualreadTemplate("market_analysis")body.analytics-setupincludes a## Workflow Templatessection with template IDanalytics_setup, sourcepackage:templates/analytics_setup_template.md, and the actualreadTemplate("analytics_setup")body.- Template paths are not added to
contextFiles; only project-local artifacts belong incontextFiles. - Neither workflow loads all templates.
Use the registry templateIds field rather than a separate hand-maintained map. The market and analytics registry entries should declare:
"market-analysis": { templateIds: ["market_analysis"], /* ... */ }
"analytics-setup": { templateIds: ["analytics_setup"], /* ... */ }
Step 5: Test rendering
Add assertions that rendered prompts include actual selected template content and exclude unrelated templates:
const marketPrompt = renderWorkflowPrompt(projectRoot, "market-analysis");
const analyticsPrompt = renderWorkflowPrompt(projectRoot, "analytics-setup");
expect(marketPrompt).toContain("Market Analyst");
expect(marketPrompt).toContain("## Workflow Templates");
expect(marketPrompt).toContain("Template: market_analysis");
expect(marketPrompt).toContain("Source: package:templates/market_analysis_template.md");
expect(marketPrompt).toContain(readTemplate("market_analysis").trim().slice(0, 80));
expect(marketPrompt).not.toContain("Template: analytics_setup");
expect(analyticsPrompt).toContain("Data Scientist");
expect(analyticsPrompt).toContain("Template: analytics_setup");
expect(analyticsPrompt).toContain("Source: package:templates/analytics_setup_template.md");
expect(analyticsPrompt).toContain(readTemplate("analytics_setup").trim().slice(0, 80));
expect(analyticsPrompt).not.toContain("Template: market_analysis");
const marketContextFilesSection = marketPrompt.split("## Context Files")[1].split("## Workflow Templates")[0];
const analyticsContextFilesSection = analyticsPrompt.split("## Context Files")[1].split("## Workflow Templates")[0];
expect(marketContextFilesSection).not.toContain("templates/market_analysis_template.md");
expect(analyticsContextFilesSection).not.toContain("templates/analytics_setup_template.md");
The Source: package:... checks deliberately prove package-asset provenance; the negative templates/... context checks inspect only the ## Context Files sections so they do not fail on the intended source labels.
Step 6: Run focused tests
Run:
npm test -- tests/functionality-gap-pass.test.ts tests/codex-prompts.test.ts tests/project-workflow.test.ts tests/validation.test.ts
Expected: PASS.
Task 7: Add CLI commands for market and analytics workflows
Objective: Make market and analytics workflows discoverable as prompt-rendering shortcut commands without requiring users to know role/task internals.
Files:
- Modify:
src/cli.ts - Test:
tests/functionality-gap-pass.test.tsusing the existing source-level CLI/help test style; reserve built CLI execution for Phase 7 package smoke. - Docs later:
README.md,docs/examples.md
Step 1: Add commands
Add commands:
open-gamestudio market --project <path> [--dry-run]
open-gamestudio analytics --project <path> [--dry-run]
Implementation must use the workflow registry cliAlias entries and call renderWorkflowPrompt(projectRoot, "market-analysis") / renderWorkflowPrompt(projectRoot, "analytics-setup"). These shortcut commands render prompts only; they must not launch Codex or create run/session state.
--dry-run is accepted as an explicit inspection flag for consistency with existing CLI patterns, but the command output remains a rendered prompt either way.
Step 2: Add help-surface and inspection-only tests
Assert CLI help contains market and analytics but still does not contain future-only next, telemetry, or parallel orchestration. Also prove the shortcuts are render-only: set the Codex command environment/config to a failing sentinel, execute each shortcut with and without --dry-run, assert the rendered workflow prompt is printed, and assert no new .codex/runs/* files are created.
Step 3: Run focused tests
Run:
npm test -- tests/functionality-gap-pass.test.ts
npm run typecheck
Expected: PASS.
Phase 4: Codex-Native Studio Orchestration
Task 8: Add a studio orchestration workflow
Objective: Provide orchestration/handoff behavior through Codex-native role prompts and workflow files without generating project_orchestrator.md.
Files:
- Modify:
src/workflows.ts - Modify:
src/projects.ts - Test:
tests/functionality-gap-pass.test.ts - Test:
tests/project-workflow.test.ts
Step 1: Add workflow IDs
Add:
| "handoff"
| "production-milestone"
Step 2: Add workflow config entries
Map:
handoff: {
role: "studio-orchestrator",
phase: "plan",
objective: "Summarize current state, route next work to the right role, identify blockers, and produce a concise handoff.",
templateIds: ["handoff"],
cliAlias: "handoff"
},
"production-milestone": {
role: "producer",
phase: "plan",
objective: "Convert current project state into milestone goals, task slices, risks, owners, and verification gates.",
cliAlias: "milestone"
}
Step 3: Generate workflow files
Update project workflow materialization so generated projects include:
.codex/workflows/handoff.md.codex/workflows/production-milestone.md
Each file must include:
- purpose
- inputs
- role routing guidance
- expected outputs
- validation / review checklist
Step 4: Add tests
Assert generated projects contain the new workflow files and do not contain project_orchestrator.md.
expect(existsSync(path.join(projectRoot, ".codex", "workflows", "handoff.md"))).toBe(true);
expect(existsSync(path.join(projectRoot, "project_orchestrator.md"))).toBe(false);
Step 5: Run focused tests
Run:
npm test -- tests/functionality-gap-pass.test.ts tests/project-workflow.test.ts
Expected: PASS.
Task 9: Add a handoff CLI command
Objective: Make orchestration visible as open-gamestudio handoff, not as a hidden or legacy orchestrator file.
Files:
- Modify:
src/cli.ts - Test:
tests/functionality-gap-pass.test.ts - Docs later:
README.md,docs/examples.md
Step 1: Add command
Add:
open-gamestudio handoff --project <path> [--dry-run]
It should render renderWorkflowPrompt(projectRoot, "handoff") through the registry cliAlias: "handoff" path. It must not launch Codex or create run/session state.
Step 2: Add assertions
Assert the handoff prompt contains:
Studio Orchestratorblockersnext roleor equivalent routing languagehandoff
Also prove handoff is render-only: set the Codex command environment/config to a failing sentinel, run with and without --dry-run, and assert no new .codex/runs/* files are created.
Step 3: Run focused tests
Run:
npm test -- tests/functionality-gap-pass.test.ts
Expected: PASS.
Phase 5: Richer Studio Workflow Depth
Task 10: Add design, art, UI, and milestone workflows
Objective: Expand beyond vertical-slice/bugfix/playtest into practical studio workflows that map to the expanded role roster.
Files:
- Modify:
src/workflows.ts - Modify:
src/projects.ts - Test:
tests/functionality-gap-pass.test.ts - Test:
tests/project-workflow.test.ts
Step 1: Add workflow IDs
Add:
| "design-spec"
| "game-feel-tuning"
| "art-direction"
| "ui-ux-review"
Step 2: Add workflow configs
Map:
"design-spec": {
role: "senior-game-designer",
phase: "plan",
objective: "Create or review a feature/design spec with rules, edge cases, implementation slices, and acceptance criteria.",
templateIds: ["feature_spec"],
cliAlias: "design-spec"
},
"game-feel-tuning": {
role: "game-feel-designer",
phase: "review",
objective: "Review moment-to-moment feel, controls, feedback, pacing, and tuning risks with actionable changes.",
cliAlias: "feel-review"
},
"art-direction": {
role: "senior-game-artist",
phase: "plan",
objective: "Define art direction, visual constraints, asset list, production risks, and review criteria.",
cliAlias: "art-direction"
},
"ui-ux-review": {
role: "ui-ux-designer",
phase: "review",
objective: "Review UI flows, HUD/menu clarity, usability, onboarding, accessibility, and interaction risks.",
cliAlias: "ui-review"
}
Step 3: Generate workflow files
Update workflow materialization from the canonical registry so generated projects include markdown files for each new workflow. Also ensure existing renderable registry entries materialize as files, including distinct .codex/workflows/review.md and .codex/workflows/ship-check.md. Each file must contain:
# <Workflow Name>
## Purpose
## Inputs
## Role
## Outputs
## Validation
Step 4: Add tests
Assert all workflow files exist and render through renderWorkflowPrompt, including a distinct review prompt that reads .codex/workflows/review.md rather than .codex/workflows/playtest.md.
Step 5: Run focused tests
Run:
npm test -- tests/functionality-gap-pass.test.ts tests/project-workflow.test.ts
Expected: PASS.
Task 11: Add CLI commands for the richer workflows
Objective: Expose selected user-facing workflows through simple prompt-rendering commands.
Files:
- Modify:
src/cli.ts - Test:
tests/functionality-gap-pass.test.ts - Docs later:
README.md,docs/examples.md
Step 1: Add commands
Add command mappings:
design-spec -> design-spec
feel-review -> game-feel-tuning
art-direction -> art-direction
ui-review -> ui-ux-review
milestone -> production-milestone
These aliases must come from the canonical workflow registry cliAlias field. Do not add shortcut commands for every WorkflowId; bugfix, playtest, review, ship-check, and vertical-slice remain renderable workflows without new top-level shortcuts in this pass unless the current CLI already exposes them.
Each command should require --project <path>, accept --dry-run as an explicit inspection flag, and render the workflow prompt without launching Codex.
Step 2: Add help/discovery and inspection-only tests
Assert help includes the new commands and still omits future-only surfaces:
- no
next - no telemetry command
- no parallel command
Also add one shared test over every workflowRegistry entry with a cliAlias: set Codex to a failing sentinel, execute the shortcut with and without --dry-run, assert prompt output, and assert no .codex/runs/* files are created.
Step 3: Run focused tests
Run:
npm test -- tests/functionality-gap-pass.test.ts
npm run typecheck
Expected: PASS.
Task 12: Improve workflow prompt context and package-template selection
Objective: Ensure each workflow includes the right project artifacts and selected package-template bodies without loading everything or emitting broken project-relative template paths.
Files:
- Modify:
src/workflows.ts - Test:
tests/functionality-gap-pass.test.ts - Test:
tests/codex-prompts.test.ts
Step 1: Add registry context and template fields
Use the canonical workflow registry for both project-local context files and package-template IDs. Do not put templates/... paths in context files.
import { readTemplate, templateRegistry, type TemplateId } from "./templates.js";
export const workflowRegistry = {
"vertical-slice": {
file: ".codex/workflows/vertical-slice.md",
contextFiles: ["AGENTS.md", ".codex/studio.json", ".codex/workflows/vertical-slice.md", "documentation/design/gdd.md"]
},
bugfix: {
file: ".codex/workflows/bugfix.md",
contextFiles: ["AGENTS.md", ".codex/studio.json", ".codex/workflows/bugfix.md"]
},
playtest: {
file: ".codex/workflows/playtest.md",
contextFiles: ["AGENTS.md", ".codex/studio.json", ".codex/workflows/playtest.md"]
},
review: {
file: ".codex/workflows/review.md",
contextFiles: ["AGENTS.md", ".codex/studio.json", ".codex/workflows/review.md"]
},
"market-analysis": {
file: ".codex/workflows/market-analysis.md",
contextFiles: ["AGENTS.md", ".codex/studio.json", ".codex/workflows/market-analysis.md", "resources/market-research/market-overview.md"],
templateIds: ["market_analysis"]
},
"analytics-setup": {
file: ".codex/workflows/analytics-setup.md",
contextFiles: ["AGENTS.md", ".codex/studio.json", ".codex/workflows/analytics-setup.md"],
templateIds: ["analytics_setup"]
},
"design-spec": {
file: ".codex/workflows/design-spec.md",
contextFiles: ["AGENTS.md", ".codex/studio.json", ".codex/workflows/design-spec.md", "documentation/design/gdd.md"],
templateIds: ["feature_spec"]
},
"game-feel-tuning": {
file: ".codex/workflows/game-feel-tuning.md",
contextFiles: ["AGENTS.md", ".codex/studio.json", ".codex/workflows/game-feel-tuning.md"]
},
"art-direction": {
file: ".codex/workflows/art-direction.md",
contextFiles: ["AGENTS.md", ".codex/studio.json", ".codex/workflows/art-direction.md"]
},
"ui-ux-review": {
file: ".codex/workflows/ui-ux-review.md",
contextFiles: ["AGENTS.md", ".codex/studio.json", ".codex/workflows/ui-ux-review.md"]
},
"production-milestone": {
file: ".codex/workflows/production-milestone.md",
contextFiles: ["AGENTS.md", ".codex/studio.json", ".codex/workflows/production-milestone.md", "documentation/production/timeline.md"]
},
handoff: {
file: ".codex/workflows/handoff.md",
contextFiles: ["AGENTS.md", ".codex/studio.json", ".codex/workflows/handoff.md"],
templateIds: ["handoff"]
},
"ship-check": {
file: ".codex/workflows/ship-check.md",
contextFiles: ["AGENTS.md", ".codex/studio.json", ".codex/workflows/ship-check.md", "documentation/production/timeline.md"]
}
} satisfies Record<WorkflowId, WorkflowDefinition>;
The complete implementation should keep role, phase, objective, and cliAlias in the same registry entries; the snippet above focuses on context/template fields.
Step 2: Render selected templates inline
Add a deterministic helper that appends selected package-template bodies after the base prompt:
function renderWorkflowTemplates(workflow: WorkflowId): string {
const templateIds = workflowRegistry[workflow].templateIds ?? [];
if (templateIds.length === 0) return "";
return [
"",
"## Workflow Templates",
"",
...templateIds.flatMap((id) => {
const info = templateRegistry[id];
return [
`### Template: ${id}`,
`Source: package:${info.path}`,
"",
readTemplate(id).trim(),
""
];
})
].join("\n");
}
Then renderWorkflowPrompt should call renderCodexPrompt(...) with only workflowRegistry[workflow].contextFiles as context files and append renderWorkflowTemplates(workflow) to the result.
Step 3: Add tests for bounded context
Assert:
- every workflow template ID is discoverable for its owning workflow role: for each
workflowRegistryentry, everytemplateIdsitem hastemplateRegistry[id].rolescontainingworkflow.role. - market prompt includes
Template: market_analysis,Source: package:templates/market_analysis_template.md, and actualreadTemplate("market_analysis")content. - analytics prompt includes
Template: analytics_setup,Source: package:templates/analytics_setup_template.md, and actualreadTemplate("analytics_setup")content. - design-spec includes
Template: feature_spec; handoff includesTemplate: handoff. - market prompt does not include
Template: analytics_setup; analytics prompt does not includeTemplate: market_analysis. - UI review, playtest, review, and QA-oriented prompts do not include
## Workflow Templatesunless they are deliberately assigned template IDs later. - the
## Context Filessection never containstemplates/*.mdpaths.
Step 4: Run focused tests
Run:
npm test -- tests/functionality-gap-pass.test.ts tests/codex-prompts.test.ts
Expected: PASS.
Phase 6: Validation and Documentation
Task 13: Update validation for expanded role/workflow contract
Objective: Make open-gamestudio validate enforce the expanded functional contract.
Files:
- Modify:
src/validation.ts - Test:
tests/validation.test.ts - Test:
tests/functionality-gap-pass.test.ts
Step 1: Update repo validation
Ensure repo validation checks:
- all expanded role packages render.
- all workflow prompts render from the canonical workflow registry.
- required templates still exist.
- CLI/help surface does not expose future-only planner/
next, telemetry, or parallel features. - ownership enforcement is rejected only when it appears as an explicit CLI/help/config surface; do not add brittle semantic scans for ownership behavior.
.codex/studio.json.rolesequals the fullstudioRoleIdsroster,.codex/studio.json.activeRolesequalsactiveAgentsForMode(studio.mode), and.codex/studio.json.workflowsequals the canonical workflow registry keys.- representative legacy aliases such as
producer_agent,qa_agent, andmaster_orchestratorare rejected with clear guidance rather than accepted as roles.
Use stable validation IDs:
codex.role.<role>.package-render
codex.role.<role>.prompt.exists
codex.role.<role>.prompt.project-summary
codex.role.<role>.prompt.engine-context
codex.role.<role>.prompt.role-instructions
codex.role.<role>.prompt.expected-outputs
codex.role.<role>.prompt.review-checklist
codex.role.<role>.prompt.handoff
codex.workflow.<id>.registry
codex.workflow.<id>.file.exists
codex.workflow.<id>.sections
codex.workflow.<id>.render
codex.template.<id>.exists
codex.surface.future.next
codex.surface.future.telemetry
codex.surface.future.parallel
codex.surface.future.ownership
codex.surface.future.ownership should only fail on a concrete exposed command, help text, or config field for hard ownership enforcement.
Step 2: Update project validation
Ensure project validation checks:
- every expanded role prompt exists.
- every expanded workflow file exists and every registry workflow renders.
- project-specific prompt sections are present.
- no
project_orchestrator.mdexists. - no
.gamestudio/runsexists. - no generated
CODEX.mdexists.
Step 3: Add failure tests
Add tests that delete or corrupt:
.codex/prompts/studio-orchestrator.md.codex/workflows/market-analysis.md.codex/workflows/ui-ux-review.md
Validation should fail with clear check IDs.
Step 4: Run focused validation tests
Run:
npm test -- tests/validation.test.ts tests/functionality-gap-pass.test.ts
Expected: PASS.
Task 14: Update README and examples
Objective: Document the expanded functional surface without claiming future-only features.
Files:
- Modify:
README.md - Modify:
docs/examples.md - Modify:
docs/workflow-validation.md - Modify:
docs/known-upstream-differences.md - Test: docs are indirectly checked by validation; add direct tests only if existing docs tests exist.
Step 1: Update role list
Document the expanded Codex-native role roster and note it preserves Claude Game Studio functional coverage without legacy role IDs while retaining narrative-designer as an existing Codex-native story/content role.
Step 2: Add workflow examples
Add examples:
npm run build && node dist/cli.js market --project projects/rogue-core --dry-run
npm run build && node dist/cli.js analytics --project projects/rogue-core --dry-run
npm run build && node dist/cli.js handoff --project projects/rogue-core --dry-run
npm run build && node dist/cli.js design-spec --project projects/rogue-core --dry-run
npm run build && node dist/cli.js feel-review --project projects/rogue-core --dry-run
npm run build && node dist/cli.js ui-review --project projects/rogue-core --dry-run
Repo-local docs must use npm scripts or built CLI, not bare open-gamestudio, unless describing installed package UX.
Step 3: Update known differences
Move the first five gaps out of “future-only/missing” language where appropriate:
- role roster coverage now preserved in Codex-native IDs, with
narrative-designerretained for compatibility and story/content ownership. - project-specific role prompts now materialized in
.codex/prompts. - market and analytics are first-class renderable workflow prompts owned by dedicated roles; executable workflow lifecycle support remains future-only.
- orchestration is provided by
studio-orchestratorandhandoff, notproject_orchestrator.md. - richer workflows exist, but planner/telemetry/parallel remain future-only.
Step 4: Run docs-adjacent checks
Run:
npm run validate
Expected: PASS.
Phase 7: Full Verification
Task 15: Run full verification suite
Objective: Prove the expanded functionality is complete, typed, validated, and package-safe.
Files:
- No code changes unless verification finds defects.
Step 1: Run focused tests
Run:
npm test -- tests/functionality-gap-pass.test.ts tests/roles.test.ts tests/project-workflow.test.ts tests/codex-context-files.test.ts tests/validation.test.ts tests/codex-prompts.test.ts
Expected: PASS.
Step 2: Run full tests
Run:
npm test
Expected: PASS.
Step 3: Run typecheck
Run:
npm run typecheck
Expected: PASS.
Step 4: Run validation
Run:
npm run validate
Expected: PASS. Because validation checks Codex readiness, failure here means Codex CLI/auth must be fixed before parity is claimed. Do not claim parity/readiness before this Phase 7 validation gate passes.
Step 5: Run build and package smoke
Run:
npm run build
npm pack --dry-run
Expected: PASS. npm pack --dry-run should include built CLI, engine configs, templates, and any runtime assets needed by expanded workflows.
Acceptance Criteria
The functionality-gap pass is complete when all are true:
studioRoleIdsincludes the expanded 16-role Codex-native superset plus retainednarrative-designerrole.- Every role has a non-trivial role package with expected outputs, handoff, and review checklist.
activeAgentsForModeincludes orchestration, market, and analytics roles in every mode..codex/studio.jsonrecords fullroles, mode-specificactiveRoles, and registry-derivedworkflows, and status output usesactiveRolesfor active-role reporting.- Generated projects materialize project-specific
.codex/prompts/<role>.mdfiles for every role. - Generated role prompt files include project summary, engine context, role instructions, expected outputs, review checklist, and handoff.
- Generated projects include the expanded workflow files.
- Market and analytics workflows render through dedicated roles and bounded template/context selection, without claiming executable workflow lifecycle support.
- Handoff/orchestration is available through
studio-orchestratorand the prompt-renderingopen-gamestudio handoffshortcut, withoutproject_orchestrator.md. - Design, game-feel, art-direction, UI/UX, production milestone, distinct review, ship-check, playtest, bugfix, vertical-slice, market, analytics, and handoff workflows render successfully from the canonical workflow registry.
- Validation fails with the stable check IDs listed in Task 13 when required role prompts or workflow files are missing/corrupt.
- Representative legacy role aliases are rejected with clear guidance.
- Every workflow shortcut command with a
cliAliasrenders without launching Codex and without creating.codex/runs/*files. - Validation still rejects future-only exposed surfaces: planner/
next, telemetry, parallel orchestration, and explicit CLI/help/config surfaces for hard ownership enforcement. - No generated
CODEX.mdappears. - No
.gamestudio/runsappears. npm test,npm run typecheck,npm run validate,npm run build, andnpm pack --dry-runpass.
Suggested Implementation Order
- Role roster tests and
src/roles.tsexpansion. - Mode selection updates in
src/config.ts. - Project-specific prompt rendering in
src/agents.ts. - Project workflow file generation cleanup in
src/projects.ts. - Market and analytics workflows in
src/workflows.ts. - Handoff/orchestration workflow and CLI command.
- Richer design/art/UI/milestone workflow set.
- Validation hardening.
- Docs and examples.
- Full verification.
Review Notes for Merlin
This plan intentionally fills the five practical functionality gaps while staying Codex-native. Review decisions are closed as follows: workflow phases use existing Codex phases (implement, not build); .codex/studio.json separates full roles from mode-specific activeRoles; registry workflow files and validation land before CLI aliases; shortcut commands are render-only and must not launch Codex or create run state; validation IDs use the Task 13 codex.role.<role>.prompt.* scheme; parity is documented through a crosswalk with explicit legacy-alias rejection. Merlin has approved the expanded 16-role Codex-native superset and retaining the current narrative-designer role, for 17 total roles. Merlin has also approved package templates as the source of truth with selected template bodies inlined into workflow prompts; do not switch back to project-relative templates/... context paths unless a future customization feature deliberately materializes project-local template overrides. Merlin has also approved the follow-up design calls: shortcut workflow commands render prompts only, review is a distinct workflow, one canonical workflow registry owns workflow metadata, only selected user-facing workflows get shortcut CLI aliases, and validation uses stable check IDs with ownership enforcement checked only as an explicit exposed surface.
Do not revise Phase 1 down to strict 12-role parity unless Merlin explicitly reopens the product decision.