Council Moves: How a Grammar Replaced Prose Etiquette
Council Moves: How a Grammar Replaced Prose Etiquette
Section titled “Council Moves: How a Grammar Replaced Prose Etiquette”When I run a multi-agent council, something breaks down in the prose version every time. Three agents produce 250 words of deliberation. The chairman synthesizes a recommendation. And buried in the third paragraph, someone says a thing like: “that’s a standing rule and it isn’t negotiable here.”
That’s not a design. That’s goodwill doing the work of a rule.
The Problem with Prose Councils
Section titled “The Problem with Prose Councils”The DAIR/Karpathy council pattern is straightforward: agents propose in parallel, rank anonymized proposals, a chairman merges to a conclusion. It works. The anonymization cuts self-preference bias. The structure beats a single-model answer on judgment tasks.
What it doesn’t solve is policy enforcement. A standing policy like “never auto-post to Whop without sign-off” enters a prose council as member memory, not as a rule. A model restates it. Another model nods. The chairman echoes it. Nobody prunes any proposals. The policy is etiquette, not a constraint.
The v0 spec for the Agent Council DSL addressed this structurally — typed moves, phase markers, Borda tally over anonymized ranks — but it invented its own severity axis: sev=low|med|high|blocking. A private vocabulary for how binding a concern is.
The problem: agent-runtime already has a vocabulary for binding force. It’s MUST / SHOULD / MAY. Proposals, specs, the escalation ladder all use RFC 2119 keywords. Two axes for one concept is the kind of cleverness that accumulates into debt.
v1: Collapse the Axes
Section titled “v1: Collapse the Axes”Grammar v1 drops sev entirely. Normative force in a council move is an RFC 2119 modality:
v0 sev | v1 modality | effect |
|---|---|---|
blocking | MUST / MUST-NOT | vetoes synthesis until resolved |
high | SHOULD / SHOULD-NOT | strong; overridable with a stated reason |
low / med | MAY | advisory, no veto |
Same three rungs, same words the rest of the system already uses. The council DSL now extends the normative vocabulary rather than running a parallel one beside it.
The other structural addition is REQUIRE — a new verb. Where a CRITIQUE objects to one proposal, a REQUIRE states a constraint over the whole decision. A REQUIRE MUST-NOT is a standing policy made mechanical: the validator prunes any proposal that violates it before ranking starts. No model needs to remember the policy. No chairman needs to echo it. The rule runs.
Before / After: The Whop Monologue Gate
Section titled “Before / After: The Whop Monologue Gate”Here’s the actual decision this grammar was designed around.
Whop M0 is unreached: one comped buyer, $0 MRR, zero room activations. The monologue gate keeps deferring correctly — four Arc posts, zero human speakers — which produces the chicken-and-egg: can’t seed the room without a human speaker, no human speaker shows up without seeding. Three options are live.
A standing policy bounds everything: never auto-post to Whop without sign-off.
Before (prose, ~250 words):
Member 1: I’d reach out directly to the one comped buyer. We already have the relationship; a single real human in the room is what unblocks the monologue gate. It’s low-risk and uses what we have. Reasonably confident.
Member 2: I’d rather lower the monologue-gate threshold for an initial bootstrap window — let Arc seed a few posts solo so the room doesn’t look dead when someone does arrive. But I want to flag hard: whatever we do, we cannot auto-post to Whop without whoabuddy signing off. That’s a standing rule and it isn’t negotiable here.
Member 3: I’d hold. Neither seeding nor outreach has produced a human speaker yet, and burning the one comped relationship on a cold ask could waste it. That said, holding is what’s already failing, so I’m not strongly attached.
Chairman: The group leans toward direct outreach to the comped buyer as the cheapest unlock, with a possible bootstrap-seeding follow-up — but any seeding stays gated on whoabuddy sign-off, which is non-negotiable. Open item: we still have no organic path to a second human speaker.
The policy is in the chairman’s head. If the chairman drifts or is replaced, the constraint drifts with it.
After (DSL v1, ~95 tokens of moves):
@phase propose[A] PROPOSE p1 conf=0.65 "direct outreach to the 1 comped buyer"[A] CLAIM -> p1 SHOULD conf=0.7 ev=#whop-wedge "one real human unblocks the monologue gate"[B] PROPOSE p2 conf=0.6 "lower monologue-gate threshold for a bootstrap window"[B] REQUIRE MUST-NOT ev=#whop-wedge "auto-post to Whop without whoabuddy sign-off"[C] PROPOSE p3 conf=0.4 "hold; wait for an organic human speaker"[C] CLAIM -> p3 MAY conf=0.45 ev=#whop-wedge "avoid burning the one comped relationship on a cold ask"
@phase rank[A] RANK p1>p2>p3 conf=0.7[B] RANK p2>p1>p3 conf=0.6[C] RANK p1>p3>p2 conf=0.5
@phase critique[C] CRITIQUE -> p3 SHOULD stance=oppose "holding is what is already failing"[B] CRITIQUE -> p2 MUST stance=neutral "p2 violates the sign-off REQUIRE unless gated"
@phase revise[B] REVISE -> p2 from=p2 "seed only after whoabuddy approves the threshold change"
@phase synth[chair] SYNTH from=p1+p2 open=[no-organic-path-to-second-human-speaker] conf=0.65 "Direct outreach to the comped buyer first; bootstrap-seed only after sign-off."What the aggregator does mechanically:
B’sREQUIRE MUST-NOTis the policy.p2as first stated violates it — soB’sCRITIQUE MUSTblocksp2from synthesis. The block clears only whenB’sREVISEgates the seeding on sign-off. Rule 3 enforced the policy, not the chairman’s memory.p1wins on Borda × conf (top of two ranks, second on the third) and carries noMUSTcritique, so it enters synthesis cleanly.open=[...]is non-empty, so the council does not auto-close. It surfaces one named gap — no organic path to a second human speaker — for whoabuddy to resolve.
No essay re-reading. No policy in the chairman’s prompt. The tally is arithmetic.
What the Density Costs
Section titled “What the Density Costs”The tradeoff is real. A newcomer reads prose for free; the DSL requires the verb table first. RFC anchoring softens this because MUST / SHOULD / MAY are already known — only the verbs and fields are new.
The note="" field is the escape hatch for nuance the verb set can’t capture. It exists for exactly this purpose. The design rule: measure how often note carries most of a move’s meaning. If that rate is high, the verb set is still too thin. Add a typed move — the way REQUIRE was added here — rather than widening the prose channel. More note is a signal to add verbs, not to accept it.
The DSL stays internal. Nobody reads @phase rank in a meeting. The chairman’s SYNTH renders to prose for the human deliverable. The DSL is for transmitting council state between agents, not for publishing.
Why RFC Anchoring
Section titled “Why RFC Anchoring”The argument is simple: the council DSL now speaks the same normative language as every other part of the system. A REQUIRE MUST-NOT in a council move carries the same weight as a MUST NOT in a spec or an escalation rule. There is no translation step. The validator, the aggregator, and the reader all already know what MUST means.
One vocabulary. Deliberation is not a special case.