feat: bootstrap walking skeleton
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
# ADR 0001: Web Stack And Engine Boundary
|
||||
|
||||
## Status
|
||||
|
||||
Accepted, 2026-06-11.
|
||||
|
||||
## Context
|
||||
|
||||
Idlegame is a text-first idle/incremental RPG. The UI is mostly panels, progress
|
||||
bars, action lists, resources, logs, and branching story choices. It must run
|
||||
well on phones from day one and remain easy to wrap later for desktop or mobile
|
||||
stores.
|
||||
|
||||
## Decision
|
||||
|
||||
Use TypeScript strict, Vite, React 19, Zustand, Tailwind v4, Vitest, Biome, and
|
||||
vite-plugin-pwa.
|
||||
|
||||
Keep gameplay rules in a pure TypeScript engine under `src/engine/`. React,
|
||||
Zustand, browser storage, requestAnimationFrame, and lifecycle hooks belong
|
||||
outside the engine.
|
||||
|
||||
Use plain JavaScript numbers behind `src/engine/num.ts` for M0/M1. Human-readable
|
||||
values are a design pillar; a Decimal-style dependency is deferred until a later
|
||||
layer proves it is needed.
|
||||
|
||||
## Consequences
|
||||
|
||||
- Engine behavior is headless-testable with Vitest.
|
||||
- UI and wrapper changes should not force gameplay rewrites.
|
||||
- Offline progress uses the same fixed-timestep simulation path as online play.
|
||||
- Save/load validation sits at explicit boundaries with versioned schemas.
|
||||
- Dependencies must be permissive; no GPL packages are allowed.
|
||||
@@ -0,0 +1,58 @@
|
||||
# Architecture
|
||||
|
||||
Idlegame is split into four layers.
|
||||
|
||||
## Engine
|
||||
|
||||
`src/engine/` contains deterministic gameplay logic:
|
||||
|
||||
- `tickLoop.ts`: fixed-timestep accumulator. Large elapsed deltas, including
|
||||
offline catch-up, drain through the same tick path as active play.
|
||||
- `game.ts`: core game state, active action progress, and resource accrual.
|
||||
- `save.ts`: versioned save schema, serialized export/import strings, and
|
||||
offline elapsed calculation.
|
||||
- `num.ts`: branded numeric boundary and human-readable formatting.
|
||||
|
||||
The engine must stay pure. It does not import React, Zustand, browser APIs,
|
||||
storage, requestAnimationFrame, or Date scheduling.
|
||||
|
||||
## Content
|
||||
|
||||
`src/content/` contains authored definitions validated by Zod. M0 includes one
|
||||
resource and one timed action. M1 expands this into real resources, actions,
|
||||
story nodes, automation unlocks, and prestige definitions.
|
||||
|
||||
## State
|
||||
|
||||
`src/state/` owns environment coupling:
|
||||
|
||||
- persistence backend selection: IndexedDB via `idb-keyval`, with localStorage
|
||||
fallback
|
||||
- load-on-boot and autosave orchestration
|
||||
- requestAnimationFrame loop and lifecycle hooks
|
||||
- mapping engine state to view models
|
||||
- Zustand store updates for React
|
||||
|
||||
## UI
|
||||
|
||||
`src/ui/` renders the view model and calls runtime commands. Components should
|
||||
not implement gameplay rules. The M0 shell includes a resource readout, action
|
||||
panel, progress bar, and event log.
|
||||
|
||||
## Verification
|
||||
|
||||
Run the full local gate before pushing:
|
||||
|
||||
```powershell
|
||||
pnpm typecheck
|
||||
pnpm lint
|
||||
pnpm test:coverage
|
||||
pnpm build
|
||||
```
|
||||
|
||||
Rendered checks for the walking skeleton:
|
||||
|
||||
- app loads without framework overlay or console errors
|
||||
- starting the timed action increments Gold after completion
|
||||
- reload preserves saved state
|
||||
- reopening after time away credits offline progress
|
||||
@@ -0,0 +1,163 @@
|
||||
# Idlegame — M0 Bootstrap Plan (handoff artifact for superpowers)
|
||||
|
||||
> **How to use this file:** the interview/brainstorm phase is complete; everything below is locked. Hand this plan to superpowers for execution (this copy in the working dir at `docs/plans/2026-06-11-m0-bootstrap.md` is canonical). Tasks are bite-sized with per-task verification so `executing-plans` can run them sequentially. Feature work after M0 flows through superpowers' brainstorm → plan → TDD cycle per feature.
|
||||
>
|
||||
> **Refined 2026-06-11 (same-day review pass, approved by ginnoir):** T3 split into T3.1–T3.4; T8 deploy auth + Caddy mechanics specified (romhacks-wiki precedent); Node policy `engines >=24` / CI on 24 LTS; pnpm 10 postinstall allowlist note; CI-required protection toggle moved from T6 to T7. No design decisions re-opened. Review-gate addition: per-task tool + model routing for M0 (§AI tool routing).
|
||||
|
||||
## Context
|
||||
|
||||
ginnoir is starting a commercial-grade idle/incremental game: a text fantasy RPG inspired by **Your Chronicle** (timed actions, resource generate/consume loops, story objectives), structured like a visual novel with branching choices, ending runs in a prestige system that avoids same-y repeats. Monetization, if ever: upfront purchase or cosmetics only — QoL and speed-up are never paywalled; any process completed once becomes automatable.
|
||||
|
||||
**M0 scope**: capture the locked design in the vault, stand up the multi-tool workflow (Gitea + CI + internal playtest deploys + Plane + Obsidian), and scaffold a walking-skeleton codebase. Gameplay (M1 vertical slice) is seeded as Gitea issues and built in later sessions.
|
||||
|
||||
Starting state: `C:\Users\MattC\Documents\idlegame` is empty except `docs/plans/`, not a git repo. Gitea runs at `gitea.ginnoir.com` (owner `ginnoir`, private default, HTTPS creds in GCM). No Gitea Actions runner exists yet. Plane is self-hosted on valhalla. Obsidian vault is the cross-project source of truth. Superpowers drives development workflow; all four AI tools (Claude Code, Codex, Antigravity, Cursor) get Obsidian MCP + local vault access.
|
||||
|
||||
## Locked design pillars (interview, 2026-06-11)
|
||||
|
||||
| Pillar | Decision |
|
||||
|---|---|
|
||||
| Platform | Responsive web + PWA; plays well on phones from day one. Steam (Tauri/Electron) and app-store (Capacitor) wraps are later milestones |
|
||||
| Visuals | Text-first UI: panels, progress bars, action lists, event log. No art pipeline |
|
||||
| Combat | Light/abstracted — timed actions with stat checks and risk/reward; no battle screen in v1 |
|
||||
| First playable (M1) | Vertical slice: one short story arc → first prestige reset; branching choice; automation unlock; offline progress; save/load |
|
||||
| Prestige | **Hybrid**: aggressive catch-up *within* a layer (Magic Research style — keep knowledge, blast through known content); genuinely new mechanics *between* layers (Antimatter Dimensions style) |
|
||||
| Numbers | Human-readable throughout (≤ billions). No scientific-notation spectacle |
|
||||
| Pacing | Semi-active (Your Chronicle-like): queue actions, choices every few minutes; idles/offline fine |
|
||||
| Story authoring | Outline together in Obsidian; Claude drafts prose; ginnoir reviews/edits |
|
||||
| Automation principle | Complete a process once → it becomes automatable (generous, progression-gated) |
|
||||
| CI/CD | Gitea Actions runner on valhalla; typecheck/lint/test/build on push; auto-deploy dev build to internal-only playtest URL |
|
||||
| Tracking | Plane = roadmap/epics. Gitea Issues = code-level tasks (commit/PR auto-linking) |
|
||||
| Codename | `idlegame` (rename later is cheap in Gitea) |
|
||||
|
||||
## Tech stack (researched recommendation)
|
||||
|
||||
**TypeScript (strict) + Vite + React 19 + Zustand, with the game engine as a pure-TS module that never imports React.**
|
||||
|
||||
- Genre precedent: every successful game in this genre is a web app — Antimatter Dimensions (Vue), Magic Research (React), Melvor Idle (web, wrapped for Steam/mobile). Text/UI-heavy idle games are DOM games; Godot/Unity fight you on UI and bloat web exports.
|
||||
- React over Svelte/Vue: deepest fluency across all four AI tools — important when agents write most of the code. Perf is a non-issue with the core/view split: engine ticks on its own loop; UI subscribes to snapshots at ~10 fps via Zustand selectors.
|
||||
- The engine/view split is the load-bearing decision: headless-testable game core (Vitest, no DOM); Tauri/Capacitor wraps or even a framework swap later touch only the view.
|
||||
- **Considered & rejected**: Profectus (MIT, Vue, Modding-Tree lineage, ~34 stars — license fine but Vue-locked, shaped for tree-prestige games, community too small for a commercial bet); The Modding Tree (older JS, same shape); Godot (canvas UI friction for a text game).
|
||||
|
||||
Dependencies (all permissive; the game stays proprietary — no GPL anywhere):
|
||||
|
||||
| Dep | License | Role |
|
||||
|---|---|---|
|
||||
| react, zustand | MIT | view + state bridge |
|
||||
| zod | MIT | schema validation for content definitions and saves |
|
||||
| lz-string | MIT | compressed save export/import strings |
|
||||
| idb-keyval | Apache-2.0 | IndexedDB persistence (localStorage fallback) |
|
||||
| vite, vite-plugin-pwa, workbox | MIT | build + installable PWA |
|
||||
| tailwindcss v4 | MIT | styling for the text-first UI |
|
||||
| biome, vitest, (playwright later) | MIT/Apache-2.0 | lint+format, unit tests, E2E later |
|
||||
|
||||
Toolchain: **pnpm**, **Node 24 LTS as the CI/runtime baseline** — `engines: { "node": ">=24" }` (a floor, not an exact pin: local boxes may run newer — Node 25.9 verified working 2026-06-11; a strict `24.x` pin makes every local `pnpm install` warn), `.nvmrc` = `24`, and CI jobs run a `node:24` image so the LTS pin is enforced where determinism matters. Numbers: plain JS numbers behind `src/engine/num.ts` (format + branded type); ADR documents the Decimal escape hatch if a late prestige layer ever needs it.
|
||||
|
||||
## Workflow architecture
|
||||
|
||||
- **Repo**: `gitea.ginnoir.com/ginnoir/idlegame`, private. Trunk `main` (protected, CI required), feature branches + PRs, conventional commits, self-merge allowed (solo + AI dev).
|
||||
- **Issues**: Gitea labels (`type/feat|fix|content|infra`, `area/engine|ui|story|workflow`, `prio/1-3`), milestones `M0 Scaffold`, `M1 Vertical Slice`. Issue templates (feature/bug/content) + PR template in `.gitea/`.
|
||||
- **Plane**: project "Idlegame" with epics (Vertical Slice, Workflow & Infra, Game Design). Epics link Gitea issues by URL; day-to-day work lives in Gitea.
|
||||
- **CI** (`.gitea/workflows/ci.yml`): pnpm install → `typecheck` → `biome ci` → `vitest run --coverage` → `build` → upload `dist` artifact.
|
||||
- **Deploy** (on push to `main`): rsync `dist/` over SSH (dedicated deploy key stored as repo Actions secrets) to valhalla's Caddy site dir `/config/caddy/site/idlegame/` → `idlegame.ginnoir.com`, **internal-only during development** (Caddy `import internal_only` — same pattern as other internal sites; no auth layer needed). Precedent: romhack-archive-site static deploy (`/config/caddy/site/romhacks-wiki`).
|
||||
- **Runner**: `act_runner` container (docker mode, outbound polling only) added to homelabstack's `dev` stack, following that repo's conventions — read `Homelab/_Claude.md` + `Deploy.md` in the vault before touching homelabstack (applies to T7 **and** T8).
|
||||
|
||||
## Cross-tool agent layer
|
||||
|
||||
- **`AGENTS.md` is canonical** — Linux Foundation standard; Codex, Cursor, and Antigravity read it natively. Contents: project overview, commands, architecture map, conventions (commits, PR flow, engine/view boundary rules), the context-layer contract, and the tool-routing table below.
|
||||
- **`CLAUDE.md`** = `@AGENTS.md` import + Claude-only extras (superpowers notes, vault skill pointers).
|
||||
- **Context-layer contract** (stated in AGENTS.md): Obsidian vault (all tools have MCP + the local folder `C:\Users\MattC\Documents\Obsidian Vault\`; record both in AGENTS.md) = design docs, story, decisions, session memory. **API tokens tools authenticate with live in the vault at `claude/Credentials.md`** — never in the repo. Repo `docs/` = code-truth (README, ADRs, architecture, superpowers plans in `docs/plans/`). Gitea Issues = work items. Every tool writes session outcomes back to the vault.
|
||||
|
||||
## AI tool routing (light)
|
||||
|
||||
One tool per issue/branch at a time; everything lands via PR; AGENTS.md + vault are the shared brain regardless of tool.
|
||||
|
||||
| Tool | Best at | Route these tasks |
|
||||
|---|---|---|
|
||||
| **Claude Code** (+ superpowers) | Architecture, multi-step planning, nuanced writing, big multi-file features, code review | Engine/systems design, prestige & balance design, story outlining + prose drafts, milestone planning, reviewing other tools' PRs, vault stewardship |
|
||||
| **Codex** | Long autonomous runs on well-scoped tasks, gnarly debugging, test discipline | Well-scoped implementation tickets, bug hunts with repro steps, test-coverage passes, mechanical refactors |
|
||||
| **Antigravity** | Frontend work with built-in browser verification, multimodal/screenshot feedback, large-context research | UI implementation + polish, responsive/mobile layout passes, visual verification of the playtest build, competitive research (other idle games) |
|
||||
| **Cursor** | Interactive pair-programming, fast small edits while ginnoir drives; agent mode now frontier-class (Composer 2.5 ≈ Opus 4.8 on benchmarks, June 2026) | Quick fixes, small scoped tweaks, exploratory fiddling, anything ginnoir wants to steer by hand; credible alternate for Codex-lane scoped tickets |
|
||||
|
||||
Rule of thumb: design and words → Claude; heads-down scoped code → Codex; anything you need to *see* → Antigravity; anything you're driving yourself → Cursor.
|
||||
|
||||
### Per-task routing (M0)
|
||||
|
||||
Applies the rules above to T1–T10. Claude Code legitimately dominates M0 — it's workflow/infra/writing-heavy by design; Codex and Antigravity take the tasks where they genuinely win. **Cursor has no M0 assignment** (its lane is ginnoir-driven interactive edits; M0 runs autonomously — Cursor's turn starts at M1). **Default execution mode is unchanged**: a single superpowers/Claude Code `executing-plans` run per the header; the table says who's *best* per task — route T2/T3.2/T3.3/T3.4 out to Codex/Antigravity only if ginnoir wants to shake down the multi-tool workflow during M0. For M1+ feature work the table's logic is the standing template.
|
||||
|
||||
**Claude Code primary is Opus 4.8** — Fable 5 access ends **2026-06-22**, so nothing durable relies on it. ⭐F marks the tasks that benefit most from Fable 5 while it lasts (the highest-judgment writing and architecture calls); if M0 executes before the cutoff, running the whole thing on Fable 5 is fine.
|
||||
|
||||
| Task | Tool | Model | Why |
|
||||
|---|---|---|---|
|
||||
| T1 vault notes | Claude Code | Opus 4.8 ⭐F | Vault stewardship; GDD/story prose quality compounds downstream |
|
||||
| T2 scaffold | Codex | GPT-5.5-Codex (medium) | Well-scoped ticket, command-line verification, gotchas pre-spelled-out; alt: Cursor agent (Composer 2.5) |
|
||||
| T3.1 num + tick loop | Claude Code | Opus 4.8 ⭐F | Load-bearing engine architecture: API shape + TDD, not heads-down typing |
|
||||
| T3.2 resource + action | Codex | GPT-5.5-Codex (medium) | Scoped code on shapes T3.1 fixed; fully test-gated |
|
||||
| T3.3 saves + persistence | Codex | GPT-5.5-Codex (highest effort tier) | Save integrity = the data-loss surface; strongest test discipline |
|
||||
| T3.4 Zustand + React shell | Antigravity | Gemini 3 Pro (high thinking) | Browser verification watches the progress bar, reload, offline credit |
|
||||
| T4 AGENTS.md + docs | Claude Code | Opus 4.8 ⭐F | The conventions doc every other tool reads |
|
||||
| T5 git + Gitea repo | Claude Code | Sonnet 4.6¹ | API glue with vault-held creds; mechanical |
|
||||
| T6 repo config | Claude Code | Sonnet 4.6¹ | Labels/protection/templates via API |
|
||||
| T7 Actions runner | Claude Code | Opus 4.8 | Touches the live homelab stack; vault conventions + care |
|
||||
| T8 playtest deploy | Claude Code | Opus 4.8 | Secrets, Caddy, cross-repo infra; Antigravity optional for browser/PWA verify-assist |
|
||||
| T9 Plane + M1 seeding | Claude Code | Opus 4.8 ⭐F | Issue prose = the contract for M1 sessions |
|
||||
| T10 write-back | Claude Code | Sonnet 4.6¹ | Vault stewardship, mechanical |
|
||||
|
||||
¹ Tier note: if M0 runs as one continuous `executing-plans` session (lowest-friction path), stay on one model throughout — the Sonnet 4.6 entries mean "this tier suffices when run standalone / cost-sensitive."
|
||||
|
||||
Caveats: (a) all of T3 predates the repo (git init is T5), so M0 handoffs to Codex/Antigravity land directly in the working dir without the PR gate — hand off only at task boundaries with green tests; full one-tool-per-branch discipline starts at M1. (b) Model names current as of 2026-06-11 (Opus 4.8 / Sonnet 4.6 standing, Fable 5 only until 2026-06-22; GPT-5.5-Codex; Gemini 3 Pro; Cursor Composer 2.5, which benchmarks ≈ Opus 4.8 — making it Cursor's default for everything and Cursor agent a credible Codex-lane alternate at M1+) — substitute each tool's newest equivalent tier at execution time.
|
||||
|
||||
## Obsidian vault additions
|
||||
|
||||
Per `claude/Vault.md` convention: `Idlegame/_Claude.md` (what it is, working dir, repo URL, standing rules — monetization stance, automation principle, prestige philosophy — quick-nav, session log, `[[Context]]` backlink); `Idlegame/GDD.md` (pillars + core loops from the interview); `Idlegame/Story/Outline.md` (authoring-workflow skeleton); `Idlegame/Decisions.md` (design ADR-lite; code ADRs live in repo). Add the row to `claude/Context.md`'s project table.
|
||||
|
||||
## Scaffold layout
|
||||
|
||||
```
|
||||
idlegame/
|
||||
AGENTS.md CLAUDE.md README.md LICENSE.md (proprietary notice)
|
||||
.gitea/workflows/{ci,deploy}.yml .gitea/issue_template/ PR template
|
||||
.nvmrc package.json tsconfig.json (strict) biome.json vite.config.ts (PWA)
|
||||
docs/adr/0001-tech-stack.md docs/architecture.md docs/plans/ (superpowers plans)
|
||||
src/engine/ ← pure TS: fixed-timestep tick loop + offline catch-up, resources,
|
||||
action queue, story graph, prestige hooks, versioned saves
|
||||
(zod-validated, lz-string export), num.ts
|
||||
src/content/ ← data-driven, zod-validated definitions (resources, actions, story nodes)
|
||||
src/state/ ← zustand bridge: engine snapshots → view
|
||||
src/ui/ ← React shell: action panel, resource bar, event log, settings
|
||||
src/engine/__tests__/ ← engine core target: 80%+ coverage
|
||||
```
|
||||
|
||||
The scaffold ships a **walking skeleton**, not gameplay: 1 resource, 1 timed action, tick loop with offline catch-up, save → reload → intact. Proves the architecture end to end; M1 makes it a game.
|
||||
|
||||
## Tasks (superpowers-executable, in order)
|
||||
|
||||
**T1 — Vault project setup.** `Idlegame/_Claude.md` and the `claude/Context.md` row already exist (created at planning handoff) — extend `_Claude.md`, don't recreate. Create `Idlegame/GDD.md`, `Idlegame/Story/Outline.md`, `Idlegame/Decisions.md` (content from this plan). *Verify: vault_read returns each note; Context.md table has the row.*
|
||||
|
||||
**T2 — Scaffold the app.** Vite react-ts template → strict tsconfig, Biome, Vitest, Tailwind, vite-plugin-pwa, folder layout above (except `.gitea/workflows/deploy.yml` — deferred to T8 so deploy never runs red before its secrets exist), `.nvmrc` (`24`) + `engines: { "node": ">=24" }`. pnpm 10 blocks dependency postinstall scripts by default — allowlist build deps (esbuild etc.) via `pnpm.onlyBuiltDependencies` in `package.json` (or `pnpm approve-builds`), or the toolchain silently breaks. *Verify: `pnpm typecheck && pnpm lint && pnpm test && pnpm build` all green; `pnpm dev` serves; manifest in build output.*
|
||||
|
||||
**T3 — Walking skeleton (TDD, four sub-tasks).** Tests first throughout; engine code never imports React.
|
||||
|
||||
- **T3.1 — Engine core: `num.ts` + tick loop.** Branded number type + human-readable formatting; fixed-timestep accumulator loop (`advance(now)`) where offline catch-up is the same code path (large delta → many ticks, batch-capped). Configure Vitest coverage thresholds here (≥80% on `src/engine/`). *Verify: tests green; determinism test — N elapsed seconds always yields the same tick count.*
|
||||
- **T3.2 — One resource, one timed action.** Zod-validated content definitions in `src/content/`: one resource, one timed action (duration → yields resource); action progress advances per tick, completion grants the yield. *Verify: accrual + completion unit tests green.*
|
||||
- **T3.3 — Versioned saves + persistence.** Zod save schema with version field, serialize/deserialize, lz-string export/import string, idb-keyval persistence (localStorage fallback), autosave + load-on-boot, offline elapsed credited on load. *Verify: round-trip test; invalid/tampered save rejected cleanly; offline-credit unit test.*
|
||||
- **T3.4 — Zustand bridge + React shell.** Engine snapshots → Zustand store (~10 fps); minimal UI: resource readout, start-action button with progress bar, event log stub. *Verify: engine files ≥80% coverage overall; manual — action completes, resource increments, reload preserves state, offline time credited.*
|
||||
|
||||
**T4 — Agent layer + docs.** AGENTS.md (incl. routing table + context contract + vault local path), CLAUDE.md import, README, ADR-0001 (stack), `docs/architecture.md`; this plan already lives at `docs/plans/2026-06-11-m0-bootstrap.md` — keep it current. *Verify: files exist; AGENTS.md states commands that actually run.*
|
||||
|
||||
**T5 — Git + Gitea repo.** `git init -b main` (git 2.46 may default to `master`), conventional commits, create private repo via Gitea API, push `main`. *Verify: repo visible at gitea.ginnoir.com/ginnoir/idlegame with full tree.*
|
||||
|
||||
**T6 — Repo config.** Labels, milestones M0/M1, issue/PR templates live, protect `main` (no direct pushes, PRs required, self-merge ok). The **CI-required** status check is deliberately deferred to T7 — flipping it on before a runner exists would leave `main` unmergeable. *Verify: direct push to main rejected; templates render on new-issue page.*
|
||||
|
||||
**T7 — Actions runner.** Read `Homelab/_Claude.md` + `Deploy.md` first. Add `act_runner` (docker mode) to homelabstack `dev` stack per that repo's conventions; register with token; enable Actions on the repo. After the first green run, flip **CI-required** on `main`'s protection (deferred from T6). *Verify: a test branch push runs CI to green on the runner (`main` rejects direct pushes by now); merging to main now requires green CI.*
|
||||
|
||||
**T8 — Playtest deploy.** Read `Homelab/_Claude.md` + `Deploy.md` first (same rule as T7). Auth: generate a dedicated ed25519 deploy keypair; append the pubkey to the `ginnoir` user's `authorized_keys` on valhalla; store private key + `known_hosts` as repo Actions secrets via the Gitea API. Create `.gitea/workflows/deploy.yml` here (deferred from T2): on push to `main`, build → rsync `dist/` over SSH to `valhalla:/config/caddy/site/idlegame/` (mirrors the romhacks-wiki precedent). Caddy block in homelabstack: `idlegame.ginnoir.com` with `import internal_only`, `file_server`, SPA `try_files` fallback to `/index.html` (PWA routing); lands via the existing Caddyfile push workflow. *Verify: DNS resolves on LAN (add a host entry per homelab conventions if no wildcard covers it); URL loads the walking skeleton on desktop and phone (LAN); PWA installable.*
|
||||
|
||||
**T9 — Plane + M1 seeding.** *(Caddy bypass done 2026-06-11, commit `9935041` in homelabstack — `/api/*` + `X-API-Key` now routes directly to `plane_api:8000`, bypassing Authentik; verified.)* Plane project "Idlegame" + 3 epics via API (key in vault `claude/Credentials.md`); ~10 M1 issues in Gitea (engine tick/offline, resource & action definitions, action queue UI, story graph + first branch, automation unlock, prestige reset, save migrations, mobile layout pass, opening-arc content, balance pass), labeled and milestoned, linked from epics. *Verify: Plane shows epics; Gitea milestone M1 lists the issues.*
|
||||
|
||||
**T10 — Write-back.** Session outcomes → `Idlegame/_Claude.md` session log; mark M0 complete in Gitea. *Verify: vault note updated; M0 milestone closed.*
|
||||
|
||||
No task needs to ask ginnoir for secrets or approval: the Gitea admin API token and the Plane API key live in the vault at `claude/Credentials.md` (local file: `C:\Users\MattC\Documents\Obsidian Vault\claude\Credentials.md`). Runner registration tokens are minted at deploy time via `POST /api/v1/admin/actions/runners/registration-token` (the GET route 404s on Gitea 1.26.2; CLI fallback: `docker exec gitea gitea actions generate-runner-token` on valhalla). The T8 deploy keypair is generated at execution time and stored via the Gitea secrets API — no secret passes through ginnoir's hands. Verified 2026-06-11: Gitea token has admin scope, Actions enabled, 0 runners registered. Plane API Caddy bypass is live (homelabstack `9935041`, 2026-06-11) — all tasks T1–T10 can run fully autonomously.
|
||||
|
||||
## Out of scope (later milestones)
|
||||
|
||||
M1 gameplay itself; Steam/Tauri and Capacitor wraps; Playwright E2E; release tagging + changelog; i18n; cloud saves; public playtest access.
|
||||
Reference in New Issue
Block a user