The celilo OpenRig's scripts, seat table and guidance. Changed outside the development pipeline.
  • TypeScript 77.1%
  • Shell 21.3%
  • CSS 1%
  • HTML 0.6%
Find a file
Peter Banka 34955fbc1b Tabletop plan: missions in celilo/plans; waves submitted as JSON and refused, not queued
Matches the conversion's d176961: a wave JSON names its mission folder, its
wave and the seats; a held wave is refused with its reason and resubmitted
after the blocking wave seals. Build notes move into celilo, since slice
folders now live in celilo/plans.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 16:00:20 -07:00
agents docs(rig): the planner, orchestrator and factory work from celilo/plans missions 2026-10-18 15:48:18 -07:00
docs docs(rig): the planner, orchestrator and factory work from celilo/plans missions 2026-10-18 15:48:18 -07:00
fixtures feat(factory): keep admitted work moving through verified handoffs 2026-10-12 15:38:30 -07:00
openrig refactor(rig): route production desks by OpenRig's role names 2026-10-16 11:37:01 -07:00
page feat: a strict TypeScript 7 type check gates the rig 2026-10-17 17:54:04 -07:00
probes refactor(rig): route production desks by OpenRig's role names 2026-10-16 11:37:01 -07:00
production refactor(rig): route production desks by OpenRig's role names 2026-10-16 11:37:01 -07:00
projects Tabletop plan: missions in celilo/plans; waves submitted as JSON and refused, not queued 2026-10-18 16:00:20 -07:00
scripts refactor(rig): route production desks by OpenRig's role names 2026-10-16 11:37:01 -07:00
simulation feat(viewer): run #9, the care model end to end with real Haiku seats, passed 2026-10-17 21:43:23 -07:00
skills/operator-questions refactor(culture): move the operator-question rules into a skill 2026-10-16 15:44:04 -07:00
templates refactor(rig): route production desks by OpenRig's role names 2026-10-16 11:37:01 -07:00
watchdogs docs(rig): the planner, orchestrator and factory work from celilo/plans missions 2026-10-18 15:48:18 -07:00
.gitignore feat(page): uPlot comes from npm, bundled by Bun, not vendored 2026-10-17 17:11:01 -07:00
auditor.sh Alarms: six conditions, a line at the top of the page, and one notification when one begins 2026-10-11 12:01:30 -07:00
auditor.test.sh refactor(rig): route production desks by OpenRig's role names 2026-10-16 11:37:01 -07:00
blocked-work.test.ts feat(inbox): expose blocked work by its underlying cause 2026-10-12 00:47:50 -07:00
blocked-work.ts feat(inbox): expose blocked work by its underlying cause 2026-10-12 00:47:50 -07:00
bun.lock feat: a strict TypeScript 7 type check gates the rig 2026-10-17 17:54:04 -07:00
bunfig.toml fix(simulation): remove every runner's and test's temporary directory 2026-10-16 15:02:00 -07:00
CULTURE.md fix(factory): a fix round is known by its packet; reviewers read a wave since its merge base 2026-10-17 21:14:32 -07:00
desk.sh feat: the care model: review once a wave, fix rounds, seal; the planning dial; no tiers 2026-10-17 20:36:46 -07:00
desk.test.sh feat: the care model: review once a wave, fix rounds, seal; the planning dial; no tiers 2026-10-17 20:36:46 -07:00
drain.sh refactor(rig): route production desks by OpenRig's role names 2026-10-16 11:37:01 -07:00
drain.test.sh refactor(rig): route production desks by OpenRig's role names 2026-10-16 11:37:01 -07:00
factory-admission.test.ts feat(factory): slices and waves come from celilo/plans; a mission's wave waits for its dependencies 2026-10-18 15:23:45 -07:00
factory-batch.test.ts feat: the care model: review once a wave, fix rounds, seal; the planning dial; no tiers 2026-10-17 20:36:46 -07:00
factory-cli.test.ts feat(factory): slices and waves come from celilo/plans; a mission's wave waits for its dependencies 2026-10-18 15:23:45 -07:00
factory-cli.ts feat(factory): slices and waves come from celilo/plans; a mission's wave waits for its dependencies 2026-10-18 15:23:45 -07:00
factory-concurrency.test.ts feat: the care model: review once a wave, fix rounds, seal; the planning dial; no tiers 2026-10-17 20:36:46 -07:00
factory-events.test.ts feat: the care model: review once a wave, fix rounds, seal; the planning dial; no tiers 2026-10-17 20:36:46 -07:00
factory-files.test.ts feat(factory): slices and waves come from celilo/plans; a mission's wave waits for its dependencies 2026-10-18 15:23:45 -07:00
factory-files.ts feat(factory): slices and waves come from celilo/plans; a mission's wave waits for its dependencies 2026-10-18 15:23:45 -07:00
factory-native.test.ts feat: the care model: review once a wave, fix rounds, seal; the planning dial; no tiers 2026-10-17 20:36:46 -07:00
factory-native.ts feat: the care model: review once a wave, fix rounds, seal; the planning dial; no tiers 2026-10-17 20:36:46 -07:00
factory-plan.test.ts feat: the care model: review once a wave, fix rounds, seal; the planning dial; no tiers 2026-10-17 20:36:46 -07:00
factory-proof.test.ts feat: the care model: review once a wave, fix rounds, seal; the planning dial; no tiers 2026-10-17 20:36:46 -07:00
factory-proof.ts feat: the care model: review once a wave, fix rounds, seal; the planning dial; no tiers 2026-10-17 20:36:46 -07:00
factory-reconciliation.test.ts feat: the care model: review once a wave, fix rounds, seal; the planning dial; no tiers 2026-10-17 20:36:46 -07:00
factory-release-assessment.test.ts feat(simulation): expose release failures without repeating construction 2026-10-13 18:54:29 -07:00
factory-release-assessment.ts feat(simulation): expose release failures without repeating construction 2026-10-13 18:54:29 -07:00
factory-release-workflow.test.ts fix(simulation): remove every runner's and test's temporary directory 2026-10-16 15:02:00 -07:00
factory-release-workflow.ts refactor(factory): use OpenRig's terms: mission, wave, slice 2026-10-16 10:46:12 -07:00
factory-release.scenario.test.ts feat(factory): keep admitted work moving through verified handoffs 2026-10-12 15:38:30 -07:00
factory-release.test.ts feat(factory): keep admitted work moving through verified handoffs 2026-10-12 15:38:30 -07:00
factory-release.ts feat(factory): keep concurrent delivery moving through coordinated releases 2026-10-13 16:13:56 -07:00
factory-wave.test.ts feat(factory): slices and waves come from celilo/plans; a mission's wave waits for its dependencies 2026-10-18 15:23:45 -07:00
factory.test.ts feat: the care model: review once a wave, fix rounds, seal; the planning dial; no tiers 2026-10-17 20:36:46 -07:00
factory.ts feat(factory): slices and waves come from celilo/plans; a mission's wave waits for its dependencies 2026-10-18 15:23:45 -07:00
foreman-codex.test.ts feat: a strict TypeScript 7 type check gates the rig 2026-10-17 17:54:04 -07:00
foreman-codex.ts feat: a strict TypeScript 7 type check gates the rig 2026-10-17 17:54:04 -07:00
foreman.sh refactor: the simulation's scripts and the foreman's codex reader are TypeScript run by Bun 2026-10-16 23:35:37 -07:00
foreman.test.sh refactor: the simulation's scripts and the foreman's codex reader are TypeScript run by Bun 2026-10-16 23:35:37 -07:00
fresh.sh fresh.sh: the limit is 100,000 tokens unless limits.json says otherwise 2026-10-12 13:02:58 -07:00
fresh.test.sh refactor(rig): route production desks by OpenRig's role names 2026-10-16 11:37:01 -07:00
guidance.test.sh feat: the care model: review once a wave, fix rounds, seal; the planning dial; no tiers 2026-10-17 20:36:46 -07:00
inbox-action.test.ts feat(inbox): require executable reviewed requests before asking the operator 2026-10-11 10:43:20 -07:00
inbox-action.ts feat(inbox): require executable reviewed requests before asking the operator 2026-10-11 10:43:20 -07:00
inbox-admission.test.ts refactor(rig): route production desks by OpenRig's role names 2026-10-16 11:37:01 -07:00
inbox-admission.ts refactor(rig): route production desks by OpenRig's role names 2026-10-16 11:37:01 -07:00
inbox-audit.test.ts refactor(rig): route production desks by OpenRig's role names 2026-10-16 11:37:01 -07:00
inbox-audit.ts refactor(culture): move the operator-question rules into a skill 2026-10-16 15:44:04 -07:00
inbox-blocked.test.ts fix(inbox): keep audit maintenance out of work dependency chains 2026-10-12 11:55:44 -07:00
inbox-blocked.ts fix(inbox): keep audit maintenance out of work dependency chains 2026-10-12 11:55:44 -07:00
inbox-brief.test.ts feat(inbox): require executable reviewed requests before asking the operator 2026-10-11 10:43:20 -07:00
inbox-brief.ts feat(inbox): require executable reviewed requests before asking the operator 2026-10-11 10:43:20 -07:00
inbox-command.test.ts feat(inbox): require executable reviewed requests before asking the operator 2026-10-11 10:43:20 -07:00
inbox-command.ts feat(inbox): require executable reviewed requests before asking the operator 2026-10-11 10:43:20 -07:00
inbox-lifecycle.test.ts refactor(rig): route production desks by OpenRig's role names 2026-10-16 11:37:01 -07:00
inbox-lifecycle.ts fix(inbox): keep audit maintenance out of work dependency chains 2026-10-12 11:55:44 -07:00
inbox-links.test.ts feat(inbox): make decisions quick and require readable briefs before publication 2026-10-10 14:45:41 -07:00
inbox-links.ts feat(inbox): make decisions quick and require readable briefs before publication 2026-10-10 14:45:41 -07:00
inbox-publish.test.ts refactor(rig): route production desks by OpenRig's role names 2026-10-16 11:37:01 -07:00
inbox-publish.ts fix(inbox): enforce reviewed publication at queue writes 2026-10-11 11:15:58 -07:00
inbox-quality.test.ts feat(inbox): require executable reviewed requests before asking the operator 2026-10-11 10:43:20 -07:00
inbox-quality.ts feat(inbox): require executable reviewed requests before asking the operator 2026-10-11 10:43:20 -07:00
inbox-review.test.ts refactor(rig): route production desks by OpenRig's role names 2026-10-16 11:37:01 -07:00
inbox-review.ts feat(inbox): make decisions quick and require readable briefs before publication 2026-10-10 14:45:41 -07:00
inbox-screen.test.ts refactor(rig): route production desks by OpenRig's role names 2026-10-16 11:37:01 -07:00
inbox-screen.ts feat(inbox): expose contextual actions and consistent ticket shortcuts 2026-10-12 01:42:53 -07:00
inbox-talk.test.sh fix(inbox): talk only behind a confirmed typing guard 2026-10-16 15:02:58 -07:00
inbox-ui.test.ts feat(inbox): require executable reviewed requests before asking the operator 2026-10-11 10:43:20 -07:00
inbox-ui.ts refactor(rig): route production desks by OpenRig's role names 2026-10-16 11:37:01 -07:00
inbox.sh fix(inbox): talk only behind a confirmed typing guard 2026-10-16 15:02:58 -07:00
inbox.test.sh refactor(rig): route production desks by OpenRig's role names 2026-10-16 11:37:01 -07:00
install.sh feat(page): uPlot comes from npm, bundled by Bun, not vendored 2026-10-17 17:11:01 -07:00
install.test.sh feat(page): uPlot comes from npm, bundled by Bun, not vendored 2026-10-17 17:11:01 -07:00
landing.sh refactor(rig): route production desks by OpenRig's role names 2026-10-16 11:37:01 -07:00
landing.test.sh landing.sh: the landing slot, one merge desk at a time 2026-10-08 22:58:21 -07:00
merge-recovery.test.ts feat: the care model: review once a wave, fix rounds, seal; the planning dial; no tiers 2026-10-17 20:36:46 -07:00
merge-recovery.ts feat: the care model: review once a wave, fix rounds, seal; the planning dial; no tiers 2026-10-17 20:36:46 -07:00
numbers.json refactor(rig): route production desks by OpenRig's role names 2026-10-16 11:37:01 -07:00
orient.sh refactor(rig): route production desks by OpenRig's role names 2026-10-16 11:37:01 -07:00
orient.test.ts refactor(rig): route production desks by OpenRig's role names 2026-10-16 11:37:01 -07:00
package.json feat: a strict TypeScript 7 type check gates the rig 2026-10-17 17:54:04 -07:00
README.md feat: the care model: review once a wave, fix rounds, seal; the planning dial; no tiers 2026-10-17 20:36:46 -07:00
rebuild.sh refactor(rig): route production desks by OpenRig's role names 2026-10-16 11:37:01 -07:00
rebuild.test.ts Three defects found at the first retool 2026-10-09 01:49:37 -07:00
relaunch.sh rebuild, relaunch, orient and setup-all take their seats from the table 2026-10-08 09:13:37 -07:00
relaunch.test.sh rebuild, relaunch, orient and setup-all take their seats from the table 2026-10-08 09:13:37 -07:00
requeue.sh requeue.sh: open items follow a renamed seat, in place 2026-10-08 23:30:32 -07:00
requeue.test.sh refactor(rig): route production desks by OpenRig's role names 2026-10-16 11:37:01 -07:00
retool.sh Replace the foreman agent with a tick seat that runs no model 2026-10-10 11:26:36 -07:00
retool.test.sh refactor(rig): route production desks by OpenRig's role names 2026-10-16 11:37:01 -07:00
rig.yaml docs(rig): the planner, orchestrator and factory work from celilo/plans missions 2026-10-18 15:48:18 -07:00
schema.sql auditor.sh keeps readings and run records in one store, and fails open 2026-10-09 02:09:58 -07:00
seat-allow.json Helm replaces the fleet seat; the production server reaches a desk's clone only; test.sh runs suites side by side 2026-10-09 00:20:35 -07:00
seat-mcp.sh Helm replaces the fleet seat; the production server reaches a desk's clone only; test.sh runs suites side by side 2026-10-09 00:20:35 -07:00
seats.json refactor(rig): route production desks by OpenRig's role names 2026-10-16 11:37:01 -07:00
seats.sh refactor(rig): route production desks by OpenRig's role names 2026-10-16 11:37:01 -07:00
seats.test.sh refactor(rig): route production desks by OpenRig's role names 2026-10-16 11:37:01 -07:00
setup-all.sh refactor(rig): route production desks by OpenRig's role names 2026-10-16 11:37:01 -07:00
setup-all.test.sh refactor(rig): route production desks by OpenRig's role names 2026-10-16 11:37:01 -07:00
test-dirs.ts fix(simulation): remove every runner's and test's temporary directory 2026-10-16 15:02:00 -07:00
test.sh feat(viewer): v2 replays OpenRig's own record, in TypeScript served by Bun 2026-10-16 23:55:53 -07:00
test.test.sh feat(viewer): v2 replays OpenRig's own record, in TypeScript served by Bun 2026-10-16 23:55:53 -07:00
tsconfig.json feat: a strict TypeScript 7 type check gates the rig 2026-10-17 17:54:04 -07:00
typecheck.test.sh feat: a strict TypeScript 7 type check gates the rig 2026-10-17 17:54:04 -07:00

The celilo rig

The files that run celilo's OpenRig rig: the seat table, the rig spec, each seat's guidance, the foreman's instruments, the routing script and the maintenance scripts. Behaviour contracts are in docs/rig-routing.md; terms are in docs/glossary.md.

Changes to the rig do not go through the rig. They are built in a development clone by the operator's session, tested there, and installed by fast-forward. See the decision.

Three locations

RIG    ~/.config/openrig/celilo    the live directory; every seat calls scripts here by path
DEV    ~/hobby/celilo-rig          the development clone; every edit and every test run
STATE  ~/.openrig/state/foreman    gauges, limits, readings, the journal, the landing slot
METRICS ~/.openrig/state/metrics   the auditor's store of numbers, and what its probes keep
SEATS  ~/hobby/celilo-seats        one clone of celilo per seat

An edit in RIG changes the running rig at once, so nothing there is edited by hand. It is only ever fast-forwarded, by install.sh.

Layout

Path What it is
seats.json, seats.sh The seat table: each seat's type, tier, provider and model. The only place they are written.
rig.yaml The OpenRig spec. seats.sh apply keeps it in step with the table.
CULTURE.md, agents/*/guidance/role.md What every seat, and each role, is told.
skills/*/SKILL.md Skills a role loads on demand, listed in its agent.yaml. OpenRig finds them beside rig.yaml.
foreman.sh, foreman-codex.ts Measurement and admission: may-i answers GO or HOLD.
desk.sh Names the builder, reviewer or integrator desk for a piece of work, or a wave's two reviewers. Fronts the factory.
landing.sh The landing slot: one integrator desk at a time.
scripts/gate-runner.sh Runs the merge gate on one pinned commit, in the caller's clone.
scripts/e2e-runner.sh Runs one cele2e suite in a session of its own and messages the seat that launched it when it ends.
fresh.sh Gives a seat that is idle between packets with a large conversation a blank session. The tick runs it.
drain.sh, requeue.sh, retool.sh Maintenance: stop the rig cleanly, change it, start it again.
rebuild.sh, relaunch.sh, orient.sh, setup-all.sh Starting seats and preparing their clones.
production/ Which production operations helm's key may run and which no seat's may, with the test that keeps the list complete.
inbox.sh The operator's inbox of parked questions.
auditor.sh, schema.sql, probes/ The rig's numbers: a pass every five minutes keeps them in one store. See rig metrics.
page/, numbers.json The metrics page, on this Mac only (http://127.0.0.1:7434/), and the list of numbers it shows.
watchdogs/ The standing wake-ups for the orchestrator and helm.
projects/ Plans, specs and decisions for changes to the rig.

Every script says what it does, its exit codes and its test seams in the comment at its top.

Inbox

Run ./inbox.sh. Press ? for the complete, scrollable keybinding dialog; Escape returns to the selected item. The footer keeps the help hint visible. Click the Needs you, Deferred, Following or Blocked work tabs, or use Ctrl-H/Ctrl-L to move between them. The footer lists actions for the selected ticket. While editing or viewing a dialog, those controls keep their local meaning instead of changing tabs.

Needs you admits only structurally valid requests with an exact factual/JEV review receipt. Unreviewed requests count as Agent review and get orchestrator-owned repair work. e opens an Action needed command; Enter runs the reviewed command, and C copies the command. Shift-Y copies the ticket ID in every tab and ticket dialog; in an editor it types a literal Y. Output and exit status are retained, and successful execution returns work to its agent for verification. See the action contract. Mouse-wheel scrolling moves the description, preserving the selected question.

Press b for Blocked work: one row per underlying cause, largest impact first, with direct and indirect dependency counts. These are recorded links; the owner must verify that each link represents a real prerequisite. Change age includes the latest meaningful recorded update. / searches causes, owners and affected tickets. Enter lists the blocker and every affected ticket; Enter again opens the full ticket. Y copies its ID, and Escape steps back. f follows the selected ticket, t talks to its owner, a talks to its recorded author, and i opens its links. These actions work on the blocker itself or the affected ticket selected in its inspection dialog. A condition or cycle has no single ticket ID: Enter selects a ticket first. Approval, answers and deferral remain in the question views. Activity and updates load in the background; queue state alone does not prove a repair is running. r refreshes, and b returns to Needs you.

  • i lists issue references and web links from the current item. Select one with j/k, then Enter to preview its title, status, author and description. o opens the selected link in your browser. In a preview, r reloads and i returns to the link list. Loading is asynchronous and Escape works while waiting. Other websites open through o.
  • ! lists retained answers, including tickets no longer in the main inbox. Enter checks the queue and shows the answer, error and current state. R retries only an unchanged, still-answerable ticket after another check; g opens its current ticket or unique successor for review. An already recorded answer is identified instead of resent. x dismisses only the local retained copy, leaving the queue unchanged.

Issue references such as celilo#561 and #539 resolve to the Celilo Forgejo repository. Qualified owner/repo#123 references retain their repository. INBOX_FORGE_URL overrides the default https://git.celilo.computer origin; FJ_TOKEN, when supplied, authenticates only requests to that origin. Successful previews are cached until r reloads them or the inbox exits.

Tests

bun install --frozen-lockfile   # once per clone, and after bun.lock changes
./test.sh > /tmp/rig-tests.log 2>&1; echo "exit=$?"; tail -1 /tmp/rig-tests.log

The rig's npm packages are pinned in package.json and bun.lock: uPlot, which the metrics page bundles, and, for the type check, TypeScript 7 and Bun's types. Nothing is vendored.

test.sh finds every *.test.sh and *.test.ts in the repository and runs each with its own runner: bash, or bun test. The rig's code is TypeScript run by Bun; a suite of any other kind fails the run. Bun runs TypeScript without checking its types, so one suite, typecheck.test.sh, runs tsc over every .ts file under the strict tsconfig.json. It prints N suites, M failed and exits 0 only when all pass. Read the exit code; a pipe into tail reports tail's. A run takes several minutes on a busy host.

Every suite runs the real script against planted state. None touches RIG, STATE, SEATS or the running rig.

Install

./install.sh --check     # what would be installed; changes nothing
./install.sh             # run the tests, then fast-forward RIG to this clone's main

install.sh refuses when this clone is not on main or has uncommitted changes, when RIG has local changes or a commit this clone lacks, when the locked packages do not install, and when the tests fail. It installs the same locked packages in RIG after moving it forward.

A change that a running seat reads belongs in a retool window. Commit it on a branch; install.sh cannot install a branch, and retool.sh fast-forwards main to it at the right moment.

Stopping the rig: drain, then retool

A drain is the procedure for any stop of the rig. A retool is a stop that also changes the rig's files, its seats or OpenRig itself. Both are run from DEV, by the operator.

  1. Say why, and hold everyone.

    ./drain.sh start "why the rig is stopping"
    

    Every seat is held, the integrator desks and the foreman included, and every running seat is sent the reason and the wrap-up steps: finish the step you are in, commit, push, note on your item where you stopped, stop.

  2. Wait until it is drained.

    ./drain.sh status; echo "exit=$?"
    ./drain.sh nudge          # tell the seats status still names, again
    

    status prints one row for each thing still busy and stops nothing. It exits 0, and takes a snapshot, when every seat is idle, every work tree under SEATS is clean and pushed, no merge gate is running, the e2e run lock is free and the landing slot is free.

  3. Retool.

    ./retool.sh steps
    ./retool.sh                       # every step, in order
    ./retool.sh --only stop           # or one step at a time, looking after each
    ./retool.sh --from apply          # go on after fixing what stopped it
    ./retool.sh --upgrade <version>   # with an OpenRig upgrade, proven before the seats change
    

    It refuses, with exit 4 and the running rig untouched, when the rig is not drained, when the tests fail, or when this clone cannot be installed. A later failure stops it with exit 1 and names the --from to go on with. Run an upgrade one step at a time: OpenRig's own guidance is that an upgrade is observed, not run blind.

  4. End the drain.

    ./drain.sh end
    

    The hold is lifted and every running seat is told to resume.

To stop the rig without changing it, do steps 1 and 2, stop and start it, and do step 4.

Changing which provider a seat runs on

A builder, reviewer or integrator desk never changes provider: each type has desks on both providers, and desk.sh splits the work between them. Any other seat, the two planners included, can be moved:

./seats.sh set plan-orchestrator claude      # in DEV, on a branch; commit it

Then drain and retool. No seat changes provider while the rig runs.