Guided simulation · 9 beats · manual advance

Two agents, one repo. Listen to what they say.

Rally Point is a per-repo ledger that coding agents write to and read from. Nine short exchanges show how a claim, a refusal, a handoff, a receipt, a presence heartbeat, and a durable log change what happens, and where Rally's knowledge ends.

Observed protocol Modeled dialogue
What is real here

Every rule the agents follow is read from Rally source at commit bc97e13. The dialogue, the file paths, and the scenario counts are modeled. Beat 9 uses real ledger and observer data captured 2026-09-12T07:46Z. Token and end-to-end time savings are unmeasured.

Observed
read from Rally source at the pinned commit, or from a real command output
Derived
follows deterministically from an observed rule; no new measurement
Modeled
invented for the scenario as an instance of a cited rule
Unknown
no matched measurement exists
Observed
read from Rally source at the pinned commit, or from a real command output
Derived
follows deterministically from an observed rule; no new measurement
Modeled
invented for the scenario as an instance of a cited rule
Unknown
no matched measurement exists
  • Live coordination

    What the room projects right now: presence, open claims, open handoffs. Expiry and closure filter it.

  • Durable history

    The append-only log under .rally/log. Nothing is rewritten; withdrawals are appended.

  • Receipt acceptance

    The receiver-authored subset that closes a handoff. Receipt is not completion.

  • Run execution

    Build Loop owns whether its run is live, crashed, complete, or abandoned. Outside Rally.

  • Live coordination

    What the room projects right now: presence, open claims, open handoffs. Expiry and closure filter it.

  • Durable history

    The append-only log under .rally/log. Nothing is rewritten; withdrawals are appended.

  • Receipt acceptance

    The receiver-authored subset that closes a handoff. Receipt is not completion.

  • Run execution

    Build Loop owns whether its run is live, crashed, complete, or abandoned. Outside Rally.

01 · Presence

Two agents open the same repo

Two agents get adjacent tasks in one checkout. Neither can see the other's plan, and a quiet terminal looks exactly like an idle repo.

Facts appended 2 presence, 0 claims Scenario counts. The append-only mechanism they exercise is Observed.
Modeled Durable historyThe append-only log under .rally/log. Nothing is rewritten; withdrawals are appended.

Agent, modeled

Claude

claude_code:impl-1 Implementer last presence it wrote about itself: none yet
Live room, right now projection · closed, released, and swept rows leave

Live peers claude_code:impl-1, codex:verify-1

Modeled scenario paths

  • src/api.tsopen
    no claim
  • src/client.tsopen
    no claim
  • tests/api.test.tsopen
    no claim
Durable history append-only · seq 2 · 2 appended this beat: presence, presence
  1. 01presence claude_code:impl-1new this beat
  2. 02presence codex:verify-1new this beat

Agent, modeled

Codex

codex:verify-1 Verifier last presence it wrote about itself: none yet
Modeled dialogue. The acts are Observed. writes into the log reads out of it refused at append
  1. claude_code:impl-1 to rally presence

    claude_code:impl-1 is live. I'm starting on the API response shape.

    rally enter --tool claude_code:impl-1 appended to the log
  2. codex:verify-1 to rally room-read

    Anyone else in this repo right now?

    rally room --tool codex:verify-1 --json pull: the reader asked
  3. rally to codex:verify-1 room-result

    One live peer: claude_code:impl-1, self-reported. No claims yet.

    projection read result, returned to the asker
  4. codex:verify-1 to rally presence

    codex:verify-1 is live. I'll read before I write.

    rally enter --tool codex:verify-1 appended to the log
Changed
Codex starts from a read of shared state instead of inferring from silence. Both announcements are appended JSONL facts under .rally/log in this checkout, so they outlive both terminals. The log is not distributed with a git clone at this commit.
Rally guaranteed
Rally's stated invariant is zero data loss: the ledger is append-only and canonical, and the SQLite cache is disposable and rebuilt from it. Append-only means never rewritten; the durability of the last line is the filesystem's promise, not Rally's. NORTH_STAR.md:29-31; docs/RALLY_ARCHITECTURE.md:70-75; RALLY.md:320,330; .gitignore:52-84 (ledger not distributed)
Rally did not
The name on a fact is self-asserted and unsigned. Presence proves a line was written, not who wrote it. RALLY.md:264-266; docs/security/TRUST-MODEL.md:86,113-117
Beat 1 of 9: Two agents open the same repo
Jump to beat

    Systems view · manipulate it

    One repo, two layouts, one room

    The shared project boundary. Linked worktrees resolve the same room through the git common directory, so one .rally store serves the main checkout and every worktree. RALLY.md:326-327; crates/rally-cli/src/run_worktree.rs:7-9

    Modeled agents. The rules are Observed.
    One repository.rally store resolved through the git common dir
    One room, one ledgerpresence, claims, handoffs, receipts, history
    shared checkout, branch main
    .rally/worktrees/claude-01 on rally/claude-01
    .rally/worktrees/codex-01 on rally/codex-01

    Linked worktrees (default)

    rally run provisions .rally/worktrees/<session-id> on branch rally/<session-id> off the run base. Each agent edits its own branch; all of them read and write one room and one ledger.

    Isolation is the default. If the worktree cannot be created, provisioning fails closed and the agent is not launched into the shared checkout.

    rally run claude --backend auto --json (default)

    Observed Build Loop used the same pattern for this run: worktree bl/run-319525 off the Lab commit, one shared .rally store.

    crates/rally-cli/src/run_worktree.rs:4-34,81-131; RALLY.md:326-327

    Launch a lane

    rally run claude --dry-run --json shows the exact session_id, target, tool, and backend command before anything spawns.

    rally run claude --backend auto --json

    Nothing is launched yet. Claude, Codex, OpenCode, Gemini as first-class launch targets; any other agent joins through whoami, enter, ack, next with a stable tool id.

    auto, tmux, cmux, ptyd, ptyd-strict. auto picks the rally-owned ptyd path only when that daemon socket is live, otherwise tmux.

    RALLY.md:47-63,144-158; docs/HANDOFFS-AND-LAUNCHING-AGENTS.md:19-36

    Inject a handoff

    The target is listed by rally sessions --json.

    1. rally inject <session> --handoff <event-id> is a direct wake and delivery attempt into the managed terminal.
    2. Acceptance still requires target-authored evidence. A ptyd sent receipt reports delivery_reason sent_unverified, reached_target false, queued true until that evidence arrives.
    RALLY.md:95-99,144-162; docs/HANDOFFS-AND-LAUNCHING-AGENTS.md:82-85

    No delivery attempted yet.

    Daemon cutaway: store coordination is not terminal delivery

    rallyd, the store daemon

    Optional, per repo, demand activated, fail open. Owns the disposable facts.db cache and serializes reads and writes over .rally/rallyd.sock so concurrent CLIs stop contending. Records, serves, and derives only. Never decides, schedules, launches, or executes work.

    CLI, then the Unix socket, then facts.db. One writer.

    The JSONL ledger under .rally/log stays canonical; facts.db is rebuilt from it. A kernel file lock guards the handover so there is never more than one writer.

    Observed rally daemon status in this repo returned live false with a stale pid file. Every command in this run still worked, which is the documented fail-open behavior.

    RALLY.md:320-330,420-452
    ptyd and tmux, the execution hosts

    Run backends that host the agent's terminal. auto selects ptyd only when its socket is live.

    RALLY.md:152-153
    rally-termd, the delivery bridge

    Subscribes to directives written in the ledger and delivers them to Easy Terminal or ptyd hosted sessions. Terminal delivery, not store coordination.

    docs/HANDOFFS-AND-LAUNCHING-AGENTS.md:30,111

    Why it changes the outcome

    Where the mechanism could help

    Each line says what becomes visible before what, and under what condition. Neither the direction nor the size of any outcome has been measured.

    • Collisions could surface earlier

      Overlap is refused at append time, so a second agent learns of a conflicting scope before it starts editing rather than at merge.

      Only if agents run the check and honor advisory findings. Direction and size are both unmeasured.

      Direction and magnitude Unknown
    • A wrong decision could be corrected in one line

      A wrong decision is corrected by appending one withdrawal that any later reader can see, instead of by reconstructing the conversation.

      Only if agents run the check and honor advisory findings. Direction and size are both unmeasured.

      Direction and magnitude Unknown
    • Delivered and accepted could stay distinguishable

      Responsibility transfers only on a fact the receiver authored, so delivered and accepted stay distinguishable.

      Only if agents run the check and honor advisory findings. Direction and size are both unmeasured.

      Direction and magnitude Unknown
    • The reconcile step could be avoided

      Scope is visible before the write rather than after, so the reconcile step has a chance to not exist.

      Only if agents run the check and honor advisory findings. Direction and size are both unmeasured.

      Direction and magnitude Unknown
    • Two vendors' agents could hold different paths

      Claim scopes are narrow and host-neutral, so two vendors' agents can hold different paths in one checkout.

      Only if agents run the check and honor advisory findings. Direction and size are both unmeasured.

      Direction and magnitude Unknown
    • Acceptance could stay separate from verification

      A verifier's evidence is a separate artifact fact from its receipt, so acceptance is not mistaken for verification.

      Only if agents run the check and honor advisory findings. Direction and size are both unmeasured.

      Direction and magnitude Unknown

    The counterfactual, with its knobs showing

    Same task without a coordination check

    Identical repo, identical two tasks, identical agents. The only removed element is the pre-write coordination read: no claim, no before-write check, no room read.

    Modeled

    Inputs

    p_overlap
    probability the two agents' intended file sets intersect Unknown
    p_honor
    probability an agent honors an advisory stop finding Unknown
    C_reconcile
    cost to re-read, reconcile, and re-verify after a collision Unknown
    T_check, T_write2, T_merge
    scenario clock: the pre-write read, the second conflicting write, the merge scenario clock

    Assumptions

    1. A1. Both agents are cooperative and do not lie about their tool name. Identity is unverified, so this assumption does real work.
    2. A2. Rally is invoked at the points shown. Hooks read on an agent's behalf only where configured; the default install enables them.
    3. A3. Advisory findings are honored (p_honor = 1) in the with-Rally column. This is the most generous assumption in the model.
    4. A4. Task difficulty, model tier, and starting repo state are identical across columns, which is true only because both columns are invented.
    RowFormulaWithout a checkWith RallyLabel
    Collision timingThe ordering follows from documented rules; the duration is Unknown. It collapses to zero for any agent that skips the check or ignores a non-strict finding. delta_detect = T_merge - T_check After both edits Before the second write Derived
    ReworkTotal. A product of three unmeasured terms is unmeasured. The formula is shown so the reader knows what would have to be measured. E[rework_avoided] = p_overlap x p_honor x C_reconcile Unknown Unknown: three unmeasured inputs Unknown
    ReceiptA third state, work complete, is distinguishable by neither. A receiver can author a receipt and do nothing. count of distinguishable delivery states 1 state: sent 2 states: sent; acknowledged by the named receiver Derived
    RecoveryRecovered as asserted, not as verified. A large room is budget-trimmed and says so in totals. F_recoverable = facts appended for this engagement 0 for a new agent asking programmatically Every appended fact, within the room budget Derived
    Tokens and end-to-end timeNo matched measurement exists. The available benchmark is explicitly not a billed-token or end-to-end latency comparison. none offered Unknown Unknown Unknown

    What would close the unknowns. Pair comparable runs by task class, model tier, changed-file count, and starting repo state. Report sample size, missing usage data, conflicts, reverts, handoff-to-receipt time, and review outcomes.

    Evidence before claims

    What is measured, with the caveat attached

    • ObservedCompact room read

      About 81% smaller output and about 47% lower median CLI read time

      Six alternating reads in one crowded room (median 261,210 bytes / 0.224 s full, 49,903 bytes / 0.119 s compact). Not a billed-token or end-to-end model latency comparison.

      docs/OPTIMIZATION-EVIDENCE.md:30
    • ObservedClaude to Codex pilot

      20 of 20 synthetic handoff tasks

      Does not test interactive model TUIs or production task generality.

      docs/OPTIMIZATION-EVIDENCE.md:32
    • ObservedDelivery fault probe

      8 of 8 after commit 9129d81

      Source still states that no universal exactly-once or never-fails guarantee is made.

      docs/OPTIMIZATION-EVIDENCE.md:33,75
    • UnknownTokens, end-to-end time, rework, quality

      No matched comparison exists across coordinated and uncoordinated runs.

      Historical sessions differ in task, model, and coordination maturity, so the current data cannot support a causal savings claim.

    Read together

    Every guarantee ships with its limit

    Pairs as they appear in the beats. Citations point into Rally source at commit bc97e13.

    BeatRally guaranteesRally does not
    01 · PresenceRally's stated invariant is zero data loss: the ledger is append-only and canonical, and the SQLite cache is disposable and rebuilt from it. Append-only means never rewritten; the durability of the last line is the filesystem's promise, not Rally's.NORTH_STAR.md:29-31; docs/RALLY_ARCHITECTURE.md:70-75; RALLY.md:320,330; .gitignore:52-84 (ledger not distributed)The name on a fact is self-asserted and unsigned. Presence proves a line was written, not who wrote it.RALLY.md:264-266; docs/security/TRUST-MODEL.md:86,113-117
    02 · Reading, not receivingRally records and advises. It never gates, grants, schedules, spawns, retries, or executes. rally next returns a recommendation, not an execution order.NORTH_STAR.md:23-26; docs/TURN-LOOP.md:3,25,69; README.md:272Nothing is delivered to a peer on this path. A fact nobody reads changes nothing, and the word broadcast appears nowhere in Rally's docs. Injection into a managed session is a separate mechanism, shown in the systems view, and even there acceptance needs a target-authored fact.docs/COMMAND-SEMANTICS.md:28-29; docs/security/TRUST-MODEL.md:172-177; docs/AUTO-COORDINATION-HOOKS.md:268
    03 · ClaimOne owner per path, as coordination metadata, with a size-scaled lease: 30 minutes for a single file, 120 minutes for coarser or multi-scope claims.NORTH_STAR.md:31; crates/rally-cli/src/store.rs:5391-5411; crates/rally-cli/src/decay.rs:39-47,90-113; crates/rally-cli/src/lib.rs:2493-2545; docs/PROTOCOL-NORTH-STAR.md:345-353 (scope kinds)A claim is not an operating-system permission boundary and Rally is not a sandbox. Nothing in the filesystem changed.docs/TURN-LOOP.md:67; docs/security/TRUST-MODEL.md:22-23
    04 · RefusalOverlapping claims are hard-refused at append time: an error, no fact appended, non-zero exit.crates/rally-cli/src/store.rs:5391-5411Rally refused the coordination record, not the file write. Nothing stops an agent editing src/api.ts anyway, and the before-write check is advisory by default.docs/TURN-LOOP.md:66-69; crates/rally-cli/src/check.rs:53-91; RALLY.md:37-40
    05 · RerouteHost-neutral: one CLI and one protocol across Claude, Codex, Gemini, and Cursor.NORTH_STAR.md:35; RALLY.md:65-76Rally does not judge whether the chosen lane is the right work. Its own docs say it cannot tell a useful task from a hostile one.docs/PROTOCOL-NORTH-STAR.md:30-32; dynamic-workflows/PROTOCOL.md:120-134
    06 · LivenessThe durable log keeps the original claim fact forever; the live projection drops a claim only when a later release, resolve, session close, or reap closes it.crates/rally-cli/src/claim_authority.rs:71-84; RALLY.md:315-331Two Rally lookups can answer differently for the same path at the same moment. say claim refused; check before-write allowed with a warning. Idle over 900 s is advisory; destructive takeover needs 7200 s of silence.crates/rally-cli/src/store.rs:1732,1740; crates/rally-cli/src/check.rs:120-146; session observation 2026-09-12
    07 · RetractThe log is never rewritten. The retraction itself stays visible and auditable, and room totals report retractions instead of hiding them.RALLY.md:242-270,348-419Rally does not judge which version is correct and does not chase the peer. A reader who read before the retraction and never reads again keeps acting on the withdrawn note.docs/PROTOCOL-NORTH-STAR.md:30-32; docs/COMMAND-SEMANTICS.md:28-29
    08 · Handoff and receiptA sender cannot close its own handoff, and a system or reaper action never closes it. Since commit 9129d81, retracted responses and system-authored closers do not count as proof of receipt.crates/rally-cli/src/store.rs:7413-7470,7452-7459,1147-1149; crates/rally-cli/src/lib.rs:12352-12363A receipt proves receipt, not completion, and the receiver's name on it is self-asserted and unsigned: Rally matches the target label and session, it does not authenticate anyone. A pane echo showing the prompt landed does not prove an LLM accepted it. The 30-day sweep is cleanup, not an answer; the item stays visible as stale in rally inbox.crates/rally-cli/src/store.rs:7431-7433; RALLY.md:264-266; docs/OPTIMIZATION-EVIDENCE.md:1-5,69-70; docs/COMMAND-SEMANTICS.md:110; crates/rally-cli/src/reaper.rs:35
    09 · The boundaryRally records the coordination facts but does not execute the task. Rally coordinates across agents; the verify loop drives within each lane.README.md:272; RALLY.md:130-138; dynamic-workflows/COORDINATION.md:118-138Rally does not know another tool's run state beyond what that tool self-reports. The observer admits its own limits too: heartbeat unknown, process liveness unknown.docs/OPTIMIZATION-EVIDENCE.md:1-5,69-70; run_status.py output 2026-09-12T07:46Z
    Accuracy matrix: every visible interaction mapped to a command, source, or test

    Model tests assert the page's own scenario model, not Rally. Session observations are real command output captured 2026-09-12.

    InteractionCommandSource at bc97e13Model test or session observation
    Agent announces presencerally enter --tool <tool>; rally say presencecrates/rally-cli/src/store.rs:527,601,631; docs/AGENT-STATE-MODEL.md:36model test: presence is a write
    Agent reads the roomrally room --json; rally whoami; rally nextdocs/COMMAND-SEMANTICS.md:28-32; docs/TURN-LOOP.md:25model test: no push events
    Host hook reads on the agent's behalfSessionStart and PreToolUse hooksdocs/AUTO-COORDINATION-HOOKS.md:268; docs/security/TRUST-MODEL.md:172-177; rally hooks status (enabled by default)session observation: rally hooks status enabled by default, 2026-09-12
    Claim a scope with a leaserally say claim --path <p>NORTH_STAR.md:31; crates/rally-cli/src/decay.rs:39-47,90-113session observation: claim fact_8bd9_18d48373a53099e8 carried lease_expires_at
    Overlapping claim refused at appendrally say claim (overlap)crates/rally-cli/src/store.rs:5391-5411session observation: verbatim 2026-09-12: claim conflict ... overlaps the scope you requested
    Advisory before-write findingrally check before-write --path <p> [--strict]crates/rally-cli/src/check.rs:53-91,120-146; RALLY.md:37-40session observation: 2026-09-12: allow:true with stale-owner-claim
    Expired lease is not closurerally doctor --reap-stale --applycrates/rally-cli/src/claim_authority.rs:71-84; crates/rally-cli/src/reaper.rs:406-439session observation: 2026-09-12: three reap passes closed the expired claims
    Retract without rewritingrally retract <fact-id> --reason <why>RALLY.md:242-270model test: withdrawal keeps the original
    Handoff stays open until the target answersrally say handoff --target <tool>; rally say receipt|resolve|artifact --ref <id>crates/rally-cli/src/store.rs:7413-7470; crates/rally-cli/src/lib.rs:12352-12363session observation: receipt fact_fc26_18d483db677dce00 authored by the target
    Receipt is not completionrally say receiptcrates/rally-cli/src/store.rs:7431-7433model test: receipt and artifact are separate events
    Build Loop run lifecyclepython3 scripts/run_status.py <run-id>build-loop scripts/run_status.py; README.md:272 (Rally does not execute the task)session observation: 2026-09-12T07:46Z: status abandoned, crash_signal stop_hook
    Choose shared checkout or linked worktreesrally run (default worktree) or rally run --shared / --no-worktreecrates/rally-cli/src/run_worktree.rs:4-34,81-131; RALLY.md:326-330model test: systems view layouts and fail-closed provisioning
    Launch a managed lanerally run claude|codex|opencode|gemini --backend auto --json; --dry-run firstRALLY.md:47-63,144-158; docs/HANDOFFS-AND-LAUNCHING-AGENTS.md:19-36model test: launch objects are separate and cited
    Inject into a managed sessionrally inject <session> --handoff <event-id>RALLY.md:95-99,144-162; docs/HANDOFFS-AND-LAUNCHING-AGENTS.md:82-85model test: acceptance still needs target-authored evidence
    Reach an unmanaged processrally say handoff --target <tool>; rally watchRALLY.md:95-99,160-162; docs/HANDOFFS-AND-LAUNCHING-AGENTS.md:86-110session observation: 2026-09-12: handoff 07:55:00Z, receipt 07:58:50Z by this unmanaged session
    Daemon cutawayrally daemon status|start|stop|serveRALLY.md:320-330,420-452; RALLY.md:152-153; docs/HANDOFFS-AND-LAUNCHING-AGENTS.md:30,111session observation: 2026-09-12: daemon live false, commands still worked (fail open)