Skip to content

The Loop and Triggers

The kit runs as a long-lived agent loop (ralph-claude.js / ralph-ollama.js) that repeatedly checks for work and idles quietly when there is none. It implements the Eventmodelers Build Kits platform contract.

Each loop iteration checks two conditions. They are not causally linked — either can fire on its own, and both can fire in the same iteration:

TriggerConditionWhat runs
Task trigger.build-kit/tasks.json is non-emptylib/prompt.md — reacts to board status changes (fetches newly Planned slices, logs Done/Blocked results)
Build triggerA slice under .build-kit/.slices/*/index.json has status "planned"lib/backend-prompt.md — builds exactly one slice, then stops so the loop can re-check for more work

Building one slice per iteration, rather than draining the whole queue at once, keeps each build isolated: if one slice fails, it doesn’t block the others from being picked up on the next pass.

If .build-kit/.eventmodelers/config.json is missing, the task trigger is disabled — there’s no board to sync with — but the build trigger still runs. You can drop a slice definition directly into .build-kit/.slices/<context>/<slice>/index.json with "status": "planned" and the kit will still generate, build, and test it locally. See Connect a Board to enable full board sync.

When the build trigger fires, the kit reads the slice definition and routes to one of three build skills:

ConditionSkillGenerates
sliceType === "TRANSLATION"build-automationA reactor that adapts an external fact into a local command
processors[] is non-emptybuild-automationA reactor that reacts to a fact and issues a follow-up command
projections / queries / readModel presentbuild-state-viewA projection and read model
Otherwise (commands / events only)build-state-changeA command and its event(s)

This mirrors event modeling’s four slice patterns — Command, View, Automation, and Translation — applied to Cratis’s Arc and Chronicle primitives.

  1. Check triggers. Read tasks.json and scan .slices/*/index.json for a planned entry.
  2. If a task is pending: run prompt.md — fetch the slice from the board via the load-slice skill, persist it under .slices/, and clear the task.
  3. If a slice is planned: run backend-prompt.md — route to the correct build skill, generate the code, run dotnet build and dotnet test, then call update-slice-status to mark the slice Done (or Blocked, with the failure reason, if the build or tests fail).
  4. Idle. If neither trigger fired, wait and check again.