repo.box Spec: Workflows
Overview
Workflows are generic state machines defined in .repobox/config.yml. PRs, ideas, releases, governance proposals — all are instances of workflows. States, transitions, guards, and actions are the building blocks. Instances live as JSONL files in the repo.
Everything as code. Workflow definitions, instance data, discussions — all are files in the repo, versioned by git, governed by permissions.
Core Concepts
- Workflow: a named state machine with states and transition rules
- State: a named position in the machine (e.g.
draft,review,merged) - Transition: a movement from one state to another, with rules about who can trigger it
- Guard: a condition that must be true for a transition to proceed (onchain call, HTTP check, internal requirement)
- Action: a side effect that fires when a transition completes (merge branch, webhook, notification)
- Instance: a single item moving through a workflow (a specific PR, idea, release)
Workflow Definitions
Defined in .repobox/config.yml under workflows::
workflows:
pull-request:
states:
- draft
- review
- approved
- merged
- closed
transitions:
draft -> review:
who:
- $author
review -> approved:
who:
- @devs
requires:
approvals: 2
review -> draft:
who:
- $author
approved -> merged:
who:
- @founders
actions:
- merge-branch
- close-branch
* -> closed:
who:
- $author
- @founders
Special Variables
$author— the identity that created the instance$assignee— the assigned identity (if set)*— wildcard state (any state)
Terminal States
States that have no outgoing transitions are terminal. An instance in a terminal state is immutable — no further transitions possible. In the example above, merged and closed are terminal.
Guards
Guards are conditions checked before a transition is allowed. If any guard fails, the transition is rejected.
Approval Guard
review -> approved:
who:
- @devs
requires:
approvals: 2 # need 2 approved reviews from @devs
The workflow engine counts review entries with verdict: approved in the instance thread from identities in the who list.
Onchain Guard
Calls a smart contract function. The function takes a single uint256 (the instance ID) and returns bool.
voting -> executed:
who:
- @everyone
guard:
onchain:
chain: 8453
contract: "0xGovernance..."
function: isApproved # f(uint256) → bool
arg: $instance.id
Use case: DAO governance. Members vote onchain, setting proposalId → true in a mapping. The transition only proceeds if the contract confirms.
Server calls the contract via its own RPC (same as group resolvers — users don't need nodes).
HTTP Guard
POSTs instance data to an HTTP endpoint. Expects {"approved": true} or {"approved": false} in response.
review -> approved:
who:
- @devs
guard:
http:
url: https://ci.example.com/status
# POSTs: {"instance_id": 1, "workflow": "pull-request", "branch": "feature/...", ...}
Use case: CI status checks, external review tools (Watson/Gaston), security scanners.
Combined Guards
Multiple guards can be required. All must pass.
approved -> merged:
who:
- @founders
requires:
approvals: 2
guard:
http:
url: https://ci.example.com/status
onchain:
chain: 8453
contract: "0xApprovalRegistry..."
function: isApproved
arg: $instance.id
actions:
- merge-branch
This transition requires: 2 approvals from @founders + CI passing + onchain approval. All three must be true.
Actions
Actions fire after a transition completes successfully. They are side effects.
Built-in Actions
| Action | Meaning |
|---|---|
merge-branch |
Merge the instance's source branch into its target branch |
close-branch |
Delete the source branch after merge |
Webhook Action
Fire-and-forget HTTP POST with instance data.
actions:
- webhook:
url: https://hooks.example.com/deploy
# POSTs full instance data
Use cases: trigger deploys, notify external systems, update dashboards.
Onchain Action
Call a contract function after transition.
actions:
- onchain:
chain: 8453
contract: "0xRegistry..."
function: recordMerge # f(uint256) → void
arg: $instance.id
Use case: record events onchain (audit trail, reputation, rewards).
Instance Storage
Instances are JSONL files in .box/workflows/<workflow-name>/.
Directory Structure
.box/
workflows/
pull-request/
index.jsonl # master index — one line per instance
fix-auth-bug.jsonl # discussion thread for PR #1
add-streaming.jsonl # discussion thread for PR #2
idea/
index.jsonl
monorepo-migration.jsonl
release/
index.jsonl
index.jsonl — Master Index
One JSON line per instance. Line number = instance ID (1-indexed).
{"title":"Fix auth bug","slug":"fix-auth-bug","branch":"feature/fix-auth","target":"main","author":"evm:0xAlice...","state":"review","labels":["bug","security"],"created":"2026-03-17T10:00:00Z","updated":"2026-03-17T11:15:00Z"}
{"title":"Add streaming support","slug":"add-streaming","branch":"feature/streaming","target":"main","author":"evm:0xBob...","state":"draft","labels":["feature"],"created":"2026-03-17T11:00:00Z","updated":"2026-03-17T11:00:00Z"}
Fields:
title— human-readable titleslug— URL/file-safe name, used for the thread filenamebranch— source branch (optional — ideas don't have branches)target— target branch for merge (optional)author— identity that created the instancestate— current state in the workflowlabels— freeform tagscreated/updated— timestamps- Any additional fields defined by the workflow
State transitions modify the instance's line in index.jsonl. This requires edit permission on the index file, which is controlled by the workflow's transition rules.
<slug>.jsonl — Discussion Thread
One file per instance. Append-only bulletin board. Each line is a self-contained JSON event.
Line Types
Description (first line, by author):
{"type":"description","author":"evm:0xAlice...","body":"This PR fixes the auth bypass in the middleware. The bug was caused by...","ts":"2026-03-17T10:00:00Z"}
Comment:
{"type":"comment","author":"evm:0xBob...","body":"Looks good but check line 42 in auth.ts","ts":"2026-03-17T10:30:00Z"}
Code suggestion (inline review comment):
{"type":"suggestion","author":"evm:0xBob...","file":"src/auth.ts","line":42,"old":"if (token) {","new":"if (token && verify(token)) {","body":"Should verify the token, not just check existence","ts":"2026-03-17T10:31:00Z"}
Review verdict:
{"type":"review","author":"evm:0xBob...","verdict":"approved","body":"LGTM after the fix","ts":"2026-03-17T11:15:00Z"}
Verdict values: approved, changes-requested, comment-only.
Suggestion accepted:
{"type":"suggestion-accepted","ref":3,"by":"evm:0xAlice...","commit":"abc123","ts":"2026-03-17T11:00:00Z"}
ref is the line number of the original suggestion.
Transition log:
{"type":"transition","from":"review","to":"approved","by":"evm:0xBob...","ts":"2026-03-17T11:15:00Z"}
Cross-reference:
{"type":"reference","ref":"idea/3","body":"Implements idea #3","author":"evm:0xAlice...","ts":"2026-03-17T10:00:00Z"}
Why JSONL
- Append-friendly: new events are new lines. Works perfectly with
appendpermission. - Machine-readable: every line is valid JSON. Agents parse it trivially.
- Git-diffable: each line is self-contained. Merges are clean. Conflicts are rare (append-only).
- No schema migration: new line types can be added without changing existing data.
- Line number as ID: implicit, stable, free.
Creating Instances
To open a new PR/idea/etc:
- Append a line to
index.jsonlwith metadata and initial state - Create a new
<slug>.jsonlfile with the description as the first line
The shim provides a helper: git repobox pr create --title "Fix auth bug" --branch feature/fix-auth --target main (which generates the JSONL entries and commits them). But you can also just manually append to the files with git commit.
Permission Model for Instances
Controlled by the standard file permissions in .repobox/config.yml:
.box/workflows/pull-request/index.jsonl:
append: @everyone # anyone can open a PR (append to index)
edit: @founders # only founders can change state
.box/workflows/pull-request/*.jsonl:
append: @everyone # anyone can comment on any PR
The workflow engine validates transitions additionally — even if you have edit on index.jsonl, you can only perform transitions allowed by the workflow definition for your identity.
Example Workflows
Idea / Discussion
No branch required. Pure discussion workflow.
workflows:
idea:
states:
- open
- discussing
- accepted
- rejected
- implemented
transitions:
open -> discussing:
who:
- @everyone
discussing -> accepted:
who:
- @founders
discussing -> rejected:
who:
- @founders
accepted -> implemented:
who:
- @devs
guard:
requires:
linked-pr: merged # must link to a merged PR
Release
workflows:
release:
states:
- proposed
- testing
- approved
- published
transitions:
proposed -> testing:
who:
- @devs
testing -> approved:
who:
- @auditors
requires:
approvals: 1
guard:
http:
url: https://ci.example.com/release-check
approved -> published:
who:
- @founders
actions:
- webhook:
url: https://deploy.example.com/publish
Governance Proposal
Token-gated voting with onchain confirmation.
workflows:
proposal:
states:
- draft
- voting
- passed
- rejected
- executed
transitions:
draft -> voting:
who:
- @token-holders
voting -> passed:
who:
- @everyone
guard:
onchain:
chain: 8453
contract: "0xGovernor..."
function: hasPassed
arg: $instance.id
voting -> rejected:
who:
- @everyone
guard:
onchain:
chain: 8453
contract: "0xGovernor..."
function: hasRejected
arg: $instance.id
passed -> executed:
who:
- @founders
actions:
- merge-branch
- onchain:
chain: 8453
contract: "0xGovernor..."
function: markExecuted
arg: $instance.id
Tooling
git repobox pr create
Create a pull request (appends to index.jsonl + creates thread file).
git repobox pr review --approve|--request-changes
Submit a review verdict (appends review line to thread).
git repobox pr merge
Attempt the approved → merged transition.
git repobox workflow list <workflow-name>
List all instances of a workflow (reads index.jsonl).
git repobox workflow transition <workflow-name> <id> <target-state>
Generic transition command for any workflow.
git repobox workflow create <workflow-name> --title "..." [--branch ...] [--target ...]
Create a new instance of any workflow.
Note: All of these are convenience wrappers. The underlying operation is always a git commit that modifies JSONL files — users and agents can do it manually too.
What Workflows Does NOT Cover
- CI/CD execution — workflows can trigger webhooks to external CI systems, but don't run builds themselves.
- Notifications — webhook actions can ping notification services, but there's no built-in notification system.
- Time-based transitions — "auto-close after 30 days of inactivity" requires an external cron-like system. Could be a future addition.
- Voting weight — the onchain guard is boolean (passed/not passed). Vote counting, quorum rules, etc. live in the contract, not in repo.box.