diff --git a/docs/_diagrams/actor_tree.svg b/docs/_diagrams/actor_tree.svg
new file mode 100644
index 00000000..bc09dc38
--- /dev/null
+++ b/docs/_diagrams/actor_tree.svg
@@ -0,0 +1,125 @@
+
diff --git a/docs/_diagrams/context_handshake.svg b/docs/_diagrams/context_handshake.svg
new file mode 100644
index 00000000..04c7e988
--- /dev/null
+++ b/docs/_diagrams/context_handshake.svg
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+parent task(Portal)child actor task(@tractor.context fn) Start: open_context(fn, **kwargs) StartAck Started: await ctx.started(value) Yield: stream.send() Yield: stream.send() Stop: stream closed Return: fn return value
+
+
+
+
+
+
+
+
+
diff --git a/docs/_diagrams/debug_lock.svg b/docs/_diagrams/debug_lock.svg
new file mode 100644
index 00000000..21a7e67e
--- /dev/null
+++ b/docs/_diagrams/debug_lock.svg
@@ -0,0 +1,118 @@
+
+
+
+
+
+
+
+
+
+
+
+
+subactor 'mary'root actor(owns the tty)subactor 'bob' tractor.pause(): acquire tty lock granted: pdb REPL is yours tractor.pause(): acquire tty lock continue: release lock granted: pdb REPL is yours
+
+
+
+
+
+
+
diff --git a/docs/_diagrams/error_propagation.svg b/docs/_diagrams/error_propagation.svg
new file mode 100644
index 00000000..6684a4c3
--- /dev/null
+++ b/docs/_diagrams/error_propagation.svg
@@ -0,0 +1,117 @@
+
+
+
+
+
+
+
+
+
+
+
+
+root actor(ActorNursery)subactor 'gertie'(healthy, gets cancelled)subactor 'bobbie'raises NameError supervises supervises RemoteActorError(boxed NameError) cancel()
+
+
+
+
+
+
diff --git a/docs/_diagrams/infected_aio.svg b/docs/_diagrams/infected_aio.svg
new file mode 100644
index 00000000..66dc8b84
--- /dev/null
+++ b/docs/_diagrams/infected_aio.svg
@@ -0,0 +1,122 @@
+
+
+
+
+
+
+
+
+
+
+
+
+subactor process (infect_asyncio=True)parent actor (pure trio)asyncio event loopasyncio.Taskaio_echo_server()trio (guest mode)trio task@tractor.context fn LinkedTaskChannel.send()/.receive() IPC: Context + MsgStream
+
+
+
+
diff --git a/docs/_diagrams/runtime_stack.svg b/docs/_diagrams/runtime_stack.svg
new file mode 100644
index 00000000..e8da9bc2
--- /dev/null
+++ b/docs/_diagrams/runtime_stack.svg
@@ -0,0 +1,107 @@
+
+
+
+
+
+
+
+
+
+
+
+
+your app: plain trio tasks + nurseriestractor runtime: actors, portals,contexts + streams, RPCIPC Channel: msgspec-typed msgsover TCP | UDS transportsOS: one process per actor
+
+
+
diff --git a/docs/_diagrams/streaming_pipeline.svg b/docs/_diagrams/streaming_pipeline.svg
new file mode 100644
index 00000000..a0015947
--- /dev/null
+++ b/docs/_diagrams/streaming_pipeline.svg
@@ -0,0 +1,123 @@
+
+
+
+
+
+
+
+
+
+
+
+
+actor 'streamer_0'actor 'streamer_1'actor 'aggregator'root actorstream_data(0)stream_data(1)aggregate()main() async for:yielded ints async for:yielded ints dedupedstream
+
+
+
+
+
diff --git a/docs/diagrams/actor_tree.d2 b/docs/diagrams/actor_tree.d2
new file mode 100644
index 00000000..6bec7a9e
--- /dev/null
+++ b/docs/diagrams/actor_tree.d2
@@ -0,0 +1,31 @@
+# tractor docs diagram: the hero supervision tree.
+# A process tree of trio-task-trees; every arrow is
+# a parent which *must wait* on its children.
+vars: {
+ d2-config: {
+ sketch: true
+ theme-id: 1
+ pad: 16
+ layout-engine: elk
+ }
+}
+direction: down
+root: "root actor" {
+ main: "main()"
+ an: "ActorNursery"
+ main -> an: opens
+}
+w0: "subactor\n'worker_0'" {
+ tasks: "trio task tree"
+}
+w1: "subactor\n'worker_1'" {
+ main: "serve()"
+ an: "ActorNursery"
+ main -> an: opens
+}
+gc: "subactor\n'deeper'" {
+ tasks: "trio task tree"
+}
+root.an -> w0: "spawns +\nsupervises"
+root.an -> w1: "spawns +\nsupervises"
+w1.an -> gc: "spawns +\nsupervises"
diff --git a/docs/diagrams/context_handshake.d2 b/docs/diagrams/context_handshake.d2
new file mode 100644
index 00000000..11971825
--- /dev/null
+++ b/docs/diagrams/context_handshake.d2
@@ -0,0 +1,21 @@
+# tractor docs diagram: the inter-actor `Context`
+# dialog; tractor's SC-transitive msg protocol as
+# seen from both sides of `Portal.open_context()`.
+vars: {
+ d2-config: {
+ sketch: true
+ theme-id: 1
+ pad: 16
+ layout-engine: elk
+ }
+}
+shape: sequence_diagram
+parent: "parent task\n(Portal)"
+child: "child actor task\n(@tractor.context fn)"
+parent -> child: "Start: open_context(fn, **kwargs)"
+child -> parent: "StartAck"
+child -> parent: "Started: await ctx.started(value)"
+parent -> child: "Yield: stream.send()"
+child -> parent: "Yield: stream.send()"
+parent -> child: "Stop: stream closed"
+child -> parent: "Return: fn return value"
diff --git a/docs/diagrams/debug_lock.d2 b/docs/diagrams/debug_lock.d2
new file mode 100644
index 00000000..7a96b430
--- /dev/null
+++ b/docs/diagrams/debug_lock.d2
@@ -0,0 +1,19 @@
+# tractor docs diagram: multi-actor debugger REPL
+# serialization via the root actor's tty lock.
+vars: {
+ d2-config: {
+ sketch: true
+ theme-id: 1
+ pad: 16
+ layout-engine: elk
+ }
+}
+shape: sequence_diagram
+mary: "subactor 'mary'"
+root: "root actor\n(owns the tty)"
+bob: "subactor 'bob'"
+mary -> root: "tractor.pause(): acquire tty lock"
+root -> mary: "granted: pdb REPL is yours"
+bob -> root: "tractor.pause(): acquire tty lock"
+mary -> root: "continue: release lock"
+root -> bob: "granted: pdb REPL is yours"
diff --git a/docs/diagrams/error_propagation.d2 b/docs/diagrams/error_propagation.d2
new file mode 100644
index 00000000..5a956d8f
--- /dev/null
+++ b/docs/diagrams/error_propagation.d2
@@ -0,0 +1,27 @@
+# tractor docs diagram: one-cancels-all error
+# propagation up a (sub-)actor tree; no zombies,
+# no lost errors.
+vars: {
+ d2-config: {
+ sketch: true
+ theme-id: 1
+ pad: 16
+ layout-engine: elk
+ }
+}
+direction: down
+root: "root actor\n(ActorNursery)"
+gertie: "subactor 'gertie'\n(healthy, gets cancelled)"
+bobbie: "subactor 'bobbie'\nraises NameError"
+root -> gertie: supervises
+root -> bobbie: supervises
+bobbie -> root: "RemoteActorError\n(boxed NameError)" {
+ style: {
+ stroke-dash: 3
+ }
+}
+root -> gertie: "cancel()" {
+ style: {
+ stroke-dash: 3
+ }
+}
diff --git a/docs/diagrams/infected_aio.d2 b/docs/diagrams/infected_aio.d2
new file mode 100644
index 00000000..da706053
--- /dev/null
+++ b/docs/diagrams/infected_aio.d2
@@ -0,0 +1,23 @@
+# tractor docs diagram: "infected asyncio" mode;
+# trio runs as a guest on the asyncio loop with
+# SC supervision linking tasks across both.
+vars: {
+ d2-config: {
+ sketch: true
+ theme-id: 1
+ pad: 16
+ layout-engine: elk
+ }
+}
+direction: down
+sub: "subactor process (infect_asyncio=True)" {
+ aio: "asyncio event loop" {
+ aiotask: "asyncio.Task\naio_echo_server()"
+ trio: "trio (guest mode)" {
+ triotask: "trio task\n@tractor.context fn"
+ }
+ trio.triotask <-> aiotask: "LinkedTaskChannel\n.send()/.receive()"
+ }
+}
+parent: "parent actor (pure trio)"
+parent <-> sub.aio.trio.triotask: "IPC: Context + MsgStream"
diff --git a/docs/diagrams/runtime_stack.d2 b/docs/diagrams/runtime_stack.d2
new file mode 100644
index 00000000..72602060
--- /dev/null
+++ b/docs/diagrams/runtime_stack.d2
@@ -0,0 +1,16 @@
+# tractor docs diagram: the layered runtime view
+# inside any single actor process.
+vars: {
+ d2-config: {
+ sketch: true
+ theme-id: 1
+ pad: 16
+ layout-engine: elk
+ }
+}
+grid-rows: 4
+grid-gap: 0
+app: "your app: plain trio tasks + nurseries"
+tractor: "tractor runtime: actors, portals,\ncontexts + streams, RPC"
+ipc: "IPC Channel: msgspec-typed msgs\nover TCP | UDS transports"
+os: "OS: one process per actor"
diff --git a/docs/diagrams/streaming_pipeline.d2 b/docs/diagrams/streaming_pipeline.d2
new file mode 100644
index 00000000..1a13ba7b
--- /dev/null
+++ b/docs/diagrams/streaming_pipeline.d2
@@ -0,0 +1,27 @@
+# tractor docs diagram: multi-actor streaming
+# pipeline topology from
+# examples/full_fledged_streaming_service.py
+vars: {
+ d2-config: {
+ sketch: true
+ theme-id: 1
+ pad: 16
+ layout-engine: elk
+ }
+}
+direction: right
+s0: "actor 'streamer_0'" {
+ fn: "stream_data(0)"
+}
+s1: "actor 'streamer_1'" {
+ fn: "stream_data(1)"
+}
+agg: "actor 'aggregator'" {
+ fn: "aggregate()"
+}
+main: "root actor" {
+ fn: "main()"
+}
+s0 -> agg: "async for:\nyielded ints"
+s1 -> agg: "async for:\nyielded ints"
+agg -> main: "deduped\nstream"