diff --git a/README.md b/README.md index c93b0e9..2006c79 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,12 @@ Code](https://code.claude.com/docs/en/skills) and TADA, then how, then the challenges, tagged for an emoji retro. - [ibis-design](ibis-design/SKILL.md) — search a design space: issues, positions, and arguments. +- [wiring-diagram](wiring-diagram/SKILL.md) — who holds what, drawn + like MarkM's ERTP slides: every arrow cites the code, and Mallory + shows what a leak doesn't reach. + TODO: consider copying or adapting its companion for message order, + sequence-diagram-actor-sim (agoric-sdk `.agents/skills/` on branch + `connolly/ago-1299-agentic-planning-tdd`). - [obsidian-markdown](obsidian-markdown/SKILL.md) — the workspace is an Obsidian vault: one line per paragraph, relative links, no file symlinks you expect Obsidian to show. diff --git a/wiring-diagram/SKILL.md b/wiring-diagram/SKILL.md new file mode 100644 index 0000000..bcd13ee --- /dev/null +++ b/wiring-diagram/SKILL.md @@ -0,0 +1,113 @@ +--- +name: wiring-diagram +description: >- + Capability wiring diagram, "who holds what" — use when asked for a wiring diagram, a picture of who holds what, a capability diagram, or "a diagram like the cookie-rotation one"; when reviewing a design for POLA and wanting to see the reference graph. MarkM ERTP-slide style: actors are balls, makers pale regions, objects rounded squares, state ledger tables, references dot-to-arrowhead; HTML/SVG plus a headless-Chromium PNG. Not for message order over time: that's a sequence diagram (sequence-diagram-actor-sim in agoric-sdk). +--- + +# Capability wiring diagram + +One picture that answers, for a design: **who holds a reference to what, +and therefore who can do what.** It complements a sequence diagram, +which shows *when* messages flow. This one shows the standing graph of +authority that makes those messages possible. For sequences, see +`~/projects/ymax-workspace/agoric-sdk/.agents/skills/sequence-diagram-actor-sim/SKILL.md` +(on agoric-sdk branches `connolly/ago-1264-agentic-planning` and +`connolly/ago-1299-agentic-planning-tdd`, not yet on master). + +Exemplars: +- `~/oros-bots/capsite-cookie-rotation/docs/cookie-rotation-wiring.html` + (+ `.png`): the original. +- `~/qtrx/packages/umb-download/docs/wiring.html` (+ `.png`): three + makers, two outside parties, and an adversary holding a webkey. + +Start from [`template.html`](template.html), next to this file. It has +the drawing helpers and a small example scene to replace. + +## Read the graph from the code, not the story + +Every arrow must correspond to something real: a constructor argument, a +stored id, a binding, a held token, or a file someone keeps. Before +drawing, list the references as `holder → target: where in the code`. +Read the factories (`make…`, `newX`, `configure`) and anything that +stores an id: a DO id held as a string *is* a reference. If you can't +cite where a reference comes from, it doesn't get an arrow. + +Watch for references that are dropped on purpose (e.g. a setup route +that mints an instance, hands its id to one holder and forgets it). +That's often the point of the design. Say so in a caption, or just +leave the arrow out. + +## Vocabulary + +| element | helper | means | +|---|---|---| +| blue ball | `actor(cx, cy, label)` | a person or a program with its own agency | +| grey ball | `actor(cx, cy, label, "url(#ext)")` | outside the system: a browser extension, a third-party service | +| pale region | `maker(x, y, w, h, "makeFoo")` | a maker (factory, DO class) and the instances it made; the stacked inner panes say "there are many" | +| rounded square | `obj(x, y, w, h, label, stacked)` | an object or facet; `stacked` when one is made per instance | +| ledger table | `table(x, y, title, rows, [colW0, colW1])` | an object's state; rows are key/value; `rowY(i)` and `colX` give arrow anchors | +| dot → arrowhead | `ref(x1, y1, x2, y2, bend)` | holder references target; `bend` (±0.05–0.3) curves around things | +| speech bubble | the `path` + `code` block | the one call the picture is about, in `E(target).method(args)` form | +| caption | `cap(x, y, text, attrs)` | what an actor holds, and what it can't reach | + +Facets are separate objects (`store` vs `readOnly`): drawing them apart +is how the picture shows attenuation. + +## Include an adversary + +Add a Mallory who holds whatever is most likely to leak (an instance +id, a webkey, a URL), with an arrow to exactly what it reaches. The +caption says what she *can't* reach. Absent arrows are the security +argument, and Mallory makes them visible. + +## Layout + +- Actors in a row along the top (y≈200), makers below (y≈320 onward), + captions along the bottom (y≈ height − 14). +- Put each maker under the actors that mostly use it, so arrows run + short and downward. +- Speech bubble at the top, its tail pointing at the speaker. Move the + bubble's path (`M x,y`) and the tail segment (`h… l-38,48 l6,-48`) + together. +- Captions: two or three short lines, never on top of an arrow or a + ball. Use `"text-anchor": "start"` to set one beside a ball. +- Long arrows that cross a maker: increase `|bend|` until the curve + clears tables and objects. The control point is the midpoint offset + by `bend × (−dy, dx)`. + +## Accessibility + +Keep `