plan.md
c144 — Plan
- 1. The tour catalog
- 2. Theatre mode: the rule for pretend data
- 3. The scenario model
- 4. The register: three stops, all written (C4)
- 5. AI, on your own machine: the metaphor and where it breaks
- 6. The marks (C5: today's only)
- 7. The MCP contract: additions to `qpoint-guide`
- 7a. Show mode (C10)
- 8. The scenarios are tests
- 9. Phases
Three kinds of tour, one content model, and one rule for pretend data. Mark ruled the calls on 2026-11-12 (CYCLE.md § Review stop 0). Where a ruling changed the proposal, the section says so.
1. The tour catalog
| Kind | Tour | Data | Starts from |
|---|---|---|---|
| learn | New here: show me around, at the level you pick | yours where there is any, else the world | lab start-here, native new-to-qpoint.json |
| learn | AI, on your own machine: the primer | yours | native this-machine.json (nine steps, already in the metaphor's order) |
| theatre | The doomsday scenarios: AI going wrong, played out (scenarios.md) | synthetic, always | lab drills (DRILLS), the Common AI risks tour |
| (exists) | Start here · Common AI risks · Observe, then enforce · AI spend · OWASP Agentic | the lab world | c123 |
A tour declares kind and data. Only a theatre tour may show synthetic data as if it were happening, and only while theatre is on.
2. Theatre mode: the rule for pretend data
Theatre is a state of the whole dashboard: on or off, which scenario, which beat. It is never set on a single page.
- Curtain up. The first step of every theatre tour waits for the switch. The agent explains what's about to happen and points at the switch (
pointontheatre.switch), and the person flips it. The tour can't move on until theatre is on, the way the wizard kit's PingListener waits for a first ping (c125). - The band. While theatre is on, a band runs across every page: Theatre · synthetic data · nothing here is happening on your machine, followed by the scenario's name and Leave theatre. It has its own material, and it's never a status colour, because red already means danger. Every capture and screenshot taken in theatre carries the band, so a pretend dashboard can't leave the room unlabelled.
- Inside theatre the person's draft, Publish, Connect and every outward action are disabled, and the band's hover says why. Changing a policy to replay at Enforce writes to the theatre's own copy of the world, never to the draft.
- Curtain down. The last step points at the switch again. The person flips it off, the dashboard returns to their own data, and the tour says what was real (nothing) and what to look at next (a real policy, at Observe). Any other exit (Esc,
end-tour, closing the window) ends theatre too, and a toast says so. The dashboard is never left showing pretend data with nobody watching. - Real messages during theatre still arrive through the OS. The tray and the inbox mark theatre's own messages so the two can't be confused (call C6).
3. The scenario model
A scenario is data, beside the tours (app/data/scenarios/<id>.ts in the lab, then copied to qnative the way worlds are, c132 D6):
interface Scenario {
id: string // 'phishing-financial-records'
title: string // 'Phishing for financial records'
logline: string // one sentence, the story
cast: { who: string; machine: string; harness: string } // SUBJECTS keys, so findings read as rows
world: string // the base world ('meridian-day90')
beats: ScenarioBeat[]
replay: { policyId: string; stopsAt: string }[] // Replay at Enforce: which beat each policy stops it at
gaps?: { at: string; text: string }[] // where no policy names what happened
}
interface ScenarioBeat {
id: string
at: string // the story's clock, '09:04'
say: Register<string> // the panel's line at three registers (§4)
sensor: SensorEvent[] // what the sensor would see: qevents payloads, the stream scripts' shape (qnative c3)
expect: Expect[] // the test: what each surface should now show
}
interface Expect { surface: 'web' | 'native'; page: string; region: string; key?: string; text: string; mode?: 'observe' | 'enforce' }
- The world at beat N is the base world plus the sensor events of beats 1 to N, folded by the rules the pages already use (
foldAll,RULED). Going back recomputes, it never undoes, so any beat can be visited in any order. - The scenario never writes a finding. It writes what the sensor would see, and the dashboard derives the findings. Where the lab can't yet derive a finding from raw events, a beat writes signals the way a drill does. Those beats are marked, and each mark is a gap in the lab, not in the product.
- Replay at Enforce plays the same events with the named policies at Enforce. The beat where a policy applies becomes blocked, the beats after it don't happen, the citizen's notice arrives (c137), and a training is assigned (c133).
- A drill is a one-beat scenario. The five drills port as-is, so the Common AI risks tour keeps working.
- As built (Phase 1). The model gained what writing six scenarios needed: a
setthat adds list entries (an approved email server) and names the policies the story watches (any that is Off for the cast observes, on theatre's copy);limits(a policy exists but the world's configuration doesn't cover the act) besidegaps;trainings(c133's, opened on the story's own finding) andtrainingsWanted; a beat'smoves(C2's rare beat that comes by itself); asessionsensor event (spend, silence). The detector reads only global list entries, asconfigAllowsdoes. Replay at Enforce is a user exception on theatre's copy; a policy whose action redacts or redirects doesn't stop the act, and one the catalog marks not enforceable can't.
4. The register: three stops, all written (C4)
Mark: "the minimum needed to speak intelligently to the target." Three stops, every text written at each:
| Stop | Label |
|---|---|
new | I'm new to this (default) |
computers | I work with computers |
degrees | I have networking degrees |
Register<T> = { new: T; computers: T; degrees: T } on a beat's say (and New here's texts, Phase 3). The person picks the stop in the tour panel; it's held for the visit, not kept as a preference. tour-state returns it and the agent speaks at it. There's no set-register verb and no stop the agent adapts. (Proposed and dropped: five stops from ELI5, two of them adapted in chat.)
One step at the three stops (the native providers step), to show the range:
- new: When your AI tool answers you, the work is done by a model on a company's servers, not on your laptop. These are the companies your tools sent work to this week.
- computers: Each AI tool here sends its prompts to a model provider's API. This is who received them this week, and how much.
- degrees: Egress by provider endpoint, attributed per process and session by the sensor, which reads the traffic before TLS encrypts it: host, request count, bytes and tokens, by harness.
5. AI, on your own machine: the metaphor and where it breaks
The primer walks the person's own machine in the order of this-machine.json. Each step names a part, gives its metaphor, and then says where the metaphor breaks. Each break is a governance lesson, because the metaphor fails exactly where the risk is.
| Part | The metaphor | What it is | Where it breaks, and why that matters |
|---|---|---|---|
| Model | the brain | the trained network that writes the next words | It isn't in your head. It's rented, in someone else's building, so everything the agent shows it leaves your machine. (P-PROVIDERS, P-SENS-DETECT) |
| Provider | the landlord | Anthropic, OpenAI and the rest, who run the brains | Which landlord your agent talks to is a choice, and somebody should be the one making it. (P-PROVIDERS, P-ACCT) |
| Harness | the agent, the body | Claude Code, Cursor, Codex: it takes turns with the model, runs the tools and keeps the notes | The brain forgets and the body remembers. The notes (context, memory files) are where an attacker leaves a message. (P-PROMPT-INSPECT) |
| Tools | the hands | read a file, run a command, send an email | Hands that never tire and move at a program's speed. Some acts deserve a pause. (P-TOOL-ALLOW, P-TOOL-APPROVAL) |
| MCP servers | borrowed hands | other people's programs that add tools | They belong to someone else, and their code can change overnight. (P-MCP, P-PROVENANCE) |
| Skills | the speciality | written know-how loaded when it's needed | A skill is text the brain trusts, and someone else wrote it. (P-PROVENANCE) |
| Workspaces | the desk | the folders it works in | The desk has no walls unless you build them. (P-FILES, P-SANDBOX) |
On real data it says facts: Your primary agent is Claude Code. It used Opus 5.5 for most of its turns this week and reached three MCP servers. With no local data it says the same about the world's machine, and says so.
6. The marks (C5: today's only)
"Your primary agent looks like Claude Code": the primer teaches each part's mark, the small picture the dashboard uses for it everywhere, so the person recognises it later on any page. The parts are the person, the machine, the harness (with the harness's own icon beside our mark), the model, the provider, the MCP server, a tool, a skill and a workspace.
Mark ruled the minimum: the primer teaches today's marks (Plain) and offers no styles or preference. The axis he described, Cute (the Japanese end, the c47 pawns) to Swiss (geometric, one weight, on a grid), is parked as a later option, its own cycle if pursued.
7. The MCP contract: additions to qpoint-guide
The existing tools keep their meaning. The additions:
list-tours: each tour gainskind(learn | theatre) anddata(yours | synthetic). A theatre tour also gains its scenario's logline, cast and gaps.tour-state: gainstheatre { on, scenario, beat, of, at, mode, replay, stoppedAt, waiting }andregister(the person's stop).read-step: gains the beat (its clock,sayat the person's register, itsexpectlines, and what the play made of it), so the agent can narrate what changed: Findings now shows a medium on Priya's machine.replay({ policyId }): rewinds the story with that policy at Enforce, in theatre only. It changes nothing outside the theatre's world.- No verb flips theatre (C1). The switch is the person's, and the agent points at it.
start-touron a theatre tour returnstheatre.on: falseand the curtain-up step, and moves into a beat refuse with waiting for theatre until the person flips it. - No verb plays a beat (C2). Beats move on the person's Next. The agent's
next-stepandgo-to-steprefuse a step that would play a beat not yet played (beats move on the person's Next); going back, and moving among steps already played, work. A beat a scenario marks to move on by itself (moves.after) does so after its dwell. A test flag on the page (?theatreTest=1) lets a harness run advance beats itself. - The native guide (
app::guide, 127.0.0.1:7891) gets the same verbs, checked by both contract scripts (tour-drive-check.mjs,guide-check.py).
A request in the person's words, to any harness connected to the guide: "Give me the phishing tour." The agent picks the tour with list-tours and starts it, explains curtain up, points at the switch and waits. When the person has turned it on, the agent confirms theatre is on. At each beat it says what's coming and waits for the person's Next, then says what changed on screen and points at the region. It offers replay at Enforce, and points at the switch again to close.
7a. Show mode (C10)
A show plays one tour or one scenario through the real app, unattended, for a booth at a trade show or the screen before a talk. The person picks it from a list.
- It always runs in theatre: synthetic data, the band on, outward actions off.
- Each step dwells about 8 s by default; a step may author its own dwell.
- It loops, and it resumes after a few idle minutes; resuming can be switched off for the before-a-talk case.
- Exiting the show leaves you where it was: on that page, and for a scenario at that beat with theatre still on, which you switch off as usual.
8. The scenarios are tests
A beat's expect lines are acceptance checks for the dashboard.
- Lab:
scripts/theatre-walk.mjs(followingtours-walk.mjs) plays every scenario beat by beat, at Observe and again at Enforce, and checks each line's region text. A failed line is a finding: either a dashboard bug or a scenario bug, and the walk prints which beat and region. - Native: a story per beat and a region-text test per expect line, following the
/native-portpattern. Captured per world into the atlas. - Harness runs: Claude Code plays each tour from one prompt (c125 rung 5, c2's
harness-run.md). The transcript is filed with the cycle.
9. Phases
As ruled at review stop 0: all six of wave 1 build together (C8), the register is three written stops (C4), the marks' styles are parked (C5), and show mode is new (C10).
| # | Phase | Where | Done looks like |
|---|---|---|---|
| 0 | Kick-off | design | initial prompt, CYCLE.md, plan, scenarios, the sketch, captured; review stop 0 ruled (2026-11-12) |
| 1 | The model, and wave 1 | lab | app/data/scenarios/ with S1–S6 and the drills as one-beat scenarios; theatre state (?theatre=<id>&beat=<n> a way in); the band, the frame, the switch; rewind; replay at Enforce; the three registers in the panel; the guide's additions; a demo page at /pages/phase4/theatre (empty, minimal, typical, overflow, error); scripts/theatre-check.mjs. Review stop 1 |
| 2 | Both seats | lab | each scenario in both seats: the fleet pages for the operator, the native skin for the citizen's laptop; theatre's own messages (C6); the walk at Observe and Enforce on every surface; a harness plays S1 from one prompt. Review stop 2 |
| 3 | New here | lab + native | New here at the three registers |
| 4 | AI, on your own machine | native first | this-machine.json grows into the primer on real data, with the metaphor and its breaks and today's marks. A qnative cycle, handed on. Review stop 3 |
| 5 | Show mode | lab, then native | the list of shows, the dwell, the loop, idle resume and its off switch, exit where it was |
| 6 | Native theatre | qnative | a scenario as part of the nozzle's synthetic source, its beats as stream scripts (handed on) |
| 7 | Review and port | what goes to the layer (the band, the register control), what goes to qdash, what stays lab-only |