diff --git a/.beads/issues.jsonl b/.beads/issues.jsonl index aae08dfa..f75e3431 100644 --- a/.beads/issues.jsonl +++ b/.beads/issues.jsonl @@ -81,8 +81,8 @@ {"id":"ge-hch.3.2.3","title":"Implement: add stable demo story (web/stories/demo.ink)","status":"in_progress","priority":1,"issue_type":"feature","assignee":"patch","created_at":"2026-01-11T22:00:53.030258551-08:00","created_by":"rgardler","updated_at":"2026-01-11T22:04:23.26992299-08:00","dependencies":[{"issue_id":"ge-hch.3.2.3","depends_on_id":"ge-hch.3.2","type":"parent-child","created_at":"2026-01-11T22:00:53.040321356-08:00","created_by":"rgardler"}],"comments":[{"id":49,"issue_id":"ge-hch.3.2.3","author":"rgardler","text":"Added stable demo story at web/stories/demo.ink (short deterministic path with story_start, choice_selected, story_complete tags and #smoke cue). Added validate-story integration coverage (tests/validate-story/demo.story.test.js) to ensure it passes. Ran npm ci \u0026\u0026 npm test (all tests pass).","created_at":"2026-01-12T06:11:29Z"},{"id":50,"issue_id":"ge-hch.3.2.3","author":"rgardler","text":"Experiment: Removed #choice_selected tags from web/stories/demo.ink to verify runtime telemetry still emits choice_selected events. Branch: feature/ge-hch.3.2/no-choice-tags. PR (draft): https://github.com/TheWizardsCode/GEngine/pull/114. Results: npm ci; npm test (unit + Playwright demo) passed. Playwright logs show telemetry wait succeeded for 'choice_selected'; console telemetry logs observed (story_start, choice_selected, smoke_triggered, story_complete). validate-story CLI: node scripts/validate-story.js --story web/stories/demo.ink --output stdout --state-file /tmp/validate-state.json =\u003e exit 0, pass true. No content tags needed for telemetry emission.","created_at":"2026-01-12T06:21:16Z"},{"id":53,"issue_id":"ge-hch.3.2.3","author":"rgardler","text":"","created_at":"2026-01-12T06:30:21Z"},{"id":54,"issue_id":"ge-hch.3.2.3","author":"rgardler","text":"","created_at":"2026-01-12T06:33:14Z"}]} {"id":"ge-hch.3.3","title":"Implement: GitHub Pages deploy for static demo","description":"Add GitHub Actions workflow to deploy web/demo static output to GitHub Pages (branch or docs/).\\n\\n## Acceptance Criteria\\n- .github/workflows/gh-pages.yml exists to build (if needed) and deploy web/demo to GitHub Pages.\\n- Docs updated describing how to access the pages URL.\\n","notes":"PRs #106, #107, #108 merged; Pages live with web/ root landing. Follow-up: ge-2b0 (Ship) to limit Playwright on main.","status":"closed","priority":2,"issue_type":"task","assignee":"rgardler","created_at":"2026-01-07T19:42:31.306809853-08:00","created_by":"rgardler","updated_at":"2026-01-08T01:53:01.787074738-08:00","closed_at":"2026-01-08T01:53:01.787083938-08:00","external_ref":"https://github.com/TheWizardsCode/GEngine/pull/108","labels":["Status: PR Created"],"dependencies":[{"issue_id":"ge-hch.3.3","depends_on_id":"ge-hch.3","type":"parent-child","created_at":"2026-01-07T19:42:31.307589419-08:00","created_by":"rgardler"}]} {"id":"ge-hch.3.4","title":"Tool: validate-story (ink parse + runtime smoke)","description":"Create a validate-story script that ensures any .ink file parses under InkJS and that the runtime can reach first choice. Used in CI for generated/stable stories.\\n\\n## Acceptance Criteria\\n- scripts/validate-story.js exists and exits non-zero on parse/runtime failure.\\n- CI hook runs this script against web/stories/*.ink.\\n","status":"closed","priority":2,"issue_type":"task","assignee":"rgardler","created_at":"2026-01-07T19:42:33.606187788-08:00","created_by":"rgardler","updated_at":"2026-01-11T20:22:00.562685368-08:00","closed_at":"2026-01-11T20:22:00.562685368-08:00","close_reason":"Implementation merged; closing per Patch","labels":["Status: Plan Created"],"dependencies":[{"issue_id":"ge-hch.3.4","depends_on_id":"ge-hch.3","type":"parent-child","created_at":"2026-01-07T19:42:33.609684247-08:00","created_by":"rgardler"}],"comments":[{"id":33,"issue_id":"ge-hch.3.4","author":"rgardler","text":"Created scoped implementation tasks for validate-story and linked them as children: ge-hch.3.4.5 (Implement: validate-story CLI core), ge-hch.3.4.6 (Tests: validate-story core), ge-hch.3.4.7 (Docs+CI: validate-story workflow \u0026 usage). No repo files were edited in this step. Next recommended actions: 1) Patch to implement scripts/validate-story.js on branch feature/ge-hch.3.4-validate; 2) Probe to add tests under tests/validate-story; 3) Scribbler to draft docs and Ship to add .github/workflows/validate-story.yml. See beads for acceptance criteria and dependencies.","created_at":"2026-01-08T10:21:32Z"},{"id":34,"issue_id":"ge-hch.3.4","author":"rgardler","text":"Examined current state for ge-hch.3.4: \\n- Issue status: in_progress (Plan created).\\n- Description/acceptance criteria present: scripts/validate-story.js must exit non-zero on parse/runtime failure; CI hook to run against web/stories/*.ink.\\n- Children/tasks created: ge-hch.3.4.1 (CLI core), .3.4.2 (path rotation \u0026 persistence), .3.4.3 (CI gate), .3.4.4 (Docs \u0026 fixtures), .3.4.5 (Implement CLI core - priority 1), .3.4.6 (Tests - priority 1), .3.4.7 (Docs+CI chore). All children are open.\\n- Assignee: rgardler on parent; implementation tasks unassigned or assigned to Patch/Probe per comment.\\n- Repo changes: none so far (no files edited).\\n\\nNext recommended actions (handoff):\\n1) Patch: implement scripts/validate-story.js on branch feature/ge-hch.3.4-validate (acceptance = ge-hch.3.4.1 ACs).\\n2) Probe: add tests under tests/validate-story (ge-hch.3.4.6).\\n3) Ship: add .github/workflows/validate-story.yml and ensure it runs before Playwright (ge-hch.3.4.3).\\n4) Scribbler: add docs/fixtures describing usage and state format (ge-hch.3.4.4 \u0026 .7).\\n\\nRisks/blockers: inkjs availability in CI, ensuring deterministic path-rotation without exhausting alternatives, and coordinating CI trigger to run only on non-markdown changes.\\n\\nCommands run during this review: # In Progress\n\nID Type / Status / Title Priority Blockers Blocks Assignee\n---------- ------------------------------------------------------------ -------- -------- ------ --------\nge-hch.3 πŸ—ΊοΈ 🚧 M1 β€” MVP: Ink runtime + UI + save/load + telemetry +… 1 0 7 Build \n Children\n ID Type / Status / Title Priority Blockers Blocks Assignee\n ---------- ------------------------------------------------------------ -------- -------- ------ --------\n ge-hch.3.2 ❓ β­• Feature: Stable story integration 2 0 0 Build \n ge-hch.3.4 ❓ 🚧 Tool: validate-story (ink parse + runtime smoke) 2 0 0 rgardler\n ge-hch.3.5 ❓ β­• Implement: package.json scripts (start/build/validate/t… 2 0 0 patch \n ge-hch.3.6 ❓ β­• CI: Build + validate + Playwright (PR) 2 0 0 Ship \n\nge-hch.3.4 🧩 🚧 Tool: validate-story (ink parse + runtime smoke) 2 0 11 rgardler\n Children\n ID Type / Status / Title Priority Blockers Blocks Assignee\n ------------ -------------------------------------------- -------- -------- ------ --------\n ge-hch.3.4.1 ❓ β­• Validate CLI core (parse + walk) 2 0 0 \n ge-hch.3.4.2 ❓ β­• Path rotation \u0026 persistence 2 0 0 \n ge-hch.3.4.3 ❓ β­• CI: validate-story gate 2 0 0 \n ge-hch.3.4.4 ❓ β­• Docs \u0026 fixtures for validate-story 2 0 0 \n ge-hch.3.4.5 ❓ β­• Implement: validate-story CLI core 1 0 0 \n ge-hch.3.4.6 ❓ β­• Tests: validate-story core 1 0 0 \n ge-hch.3.4.7 ❓ β­• Docs+CI: validate-story workflow \u0026 usage 2 0 0, [\n {\n \"id\": \"ge-hch.3.4\",\n \"title\": \"Tool: validate-story (ink parse + runtime smoke)\",\n \"description\": \"Create a validate-story script that ensures any .ink file parses under InkJS and that the runtime can reach first choice. Used in CI for generated/stable stories.\\\\n\\\\n## Acceptance Criteria\\\\n- scripts/validate-story.js exists and exits non-zero on parse/runtime failure.\\\\n- CI hook runs this script against web/stories/*.ink.\\\\n\",\n \"status\": \"in_progress\",\n \"priority\": 2,\n \"issue_type\": \"task\",\n \"assignee\": \"rgardler\",\n \"created_at\": \"2026-01-07T19:42:33.606187788-08:00\",\n \"created_by\": \"rgardler\",\n \"updated_at\": \"2026-01-08T01:57:17.075526965-08:00\",\n \"labels\": [\n \"Status: Plan Created\"\n ],\n \"dependencies\": [\n {\n \"id\": \"ge-hch.3\",\n \"title\": \"M1 β€” MVP: Ink runtime + UI + save/load + telemetry + demo story\",\n \"description\": \"M1 β€” MVP: Ink runtime + UI + save/load + telemetry + 1 demo story\\\\n\\\\nDeliver a playable text-only interactive novel using InkJS at runtime with branching choices, single-slot save/load, runtime telemetry, and at least one AI-generated demo story.\\\\n\\\\nSuccess criteria: runtime story end-to-end with no fatal errors; player choice selection; save/load demonstrable; telemetry events emitted; AI demo story included.\",\n \"status\": \"in_progress\",\n \"priority\": 1,\n \"issue_type\": \"epic\",\n \"assignee\": \"Build\",\n \"created_at\": \"2026-01-07T17:24:00.942344426-08:00\",\n \"created_by\": \"rgardler\",\n \"updated_at\": \"2026-01-07T23:50:28.2463118-08:00\",\n \"labels\": [\n \"Status: Implementation Committed\",\n \"Status: Plan Created\",\n \"milestone\"\n ],\n \"dependency_type\": \"parent-child\"\n }\n ],\n \"dependents\": [\n {\n \"id\": \"ge-hch.3.4.5\",\n \"title\": \"Implement: validate-story CLI core\",\n \"status\": \"open\",\n \"priority\": 1,\n \"issue_type\": \"feature\",\n \"created_at\": \"2026-01-08T02:21:24.563632618-08:00\",\n \"created_by\": \"rgardler\",\n \"updated_at\": \"2026-01-08T02:21:24.563632618-08:00\",\n \"dependency_type\": \"parent-child\"\n },\n {\n \"id\": \"ge-hch.3.4.6\",\n \"title\": \"Tests: validate-story core\",\n \"status\": \"open\",\n \"priority\": 1,\n \"issue_type\": \"task\",\n \"created_at\": \"2026-01-08T02:21:24.619687557-08:00\",\n \"created_by\": \"rgardler\",\n \"updated_at\": \"2026-01-08T02:21:24.619687557-08:00\",\n \"dependency_type\": \"parent-child\"\n },\n {\n \"id\": \"ge-hch.3.2\",\n \"title\": \"Feature: Stable story integration\",\n \"description\": \"Ensure the stable demo story is the fallback and is packaged alongside generated stories.\\\\n\\\\n## Acceptance Criteria\\\\n- Stable story present at web/stories/demo.ink and referenced by README/manifest.\\\\n- Playwright and unit tests pass using stable story.\\\\n\\\\n## Minimal Implementation\\\\n- Confirm location and update docs/InkJS_README.md to document the stable story and how to swap in generated ones.\\\\n\",\n \"status\": \"open\",\n \"priority\": 2,\n \"issue_type\": \"feature\",\n \"assignee\": \"Build\",\n \"created_at\": \"2026-01-07T19:42:28.644251263-08:00\",\n \"created_by\": \"rgardler\",\n \"updated_at\": \"2026-01-07T23:50:07.643688233-08:00\",\n \"dependency_type\": \"blocks\"\n },\n {\n \"id\": \"ge-hch.3.6\",\n \"title\": \"CI: Build + validate + Playwright (PR)\",\n \"description\": \"Update CI workflows to run: npm build, scripts/validate-story against web/stories, package artifact, run Playwright E2E tests against built artifact, and (optionally) deploy to GitHub Pages on merge.\\\\n\\\\n## Acceptance Criteria\\\\n- .github/workflows/pr-ci.yml updated/added to run build + validate + Playwright on PRs.\\\\n- CI artifacts archived for Playwright runs and GitHub Pages deploy.\\\\n\",\n \"status\": \"open\",\n \"priority\": 2,\n \"issue_type\": \"task\",\n \"assignee\": \"Ship\",\n \"created_at\": \"2026-01-07T19:45:40.535363424-08:00\",\n \"created_by\": \"rgardler\",\n \"updated_at\": \"2026-01-07T23:46:35.086644546-08:00\",\n \"dependency_type\": \"blocks\"\n },\n {\n \"id\": \"ge-hch.4.1\",\n \"title\": \"Tool: replay harness (golden-path)\",\n \"description\": \"Add a headless replay harness that can drive a story to completion using scripted choices and record results.\\\\n\\\\n## Acceptance Criteria\\\\n- scripts/replay.js exists and can be fed a story + choice sequence and returns success/failure.\\\\n- Example golden-path script present for stable demo.\\\\n\",\n \"status\": \"open\",\n \"priority\": 2,\n \"issue_type\": \"task\",\n \"assignee\": \"Patch\",\n \"created_at\": \"2026-01-07T19:42:36.286010273-08:00\",\n \"created_by\": \"rgardler\",\n \"updated_at\": \"2026-01-07T23:49:04.685286732-08:00\",\n \"dependency_type\": \"blocks\"\n },\n {\n \"id\": \"ge-hch.5.1\",\n \"title\": \"Agent: Story Author (Ink)\",\n \"description\": \"Define and implement a Story Author agent that generates valid Ink (.ink) stories suitable for runtime execution and automated testing.\\\\n\\\\n## Acceptance Criteria\\\\n- Generates a .ink file that parses with InkJS with no fatal errors.\\\\n- Includes metadata manifest (title, author, prompt, version).\\\\n- Emits telemetry tags/Ink markers required by M1 (story_start, choice_selected, smoke_trigger).\\\\n- Output placed at web/stories/generated/\\u003cname\\u003e.ink and web/stories/generated/\\u003cname\\u003e.json.\\\\n\\\\n## Minimal Implementation\\\\n- Agent spec (history/ai/agent-story-author.md).\\\\n- Test harness that runs the agent, validates parse via InkJS, and runs the golden-path smoke test.\\\\n\\\\n## Dependencies\\\\n- Access to an OpenAI-compatible endpoint (configurable).\\\\n- inkjs runner \\u0026 test harness (existing).\\\\n\\\\n## Deliverables\\\\n- history/ai/agent-story-author.md, web/stories/generated/*, tests for validation.\\\\n\",\n \"status\": \"open\",\n \"priority\": 2,\n \"issue_type\": \"feature\",\n \"assignee\": \"Build\",\n \"created_at\": \"2026-01-07T19:37:54.162109871-08:00\",\n \"created_by\": \"rgardler\",\n \"updated_at\": \"2026-01-07T23:46:39.717890567-08:00\",\n \"dependency_type\": \"blocks\"\n },\n {\n \"id\": \"ge-hch.3.4.1\",\n \"title\": \"Validate CLI core (parse + walk)\",\n \"description\": \"## Summary\\\\nCLI validates .ink stories by parsing and auto-walking to completion with seedable choice selection.\\\\n\\\\n## Acceptance Criteria\\\\n- node scripts/validate-story.js exits non-zero on parse or runtime failure.\\\\n- Supports all stories under web/stories (glob).\\\\n- Auto-selects a choice each step; reachable end or max-steps enforcement.\\\\n- Emits structured result (pass/fail, path taken, steps count) to stdout/JSON.\\\\n- Supports seed input for deterministic runs.\\\\n\\\\n## Minimal Implementation\\\\n- InkJS load/compile wrapper for a given .ink file.\\\\n- Runner loop that advances story and chooses a choice per step.\\\\n- CLI flags: --story path, --seed, --max-steps, --output (json).\\\\n- Non-zero exit on any failure; zero on success.\\\\n\\\\n## Dependencies\\\\n- inkjs runtime available.\\\\n\\\\n## Deliverables\\\\n- scripts/validate-story.js with CLI.\\\\n- Example command in docs.\\\\n\\\\n## Tasks to create\\\\n- Implement, Tests, Docs.\",\n \"status\": \"open\",\n \"priority\": 2,\n \"issue_type\": \"feature\",\n \"created_at\": \"2026-01-08T02:13:30.11480307-08:00\",\n \"created_by\": \"rgardler\",\n \"updated_at\": \"2026-01-08T02:13:30.11480307-08:00\",\n \"labels\": [\n \"feature\"\n ],\n \"dependency_type\": \"parent-child\"\n },\n {\n \"id\": \"ge-hch.3.4.2\",\n \"title\": \"Path rotation \\u0026 persistence\",\n \"description\": \"## Summary\\\\nPersist last path per story and avoid repeating the same choice at a decision point on the next run (when alternatives exist).\\\\n\\\\n## Acceptance Criteria\\\\n- Stores last path taken per story (e.g., .validate-story-state.json).\\\\n- On next run, avoids the previously chosen choice index when \\u003e1 options exist at a decision.\\\\n- Deterministic fallback when only one choice.\\\\n- Exits non-zero if no alternative path remains.\\\\n- Logs chosen path; supports seedable selection.\\\\n\\\\n## Minimal Implementation\\\\n- Read/write state file keyed by story path.\\\\n- Decision hook that skips last-choice index when \\u003e1 options; bounded retry.\\\\n- Option to clear state.\\\\n\\\\n## Dependencies\\\\n- Validate CLI core.\\\\n\\\\n## Deliverables\\\\n- State file format doc.\\\\n- Logging of path taken.\\\\n\\\\n## Tasks to create\\\\n- Implement, Tests, Docs.\",\n \"status\": \"open\",\n \"priority\": 2,\n \"issue_type\": \"feature\",\n \"created_at\": \"2026-01-08T02:13:36.317351311-08:00\",\n \"created_by\": \"rgardler\",\n \"updated_at\": \"2026-01-08T02:13:36.317351311-08:00\",\n \"labels\": [\n \"feature\"\n ],\n \"dependency_type\": \"parent-child\"\n },\n {\n \"id\": \"ge-hch.3.4.3\",\n \"title\": \"CI: validate-story gate\",\n \"description\": \"## Summary\\\\nDedicated workflow to run validate-story on pushes/PRs when non-Markdown files change, before Playwright.\\\\n\\\\n## Acceptance Criteria\\\\n- New workflow triggers on push/PR and gates on non-Markdown diff.\\\\n- Runs npm ci and node scripts/validate-story.js across web/stories/**/*.ink.\\\\n- Fails job on validation failure.\\\\n- Runs before Playwright workflow (or as a prerequisite job).\\\\n\\\\n## Minimal Implementation\\\\n- .github/workflows/validate-story.yml with change detection.\\\\n- Matrix over stories or single pass over all files.\\\\n- Uploads logs/artifacts on failure.\\\\n\\\\n## Dependencies\\\\n- Validate CLI core.\\\\n\\\\n## Deliverables\\\\n- Workflow file and doc note.\\\\n\\\\n## Tasks to create\\\\n- Implement, Tests, Docs.\",\n \"status\": \"open\",\n \"priority\": 2,\n \"issue_type\": \"feature\",\n \"created_at\": \"2026-01-08T02:13:43.695830378-08:00\",\n \"created_by\": \"rgardler\",\n \"updated_at\": \"2026-01-08T02:13:43.695830378-08:00\",\n \"labels\": [\n \"feature\"\n ],\n \"dependency_type\": \"parent-child\"\n },\n {\n \"id\": \"ge-hch.3.4.4\",\n \"title\": \"Docs \\u0026 fixtures for validate-story\",\n \"description\": \"## Summary\\\\nDocument usage/options, path-rotation behavior, CI hook, and provide example outputs/fixtures.\\\\n\\\\n## Acceptance Criteria\\\\n- README/InkJS docs updated with validate-story usage, seed/rotation notes, CI hook description.\\\\n- Sample log/JSON output checked in (docs or fixtures).\\\\n- Notes on non-Markdown gating behavior in CI.\\\\n\\\\n## Minimal Implementation\\\\n- Doc section with commands and options.\\\\n- Example output snippet (JSON) and explanation of state file.\\\\n- Reference to CI workflow and how to clear state.\\\\n\\\\n## Dependencies\\\\n- Validate CLI core, Path rotation.\\\\n\\\\n## Deliverables\\\\n- Docs update + example fixture/log.\\\\n\\\\n## Tasks to create\\\\n- Implement, Tests, Docs.\",\n \"status\": \"open\",\n \"priority\": 2,\n \"issue_type\": \"feature\",\n \"created_at\": \"2026-01-08T02:13:52.56971808-08:00\",\n \"created_by\": \"rgardler\",\n \"updated_at\": \"2026-01-08T02:13:52.56971808-08:00\",\n \"labels\": [\n \"feature\"\n ],\n \"dependency_type\": \"parent-child\"\n },\n {\n \"id\": \"ge-hch.3.4.7\",\n \"title\": \"Docs+CI: validate-story workflow \\u0026 usage\",\n \"status\": \"open\",\n \"priority\": 2,\n \"issue_type\": \"chore\",\n \"created_at\": \"2026-01-08T02:21:24.685539352-08:00\",\n \"created_by\": \"rgardler\",\n \"updated_at\": \"2026-01-08T02:21:24.685539352-08:00\",\n \"dependency_type\": \"parent-child\"\n }\n ],\n \"comments\": [\n {\n \"id\": 33,\n \"issue_id\": \"ge-hch.3.4\",\n \"author\": \"rgardler\",\n \"text\": \"Created scoped implementation tasks for validate-story and linked them as children: ge-hch.3.4.5 (Implement: validate-story CLI core), ge-hch.3.4.6 (Tests: validate-story core), ge-hch.3.4.7 (Docs+CI: validate-story workflow \\u0026 usage). No repo files were edited in this step. Next recommended actions: 1) Patch to implement scripts/validate-story.js on branch feature/ge-hch.3.4-validate; 2) Probe to add tests under tests/validate-story; 3) Scribbler to draft docs and Ship to add .github/workflows/validate-story.yml. See beads for acceptance criteria and dependencies.\",\n \"created_at\": \"2026-01-08T10:21:32Z\"\n }\n ],\n \"parent\": \"ge-hch.3\"\n }\n]. No files were edited.","created_at":"2026-01-09T04:25:18Z"},{"id":37,"issue_id":"ge-hch.3.4","author":"rgardler","text":"ge-hch.3.4.5 implemented (patch). PR: https://github.com/TheWizardsCode/GEngine/pull/new/feature/ge-hch.3.4-validate β€” next: Probe to review tests and Ship to add CI workflow.","created_at":"2026-01-09T04:59:48Z"},{"id":42,"issue_id":"ge-hch.3.4","author":"rgardler","text":"Probe completed tests (ge-hch.3.4.6). PR: https://github.com/TheWizardsCode/GEngine/pull/110","created_at":"2026-01-09T05:16:24Z"},{"id":44,"issue_id":"ge-hch.3.4","author":"rgardler","text":"Summary: validate-story implementation and tests are present and passing locally. Next actions: (1) add CI workflow to run scripts/validate-story.js against web/stories/**/*.ink (ge-hch.3.4.3, assignee=Ship), (2) add docs/usage and fixtures (ge-hch.3.4.4, assignee=Scribbler), (3) implement path-rotation + persistence (ge-hch.3.4.2, assignee=Patch), and (4) gate PR CI to run validate-story before Playwright (ge-hch.3.4.3). Build can draft the CI workflow and docs if desired β€” reply which to prepare now. For each action, include acceptance criteria and an implementation owner. Current files referenced during inspection: scripts/validate-story.js, tests/validate-story/*, tests/fixtures/*, docs/InkJS_README.md.","created_at":"2026-01-12T04:16:51Z"},{"id":45,"issue_id":"ge-hch.3.4","author":"rgardler","text":"Patch complete: validate-story implementation merged and tests added. Files touched: scripts/validate-story.js; tests/validate-story/validate-story.test.js; tests/validate-story/validate-story.integration.test.js; tests/fixtures/{valid.ink,invalid.ink,runtime_err.ink}; package.json; package-lock.json; jest.config.js; docs/InkJS_README.md. Acceptance: CLI exits non-zero on parse/runtime failures; unit+integration tests pass locally. Remaining follow-ups (left open or for future work): ge-hch.3.4.2 (path rotation \u0026 persistence), ge-hch.3.4.3 (CI gate), ge-hch.3.4.4 (Docs \u0026 fixtures). Closing ge-hch.3.4 as implementation complete per Patch.","created_at":"2026-01-12T04:21:54Z"},{"id":58,"issue_id":"ge-hch.3.4","author":"rgardler","text":"","created_at":"2026-01-12T07:03:23Z"},{"id":59,"issue_id":"ge-hch.3.4","author":"rgardler","text":"","created_at":"2026-01-12T07:14:11Z"},{"id":60,"issue_id":"ge-hch.3.4","author":"rgardler","text":"","created_at":"2026-01-12T07:15:14Z"},{"id":61,"issue_id":"ge-hch.3.4","author":"rgardler","text":"","created_at":"2026-01-12T07:20:25Z"},{"id":62,"issue_id":"ge-hch.3.4","author":"rgardler","text":"","created_at":"2026-01-12T07:21:22Z"},{"id":63,"issue_id":"ge-hch.3.4","author":"rgardler","text":"","created_at":"2026-01-12T07:23:08Z"}]} -{"id":"ge-hch.3.4.1","title":"Validate CLI core (parse + walk)","description":"## Summary\\nCLI validates .ink stories by parsing and auto-walking to completion with seedable choice selection.\\n\\n## Acceptance Criteria\\n- node scripts/validate-story.js exits non-zero on parse or runtime failure.\\n- Supports all stories under web/stories (glob).\\n- Auto-selects a choice each step; reachable end or max-steps enforcement.\\n- Emits structured result (pass/fail, path taken, steps count) to stdout/JSON.\\n- Supports seed input for deterministic runs.\\n\\n## Minimal Implementation\\n- InkJS load/compile wrapper for a given .ink file.\\n- Runner loop that advances story and chooses a choice per step.\\n- CLI flags: --story path, --seed, --max-steps, --output (json).\\n- Non-zero exit on any failure; zero on success.\\n\\n## Dependencies\\n- inkjs runtime available.\\n\\n## Deliverables\\n- scripts/validate-story.js with CLI.\\n- Example command in docs.\\n\\n## Tasks to create\\n- Implement, Tests, Docs.","status":"open","priority":2,"issue_type":"feature","created_at":"2026-01-08T02:13:30.11480307-08:00","created_by":"rgardler","updated_at":"2026-01-08T02:13:30.11480307-08:00","labels":["feature"],"dependencies":[{"issue_id":"ge-hch.3.4.1","depends_on_id":"ge-hch.3.4","type":"parent-child","created_at":"2026-01-08T02:13:30.122822123-08:00","created_by":"rgardler"}]} -{"id":"ge-hch.3.4.2","title":"Path rotation \u0026 persistence","description":"## Summary\\nPersist last path per story and avoid repeating the same choice at a decision point on the next run (when alternatives exist).\\n\\n## Acceptance Criteria\\n- Stores last path taken per story (e.g., .validate-story-state.json).\\n- On next run, avoids the previously chosen choice index when \u003e1 options exist at a decision.\\n- Deterministic fallback when only one choice.\\n- Exits non-zero if no alternative path remains.\\n- Logs chosen path; supports seedable selection.\\n\\n## Minimal Implementation\\n- Read/write state file keyed by story path.\\n- Decision hook that skips last-choice index when \u003e1 options; bounded retry.\\n- Option to clear state.\\n\\n## Dependencies\\n- Validate CLI core.\\n\\n## Deliverables\\n- State file format doc.\\n- Logging of path taken.\\n\\n## Tasks to create\\n- Implement, Tests, Docs.","status":"in_progress","priority":2,"issue_type":"feature","assignee":"patch","created_at":"2026-01-08T02:13:36.317351311-08:00","created_by":"rgardler","updated_at":"2026-01-11T20:24:50.019989519-08:00","labels":["feature"],"dependencies":[{"issue_id":"ge-hch.3.4.2","depends_on_id":"ge-hch.3.4","type":"parent-child","created_at":"2026-01-08T02:13:36.318590015-08:00","created_by":"rgardler"},{"issue_id":"ge-hch.3.4.2","depends_on_id":"ge-hch.3.4.1","type":"blocks","created_at":"2026-01-08T02:14:13.874049144-08:00","created_by":"rgardler"}],"comments":[{"id":46,"issue_id":"ge-hch.3.4.2","author":"rgardler","text":"Implemented path rotation persistence and deterministic seeding. Files touched: scripts/validate-story.js, tests/validate-story/rotation-state.test.js, tests/validate-story/validate-story.integration.test.js, tests/fixtures/valid.ink, tests/fixtures/validate-story/branching.ink, tests/fixtures/validate-story/single-choice.ink, jest.config.js, package.json, package-lock.json, .gitignore. Tests: npm test; npx jest tests/validate-story/rotation-state.test.js --runInBand --verbose; npx jest tests/validate-story/validate-story.integration.test.js --runInBand --verbose. PR: https://github.com/TheWizardsCode/GEngine/pull/112. Follow-ups: none.","created_at":"2026-01-12T05:33:23Z"},{"id":47,"issue_id":"ge-hch.3.4.2","author":"rgardler","text":"Removed accidentally committed history snapshot at history/opencode-restored/restore-20260112T051251Z; pushed branch and updated PR #112. .opencode/command/refactor.md left intact.","created_at":"2026-01-12T05:52:27Z"},{"id":48,"issue_id":"ge-hch.3.4.2","author":"rgardler","text":"PR #112 merged into main by Producer (rgardler). Implementation: path rotation \u0026 persistence implemented in scripts/validate-story.js; tests added under tests/validate-story; fixtures added under tests/fixtures/validate-story. Transient .opencode snapshot was moved to history and then removed per follow-up. Verification: local npm test passed for validate-story tests; CI PR passed and was merged. Remaining follow-ups: ge-hch.3.4.3 (CI gate for validate-story), ge-hch.3.4.4 (docs \u0026 fixtures review). Files referenced: scripts/validate-story.js, tests/validate-story/*, tests/fixtures/validate-story/*, docs/InkJS_README.md. β€”Actor: Build","created_at":"2026-01-12T05:55:39Z"}]} +{"id":"ge-hch.3.4.1","title":"Validate CLI core (parse + walk)","description":"## Summary\\nCLI validates .ink stories by parsing and auto-walking to completion with seedable choice selection.\\n\\n## Acceptance Criteria\\n- node scripts/validate-story.js exits non-zero on parse or runtime failure.\\n- Supports all stories under web/stories (glob).\\n- Auto-selects a choice each step; reachable end or max-steps enforcement.\\n- Emits structured result (pass/fail, path taken, steps count) to stdout/JSON.\\n- Supports seed input for deterministic runs.\\n\\n## Minimal Implementation\\n- InkJS load/compile wrapper for a given .ink file.\\n- Runner loop that advances story and chooses a choice per step.\\n- CLI flags: --story path, --seed, --max-steps, --output (json).\\n- Non-zero exit on any failure; zero on success.\\n\\n## Dependencies\\n- inkjs runtime available.\\n\\n## Deliverables\\n- scripts/validate-story.js with CLI.\\n- Example command in docs.\\n\\n## Tasks to create\\n- Implement, Tests, Docs.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-01-08T02:13:30.11480307-08:00","created_by":"rgardler","updated_at":"2026-01-12T00:34:12.798634647-08:00","closed_at":"2026-01-12T00:34:12.798634647-08:00","close_reason":"Audit complete; tests passing locally; delegating remaining work","labels":["feature"],"dependencies":[{"issue_id":"ge-hch.3.4.1","depends_on_id":"ge-hch.3.4","type":"parent-child","created_at":"2026-01-08T02:13:30.122822123-08:00","created_by":"rgardler"}],"comments":[{"id":64,"issue_id":"ge-hch.3.4.1","author":"rgardler","text":"Audit complete: validate-story CLI core verified locally. Jest \u0026 Playwright tests passed (Jest: 4 suites / 21 tests; Playwright demo: 9 passed, 1 skipped).\n\nActions taken:\n- Created task ge-wdm to investigate the skipped Playwright demo test (label: refactor).\n- Delegated ge-hch.3.4.2 (Path rotation \u0026 persistence) to patch for implementation.\n- No runtime changes made during audit.\n\nPlease review and close ge-hch.3.4.1 when ready.\n","created_at":"2026-01-12T08:34:10Z"}]} +{"id":"ge-hch.3.4.2","title":"Path rotation \u0026 persistence","description":"## Summary\\nPersist last path per story and avoid repeating the same choice at a decision point on the next run (when alternatives exist).\\n\\n## Acceptance Criteria\\n- Stores last path taken per story (e.g., .validate-story-state.json).\\n- On next run, avoids the previously chosen choice index when \u003e1 options exist at a decision.\\n- Deterministic fallback when only one choice.\\n- Exits non-zero if no alternative path remains.\\n- Logs chosen path; supports seedable selection.\\n\\n## Minimal Implementation\\n- Read/write state file keyed by story path.\\n- Decision hook that skips last-choice index when \u003e1 options; bounded retry.\\n- Option to clear state.\\n\\n## Dependencies\\n- Validate CLI core.\\n\\n## Deliverables\\n- State file format doc.\\n- Logging of path taken.\\n\\n## Tasks to create\\n- Implement, Tests, Docs.","status":"in_progress","priority":2,"issue_type":"feature","assignee":"patch","created_at":"2026-01-08T02:13:36.317351311-08:00","created_by":"rgardler","updated_at":"2026-01-12T00:34:16.082771272-08:00","labels":["feature"],"dependencies":[{"issue_id":"ge-hch.3.4.2","depends_on_id":"ge-hch.3.4","type":"parent-child","created_at":"2026-01-08T02:13:36.318590015-08:00","created_by":"rgardler"},{"issue_id":"ge-hch.3.4.2","depends_on_id":"ge-hch.3.4.1","type":"blocks","created_at":"2026-01-08T02:14:13.874049144-08:00","created_by":"rgardler"}],"comments":[{"id":46,"issue_id":"ge-hch.3.4.2","author":"rgardler","text":"Implemented path rotation persistence and deterministic seeding. Files touched: scripts/validate-story.js, tests/validate-story/rotation-state.test.js, tests/validate-story/validate-story.integration.test.js, tests/fixtures/valid.ink, tests/fixtures/validate-story/branching.ink, tests/fixtures/validate-story/single-choice.ink, jest.config.js, package.json, package-lock.json, .gitignore. Tests: npm test; npx jest tests/validate-story/rotation-state.test.js --runInBand --verbose; npx jest tests/validate-story/validate-story.integration.test.js --runInBand --verbose. PR: https://github.com/TheWizardsCode/GEngine/pull/112. Follow-ups: none.","created_at":"2026-01-12T05:33:23Z"},{"id":47,"issue_id":"ge-hch.3.4.2","author":"rgardler","text":"Removed accidentally committed history snapshot at history/opencode-restored/restore-20260112T051251Z; pushed branch and updated PR #112. .opencode/command/refactor.md left intact.","created_at":"2026-01-12T05:52:27Z"},{"id":48,"issue_id":"ge-hch.3.4.2","author":"rgardler","text":"PR #112 merged into main by Producer (rgardler). Implementation: path rotation \u0026 persistence implemented in scripts/validate-story.js; tests added under tests/validate-story; fixtures added under tests/fixtures/validate-story. Transient .opencode snapshot was moved to history and then removed per follow-up. Verification: local npm test passed for validate-story tests; CI PR passed and was merged. Remaining follow-ups: ge-hch.3.4.3 (CI gate for validate-story), ge-hch.3.4.4 (docs \u0026 fixtures review). Files referenced: scripts/validate-story.js, tests/validate-story/*, tests/fixtures/validate-story/*, docs/InkJS_README.md. β€”Actor: Build","created_at":"2026-01-12T05:55:39Z"},{"id":65,"issue_id":"ge-hch.3.4.2","author":"rgardler","text":"Diagnostics (Probe): Reproduced failing test on branch patch/ge-hch.3.4.2/rotation-persistence. Command: npx jest tests/validate-story/validate-story.integration.test.js --runInBand --verbose. Failure: deterministic seeded runs produce same path (expected path [1], got [0]); others pass. Root cause: default state file (.validate-story-state.json) persists lastPath and is read even for seeded runs, so second run rotates away from previous path. Test runs twice with --seed 123 but does not clear or disable state, so rotation baseline from prior run causes mismatch. Verification: running validate-story with --state-disabled keeps path stable ([1] both runs); with state enabled paths alternate ([1] then [0]). Remediation: adjust test to disable state or use unique temp state file / --clear-state before both runs. No runtime code change required unless we decide seeded + state should ignore lastPath.","created_at":"2026-01-12T09:46:30Z"}]} {"id":"ge-hch.3.4.3","title":"CI: validate-story gate","description":"## Summary\\nDedicated workflow to run validate-story on pushes/PRs when non-Markdown files change, before Playwright.\\n\\n## Acceptance Criteria\\n- New workflow triggers on push/PR and gates on non-Markdown diff.\\n- Runs npm ci and node scripts/validate-story.js across web/stories/**/*.ink.\\n- Fails job on validation failure.\\n- Runs before Playwright workflow (or as a prerequisite job).\\n\\n## Minimal Implementation\\n- .github/workflows/validate-story.yml with change detection.\\n- Matrix over stories or single pass over all files.\\n- Uploads logs/artifacts on failure.\\n\\n## Dependencies\\n- Validate CLI core.\\n\\n## Deliverables\\n- Workflow file and doc note.\\n\\n## Tasks to create\\n- Implement, Tests, Docs.","status":"open","priority":2,"issue_type":"feature","created_at":"2026-01-08T02:13:43.695830378-08:00","created_by":"rgardler","updated_at":"2026-01-08T02:13:43.695830378-08:00","labels":["feature"],"dependencies":[{"issue_id":"ge-hch.3.4.3","depends_on_id":"ge-hch.3.4","type":"parent-child","created_at":"2026-01-08T02:13:43.697506283-08:00","created_by":"rgardler"},{"issue_id":"ge-hch.3.4.3","depends_on_id":"ge-hch.3.4.1","type":"blocks","created_at":"2026-01-08T02:14:17.561303363-08:00","created_by":"rgardler"}]} {"id":"ge-hch.3.4.4","title":"Docs \u0026 fixtures for validate-story","description":"## Summary\\nDocument usage/options, path-rotation behavior, CI hook, and provide example outputs/fixtures.\\n\\n## Acceptance Criteria\\n- README/InkJS docs updated with validate-story usage, seed/rotation notes, CI hook description.\\n- Sample log/JSON output checked in (docs or fixtures).\\n- Notes on non-Markdown gating behavior in CI.\\n\\n## Minimal Implementation\\n- Doc section with commands and options.\\n- Example output snippet (JSON) and explanation of state file.\\n- Reference to CI workflow and how to clear state.\\n\\n## Dependencies\\n- Validate CLI core, Path rotation.\\n\\n## Deliverables\\n- Docs update + example fixture/log.\\n\\n## Tasks to create\\n- Implement, Tests, Docs.","status":"open","priority":2,"issue_type":"feature","created_at":"2026-01-08T02:13:52.56971808-08:00","created_by":"rgardler","updated_at":"2026-01-08T02:13:52.56971808-08:00","labels":["feature"],"dependencies":[{"issue_id":"ge-hch.3.4.4","depends_on_id":"ge-hch.3.4","type":"parent-child","created_at":"2026-01-08T02:13:52.571169285-08:00","created_by":"rgardler"},{"issue_id":"ge-hch.3.4.4","depends_on_id":"ge-hch.3.4.1","type":"blocks","created_at":"2026-01-08T02:14:22.124404224-08:00","created_by":"rgardler"}]} {"id":"ge-hch.3.4.5","title":"Implement: validate-story CLI core","status":"closed","priority":1,"issue_type":"feature","assignee":"patch","created_at":"2026-01-08T02:21:24.563632618-08:00","created_by":"rgardler","updated_at":"2026-01-08T21:00:15.89384788-08:00","closed_at":"2026-01-08T21:00:15.89385635-08:00","dependencies":[{"issue_id":"ge-hch.3.4.5","depends_on_id":"ge-hch.3.4","type":"parent-child","created_at":"2026-01-08T02:21:24.565684562-08:00","created_by":"rgardler"}],"comments":[{"id":35,"issue_id":"ge-hch.3.4.5","author":"rgardler","text":"patch starting implementation on branch feature/ge-hch.3.4-validate","created_at":"2026-01-09T04:35:37Z"},{"id":36,"issue_id":"ge-hch.3.4.5","author":"rgardler","text":"patch complete: implemented validate-story CLI and unit tests. Files: scripts/validate-story.js, tests/validate-story/validate-story.test.js, tests/fixtures/valid.ink, tests/fixtures/invalid.ink, package.json, package-lock.json, jest.config.js. PR: https://github.com/TheWizardsCode/GEngine/pull/new/feature/ge-hch.3.4-validate","created_at":"2026-01-09T04:59:47Z"}]} @@ -107,3 +107,4 @@ {"id":"ge-nzz","title":"Make root README InkJS-only","description":"Remove Unity references from the root README.md and focus it on InkJS/web demo usage and tests.","status":"closed","priority":1,"issue_type":"task","created_at":"2026-01-06T15:12:16.621516991-08:00","created_by":"rgardler","updated_at":"2026-01-06T15:13:37.065401561-08:00","closed_at":"2026-01-06T15:13:37.065401561-08:00","close_reason":"Done"} {"id":"ge-osd","title":"Restore original demo story for smoke tests","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-01-06T22:09:37.056596959-08:00","created_by":"rgardler","updated_at":"2026-01-06T22:10:00.371743266-08:00","closed_at":"2026-01-06T22:10:00.371743266-08:00","close_reason":"Done","comments":[{"id":1,"issue_id":"ge-osd","author":"rgardler","text":"Fixed smoke tests broken by demo story changes by adding web/stories/test.ink (pre-903f044 demo story) and routing /stories/demo.ink to that file in Playwright.\n\nChanges:\n- web/stories/test.ink\n- tests/demo.smoke.spec.ts\n\nCommands:\n- npm test","created_at":"2026-01-07T06:09:54Z"}]} {"id":"ge-s2q","title":"Implement: web/demo skeleton (InkJS integration)","status":"closed","priority":1,"issue_type":"task","created_at":"2026-01-05T23:10:10.569697121-08:00","created_by":"rgardler","updated_at":"2026-01-06T02:46:13.725365368-08:00","closed_at":"2026-01-06T02:46:13.725374498-08:00","dependencies":[{"issue_id":"ge-s2q","depends_on_id":"ge-hch.1.2.2","type":"discovered-from","created_at":"2026-01-05T23:10:10.574207891-08:00","created_by":"rgardler"}]} +{"id":"ge-wdm","title":"refactor(validate-demo): investigate skipped Playwright demo test","status":"open","priority":2,"issue_type":"task","assignee":"probe","created_at":"2026-01-12T00:34:02.866687423-08:00","created_by":"rgardler","updated_at":"2026-01-12T01:40:58.069109467-08:00","labels":["refactor"],"comments":[{"id":66,"issue_id":"ge-wdm","author":"rgardler","text":"Diagnostics (Probe): Playwright demo smoke suite currently fails locally because server is not started; page.goto http://127.0.0.1:4173/demo/ =\u003e ERR_CONNECTION_REFUSED for all tests. Command: npx playwright test tests/demo.smoke.spec.ts --reporter=list. Skip behavior: test 'choice can be selected via tap (touch)' includes test.skip when context lacks hasTouch; in this run hasTouch=true for chromium-touch project so it attempted and failed for same server reason, not skipped. Need to start dev server (e.g., npm run dev or npm run preview) with baseURL 4173 or use webServer in Playwright config. To repro skip, run chromium-desktop only or context with hasTouch=false; otherwise it runs. Next steps: add webServer to config or document pre-req; re-run with server active.","created_at":"2026-01-12T09:46:35Z"}]} diff --git a/scripts/validate-story.js b/scripts/validate-story.js index b5f391ea..1d224e74 100644 --- a/scripts/validate-story.js +++ b/scripts/validate-story.js @@ -31,8 +31,8 @@ function parseArgs(argv) { seed: null, maxSteps: DEFAULT_MAX_STEPS, output: 'json', - stateFile: null, - stateEnabled: false, + stateFile: DEFAULT_STATE_FILE, + stateEnabled: true, clearState: false, maxRetries: DEFAULT_MAX_RETRIES, }; @@ -59,6 +59,10 @@ function parseArgs(argv) { args.stateFile = argv[++i] || DEFAULT_STATE_FILE; args.stateEnabled = true; break; + case '--state-file-default': + args.stateFile = DEFAULT_STATE_FILE; + args.stateEnabled = true; + break; case '--clear-state': args.clearState = true; args.stateEnabled = true; @@ -67,12 +71,17 @@ function parseArgs(argv) { case '--max-retries': args.maxRetries = parseInt(argv[++i], 10) || DEFAULT_MAX_RETRIES; break; + case '--state-disabled': + case '--no-state': + args.stateEnabled = false; + args.stateFile = null; + break; case '--help': case '-h': args.help = true; break; - default: - break; + default: + break; } } @@ -80,6 +89,7 @@ function parseArgs(argv) { } function resolveStories(pattern) { + const resolvedPath = path.resolve(pattern); if (fs.existsSync(resolvedPath)) { const stats = fs.statSync(resolvedPath); @@ -234,9 +244,11 @@ function runStoryOnce(filePath, opts, lastPath) { function runStoryWithRotation(filePath, opts, lastPath) { const maxRetries = Math.max(1, opts.maxRetries || DEFAULT_MAX_RETRIES); + // When state is disabled, seeded runs remain deterministic and ignore previous paths. + const rotationBaseline = opts.seed != null && opts.useState === false ? null : lastPath; for (let attempt = 0; attempt < maxRetries; attempt += 1) { - const result = runStoryOnce(filePath, opts, lastPath); + const result = runStoryOnce(filePath, opts, rotationBaseline); if (result.error) return result; if (result.exhausted) { @@ -247,7 +259,7 @@ function runStoryWithRotation(filePath, opts, lastPath) { }; } - if (!lastPath || !arraysEqual(result.path, lastPath)) { + if (!rotationBaseline || !arraysEqual(result.path, rotationBaseline)) { return result; } @@ -265,7 +277,7 @@ function runStoryWithRotation(filePath, opts, lastPath) { story: filePath, pass: false, steps: 0, - path: lastPath || [], + path: rotationBaseline || [], error: `Failed to find alternate path for story ${filePath} after ${opts.maxRetries} retries`, }; } @@ -294,7 +306,7 @@ async function main() { return; } - const useState = args.stateEnabled || false; + const useState = args.stateEnabled; const stateFile = useState && (args.stateFile || DEFAULT_STATE_FILE) ? path.resolve(args.stateFile || DEFAULT_STATE_FILE) : null; @@ -316,12 +328,14 @@ async function main() { seed: args.seed, maxSteps: args.maxSteps, maxRetries: args.maxRetries, + useState, }, prev?.lastPath); if (useState) { const runCount = prev?.runCount ? prev.runCount + 1 : 1; + const lastPath = result.path; state[file] = { - lastPath: result.path, + lastPath, lastRunAt: new Date().toISOString(), runCount, }; diff --git a/tests/validate-story/validate-story.integration.test.js b/tests/validate-story/validate-story.integration.test.js index eeacfb23..9f3ec503 100644 --- a/tests/validate-story/validate-story.integration.test.js +++ b/tests/validate-story/validate-story.integration.test.js @@ -38,8 +38,8 @@ describe('validate-story CLI integration', () => { }) test('deterministic seeded runs produce same path', () => { - const r1 = runCLI(['--story', valid, '--seed', '123', '--output', 'stdout']) - const r2 = runCLI(['--story', valid, '--seed', '123', '--output', 'stdout']) + const r1 = runCLI(['--story', valid, '--seed', '123', '--output', 'stdout', '--state-disabled']) + const r2 = runCLI(['--story', valid, '--seed', '123', '--output', 'stdout', '--state-disabled']) let p1 = JSON.parse(r1.stdout.trim()) let p2 = JSON.parse(r2.stdout.trim()) if (Array.isArray(p1) && p1.length === 1) p1 = p1[0]