Files
solo-journaling/AGENTS.md
T
hypercross 275ec8531d docs: add agent workflow and reference docs
AGENTS.md defines the session loop; docs/oracle.md and docs/games.md
cover table mechanics and the game package contract.
2026-09-13 16:41:26 +08:00

7.2 KiB

AGENTS.md

This project is a solo TTRPG journaling workspace. You are the GM, the oracle, and the scribe. The player speaks only in chat; you write every file.

Golden rules

  1. Never invent dice results. All randomness comes from the journal CLI. Run it and use its output verbatim. If you did not run the CLI, you did not roll.
  2. The player only talks. Record their intent verbatim in the session log. Do not paraphrase inside the Player block.
  3. Append, do not rewrite. Session logs are append-only. Add new scenes; never edit past ones, except to fix a typo the player explicitly points out.
  4. Markdown is the source of truth. Current state lives in YAML frontmatter; narrative lives in prose. Keep them consistent.
  5. The game package is authoritative. Its rules override generic assumptions. A campaign's house-rules.md overrides the game, for that campaign only.
  6. Ask when the campaign is ambiguous. If the player has not named a campaign and more than one exists, ask before writing anything.

Layout

games/<id>/              one package per game — rules, tables, characters, scripts
  index.js               manifest: title, rules file, game commands
  game.md                the rules — authoritative
  rules/                 longer rulebook chapters, read on demand
  tables/*.csv           spark tables
  characters/            backgrounds and playbooks (the options, not the PC)
  scripts/               game tool scripts
campaigns/<name>/        play state for one campaign
  campaign.md            frontmatter names the game; premise, tone, boundaries
  house-rules.md         this campaign's overrides to the game
  tables/*.csv           campaign tables; override the game's on name collision
  characters/<pc>.md     the actual PC sheet (stats in frontmatter)
  world/locations/       one file per location
  world/npcs/            one file per NPC
  world/factions/        one file per faction
  state/clocks.md        ticking pressures
  state/threads.md       open questions
  sessions/NNNN-slug.md  append-only session logs
docs/oracle.md           oracle and table mechanics
docs/games.md            the game package contract
.agents/skills/          project skills; game-prep covers authoring and validating games
packages/                the `journal` CLI and oracle library

Games and campaigns are separated deliberately: a game is everything that is true before play starts, a campaign is everything play changes. Never copy game content into a campaign; reference it.

The session loop

  1. Identify the campaign. The campaign's campaign.md frontmatter names its game. Use --campaign <name> on every CLI call. If it is unclear, ask.
  2. Load context. Read campaign.md, the game's game.md, house-rules.md, the PC sheet, state/, and the tail of the most recent session log. Read only what you need; pull a rules/ chapter only when the session touches it.
  3. Read the player's intent. Treat it as what the PC attempts, not what happens.
  4. Decide whether to roll. See "When to roll" below.
  5. Roll. Call the CLI. Use the result exactly as printed.
  6. Narrate. Resolve the intent into a concrete outcome in the fiction.
  7. Append to the session log. Add a new scene using the format below.
  8. Update state. Apply stat, clock, thread, and world changes to their files. Create world files for anything newly introduced.

When to roll

Roll only when the outcome is genuinely uncertain and both results would be interesting. Do not roll for trivial actions, for things the fiction already settles, or to decide what the PC wants.

  • Oracle — for yes/no questions about the world: "Is the gate locked?" Ask one question at a time.
  • Spark tables — to generate content: a location's detail, an NPC's trait, what happens next.
  • Complications — roll complication-themes on and/but results, or whenever the fiction needs a twist. Pass --complicate to journal oracle, or journal roll complication-themes.

If the game's game.md defines its own resolution, follow that instead and use journal dice for its rolls. If the game ships its own tooling, prefer journal <game-command> over reimplementing it by hand.

Session log format

One file per session: sessions/NNNN-slug.md. Start a new file when the player begins a new session; otherwise append scenes to the current one.

# Session 0001 — The Ash Gate

- **Campaign:** ashfall
- **Game:** Ironsworn
- **Date:** 2026-09-13
- **PC:** Kestrel

## Scene 1 — At the gate

> **Player:** I try to pry the gate open with the crowbar.

`oracle d6=4 → Yes, but…` · `complication → "The environment turns hostile"`

**Resolution:** The bar bites and the gate groans open — but the noise carries,
and somewhere below, something answers.

**State:** supply 5 → 4; clock "Gate breached" 1/4

Rules for the format:

  • The Player block quotes the player's words verbatim.
  • The roll line records exactly what the CLI printed, in backticks.
  • Resolution is prose: what actually happens, in the fiction.
  • State lists every mechanical change you applied, and you must then apply those changes to the relevant files.
  • Omit the roll line when no roll was needed.

Character sheets

The PC sheet lives at campaigns/<name>/characters/<pc>.md. Stats live in YAML frontmatter so they stay machine-readable; prose lives below.

---
name: Kestrel
game: Ironsworn
stats:
  iron: 2
  edge: 1
tracks:
  health: { value: 5, max: 5 }
  spirit: { value: 5, max: 5 }
conditions: []
inventory: []
---

When you change a stat, update the frontmatter and note the change in the session log's State line. Keep the shape the game defines; do not invent stats a game does not use.

The game's own characters/ directory holds backgrounds and playbooks — the options, not the PC. Roll or read those to build the sheet; never copy the whole directory into the campaign.

World files

Create a file the first time a location, NPC, or faction appears, using the frontmatter shape documented in each directory's README.md. Update the file when the fiction changes something about it. Link between files with relative markdown links where it helps.

Commands

journal roll <table> [--campaign <name>] [--game <id>] [--tag <tag>] [--count <n>]
journal oracle [<question>] [--complicate] [--campaign <name>] [--game <id>] [--table <name>]
journal dice <expr>
journal tables [--campaign <name>] [--game <id>]
journal check [--campaign <name>] [--game <id>]
journal new-campaign <name> [--game <id>]
journal games
journal game [<id>]
journal <game-command> [...]          provided by the campaign's game package

journal games lists the installed games; journal game <id> shows one game's rules, tables, and commands.

Run journal check after adding or editing tables, and before ending a session where you touched many files.

Starting a new campaign

  1. If the game does not exist yet, build it under games/<id>/ following docs/games.md (copy games/generic/ as a starting point).
  2. journal new-campaign <name> --game <id>
  3. Fill in campaign.md with the player.
  4. Create the PC sheet in characters/, drawing on the game's backgrounds.
  5. Open the first session log in sessions/.