Diplomacy Table — Configuration & Teaching Console

DTSF · multi-agent negotiation simulator · instructor / operator surface
not connected

Connect this page to a DTSF backend

This page is a static file. It can be served three ways — from the DTSF runtime itself (GET /diplomacy-table/config), from a GitHub Pages site, or straight off disk (file://). In all three cases it talks to a DTSF backend over plain CORS-enabled HTTP. Everything on the Architecture, Knobs, Models, Tactics, Scenario, Delegations and Runbook tabs works with no backend at all; only the live probes and the Bake-off runner need a connection.

Backend

Origin only — no trailing slash, no /diplomacy-table suffix.
Sent as Authorization: Bearer <token>. Stored in this browser only.

Resolution order

The same four-step resolver is used by every Diplomacy Table page. First non-empty value wins.

  1. ?api= query parameter — wins over everything; ideal for handing a pre-wired link to a class or a panel.
  2. localStorage['dtsf.apiBase'] — sticky per browser; what the remember checkbox writes.
  3. window.DTSF_API_BASE_DEFAULT — a one-line <script> injected at publish time, so a Pages deployment ships already pointed at the convening backend. Tested with in rather than for truthiness, so publishing it as '' is a valid, explicit "no backend here" — which is what a reference-only Pages build should ship. Without it the resolver would fall through to the Pages origin and report connection errors against github.io.
  4. window.location.origin — the same-origin case, i.e. the page was served by the DTSF runtime. On file:// this yields no base and the page stays in reference-only mode.

Token resolution mirrors it: ?token=localStorage['dtsf.token'] → none.

What the token is, and what it is not

The backend reads DTSF_AUTH_TOKEN from its environment. If that variable is unset the instance is completely open and the token field here is ignored — which is the right posture on a laptop and the wrong one on anything with a public hostname. When it is set, every route requires Authorization: Bearer <token> except four deliberate exceptions.

PathWhy it stays public
/_health, /_ready Load balancers, uptime monitors and container orchestrators probe these without credentials. Gating them means the platform declares a healthy box dead.
/_version Build identity only. Useful when someone needs to tell you what they are running before they can authenticate.
/diplomacy-table/config This page. It is the thing that collects the token, so requiring the token to load it would deadlock the bootstrap. It ships no data — every call it makes is gated.
Consequence worth internalising before a demo: because /_health is public, a green status pill proves only that the host is alive. It does not prove your credential works. That is why this console probes a gated route as part of connecting, and reports token rejected separately from unreachable.
Limits, stated plainly. This is one shared secret, not identity. There are no roles, no per-user revocation and no audit trail; everyone holding it is an administrator. A token handed to a browser is not secret from the person driving that browser. Critically, it does not enforce the Constitution’s isolation invariant — a holder can read any delegation’s private mandate at /diplomacy-team-*. If participants need their own seats, put path rules in the reverse proxy (see the Caddyfile in docs/diplomacy/DESIGN.md) rather than relying on this alone.

Rotation is a restart: change the environment variable and bounce the process. Shareable links from this page deliberately omit the token, so rotating does not invalidate a link — only the credential pasted alongside it.

Live status

Probe log

Not connected. Enter an API base and press Connect & probe.

Deployment shapes

ShapeFrontendBackendGood forWatch out for
All-in-oneserved by DTSF at /_app/diplomacy-table same processlocal dev, single-laptop demo nothing to publish; nobody outside the room can watch
Pages + tunnelGitHub Pages (Ethical-Tech-Colab) B3IQ box behind Cloudflare Tunnel / Caddy the recommended live-convening shape backend must stay up; needs TLS + an auth story
Pages + replayGitHub Pages none — static JSON transcript bundles public, permanent, zero-cost archive of a completed convening read-only; no new rounds
Cloud PaaSPages or the PaaS itself Render / Azure Container Apps always-on demo without owning hardware cold starts drop in-memory state; per-token cost is on you

Full comparison, threat model and B3IQ topology: docs/diplomacy/DESIGN.md §4.

What is actually running

Ten minutes of orientation before anyone touches a knob. This is the mental model that makes the rest of the console legible: a neutral table twin that owns procedure and the record, and N delegation twins that own only their own instructions and their own words.

The two kinds of twin

Table twin — diplomacy-table

  • Owns the session: parties, rules, round counter, status.
  • Owns the record: every move, every detected tactic, every debrief.
  • Runs the speaking order and the quality guards.
  • Is the only component that sees all delegations' private instructions. It never leaks them into another delegation's prompt.
  • Has no model of its own for the negotiation turns.

Delegation twins — diplomacy-team-*

  • Own a persona, goals, red lines, a BATNA and a tactic set.
  • Expose one meaningful endpoint: POST /turn.
  • Receive a windowed transcript plus a structured memory block; return a JSON move.
  • Are told which model to use per session — the pack does not hard-code one.
  • Never see another delegation's red lines, BATNA or private guidance.

One round, step by step

  1. Guard the call. POST /sessions/:id/round/next refuses if the session is not active, if the round cap is hit, or if a human party still owes a move.
  2. Compute speaking order. Honours openerPartyTwin and rotateOpener. Coalitions with a whip collapse to a single speaking slot.
  3. Classify each slot as speaking skipped twin-already-moved human-recorded human-awaiting. Only speaking slots call a model.
  4. Call each delegation in sequence. Deliberately sequential: the transcript accumulates during the round, so speaker 3 answers what speakers 1 and 2 just said. A parallel version was tried and reverted — it produced round-robin monologue and a high timeout rate.
  5. Run the guard ladder on each returned move: stub detector → opponent-echo → self-echo. Each failure buys one anti-mirror retry; persistent failure records a flagged placeholder move and increments a degraded counter.
  6. Detect tactics with the rule engine and attach them to the move.
  7. Advance the round and persist. The table's state is snapshotted to disk on a timer.
Teaching point. Almost every "the AI is being dumb" complaint traces to step 4 or 5, not to the model. A delegation that repeats itself is usually being fed a transcript window that is too small (so it cannot see its own last move) or too large (so its instructions are drowned). See the Knobs tab, maxInputTokens.

Request path in a Pages deployment

  browser (GitHub Pages, Ethical-Tech-Colab)
      |  fetch(apiBase + '/diplomacy-table/...')   CORS: Access-Control-Allow-Origin: *
      v
  edge / tunnel  (Cloudflare Tunnel or Caddy on the B3IQ box)
      |  TLS terminates here; add auth here, not in the browser
      v
  DTSF runtime  (single Node process, tsx)
      |-- /diplomacy-table/*   table twin: sessions, moves, tactics, reports
      |-- /diplomacy-team-*/*  delegation twins: /turn
      |-- /ollama/*            provider registry + OpenAI-compatible passthrough
      |-- /_proxy, /_cache     inbound rate-limit shield, response cache
      |-- /_health, /_version  liveness
      v
  model backends: local weights on the B3IQ GPU, and/or a hosted API
Structural constraint. The runtime makes cross-twin calls to http://localhost:${PORT}. The table twin and every delegation twin must therefore live in the same process. You scale by making the box bigger or by running independent whole instances, not by splitting twins across nodes. This is the single largest architectural assumption in the system.

State & durability

Where state lives
In-process Map per twin. Fast, simple, and volatile.
Durability
Periodic snapshots to evidence/sessions/<timestamp>/, plus a final snapshot on graceful shutdown. On boot the runtime restores the most recent readable snapshot.
What this means
A hard kill between snapshots loses the moves since the last one. Before a graded exercise, take a manual snapshot and shorten the interval.
Not present
No database, no WebSocket for the negotiation feed (the console polls), no per-user accounts, no row-level authorisation.

Knobs — what to turn, and what it does to the negotiation

Every knob below is real: it exists in the session payload, in a party record, in a delegation's fixture, or as an environment variable on the runtime. Each entry says where it lives, what the default is, what it mechanically changes, and — the part that matters for teaching — what it does to the negotiation. Use the filter to build a lesson around one dimension at a time.

KnobWhereDefault Mechanical effectEffect on the negotiation — teach this

Guided experiments

Each experiment isolates one variable. Run the same scenario twice, change only the named knob, and compare the outcome scoreboard and the tactic ledger. Twenty minutes each; all of them produce a result students can argue about.

Which model for which job

The system does not have "an AI". It has four distinct model jobs with genuinely different requirements, and the most common configuration mistake is using one model for all of them. Choosing per job is the cheapest quality win available.

JobWhat it has to do What actually mattersGuidance
Delegation turn
hot path
Read a windowed transcript, stay in character, advance a position, emit valid JSON, in under the round timeout. Instruction adherence, JSON reliability, latency, persona stability. Raw reasoning depth is close to irrelevant. A mid-size instruct/chat model. This is called N× per round with humans watching, so a 6 s model that is 90 % as good beats a 60 s model that is 100 %. anti-pattern reasoning models here — they burn the token budget on hidden thinking, ignore the JSON response-format hint, and blow the timeout.
Convener / chair Summarise the round, name convergence and divergence, propose the next agenda item. Long-context comprehension and neutrality. Runs once per round, off the critical path. The largest context window you can afford. Latency tolerance here is high, so this is the right place to spend on a stronger model.
Tactic judge
not yet wired
Read a move and decide whether a tactic was genuinely used. Calibration and restraint — the ability to answer "no tactic" confidently. Today detection is 100 % rule-based (regex + sequence). A judge model is the intended upgrade; it must run asynchronously so it never delays a round.
Debrief / after-action Produce per-party and convener after-action reports from the full transcript. Long context, analytic writing, willingness to be critical. Runs once, at the end, unobserved. Use the strongest model available; a reasoning model is appropriate here and nowhere else in the loop.

Model classes and their token budgets

The delegation twin classifies whatever model name you give it into one of these classes, then sizes the verbatim transcript window to fit. Reserved overhead per call: ~600 tokens of system prompt, ~700 tokens of structured memory, ~400 tokens of headroom. A transcript move averages ~134 tokens.

ClassMatchesInput capMax verbatim moves Usable windowConsequence
Read the fourth column, not the third. A 4 000-token cap sounds generous until you subtract 1 700 tokens of fixed overhead and discover the delegation can only see its last few moves. That is precisely the condition under which self-echo guards start firing. If a party keeps repeating itself, raise its maxInputTokens or move it to a larger class before you touch the prompt.

Live model catalog

Model idInferred classReasoning?Verbatim movesSuggested job
Not loaded.
No backend connected — the live catalog is unavailable. Everything else on this tab is static reference material.

Failover ladder

When a delegation's primary model fails, the twin does not simply error. It walks a ladder:

  1. Primary model. Called with a window sized for its class.
  2. Fallback model, if the failure is retryable: payload-too-large, a 5xx, a network fault, a content-filter rejection, or a rate limit with a long retry-after. The transcript window is re-sized for the fallback's class before the retry.
  3. Automatic non-filtered fallback. If a hosted content filter rejected the call and no operator fallback was configured, the twin routes to a large open-weights instruct model on its own initiative.
  4. Stub move. Last resort: a flagged placeholder is recorded so the round can complete, and the party's degraded counter increments.
Content filters and geopolitics. Realistic crisis scenarios — strikes, sanctions, hostages, escalation — routinely trip hosted safety filters. Step 3 exists because of exactly this. For an Army War College-style scenario, configure an explicit unfiltered or self-hosted fallback per party in advance rather than discovering the problem in front of the room.

Configuration anti-patterns

Same model, both sides, same settings

Produces uncanny symmetry: parties converge on identical phrasing and the self-/opponent-echo guards fire constantly. It is also bad pedagogy — students conclude the simulation is scripted. Vary at least the persona and preferably the model.

Reasoning model on the hot path

Temperature is forced, the JSON response-format hint is suppressed, the completion budget balloons, and timeouts follow. Save reasoning models for debriefs.

Tiny model with a big transcript

Instructions get pushed out of attention by transcript. The delegation drifts out of character around round 4. Lower maxInputTokens rather than raising it.

No fallback configured

One content-filter hit or one 503 and that party emits a placeholder in front of the audience. Always set fallbackModel for a live demo.

Raw API keys in provider records

Provider registrations can carry a literal key, and provider state is snapshotted to disk. Use the environment-variable form so the secret never lands in an evidence bundle.

Round timeout shorter than the model

A 30 s timeout against a model whose p95 is 40 s manufactures placeholder moves that look like model failure. Measure first, then set the timeout.

Tactics, goals, and getting a better negotiated outcome

Outcome quality is mostly decided before the first round, in how goals and red lines are written. This tab covers the two halves: what the system can detect, and how to author delegations so that detection has something interesting to find.

The rule-based tactic detectors

Detection is deterministic and explainable — every detection carries a confidence and is marked as rule-sourced. That is a feature for teaching: students can read the rule and argue about whether it is right.

TacticHow it is detected Conf.What it tells the class
False positives are real and were measured. The counter-anchoring rule originally fired on roughly two of every five detections incorrectly, because any numeric mention after an earlier number looked like a counter-anchor. It was retightened to require a substantial run of prior anchors and meaningful lexical overlap with the anchor being countered. Treat the ledger as evidence to be interrogated, not as ground truth — and say so out loud during a demo.

Writing goals that produce a real negotiation

Structure of a delegation's objective set

  • Goals — ranked, each with a priority and an explicit note about what it can be traded against.
  • Red lines — small in number, absolute, and stated in terms the other side could actually violate.
  • BATNA — a described alternative with an estimated value. This is what makes walking away a live option rather than a bluff.
  • Tactics — the named plays this delegation is authorised to run, each with a trigger condition.

The three rules that decide whether it works

  1. Goals must be tradeable across parties, not within one. If A's third priority is cheap for B to concede and vice versa, you have a deal space. If both sides rank the same single issue first and nothing else exists, you have a stalemate generator.
  2. Red lines must not overlap the ZOPA. If A's red line sits inside the only zone where B can agree, no settlement is reachable — which is a legitimate teaching scenario, but only if you did it on purpose.
  3. BATNA value must be below the midpoint of the ZOPA for a party you want to settle, and above it for a party you want to walk. This single number is the most powerful outcome dial in the whole system.

Levers on the negotiated outcome, ranked by effect size

RankLeverHow to move it Observed effect
Design the deal space before you write a word of persona. Decide the zone of possible agreement numerically, place each party's reservation value and BATNA relative to it, and only then write the prose. Scenarios authored prose-first almost always turn out to have no ZOPA or a trivially wide one. Full method: docs/diplomacy/SCENARIO-RESEARCH.md.

Researching and building a negotiation scenario

A scenario is a researched artefact, not a writing exercise. The credibility of the whole simulation rests on it: participants will accept a machine-generated argument if the underlying facts are sourced, and reject the entire exercise if one date or one number is wrong. This tab is the working checklist; the long-form method lives in docs/diplomacy/SCENARIO-RESEARCH.md.

The seven phases

Source discipline

TierWhat countsUse it forRule
Tier 1 Treaty text, UN Security Council resolutions, official communiqués, court filings, regulatory notices, published statistics, verbatim transcripts. Anything asserted as fact in context, history or pastAgreements. Cite title, publisher and date. Required for every hard number and every date.
Tier 2 Wire-service and major-outlet reporting, think-tank analysis with a named author, specialist trade press. recentEvents, characterisation of positions, atmospherics. Two independent Tier-2 sources, or one Tier-2 corroborating a Tier-1, before an item is stated as fact rather than as a claim.
Tier 3 Commentary, op-eds, unattributed briefings, model output, your own inference. Only inside a party's private guidance — i.e. what that delegation believes. Never appears in shared context. Must be labelled as assessment, not fact.
Fiction is allowed; unmarked fiction is not. A synthetic scenario is often better for teaching than a live one — nobody arrives with a fixed position. But say so in the scenario description, give the fictional entities obviously fictional names, and keep the structure (interests, ZOPA, BATNAs) faithful to a real case. A hybrid — real structure, invented names — is the sweet spot for a graded exercise.

Design the deal space first

Numbers to fix before writing prose

  1. The issue being negotiated, expressed on a single scale where possible.
  2. Each party's reservation value — the worst it will accept.
  3. The resulting ZOPA, if any: the overlap between reservation values.
  4. Each party's BATNA value on the same scale.
  5. The secondary issues that make log-rolling possible — at least two, ranked oppositely by the two sides.

Sanity tests

  • ZOPA width between roughly 5 % and 25 % of the issue range. Wider is trivial, narrower is a coin flip.
  • No party's red line falls inside the ZOPA unless deadlock is the lesson.
  • At least one party's BATNA is close enough to its reservation value that walking away is credible.
  • Every party has something the other side wants and can concede without crossing a red line.
  • If you remove any one party, the deal becomes materially easier — otherwise that party is decoration.

Scenario field reference

FieldRequiredPurposeAuthoring guidance

Live scenarios on the connected backend

Not loaded.
Connect a backend to inspect the scenarios it has loaded.

Quality gate — do not run a graded exercise until every box is ticked

Authoring a delegation

A delegation twin is a persona plus an objective set plus a model configuration. The objective set is what makes it negotiate; the persona is what makes it recognisable; the model configuration is what makes it reliable. Build all three deliberately, then export the fixture below.

Builder

Must start with diplomacy-team-; becomes the pack directory name.
Thomas–Kilmann frame. Mixing styles across the table is what makes a session interesting; five compromisers produce a dull, fast, uninstructive deal.
On the same scale as the issue. Below the ZOPA midpoint → this party settles. Above it → this party is willing to walk.

Generated delegation fixture

Fill the form and press Generate.

Generated system-prompt override

The seven-part system prompt

The delegation twin assembles its system prompt from the fixture in a fixed order. Understanding the order tells you where to intervene when a party misbehaves.

  1. Identity and persona. Who you are, your style, your temperament.
  2. Goals in priority order, with tradeability annotations.
  3. Red lines, stated as absolutes.
  4. BATNA, with its estimated value — this is what licenses walking away.
  5. Authorised tactic ids, with triggers. Anything the model claims to have used that is not in this list is silently discarded from the record.
  6. Output contract. Strict JSON shape; a short move; no meta-commentary.
  7. Identity lock and anti-repetition. Explicit instructions not to speak for other parties and not to restate its own previous move.
Keep an override under roughly 450 words. Past that, on a small model, the transcript and the instructions start competing for attention and persona drift sets in around round 4.

Installing a new delegation

  1. Copy an existing diplomacy-team-* pack directory to the new twin name.
  2. Update the manifest name and description; update the pack's exported identity.
  3. Replace the fixture with the JSON generated above.
  4. Reload the twin — POST /_twins/<name>/reload re-evaluates the pack's whole module graph in place and preserves state (RUNTIME-HOTLOAD-002). A brand-new pack directory still needs a restart, because packs are discovered at boot.
  5. Smoke-test with a two-party session before adding it to a real convening.
Route-prefix trap. Handler route patterns and OpenAPI paths inside a pack must be written without the twin-name prefix — /turn, not /diplomacy-team-x/turn. The runtime strips the twin name before dispatch. Getting this wrong yields a twin that answers direct curl calls but 404s under the test harness.

ZOPA — the zone of possible agreement

A ZOPA is not a feeling about whether two sides are "close". It is arithmetic: the overlap of the intervals each side would still sign. This tab computes what the authored data actually supports, and is explicit about what it does not — because on a teaching tool, a confident wrong overlap bar is worse than an absent one.

Why "authored" is the default. Live twin state is mutable, and anything that writes to a delegation — notably an efficacy run, which overwrites /batna with test data — silently replaces the scenario design. Switch to Runtime to see what the twins currently hold; any divergence is reported as drift below.
Pick a scenario and press Analyse.

How to close the gap

The reservation value (L4) is the load-bearing one, and it is research, not code. Elicit it with the flip question, per delegation, per issue:

"If the final text said exactly X on this issue and nothing else changed, would you sign it, or take the BATNA? Now move X until the answer flips." That crossing point is the reservation.

Then cross-check it twice — both checks are teachable in their own right:

  1. Against the BATNA. A reservation is only credible if walking away is genuinely worse. If the side with the worse BATNA also holds the tighter reservations, the scenario is internally inconsistent.
  2. Against the red lines. A red line is a reservation stated in prose. If a red line says "no enrichment above 5%" and the goal's min implies 20%, one of the two is an authoring bug. Cheap check; catches real errors.
Three tempting shortcuts, all worse than shipping nothing. (1) Infer reservations with an LLM — plausible numbers, no provenance, on an authoritative-looking chart. If ever done, it must be labelled inferred, never authored. (2) Use priority as a proxy — they are orthogonal: an issue can be critical and have a wide acceptable range. (3) Ship the {min:0, target:1} placeholders — every issue overlaps completely, every scenario reports a maximal ZOPA, and students learn the exact inverse of the lesson.

Full rationale: docs/diplomacy/DESIGN-ZOPA-CALCULATOR.md §1.3. Authoring method: docs/diplomacy/SCENARIO-RESEARCH.md Phase 3 step 6.

Model bake-off — find out what actually works

The teaching claim of this whole console is that model choice is a decision with measurable consequences. This tab makes that testable: build a session payload, run the same scenario under different model assignments, and record the metrics that matter. Everything here is honest about what it measures — small samples, noisy metrics, real conclusions only after several runs.

Session payload builder

Parties

Twin nameDisplayParticipantProviderModelFallbackMax input tok.

POST /diplomacy-table/sessions

Press Build payload.

Run and measure

Idle.

Results

SessionRoundsMovesTacticsPlaceholders Satisfaction spreadRed lines crossedWall timeModels
No runs recorded.
Connect a backend to run a bake-off. The payload builder above works offline.

What to measure, and what each metric is worth

MetricDefinitionGood looks likeCaveat
Methodological honesty. One session is an anecdote. Model comparison needs at least five runs per configuration with the same scenario, and even then satisfaction scores are self-reported by the delegations themselves and should be read as a signal about persona coherence rather than as a measure of negotiation skill. State this to students explicitly — the exercise of critiquing the metric is worth more than the metric.

Run-time evaluation — Diplomacy Simulation Demo, Army War College

A ninety-minute block for a professional military-education audience: senior officers and civilian equivalents who will be sceptical, subject-matter expert on the scenario, and unforgiving of anything that looks like a magic trick. The goal is not to impress them with the AI. It is to show them a method for structured wargaming of a negotiation, with the machine's limits stated up front.

Preflight — T−24 hours

Automated checks not run.

Run sheet

ClockSegmentWhat happensOperator actions & risk

Failure modes and what to say

If this happensLikelihoodDo thisSay this

Evaluation instrument

Collect these from participants at the end. They are deliberately about the method, not about whether the AI was impressive.

  1. Name one move a delegation made that you judged militarily or diplomatically implausible, and say why.
  2. Name one move you judged plausible and non-obvious.
  3. Did the tactic ledger identify anything you would not have noticed unaided? Did it miss anything obvious?
  4. Where did the deal land relative to where you expected it to land? What in the configuration explains the difference?
  5. Which single configuration change would most improve the fidelity of this exercise?
  6. What is one question this tool could help a staff group answer that they cannot answer today in a comparable amount of time?
Question 1 is the most important one. If nobody can name an implausible move, the scenario was too shallow to be worth playing. Harvesting those answers is how the scenario library improves.

Framing language — use it verbatim

"What you are about to see is not a prediction. It is a structured way to explore how a negotiation might unfold given a specific set of assumptions about what each party wants, what it will not give up, and what it does if the talks fail. The value is in seeing those assumptions written down, played out, and then challenged — not in the machine's opinion about the outcome."
"Every delegation is running against instructions that are visible to you and to nobody else at the table. If a delegation says something you think is wrong, that is a finding about the instructions we wrote, and we can change them and re-run in about eight minutes."
"The tactic ledger is rule-based, not a judgement call by a model. That means it is explainable and it means it is sometimes wrong in ways you can see and argue with. Both of those are deliberate."
Do not say: "the AI decided", "the model predicts", "this is what would happen", or anything that implies the system has access to intelligence, capabilities data, or planning assumptions it does not have. Do not run a scenario against a currently classified or operationally sensitive problem set on a network or a hosted model that is not accredited for it.

Deployment posture for the demo

Recommended
Backend on the local box in the room, models local, no external network dependency. Frontend served from the same box. Zero cloud, zero latency surprise, zero content-filter risk.
Acceptable
Backend on the B3IQ hardware reached over a tunnel; frontend on Pages. Requires a tested network path and a rehearsed fallback to the local box.
Fallback
A pre-recorded transcript bundle replayed by the static frontend. Prepare this regardless — it costs an hour and it is the difference between a bad day and a cancelled session.
Not acceptable
Live hosted-API models over conference Wi-Fi with no local fallback, for a scenario likely to trip a content filter.