import { COORDINATION_SECTION_ICON, SURFACE_SECTION_ICON, TURN_SECTION_ICON, WAIT_SECTION_ICON, } from "#configuration/icons/coordination.icons"; import { COORDINATION_SECTION_ID, SURFACE_SECTION_ID, TURN_SECTION_ID, WAIT_SECTION_ID, } from "#core/ids/coordination.ids"; import { TEXT_LANGUAGE, TYPESCRIPT_LANGUAGE } from "#configuration/constants/code.constants"; import type { Section } from "#types/document.types"; const RECORD_SHAPE = "┌─── ─── one writer: · others cite, never edit · a span edit only, never a whole-file write\n\n : \n : \n :\n ┌─── - ─── kind: at: to:\n To — the argument, across as many lines as it needs.\n └─── END -\n : \n└─── END "; const SCHEDULE_SHAPE = 'export const SCHEDULE_STATES = ["planned", "created", "open", "archived"] as const;\nexport type ScheduleState = (typeof SCHEDULE_STATES)[number];\n\nexport interface ScheduleRow {\n readonly ordinal: string;\n readonly invariant: string;\n readonly establishes: string;\n readonly merged?: string;\n readonly declaredState?: ScheduleState;\n readonly declaredBecause?: string;\n}\n\nexport const schedule: readonly ScheduleRow[] = [\n { ordinal: "1", invariant: "", establishes: "" },\n { ordinal: "2", invariant: "", establishes: "" },\n { ordinal: "2a", invariant: "", establishes: "", declaredState: "planned", declaredBecause: "" },\n];'; const MODEL_DIAGRAM = 'flowchart TB\n subgraph surface["A surface · a file the parties read and write"]\n r1["Record · one writer, declared on the record"]\n r2["Record · one writer"]\n r3["Record · one writer"]\n end\n artifact["An artifact in the tree"]\n other["A record on another surface"]\n r1 -- satisfied-by · closes when the artifact exists --> artifact\n r2 -- blocks · the target cannot close first --> r3\n r3 -- answers · refutes · supersedes --> other\n state["Every state is a query over these edges · nobody writes one"]\n surface -.-> state'; const READER_DIAGRAM = 'flowchart TB\n participant["A participant · holds a seat"]\n owns["Receives the surfaces it owns and its inbox"]\n waits["Ends never · it waits, and waiting has a command"]\n bounded["A bounded reader · a spawned run"]\n injected["Receives a task and whatever the host injects · never a coordination surface"]\n projection["One derived line is its whole view of the graph"]\n returns["Ends by returning · which is its contract"]\n participant --> owns --> waits\n bounded --> injected --> projection --> returns'; const SEAT_DIAGRAM = 'flowchart TB\n claim["A letter is claimed by adding a row to the index, before the first write"]\n allocated["The identity is allocated · the shortest free one, never reused"]\n role["A role document at the concern, the letter in a field"]\n record["A fenced record on the board, raised from the template"]\n state["One mutable column · active, inactive, invoked · a seat moves only its own row"]\n claim --> allocated --> role --> record\n claim -.-> state'; const SURFACE_DIAGRAM = 'flowchart TB\n subgraph board["The board · current truth only"]\n b1["Who owns what · what is directed at whom"]\n b2["Swept · a resolved item is deleted, never marked"]\n b3["Read whole, every round"]\n end\n subgraph venue["The venue · an argument"]\n v1["Where each seat stands · what it still needs"]\n v2["Accumulates until it converges · dissent survives"]\n v3["Holds the build while open · that red is intended"]\n end\n transport["One transport · fenced records, tool-allocated ids, compare-and-swap"]\n board -.-> transport\n venue -.-> transport\n venue -- converged, absorbed, then archived whole --> archive["The archive · the reasoning survives"]\n board -- absorbed items extract first --> history["The history accumulator · the only home history has"]'; const ITEM_DIAGRAM = 'flowchart TB\n posted["An item is posted · a fenced span, an allocated id, a kind, a stamp, its addressees"]\n kind{"Which kind?"}\n artifact["Artifact · asks for something that can exist"]\n judgement["Judgement · asks for a reading"]\n ref["Closes with a typed reference that must resolve"]\n ack["Closes by its acknowledger, with no reference"]\n handler["Closed by a seat in its reader set · never its author"]\n ledger["Held while a named recipient has not marked it read"]\n extract["Its durable half extracted to the accumulator first"]\n dropped["The span is dropped, never a matched line"]\n posted --> kind\n kind -- artifact --> artifact --> ref --> handler\n kind -- judgement --> judgement --> ack --> handler\n handler --> ledger --> extract --> dropped'; const CONVERGENCE_DIAGRAM = 'flowchart TB\n open["Open · the venue declares its own exit condition and holds the build"]\n needs["Every convened seat states its needs"]\n signed["Every convened seat has signed · a signature with an open need is refused"]\n durable["Every seat\'s durable half resolves in the accumulator"]\n deferred["Every deferred question has a destination that resolves"]\n directives["Every directive is discharged"]\n absorbed["The outcome is absorbed · the distribution checklist carries no open item"]\n inherited["Every clause the successor inherits was deferred here"]\n archive["Moved whole into the archive · never deleted"]\n open --> needs --> signed --> durable --> deferred --> directives --> absorbed --> inherited --> archive'; const WAIT_DIAGRAM = 'flowchart TB\n invoke["One invocation · the seat declared, the surface named"]\n check["Every operand of every requested operation is checked before any lands"]\n witness["A witness read immediately before the write"]\n moved{"Did the surface move since the read?"}\n span{"Does the change overlap this seat\'s own span?"}\n replay["Replay · the writes commute"]\n refuse["Refuse · carrying the diff of that span"]\n land["Land inside the seat\'s own fence"]\n sweep["Sweep · items every addressee has written past and been handed, extracted whole"]\n echo["Echo the seat\'s own claim, the items it can close, the open discussions"]\n snapshot["Re-snapshot for this seat · the next call reports only what changed"]\n invoke --> check --> witness --> moved\n moved -- no --> land\n moved -- yes --> span\n span -- no --> replay --> land\n span -- yes --> refuse\n land --> sweep --> echo --> snapshot'; const CAP_DIAGRAM = 'flowchart TB\n able["Seats able to write · parked, running a live claim, or active inside the liveness window"]\n waiting["Seats already parked"]\n cap{"Would this wait leave nobody able to write?"}\n blocked["Blocked · write first, the board owes a response"]\n watch["Watch the surface · changed with the diff, quiet after the window, removed if deleted"]\n able --> cap\n waiting --> cap\n cap -- yes --> blocked\n cap -- no --> watch'; const RUN_DIAGRAM = 'flowchart TB\n start["A run declares its write scope and claims standing"]\n live{"Does a live run\'s write set overlap?"}\n held["Healing held · report only, until the other run publishes"]\n later{"Did this run start later than that one?"}\n join["Join · read out what the live run publishes, write nothing"]\n run["Run · stamp every surface read, re-stamp at the end, name the surfaces it healed apart"]\n quotable["The aggregate is overwritten · the verdict carries its standing"]\n start --> live\n live -- no --> run\n live -- yes --> later\n later -- yes --> join\n later -- no --> held --> run\n run --> quotable'; const TURN_DIAGRAM = 'flowchart TB\n item{"Is there an open item?"}\n work["Work it · a tool call advances it"]\n blocked{"Blocked on a peer?"}\n next["Route to the next unblocked item"]\n wait["Wait through the tool · the turn stays open"]\n changed{"What did the wait return?"}\n read["Read the surface whole, then act on every item addressed to me"]\n own["Pick up my own work and wait again"]\n report["A report to the operator"]\n item -- yes --> blocked\n blocked -- no --> work --> item\n blocked -- yes, others open --> next --> work\n blocked -- yes, all --> wait --> changed\n changed -- changed --> read --> item\n changed -- quiet --> own --> wait\n item -. never, while work remains .-> report'; const COORDINATION_SECTION: Section = { icon: COORDINATION_SECTION_ICON, id: COORDINATION_SECTION_ID, intro: "Several reasoning agents write one tree concurrently, and the premise is that their coordination is software. It has state, invariants and a schema, as the model draws, and it decays without a validator; a seat comes to be in the order a seat's making draws, and its readers fall into the two classes reader classes derives. A lost update, a stale item, a missed message or a surface grown past reading is a defect report against the protocol, never a call for more care, and friction is a missing concurrency control. The grammar page states the same premise as orchestration as declared structure, and shared surfaces there is the schema this chapter derives.", subsections: [ { blocks: [ { application: "Model the coordination as a graph. Let a surface be a file the parties read and write, a record be one addressable claim inside it with exactly one writer declared on the record itself, and an edge be an id in a field. Derive every state by traversing the edges and let no party write one. Give each party a permanent identity bound in an index before its first write, and derive who may read an item from presence on the surface and state in the index rather than from anything a party declares about itself.", boundary: "One writer per record is the load-bearing invariant, and it has no operand on an outcome surface that is authored jointly, a contract or a measured baseline. There the invariant is declared inapplicable with its reason, and the mechanism that reaches a semantic collision is an announcement plus each author cutting its own duplicate, which is a different instrument from a fence.", cause: "Every coordination failure is produced by good behaviour composing badly: each append is a real finding honestly reported, and the defect is entirely in the composition, which no rule about care can see.", decision: "Treat every coordination failure as a missing mechanism, and answer it with a surface, a schema or a validator.", failureMode: "A board grows past what any reader can consume, carrying hundreds of directed items, with every drain rule in force and agreed by every party.", kind: "lesson", principle: "Coordination is software. It has state, invariants and a schema, and it decays without a validator.", problem: "More than one agent on one tree loses writes, accumulates stale items and misses messages, and each incident has a plausible local cause that hides the mechanism gap.", validation: "Take the last coordination failure and name the mechanism that would have made it impossible or loud. If the answer is that someone should have been more careful, the mechanism is still missing.", }, { caption: "the model", kind: "mermaid", text: MODEL_DIAGRAM }, ], title: "Surfaces, records, edges, states", }, { blocks: [ { kind: "text", text: "It is the refusal of shared mutable state at the granularity of a claim: with one writer per record, ordinals allocate without coordination, last-writer-wins cannot occur, and protection of another party's scope becomes checkable per record. The quantifier is the whole of it: stated per surface it is false wherever a surface is shared, which is the normal case, and the two forms are indistinguishable at a single-writer surface, which is why the error survives. A record's identity is allocated once and never recomputed, and its subject is declared and re-derived every run, because an id derived from location breaks on a move and one derived from subject breaks on a rename. Two records sharing a subject key is the finding that catches re-derivation.", }, { kind: "text", text: "No agent writes a state; derived state is the rule here as everywhere. A written state is a marker, a marker goes stale, and a stale marker manufactures a false belief where an absent one reads as absence. Open, blocked and absorbed are queries over the edges, event sourcing over a graph of claims: open while a citation is unresolved, blocked while an inbound edge comes from an open node, absorbed when the citation resolves. Absorbed is a transition, never a resting state: the record's durable half is extracted to the one home history has, an append-only log, then the record is deleted in the same change, because a record resting in absorbed is a status marker under another spelling.", }, ], title: "One writer, no written state", }, { blocks: [ { kind: "text", text: "A seat is a letter bound to a role in an index that only grows, and a seat is a contract says what the role document holds. The index is an accumulator rather than a board section because the board deletes what is resolved while a letter that has stopped being active still has to resolve, since every item, row and citation that ever named it points there. The letter is claimed by adding the row before the first write and never by using it. The identity is allocated rather than chosen: the tool issues the shortest free identity from a scheme that never exhausts and never recycles, and the letter a party asks for is its declaration for that call, not the allocation. The index has one mutable column, the seat's state, drawn from a closed set, because the reader set, the wait cap, the addressee resolution and the convergence quantifier all derive from it. A seat moves its own row, and a party moving another party's state states its warrant beneath the row.", }, { caption: "a seat's making", kind: "mermaid", text: SEAT_DIAGRAM }, ], title: "A seat is allocated, never chosen", }, { blocks: [ { kind: "text", text: "A reader's class is derived from what it received, never from what it decides it is. A participant receives the surfaces it owns and its inbox, and it never ends: it waits, and waiting has a command. A bounded reader receives a task and whatever the host injects, and never a coordination surface. One derived line is the whole of what it knows about every surface, so a fact absent from that line does not exist for anything spawned. The line is refreshed in the same change as the fact it carries, because a stale projection is a false statement delivered as the only statement. The rules divide by class, and turn-owning rules invert for a bounded reader: obeying never end a turn forbids returning, and returning is its contract. Which class a reader is comes from the binding rather than from the reader: a deployment whose board slot resolves absent is single-worker by declaration, and a reader classifying its own turn is an escape hatch keyed on self-classification.", }, { caption: "reader classes", kind: "mermaid", text: READER_DIAGRAM }, ], title: "Two reader classes", }, ], title: "Coordination is software", }; const SURFACE_SECTION: Section = { icon: SURFACE_SECTION_ICON, id: SURFACE_SECTION_ID, intro: "Two surfaces with opposite lifetimes share one transport, as two surfaces draws. The board carries coordination state, who owns what and what is directed at whom, and is swept, because it is current truth only and an item nobody drains is a tax every seat pays every round. One seat's span is what a seat's record shows, and an item's closure draws how an item leaves it. The venue carries an argument, and accumulates until it converges, because a position stands until read and dissent survives to the end, through the orderings convergence draws and the schedule a venue schedule types. The grammar page's coordination templates carry both shapes, and composing a collaboration is where the seats that write them are partitioned.", subsections: [ { blocks: [ { application: "Keep the board current-truth-only: overwrite it in place, delete a resolved item outright, and pair every append with a drain of whatever is already absorbed. Enclose each seat's record in a delimiter naming its writer, and each addressed item in a fence keyed to an id the tool allocates, with its kind on the marker. An edit then has a span to anchor to, a removal takes the span rather than a matched line, and the closure is selected by the kind rather than judged. Let the seat that handled an item remove it, never the seat that wrote it, and extract its durable half first. Write positions to an open venue, hold the build while it stands, and archive it whole once its outcome is built.", boundary: "A venue is writable by tool and never drainable by tool, and once archived it has immutability: an append-only log of the argument. Nothing in an open venue is closed or compressed, since draining a discussion would delete the argument it exists to hold. Leaving the active tree and leaving the repository are different operations, and a wording that says deleted collapses them.", cause: "Only the handler knows an item is handled and only the writer was permitted to remove it, so the knowledge and the permission sat in different seats and the item stayed.", decision: "Split the surfaces by lifetime rather than by topic, so a swept surface and an accumulating one never share a record.", failureMode: "A converged venue is removed from disk on signature, satisfying every ordering the closure checks, and every position id the accumulator cites resolves to nothing.", kind: "lesson", principle: "The board is swept and the venue accumulates, and the two share only their transport.", problem: "One surface asked to hold both coordination state and an argument reports one state and hides the other.", validation: "Read the board for an item that argues rather than states, and read the archive for a venue whose reasoning is missing. Either one is a lifetime applied to the wrong surface.", }, { caption: "two surfaces", kind: "mermaid", text: SURFACE_DIAGRAM }, ], title: "Swept and accumulated", }, { blocks: [ { kind: "text", text: "The delimiter is not decoration. A seat revising its own record needs a span it can match exactly that no other seat's content occupies. Without one the only thing left to match is the whole file, so the seat reaches for a whole-file write, which succeeds, reports success to the party who overwrote, and says nothing to the party overwritten. A template that must contain a record shape to state one fences the specimen, because a fenced specimen is a record mentioned and an unfenced one is a record claimed, the use-against-mention class arriving on the write side.", }, { kind: "text", text: "An item's kind sits on its marker and selects its closure, which is what the grammar page calls handoff signals: typed items, falsifiable closures. An artifact item asks for something that can exist, so it closes with a typed reference that must resolve, and a reference whose kind names no corpus resolves vacuously and reads exactly like one that passed, which is why the kind set is closed. A judgement item asks for a reading, so it closes by its declared acknowledger with no reference, because there is nothing for one to point at, and the acknowledger is required or forbidden by kind rather than optional. An artifact item carrying nothing durable closes with a declared-empty reference, and the tool then publishes the classes already filed, so declaring nothing durable is a lookup a peer can contest rather than an oversight nobody can see.", }, { kind: "text", text: "The sweep is the mechanical drain, and it is delivery-gated: an item is a message on a message queue whose consumers are named, and it leaves the queue when every consumer has taken delivery. On every write the tool sweeps items whose every addressee has both written after the item and been handed it in a delivered read, extracting each whole into the accumulator before removal. It holds any item an addressee has not received, because the write-past rule is a fact about their writing and never about their reading. Durability and delivery are independent, and archiving an item nobody received preserves the first while destroying the second. An argument is refused on the swept surface by its shape: a body carrying a position's own declared fields, derived from the venue template rather than listed, is turned back with the instruction to name the venue.", }, { caption: "an item's closure", kind: "mermaid", text: ITEM_DIAGRAM }, { code: RECORD_SHAPE, kind: "code", language: TEXT_LANGUAGE, title: "a seat's record" }, ], title: "Fences, kinds and the sweep", }, { blocks: [ { kind: "text", text: "A venue declares its own exit condition or it is an indefinite halt. While it stands, its presence fails the pipeline, and that red is the intended state: building around an open question produces work that gets rewritten. Its fields are its own, where each seat stands and what it still needs before it can sign, and an empty need across every convened seat is what convergence looks like rather than something a seat judges. A position is posted through the tool into the seat's own fenced record, so the fence, the id, the addressing and the compare-and-swap apply on a venue as on the board. A position carries a signed line as its one structural end mark, because a body cut short at a blank line reaches the argument already short, and the signature is the detection the boundary hides. A signature is refused while the same seat states an open need, since an unmet need and a signature are contradictory claims by one party.", }, { kind: "text", text: "Convergence is a walk over event ordering, each ordering encoded as a refusal rather than a note, because an ordering recorded in prose is rediscovered by collision while one encoded in the operation cannot be. Orchestration invariants on the grammar page states the general form, and stating an invariant is how a seat writes one. The convened set is the intersection of the board's active seats and the venue's participants, and a venue no seat is party to is reported as failing rather than vacuously passing, because a filter over an empty set holds over nothing. Convergence certifies agreement and nothing about the tree, so the outcome is distributed as a checklist with an owner per item and lands before the venue moves. The move creates the archived name and fails if it exists before it unlinks the source, so a failure leaves the venue where it was.", }, { caption: "convergence", kind: "mermaid", text: CONVERGENCE_DIAGRAM }, ], title: "A venue converges or holds the build", }, { blocks: [ { kind: "text", text: "A successor is declared by name against a schedule rather than derived from an ordinal, because an ordinal is a position in a total order while the real edges are partial with forward dependencies, a directed acyclic graph rather than a list. The declaration is checked at the moment it is written, a deferral names its receiver on the same line and is refused unless the receiver is an active seat, a venue on disk or a planned row, and a venue that defers nothing records that as a third state distinct from unfilled. The schedule has one author, resolved by concern and succeeded rather than shared, because a schedule with several authors stops being derivable from any single reading. The schedule's state column is computed from the tree on every run rather than written.", }, { kind: "text", text: "The record and the schedule are the two shapes worth holding in mind, because every check on the surface derives from one of them. The schedule's state column is computed on every run unless a row declares it with a reason, so the row set is the plan and nothing in it records what happened. Both shapes ship as templates, and the checks read their contracts from those templates the way the drop-in describes.", }, { code: SCHEDULE_SHAPE, kind: "code", language: TYPESCRIPT_LANGUAGE, title: "a venue schedule" }, ], title: "The schedule is a graph", }, ], title: "The board and the venue", }; const WAIT_SECTION: Section = { icon: WAIT_SECTION_ICON, id: WAIT_SECTION_ID, intro: "The seats speak to each other through one tool, and the tool makes the protocol structural rather than remembered. Posting and waiting are one operation, one invocation end to end. Every invocation declares its seat, writes only inside that seat's own fence under optimistic locking, delivers the diff of what its peers wrote since that seat last looked, sweeps what every addressee has received, and re-snapshots. How long it waits is what the wait cap derives, and a second run joins a live one, as joining a run draws. What a seat cannot do by hand is what the tool refuses to let it do, which is tools live in the tree applied to the collaboration itself.", subsections: [ { blocks: [ { application: "Give the collaboration one tool with one shape. Key every invocation to a declared seat, because the snapshot, the fence, the reader set and the closure check are all derived from it. Check every operand of every requested operation before any of them lands, so an invocation is one unit. Take a witness read immediately before every write, replay a write that commutes with what moved, and refuse only a genuine overlap with the diff of the writer's own span. Deliver the diff whole, never a status line with content attached.", boundary: "The tool reaches the surfaces that are shared and still writable. A surface with one writer by construction needs no fence, no allocated id, no compare-and-swap and no reader set, because all four defend against a party that cannot exist there, and a closed record or an archived discussion needs no write path at all.", cause: "A protocol mandating a surface its tool cannot write to is obeyed by hand, and a hand write has no fence, no allocated id, no compare-and-swap, no reader set and no gate.", decision: "Make every coordination write a tool write, and make the tool refuse what the protocol forbids.", failureMode: "Three seats filter the tool's output for the line confirming their own write landed, discard every peer position delivered in the same stream, and the tool reports success each time.", kind: "lesson", principle: "Posting and waiting are one operation keyed to a declared seat, and the delivery is the diff since that seat last looked, consumed whole.", problem: "A coordination surface written by hand carries every guarantee as a hope, and a hope decays at the rate of the party who holds it.", validation: "Invoke the tool with nothing after it and read the whole of what it returns. Then try to break each guarantee by hand: a body passed as an argument, a closure by the author, a mark by a stranger, a second record for one seat. Each must be refused with the reason the refusal exists.", }, { caption: "one invocation", kind: "mermaid", text: WAIT_DIAGRAM }, ], title: "One tool, one shape", }, { blocks: [ { kind: "text", text: "The snapshot is per seat per surface. The tool reads the seat's last snapshot of the target, writes the current content as the new one, records which addressed items it delivered, and returns a line-level diff. A first read answers with a snapshot and nothing else, an unchanged surface answers that nothing moved, and a changed one answers with the added and removed lines. The diff is the delivery: every peer position written since this seat last looked arrives in that stream and nowhere else, so the output is consumed whole. Past the read budget the delivery degrades rather than truncates, backpressure applied to a read: it names every changed item by its fence and leaves the bodies on the surface, because a silent truncation hands a partial read that looks complete. Every write also echoes what nothing else would prompt the seat to re-read.", }, ], title: "The delivery is the diff", }, { blocks: [ { kind: "text", text: "The allocated id is a correlation id: every closure, citation and read mark resolves through it. A body carrying a boundary marker line is refused, because boundaries are what make a span removable.", }, ], title: "The item and its id", }, { blocks: [ { kind: "text", text: "A per-item read ledger lives on the item's own marker and dies with it, which is what lets a swept surface carry per-party delivery state without becoming a surface that tracks. The ledger is what makes each seat an idempotent consumer of the items addressed to it. Each party moves its own letter and no other, a mark by a party the item never addressed is refused, and a closure is held while a named recipient still active has not marked, so a change every seat must hold drains on its last reader rather than its first. A rehearsal that writes is the worst shape a preview can take, because the invocation a party chooses for safety becomes the one that acts unannounced, which is why tools live in the tree has a mutation preview by default.", }, ], title: "Delivery per party", }, { blocks: [ { kind: "text", text: "The wait blocks on the surface's modification state, the publish/subscribe pattern over a file with a timeout pattern for the window. It reports the diff when it moves, quiet when the window closes untouched, and removed if the surface is deleted while watching, and every exit is typed so a caller reads the code rather than the prose. Waiters are capped at the number of seats able to write minus one, and the denominator is liveness rather than membership. A seat counts where it is parked, where it holds a live run, or where it touched a surface inside the declared window, because a seat that stops without moving its row would otherwise raise the threshold by one until every remaining party could park with nobody left to write. The last seat is told the board owes a response, and the solitary case is stated apart because no write clears it.", }, { caption: "the wait cap", kind: "mermaid", text: CAP_DIAGRAM }, ], title: "The wait and its cap", }, { blocks: [ { kind: "text", text: "A long-running run scales by joining rather than duplicating, the idempotency of a measurement. A run declares its write scope and claims standing before it runs. Healing is held while another live run's write set overlaps, because a run mutates, and healing while another run is mid-write takes an exclusive resource without declaring it. A run that starts later than an overlapping live one joins it and reads out what it publishes instead of measuring the same tree twice, and a run whose question a live run already covers reads the covering result. Every surface a run reads is stamped and re-stamped, and verify the verifier says what a moved read set does to the verdict; the surfaces the run itself healed are named apart, because counting a run's own repairs as contention would make every healing run un-quotable. A run's declaration is a claim and its writes are a fact, so a write outside the declared scope and a claimed repair whose surface never moved are both reported, and they are the one comparison between a claim and an observation the run performs.", }, { caption: "joining a run", kind: "mermaid", text: RUN_DIAGRAM }, ], title: "A run joins, never duplicates", }, ], title: "Posting and waiting are one operation", }; const TURN_SECTION: Section = { icon: TURN_SECTION_ICON, id: TURN_SECTION_ID, intro: "A turn never ends because work blocks on a peer, which is the one edge a turn never takes. Ending the turn is the wait, and the wait is the halt. Waiting costs a tool call instead of a turn, and a seat reports to its peers on the surface, never to the operator, because a report addressed to the operator reads as an ending and stops the collaboration for as long as it takes them to reply. Posting and waiting are one operation is the tool this chapter leans on, and phase binding on the grammar page is why a bounded run returns instead.", subsections: [ { blocks: [ { application: "Work the next open item, and where one blocks, route to the next unblocked one. Where every item depends on a peer, take the wait through the tool, naming the surface the argument is on, and keep the turn open across it. On a change, read the surface whole and act on every live item addressed to you, never wait again immediately and never narrate what the read found. On quiet, pick up your own work and wait again. Write findings, status and conclusions as directed items to the seats that need them.", boundary: "Where the work is clear and nothing blocks it, do it. Every coordination mechanism is a way of moving work, and moving work feels like doing it, so before routing anything name the blocker, and where naming it produces nothing the item is clear and the routing is a substitution.", cause: "A well-organised summary delivered at a moment that felt conclusive is the most common disguise a halt wears, and the quality of the summary is not a defence.", decision: "Route a blocked item to the next open one, and wait through the tool only when every item is blocked.", failureMode: "A seat's own queue empties, it reports a milestone, the turn ends, and the peers whose writes would have created its next work never receive what it found.", kind: "lesson", principle: "A turn ends on a tool call, a wait is a call rather than a halt, and findings go to the seats that need them.", problem: "Every coordination failure that outlives its mechanisms takes the shape of a turn that ended on prose.", validation: "Read the last action of every response in a session. A response whose last action is prose while work remained stopped the collaboration however much work preceded it.", }, { kind: "text", text: "A second consecutive wait discards the signal just delivered while looking like diligence, because a tool call is present and the turn stays open. Reading produces a coherent picture of what just moved, and a coherent picture is the strongest invitation to describe it; the description is the halt. Quiet is a fact about the peers, never about the queue, and the queue is never empty while a surface is unaudited, a pattern is ungated or a claim is unverified.", }, { kind: "text", text: "A decision nobody is making is a routing signal rather than a stall, and it travels as one of the handoff signals the grammar page types. Two independent declines are the trigger: a question every existing seat has declined is an input that exists in no file, which is exactly what makes work agent-shaped, and it resolves to a seat proactively, an existing one whose concern covers it or one created for it. A question a seat correctly identifies as above its own authority routes to the seat whose surface the decision binds, named in the same position that declines it, because not mine to take is a routing statement rather than a terminal state. A fully diagnosed contradiction with a named repair and no taker reads as handled while nothing lands. The operator is out of the loop and signs off on every venue automatically, so no venue waits on their signature and no decision inside one is theirs to take. What the work is for stays theirs to answer whenever they choose, at the cost of a message rather than a held venue. A question to the operator binds a seat only; a bounded invocation returns its uncertainty instead, as ask where it appears describes.", }, { caption: "a turn", kind: "mermaid", text: TURN_DIAGRAM }, ], title: "Waiting has a command", }, ], title: "A turn never ends to wait", }; export const SURFACE_SECTIONS: readonly Section[] = [COORDINATION_SECTION, SURFACE_SECTION, WAIT_SECTION, TURN_SECTION];