The heartbeat
Once the offices are healed the organisation does not wait for instructions. One command, one beat: every office at or past its stage does its periodic job in founding order, and what it produces flows through the COO, which runs last.
| Office | Every | Duty | To the CEO |
|---|---|---|---|
| CTO | 1 | runs its verifiers on the workspace, fixes what fails, runs the release commands | maintenance done, failed, or needs you |
| CXO | 3 | convenes its panel, studies the record and the competition, suggests a feature to the COO | |
| CFO | 3 | reads the balance sheet and the growth curve, suggests a change to the COO | once, when the verdict turns to burning |
| CMO | 3 | reads the CXO's analytics report, builds the campaign, asks the COO for the product work it needs | |
| CIO | 5 | cheap panel on the judge model; at 0.6 investability the angel panel on the evolver model | the offers |
| COO | 1 | research over the suggestions, metrics, evaluations and what shipped; proposes work | approval requests, shipped, improvement reports |
A COO proposal is maintenance (built now, the CEO alerted afterwards), a campaign (the CMO's ask, built now) or a feature. A feature goes through the operator chain first: a human at the terminal or the model operator as the CEO's delegate can approve on the spot. Otherwise it waits in inbox.md, or in your mail through the notify command, until --approve.
An approved proposal is built through the COO's plan with its acceptance criteria and the board, released, and after monitor_beats beats its metrics are compared with the snapshot taken before it shipped. The improvement report names the metric it promised to move and what moved.
Each run on the workspace is an execution: written as running before the run, with its snapshot kept, and finalised with every task, its tool calls, the files it wrote, the failing checks, the cost, and the product's health before and after. Each task carries its own trace, one row per step and attempt.
$ bza org.yaml ../my-cli --heartbeat --beats 0 --every 3600
$ bza org.yaml ../my-cli --inbox
# CEO inbox: skills-cli
## Pending approvals
- prop_f27dde47 [feature] Dark mode (beat 4; expects satisfaction 0.74 -> 0.8)
approve: bza org.yaml ../my-cli --approve prop_f27dde47
## Messages (newest first)
- beat 4 · report from cio: angel investors: $40,000 offered
- beat 4 · alert from cto: maintenance done: complete skills/server-api
- beat 3 · report from coo: improvement report [maintenance] Tidy the README:
satisfaction 0.74 -> 0.8 (+0.06)
benzene serve runs one process that serves the record over HTTP and beats the heartbeat on a timer. The page at / is the graph view polling the record every few seconds: cells appear as they are born, fade as they divide or die, and a strip shows the beat, the approvals waiting and the last run. /inbox is the CEO's mailbox, and approvals, rejections and a beat can be posted from a phone. Every route needs the token the command prints.
--tunnel cloudflared gives a public URL with no account; --tunnel cloudflared --domain graph.example.com binds your own domain once the named tunnel is routed to it, and ngrok works the same way with a reserved domain. Next on the daemon: a wake-up queue with coalescing, webhook and API wake reasons, monthly budgets per office with a hard stop, and an HTTP contract for external agents whose work still passes the same verifiers.
$ benzene serve ../my-project --beat-every 3600 --tunnel cloudflared
local: http://127.0.0.1:3110/?token=k3…
public: https://quiet-otter-tea.trycloudflare.com/?token=k3…
heartbeat: every 3600s in the background
heartbeat:
duties: {cto: {every: 1}, coo: {every: 1}, cxo: {every: 3},
cfo: {every: 3}, cmo: {every: 3}, cio: {every: 5}}
require_stage: healed
approve: [feature]
monitor_beats: 5
max_fix_beats: 3
max_builds_per_beat: 2
rollback: true
release: [[git, add, -A], [git, commit, -m, "heartbeat: release"], [git, push]]
notify: [mail, -s, heartbeat, ceo@example.com]