90 lines
4.6 KiB
Markdown
90 lines
4.6 KiB
Markdown
# ADR 0012: Headless CraftOS-PC As The Canonical Hypothesis Probe
|
|
|
|
## Status
|
|
|
|
Accepted
|
|
|
|
## Date
|
|
|
|
2026-06-09
|
|
|
|
## Context
|
|
|
|
[ADR-0005](adr-0005-craftos-pc-harness.md) made CraftOS-PC the local harness and
|
|
[ADR-0007](adr-0007-use-libtest-for-craftos-tests.md) /
|
|
[ADR-0008](adr-0008-keep-tests-runnable-in-craftos-and-in-game.md) /
|
|
[ADR-0009](adr-0009-layered-test-timeouts.md) wired it into the test suite via `just test`.
|
|
That work focused on the *test* path. Headless CraftOS-PC is also a cheap, deterministic
|
|
*interactive* tool: `craftos --headless --exec '<lua>; os.shutdown()'` boots the emulator,
|
|
runs an arbitrary Lua snippet against the real CC:Tweaked ROM, prints output to stdout,
|
|
and exits in well under a second. Humans and LLM agents can use it to verify hypotheses
|
|
about CC:Tweaked behavior *before* writing code or tests — "does `os.epoch('utc')` return
|
|
ms?", "does my new API factory `require` cleanly?", "does `fs.exists` follow symlinks
|
|
inside `--mount-ro`?".
|
|
|
|
Today this usage was implicit: the harness existed, but no document framed
|
|
`--headless --exec '...'` as the recommended first move when an agent is unsure about
|
|
CC:Tweaked behavior. The original recipe was also named `just craftos` even though it
|
|
mounted the entire TrapOS dev environment — so probes against it were never against
|
|
vanilla CC:Tweaked, even when the agent thought they were.
|
|
|
|
Two concrete changes triggered this ADR:
|
|
|
|
1. **Recipe split.** The old `just craftos` (TrapOS dev mounts + persistent `.craftos/`) is
|
|
renamed `just trapos`. A new `just craftos` launches a fresh, mount-less CraftOS-PC
|
|
under `.craftos-vanilla/`. A `just trapos-install` recipe exercises the real ccpm
|
|
bootstrap on an ephemeral state to validate the install path end-to-end.
|
|
2. **Explicit guidance.** Agents working in this repo should reach for a headless probe
|
|
the moment they catch themselves guessing about CC:Tweaked behavior, instead of
|
|
speculating or committing changes that only run `luacheck`.
|
|
|
|
## Decision
|
|
|
|
Frame headless CraftOS-PC as the canonical hypothesis-probe pattern, with two flavors:
|
|
|
|
- `just trapos --headless --exec '<lua>; os.shutdown()'` — probe against the **TrapOS dev
|
|
environment**. Mounts of `/apis`, `/programs`, `/servers`, `/startup`, `/tests`, and the
|
|
repo root at `/trapos` are live, so `require('/apis/eventloop')` and friends work
|
|
against the current branch. Use this when the question involves repo code.
|
|
|
|
- `just craftos --headless --exec '<lua>; os.shutdown()'` — probe against **vanilla
|
|
CraftOS-PC**. No mounts, no startup scripts. Use this when the question is purely about
|
|
CC:Tweaked behavior and TrapOS files would be a distraction, or to confirm a behavior
|
|
is upstream rather than something the dev env layered on.
|
|
|
|
- `just trapos-install` — drive the full real install (`install-ccpm.lua` →
|
|
`ccpm update` → `ccpm install trapos`) on a fresh ephemeral state. This is the probe
|
|
to run when changing anything in the install path itself.
|
|
|
|
Conventions:
|
|
|
|
- Always terminate the snippet with `os.shutdown()`. The shell watchdog from
|
|
[ADR-0009](adr-0009-layered-test-timeouts.md) governs `just test`, not these recipes;
|
|
a missing shutdown will hang until the user kills the process.
|
|
- Keep snippets minimal and side-effect-free. If the probe reveals a fact worth defending,
|
|
add a `libtest` case under `tests/` — probes are not a substitute for committed tests.
|
|
- LLM agents SHOULD prefer a quick headless probe over speculation when answering
|
|
"does X work in CC:Tweaked?" or "does my refactor still load?". The cost is one extra
|
|
emulator boot (~1s); the benefit is grounded answers instead of plausible-sounding ones.
|
|
|
|
## Consequences
|
|
|
|
- Higher CraftOS-PC invocation traffic during agent sessions; cheap enough that this is a
|
|
good trade.
|
|
- Faster convergence on correct fixes: agents stop committing speculative changes that pass
|
|
`luacheck` but fail in-game.
|
|
- A named pattern (`--headless --exec '<lua>; os.shutdown()'`) shows up in `CLAUDE.md` and
|
|
`DEVELOPMENT.md`, so contributors and agents reach for it without rediscovery.
|
|
- `.craftos-vanilla/` is added to `.gitignore` alongside `.craftos/`.
|
|
- `just trapos-install` is *not* part of `just ci`: it is network-dependent and slower
|
|
than `just test`. Run it manually when touching `install-ccpm.lua` or ccpm package
|
|
descriptors.
|
|
|
|
## Cross-references
|
|
|
|
- [ADR-0005](adr-0005-craftos-pc-harness.md) — CraftOS-PC as the local harness.
|
|
- [ADR-0007](adr-0007-use-libtest-for-craftos-tests.md) — libtest for CraftOS tests.
|
|
- [ADR-0009](adr-0009-layered-test-timeouts.md) — layered test timeouts.
|
|
- [ADR-0010](adr-0010-ccpm-package-manager.md) — ccpm package manager (drives the
|
|
`just trapos-install` flow).
|