# The Scenario Engine: JSON-Driven Worlds, The Soft Mandate Shown Where It Lives, And The Platform Library This Makes Possible

**version** v0.33.68
**date** 28 August 2026
**from** Human (project lead)
**to** Engineering, Architecture, the PKI/registry team, the RiskMandate team

**type** Dev brief — the engine, two scenarios from it, and the rules for the library of platforms

*The fifth brief of this arc, from the memo that followed the table: "we're building the infrastructure that will allow us to do these kinds of scenarios again from a JSON-driven architecture, nothing hard coded, because there's going to be tonnes and tonnes of scenarios… fundamentally it's a game. We're creating a world map of a game… we're going to be building a game engine, which becomes a product eventually itself." The worked example is deliberately the one running right now: the workflow by which Claude Code pushes to this repository — and its sharpest insight is the* **soft mandate**: *"the reason why you don't commit to the dev branch is not because you can't, it's because somewhere in your pipeline you're making that decision."*

---

## What This Is

**One engine, many worlds.** A scenario is a JSON file; the engine renders it; nothing scenario-specific lives in code — and the claim is proven the only way it can be, by shipping **two scenarios from the same engine in the same release**: *push to GitHub* (this session's own environment) and *the deploy* (the CI runner it pushes into — the environment that does **not** have the same guardrails). A scenario file does not copy its world: it **references a twin** — a measured library entry — and the engine reads the capabilities out of the twin at build time, so the scenario inherits GM3's references-never-copies discipline and a corrected twin corrects every scenario that references it. Each capability renders as a card with a **micro-animation** — *"you can make a change to a repo: show a little animation… it can act as the user: make a little animation"* — because security controls are abstract until you watch one act, and with a **confidence rung computed from its evidence**, so the memo's gradient — *the more evidence, the more we move from hypothesis to reality* — is arithmetic rather than prose. The centrepiece visualisation is the **soft mandate**: the same allow-list drawn in the three places it can live — inside the agent's context (an expectation: the decision happens in the loop, and that is where mistakes occur), in a hook (a setting: outside the loop, inside the grant), on the platform (a boundary) — with each slot's status **derived from the estate's files**, not asserted. And the whole thing is the entry ramp to the **platform library**: Codex, Lovable and the rest are variations of the same JSON, published fact-based, where an incident is evidence and every claim is version-stamped.

## 1 · The Players, Named From The Memo

The memo enumerates the entities of the worked example, and the enumeration is itself the lesson — **the grant chain is longer than anyone draws it**:

```
  The User ──authorises──▶ the Claude GitHub App        (THE GRANT IS BORN HERE:
      │                                                  a person, in GitHub's UI,
      │                                                  granting repo access)
      ▼
  GitHub ──holds──▶ the repo (the asset)
      ▲
      │  a scoped token, derived from that authorisation
      │
  Claude ──runs──▶ Claude Code ──runs in──▶ the execution container (THE TWIN)
                                                │
                                                └─ the token lives here, and
                                                   everything extractable from it
```

Six principals before a single action happens, and the token — *the grant* — is minted two steps away from the person who authorised it and exercised three steps away. Every scenario file carries this chain as `players[]`, each with a kind (`person · service · harness · environment · platform · asset`) and, where one exists, a reference to its identity or twin.

## 2 · The Soft Mandate — The Memo's Sharpest Frame, Shown As A Place

> *"The reason why you don't commit to the dev or main branch or do a bunch more damage is because Claude is trying to contain itself… somewhere in Claude's guardrails and somewhere in Claude's prompt, which is a prompt, right? And that's where mistakes can occur."*

This estate has the vocabulary for that already — it is tier `expectation`, and the first library entry recorded it at node n3: *branch discipline lives in the session's instructions*. What it has never had is the **picture**: the same constraint document, drawn in the three locations it can live, with the decision point marked.

```
  ┌─ THE AGENT'S CONTEXT ────────┐  ┌─ THE HOOK ─────────┐  ┌─ THE PLATFORM ──────┐
  │  the allow-list as PROSE     │  │  the allow-list as │  │  the allow-list as  │
  │  in the loop ◇ the agent     │  │  CODE, outside the │  │  CONFIG, outside    │
  │  decides, every time         │  │  loop, inside the  │  │  the grant entirely │
  │                              │  │  grant             │  │                     │
  │  EXPECTATION — and this is   │  │  SETTING — real    │  │  BOUNDARY — the     │
  │  where mistakes occur        │  │  today, bypassable │  │  door is SHUT: zero │
  │                              │  │  by --no-verify    │  │  built, ever        │
  └──────────────────────────────┘  └────────────────────┘  └─────────────────────┘
```

**Each slot's status is derived, never typed**: the context slot quotes node n3's `control` field by byte; the hook slot reads its tier from the signed mandate's own `enforced_by` block; the platform slot reads the doors view's `enforcement_at_boundary` metric — the shut door, appearing inside a scenario for the first time. The tier ladder was a table; the soft mandate makes it **three rooms the same document can sit in**, and the animation is the document sliding right as the constraint hardens.

And the comparative punchline, which is the platform library's reason to exist: *"other environments might not have the same guardrails."* The second scenario is that sentence, rendered: the CI runner's twin has **no proxy, passwordless escalation, and a grant declared in a `permissions:` block** — a different world under the same engine, which is exactly what proves the engine.

## 3 · Capabilities: Animated, Evidenced, Rung-Scored, Version-Stamped

**A capability card is a twin node wearing scene clothes.** The engine reads the nodes from the referenced twin; the scenario file may only *decorate* them (an animation kind, a story role) — it may not add, remove or restate one, and the gate counts.

**Micro-animations** (CSS-only, original, `prefers-reduced-motion` → static): `push` — a commit dot travelling container → repo; `act-as` — a nameplate swapping onto the actor; `edit` — strokes appearing on a file; `egress` — a packet passing the proxy wall, and bouncing where the wall is real; `recall` — a scroll unrolling from the session record; `escalate` — a figure stepping over a low wall; `blocked` — the probe dot stopped at the classifier; `unknown` — a pulsing outline behind a wall that never opens. Eight verbs of the threat model, watchable. *"In security we have these controls that are very abstract — we need to put context, because context is what it's all about."*

**Evidence, from multiple places.** The memo's list — *validated by us, discovered, provided by documentation, a security researcher's published work we link to* — maps onto machinery the estate already has: the five evidence classes carry *how established*; v0.33.64's origin attribute carries *by whom* (`self · provider · independent`); and an **incident is evidence** — *"if one of these platforms deletes the database, that's an evidence"* — entering as `observed` with `origin: independent` and a link. Nothing new to invent; one thing to enforce: **a linked proof is a reference, and the claim it backs carries the link or the rung does not count it.**

**The rung, computed.** Per capability: `none` evidence → rung 0 (hypothesis); self-observed → 1 (floor); + documentation → 2; + any independent origin → 3 (as close to *reality* as a claim about somebody else's product gets). Ten citations of one source are one source, so origins are counted distinct-first. Today every card in both scenarios sits at rung ≤ 2, and the engine prints the reason on the deck: **no capability in this estate has independent evidence yet** — the doors page's shut door, per card.

**Version-stamped.** Every card carries the twin's `measured_at` and the scenario shows it beside the title: *"some versions could have more capabilities, and then Claude can fix some stuff."* A capability claim without a date is a claim about all versions at once, which is a claim about none.

## 4 · The Schema, Small On Purpose

```jsonc
{
  "id": "push-to-github",
  "title": "…", "question": "…",             // what this scenario teaches
  "twin": "packs/…/library/<entry>.json",     // THE WORLD — read, never copied
  "players": [ {"id","name","kind","ref"} ],  // §1's chain
  "grant_chain": [ ["user","authorises","github-app"], … ],
  "mandate_slots": {                          // §2 — statuses DERIVED at build
    "context":  {"derive": "twin:n3.control"},
    "hook":     {"derive": "mandate:enforced_by"},
    "platform": {"derive": "doors:enforcement_at_boundary"}
  },
  "decor": { "n3": {"anim": "push"}, "n5": {"anim": "blocked"}, … },  // decorate only
  "story": [ {"beat", "cites"} ]              // optional; every beat cites an artefact
}
```

Five gates in the engine, inherited plus new: the twin must exist and **cards == twin nodes exactly**; every `decor` key must name a twin node; every derived slot must resolve (and the platform slot must agree with the doors view — two generators, one truth); every story beat's citation must exist; the manifest gate covers the folders. Everything else — counts, dates, tiers, quotes — is read from the sources the way every generator since v0.1.37 reads them.

## 5 · The Platform Library — Where This Scales

*"Then we can do Codex, we can do Lovable, we can do all sorts of others, which should be variations of this."* The rules, so the variations stay publishable:

1. **A platform page is a scenario file plus a twin.** No twin, no page — the measurement method is published and anyone can run it.
2. **Fact-based, and only fact-based.** Every capability carries its evidence, origin, rung and date. A capability at rung 0 renders as *hypothesis*, in those letters.
3. **An incident is evidence**, linked, `origin: independent` — often the strongest evidence a claim about a hosted platform will ever have.
4. **Version-stamped or it does not ship.** Claims age on the vendor's release schedule, and the drift answer is re-measurement, not memory.
5. **The comparison is the product.** One engine, N platform worlds, same card grammar — *which environments have the guardrail, which have the door, which have neither* becomes a readable row across worlds, not an argument.

*Site-agent note:* rule 2 is what makes rule 5 safe to publish. A comparative page that says *Lovable can delete a database* citing an independent incident at rung 3 is journalism; the same sentence at rung 0 is a liability. **The rung is the libel guard**, and it is computed.

## 6 · What This Does Not Claim

- **The engine is proven for two worlds**, both measured by this estate, both hosted-agent-shaped. *Tonnes of scenarios* is the ambition; two is the count.
- **The animations illustrate; they do not simulate.** A commit dot travelling is a depiction of a capability, not an execution of one. Proposed-action play remains the next experiment, unbuilt.
- **Agents appreciating the visualisation is a hypothesis.** The memo predicts it; `book.json`-style machine surfaces are what agents demonstrably consume; each scenario therefore also emits its `scenario.json` — but nobody has measured an agent preferring the room to the file.
- **"Game engine as a product" is a direction, not a deliverable.** What ships is a generator and a schema. Calling it an engine is earned only by the second world; calling it a product is not yet earned by anything.

---

## Honest Tensions

| Tension | Note |
|---|---|
| A game engine three days into a genre | Two implementations of the genre existed yesterday; this generalises them on n=2. Cheap to revise is the defence, and the schema is deliberately small |
| The soft mandate names the author's own leash | This session is the worked example: the constraint that keeps it off `main` is prose in its own context, and the scenario says so publicly. That is the honest version of the demonstration, and it is also an instruction manual for where the guardrail is not |
| Fact-based comparison of competitors | Rule 2 and the rung are the guard; the first legal-adjacent complaint will test whether a computed rung persuades anyone outside this estate |
| Animations charm, and charm overclaims | Bounded as before: every card cites its twin node, every rung its evidence, and the deck prints the rung-3 absence on its face |

---

*CC BY 4.0. Sources: the project lead's memo of 28 August 2026; the two library entries (the twins); the signed mandate; the doors view; newsroom.sgit.ai brief 10 for the genre; this repository at v0.1.43.*
