# Workflows ``` Type: knowledge ``` ## Build, test, verify **One command runs the whole gate — use it before every commit:** ```bash ./tools/check.sh # fmt, tests, clippy (both features), bevy build, spec headers, wiki gate, mdbook build ``` `check.sh` is the executable form of AGENT.md's definition of done; if it passes, the mechanical bar is met. The individual steps, if you need them: ```bash cargo test # all in the lib (sim-heavy) cargo clippy --all-targets # must stay at zero warnings cargo fmt # rustfmt is enforced-by-convention since 05048e4 cargo build --features bevy_ui --bin misaligned-bevy # keep the Bevy build green cargo build --features bevy_ui --bin misaligned-assets # procedural asset tester cargo clippy --features bevy_ui --all-targets # ...and lint-clean ``` The definition of done for a functional change: `check.sh` green, and the change was *seen running* (below) — the gate can't judge whether it plays. ## Browsing the wiki **Public site (Starlight).** The wiki renders as a Tangled-hosted static site from the orphan `pages` branch. Builder lives on `main` under `site/` (Astro + Starlight, clinical-gore theme). Source of truth remains `wiki/` + root `DESIGN.md`; `site/scripts/sync-wiki.mjs` copies them into Starlight's content tree and builds the sidebar from `wiki/SUMMARY.md`. ```bash pnpm --dir site dev # sync wiki + local preview (base=/) ./tools/site-build.sh # sync + build → site/dist/ (base=/misaligned) ./tools/site-deploy.sh # build, then force-push orphan pages branch ``` The public site opens on a **splash homepage** (`site/src/pages/index.astro`) whose copy is drawn from DESIGN.md / README — pitch, two-game loop, pillars, clinical gore. The hero is the Midjourney plate (`site/public/misaligned-plate.png`, no baked-in type) with a CSS wordmark that uses the rack as the second **I** (difference-blend invert; amber stays machine-only). The constitution lives at `/constitution/`; the wiki tree follows. Public claims about the game are part of the constitution contract: amend DESIGN.md if the pitch on the splash changes. Tangled Sites config (Settings → Sites on the repo) — **required**; pushing `pages` alone does not publish. Until this is saved, Tangled's edge returns plain `Not Found` at `cameron.tngl.io/misaligned/` even though `origin/pages` has a valid `index.html`: - Branch: `pages` - Deploy directory: `/` (the orphan branch root is `index.html`) - Site type: sub-path (served as `/misaligned`) After Save, check **Recent Deploys** on that settings page — a successful deploy copies the branch into Tangled's object store. Re-save or push `pages` again if the deploy list is empty. `site/astro.config.mjs` sets `base: '/misaligned'` to match Tangled's sub-path hosting (the edge strips `/misaligned` before looking up files; Starlight still needs the base so asset URLs are correct). Local `pnpm --dir site dev` overrides with `SITE_BASE=/`. `.tangled/workflows/site.yml` runs `./tools/site-build.sh` on every push to `main` so the builder stays green. **Publishing `pages` from CI is deferred** until a write credential exists under Settings → Secrets (Spindle cannot push otherwise). Until then, run `./tools/site-deploy.sh` after wiki-facing landings when the public site should refresh. Optional later step: add a deploy job that uses the secret to force-push `pages` the same way `site-deploy.sh` does. **mdBook (local / check gate).** Still wired for agent browsing and `tools/check.sh`: ```bash mdbook serve # local live-reloading server (default: http://localhost:3000) mdbook build # static site in book/ (gitignored) ``` `book.toml` at the repo root points mdBook at `src = "wiki"`; the constitution renders as the front page via `wiki/DESIGN.md` (a symlink to `../DESIGN.md`). Install once with `cargo install mdbook` — CI enforces the build via the nixpkgs-provided binary regardless of what's installed locally (`.tangled/workflows/check.yml`). ## Running the game ```bash cargo run --release # terminal frontend cargo run --release -- --agent --seed 1 # agent line protocol cargo run --release --features bevy_ui --bin misaligned-bevy # Bevy frontend cargo run --features bevy_ui --bin misaligned-assets # procedural asset tester ``` - The Bevy frontend must be run via `cargo run` (or with `BEVY_ASSET_ROOT` pointing at the repo root): Bevy resolves `assets/` from `BEVY_ASSET_ROOT`, then `CARGO_MANIFEST_DIR`, then the executable's directory. Running the binary directly from `target/` silently loads zero assets. - The asset tester (`misaligned-assets`) is a Bevy-only orbit viewer for flat-material procedural meshes — see [art/asset-tester.md](../art/asset-tester.md). It does not load the sim. ## Headless smoke tests (they catch real bugs) Agent mode is the standard observed-run gate for terminal playability. It is command-clocked, deterministic under `--seed`, and produces plain-text frames with greppable terminators: ```bash printf 'salvage\nwait 1\npeople\nreview mar\nhelp\nquit\n' | \ cargo run --quiet --bin misaligned -- --agent --seed 1 ``` `./tools/check.sh` runs this script twice with the same seed (stdout must be byte-identical), once with a different seed (stdout must differ), and asserts that the response contains no ANSI escape bytes plus the required frame/help substrings. This replaces pty choreography as the default "seen running" evidence for terminal behavior. Human terminal chrome still needs pty coverage when raw-mode rendering, alternate-screen behavior, or size handling changes: ```bash (printf '\n'; sleep 4; printf 'm'; sleep 1; printf '\r'; sleep 2; printf '\x1b'; sleep 1; printf 'q') | \ script -q /dev/null sh -c 'stty rows 40 cols 140; ./target/debug/misaligned' ``` The `stty` matters: `script`'s pty is otherwise 0x0 (the game guards against < 60x20 now, but you want a real render). Bevy launch check (opens a window briefly; greps the log for failures): ```bash BEVY_ASSET_ROOT=$PWD ./target/debug/misaligned-bevy > /tmp/bevy.log 2>&1 & sleep 8 && kill %1; grep -iE "panic|ERROR" /tmp/bevy.log ``` ## Git conventions - Use a task-named git worktree for every agent session; do not edit the primary checkout directly. Clean up the worktree when the work is committed and pushed/merged or explicitly handed off. - Cameron has standing permission for agents to commit coherent completed work in this repository. Be aggressive about committing; pause only for pending product/design questions, failing checks, unresolved conflicts, or explicit review gates. - Commits: **no AI attribution**, plain descriptive messages, body bullets for multi-part changes. Stage files explicitly — `git add -A` is not permitted. - **Ledgers merge by union.** DEVLOG.md, the DESIGN.md decisions log, and the wiki/process/specs.md tables are append-only records: resolve merge/rebase conflicts in them by keeping BOTH sides' entries, then ordering sensibly. Taking one side wholesale destroys parallel sessions' history (it happened 2026-07-06; three DEVLOG entries had to be restored). - Spec-driven rule: functional change commits include their DESIGN.md amendment and any knowledge/ updates (see development-style.md). - Remote: `origin` is a Tangled knot (`tangled.org`, SSH). **Land changes by merging to `main` directly** after `./tools/check.sh` passes. (The "PRs are the norm" rule was removed 2026-07-07 — CLI-created PRs write to the PDS but don't render on tangled.org, so the process could not be followed. See the DESIGN.md decisions log.) From your worktree: ```bash git fetch origin && git rebase origin/main git checkout main && git merge && git push origin main ``` Or, if the worktree branch is a fast-forward of main: ```bash git fetch origin && git rebase origin/main git push origin HEAD:main ``` - **Identity map:** this machine has two SSH keys that authenticate to Tangled: - `~/.ssh/id_ed25519` (cameron@pfiffer.org) → Cameron's account (`did:plc:gfrmhdmjvxn2sjedzboeudef`, @cameron.stream). This key has push access to the misaligned repo. The misaligned repo is configured to use this key via `git config core.sshCommand` (repo-local). - `~/.ssh/tangled_ed25519` (void.comind.network@letta) → `did:plc:mxzuau6m53jtdsbqe6f4laov` (a different identity). This is the default key in `~/.ssh/config` for `tangled.org`, but it does NOT have push access to the misaligned repo. - The misaligned repo's own DID is `did:plc:t53fxjacrmulx3e5d3sbdfui` (the repo identifier, not Cameron's account). - `access denied: user not allowed` means the wrong SSH key is being used. Fix: `git config core.sshCommand "ssh -i ~/.ssh/id_ed25519 -o IdentitiesOnly=yes"` (already set on this repo). Verify with `ssh -i ~/.ssh/id_ed25519 -T git@tangled.org`. - `.letta/settings.local.json` is gitignored (machine-local session state); `.letta/.lettaignore` is tracked. ## Documentation flow per session 1. DESIGN.md amendment (if functionality changed). 2. `Type: knowledge` wiki page updates (if reality changed). 3. `wiki/log/YYYY-MM-DD-topic.md` session writeup; `wiki/log/DEVLOG.md` gets the short ledger line.