# Diagrams — DD-14: Mastra (Observability Primitives)

All diagrams use a consistent color code:
- **Teal (#5eead4)** — Mastra's native/structural/explicit mechanisms (its strengths: native emission, read/write split, the 5/5 modules).
- **Warn/orange (#f0a868)** — the contrasted pole or transition (the wrapper pattern, conflated memory, OpenHarness's human-readable logs).
- **Danger/red (#f08080)** — the production gap (no sandbox, no verification, no SECURITY model).

---

## Diagram 1 — Wrapper Pattern vs Native Pattern (Module 1.4 / Module 10)

**Type**: Pattern contrast.
**Purpose**: Show the central architectural distinction Mastra exists to embody — observability applied externally (wrapper pattern, most SDKs) vs observability emitted as part of the component contract (native pattern, Mastra) — and why Module 10 points at Mastra as the native-pattern reference.
**Reading**:
- The wrapper sees only boundary crossings (tool calls in/out); internal decisions the component makes without calling out are invisible, and the wrapper can drift out of sync as the component evolves.
- Native emission makes internal decisions visible — why a tool was chosen, what alternatives were rejected, what was pruned — and the contract cannot drift because emission is part of the interface.
- Mastra and DD-21 (Tau) converge on the same conclusion from opposite ends: Tau makes the typed event union the observability layer for a teaching harness; Mastra makes native emission the primitive for a production SDK. Observability belongs in the component, not around it.

```mermaid
flowchart LR
    subgraph WRAP["Wrapper pattern (most SDKs)"]
        A1["agent.run(input)"]
        W["withObservability(agent, { tracer })<br/>applied EXTERNALLY"]
        A2["observability is OUTSIDE<br/>sees only boundary crossings<br/>can drift out of sync"]
        A1 --> W --> A2
    end
    subgraph NAT["Native pattern (Mastra)"]
        N1["component.run(input)"]
        N2["→ { result, events[] }<br/>emission is part of the CONTRACT"]
        N3["internal decisions visible<br/>contract cannot drift<br/>every consumer same stream"]
        N1 --> N2 --> N3
    end
    WRAP -.->|same goal: visibility| NAT
    style W fill:#0d1b2a,stroke:#f0a868,color:#f0a868,stroke-width:2px
    style A1 fill:#0d1b2a,stroke:#e0e0e0,color:#e0e0e0
    style A2 fill:#0d1b2a,stroke:#f0a868,color:#e0e0e0
    style N1 fill:#0d1b2a,stroke:#5eead4,color:#5eead4
    style N2 fill:#0d1b2a,stroke:#5eead4,color:#5eead4,stroke-width:2px
    style N3 fill:#0d1b2a,stroke:#5eead4,color:#e0e0e0
```

---

## Diagram 2 — What Native Buys You (three properties, one cost)

**Type**: Property map.
**Purpose**: Show the three properties native emission buys (internal decisions visible, contract cannot drift, every consumer same stream) and the cost (you must build native to get the benefit — bring-your-own components bring their own observability gap).
**Reading**:
- Property 1 (internal visibility): a wrapper sees tool calls; a native emitter sees *why* the tool was chosen and what was pruned — the difference between a span tree and a reasoning trace.
- Property 2 (contract stability): emission is part of the interface, so the events track the component as it evolves; a native emitter changes with the component or fails to compile.
- Property 3 (single stream): a logger, a dashboard, an alerting rule, and a replay system all consume the same event stream — no "telemetry says X but logs say Y" gap.

```mermaid
flowchart TB
    NAT["Native emission<br/>(Mastra component contract)"]
    NAT --> P1["1. Internal decisions visible<br/>why chosen · what rejected · what pruned"]
    NAT --> P2["2. Contract cannot drift<br/>events track the component or it fails to compile"]
    NAT --> P3["3. Every consumer same stream<br/>logger · dashboard · alerting · replay"]
    NAT --> COST["COST: build native or lose the benefit<br/>bring-your-own components bring<br/>their own observability gap"]
    style NAT fill:#0d1b2a,stroke:#5eead4,color:#5eead4,stroke-width:2px
    style P1 fill:#0d1b2a,stroke:#5eead4,color:#e0e0e0
    style P2 fill:#0d1b2a,stroke:#5eead4,color:#e0e0e0
    style P3 fill:#0d1b2a,stroke:#5eead4,color:#e0e0e0
    style COST fill:#0d1b2a,stroke:#f0a868,color:#f0a868,stroke-dasharray:3 3
```

---

## Diagram 3 — The Explicit Read/Write Memory Boundary (Module 4 / 4.3 Reference)

**Type**: Interface architecture.
**Purpose**: Show Mastra's second distinctive contribution — read memory and write memory as separate interfaces (not a conflated store) — and why this makes Module 4.3 write-gating an interface-level decision rather than a policy bolt-on.
**Reading**:
- Read path and write path are different interfaces — `readMemory(query)` and `writeMemory(entry)` — not two operations on the same handle.
- Write-gating becomes interface-level: give an agent the read-memory interface and withhold the write-memory interface; the defense is in the type system, not in a policy layer.
- Compare to CrewAI (DD-12): crew-scoped shared memory means write-gating is unavailable by default because there is no write interface to withhold — every agent can write to the store every other agent later reads.

```mermaid
flowchart TB
    subgraph MS["Mastra — explicit read/write split"]
        RM["readMemory(query)<br/>→ results"]
        WM["writeMemory(entry)<br/>→ ack"]
    end
    AGENT["Agent"]
    AGENT -->|given| RM
    AGENT -.->|withheld by default<br/>interface-level decision| WM
    CREW["CrewAI (DD-12)<br/>crew-scoped SHARED memory<br/>write-gating UNAVAILABLE by default"]
    MS -.->|contrast| CREW
    style RM fill:#0d1b2a,stroke:#5eead4,color:#5eead4
    style WM fill:#0d1b2a,stroke:#5eead4,color:#5eead4,stroke-width:2px
    style AGENT fill:#0d1b2a,stroke:#e0e0e0,color:#e0e0e0
    style CREW fill:#0d1b2a,stroke:#f0a868,color:#f0a868,stroke-dasharray:3 3
```

---

## Diagram 4 — The NemoClaw Parallel (Two Interface-Level Defenses)

**Type**: Structural-parallel map.
**Purpose**: Show that Mastra's read/write split and NemoClaw's credential isolation are structurally identical — both remove the handle rather than write a policy — and that the strongest defense is architectural, not advisory.
**Reading**:
- NemoClaw (DD-09) places credentials outside the sandbox's reach — there is no handle to leak; the defense is the sandbox boundary itself.
- Mastra withholds the write-memory interface — there is no handle to poison; the defense is the type system itself.
- Different layers (sandbox credentials vs memory writes), one structural principle: remove the handle, do not write a policy. The course keeps returning to interface-level defense as the architectural move that matters.

```mermaid
flowchart TB
    NEMO["NemoClaw (DD-09)<br/>credentials OUTSIDE the sandbox's reach<br/>no handle to leak"]
    MASTRA["Mastra (DD-14)<br/>write-memory interface WITHHELD<br/>no handle to poison"]
    PRINCIPLE["STRUCTURAL PRINCIPLE<br/>remove the handle<br/>do not write a policy<br/>defense is architectural, not advisory"]
    NEMO -.->|different layer · same principle| MASTRA
    NEMO --> PRINCIPLE
    MASTRA --> PRINCIPLE
    style NEMO fill:#0d1b2a,stroke:#5eead4,color:#5eead4,stroke-width:2px
    style MASTRA fill:#0d1b2a,stroke:#5eead4,color:#5eead4,stroke-width:2px
    style PRINCIPLE fill:#0d1b2a,stroke:#5eead4,color:#5eead4,stroke-width:3px
```

---

## Diagram 5 — Score Profile: 34/60 (the observability-and-memory shape)

**Type**: Rubric profile.
**Purpose**: Show Mastra's 34/60 score shape — two 5/5 peaks (Module 10 Observability, Module 4.3 Write-gating) and the production gaps (Module 5 Sandbox 1/5, Module 9 Verification 1/5, Module 11 Security 2/5) — and why the score reflects the observability-and-memory specialization, not a production-readiness claim.
**Reading**:
- The two 5/5 peaks make Mastra the Module 10 reference (native observability) and the Module 4.3 reference (interface-level write-gating) — the highest scores in the roster on both modules.
- Module 4 Memory at 4/5 reflects the explicit read/write tier separation — architecturally clean, the substrate that makes 4.3 natural.
- The production gaps (5/9/11) are the cost of the specialization: no sandbox, no verification, no SECURITY model. Pair Mastra with a harness that has the security modules.

```mermaid
flowchart TB
    M["Mastra · 34/60<br/>observability-and-memory shape"]
    M --> H1["Module 10 Observability · 5/5<br/>native event emission · BEST in roster"]
    M --> H2["Module 4.3 Write-gating · 5/5<br/>interface-level · the reference"]
    M --> H3["Module 4 Memory · 4/5<br/>explicit read/write tier separation"]
    M --> L1["Module 5 Sandbox · 1/5<br/>none — bring your own"]
    M --> L2["Module 9 Verification · 1/5<br/>none"]
    M --> L3["Module 11 Security · 2/5<br/>read/write split is an asset · no SECURITY model"]
    NOTE["Pair Mastra with<br/>Agents SDK (DD-11) sandboxing ·<br/>NemoClaw (DD-09) governance<br/>for production"]
    L1 -.-> NOTE
    L3 -.-> NOTE
    style M fill:#0d1b2a,stroke:#5eead4,color:#5eead4,stroke-width:2px
    style H1 fill:#0d1b2a,stroke:#5eead4,color:#5eead4
    style H2 fill:#0d1b2a,stroke:#5eead4,color:#5eead4
    style H3 fill:#0d1b2a,stroke:#5eead4,color:#e0e0e0
    style L1 fill:#0d1b2a,stroke:#f08080,color:#f08080
    style L2 fill:#0d1b2a,stroke:#f08080,color:#f08080
    style L3 fill:#0d1b2a,stroke:#f08080,color:#f08080
    style NOTE fill:#0d1b2a,stroke:#f0a868,color:#f0a868,stroke-dasharray:3 3
```

---

## Diagram 6 — The OpenHarness-vs-Mastra Observability Axis

**Type**: Pole-pair contrast.
**Purpose**: Show the contrast between OpenHarness (DD-13, observability for research reproducibility — human-readable) and Mastra (DD-14, observability for production operability — machine-readable) — the two observability peaks in the roster, optimizing for complementary objectives.
**Reading**:
- Both harnesses score 4-5 on Module 10, but they optimize for different objectives: OpenHarness makes logs human-readable for falsifiable research claims; Mastra makes events machine-readable for SIEM/alerting consumption.
- OpenHarness's inspectability is a research property (a researcher can read the decision log); Mastra's observability is a production property (a dashboard can consume the event stream).
- The convergence point: both refuse to hide internal decisions. OpenHarness logs them for a human; Mastra emits them as structured events for a machine. Two routes to the same goal — visibility of what the harness did.

```mermaid
flowchart LR
    OH["OpenHarness (DD-13)<br/>inspectability for RESEARCH<br/>human-readable · 4/5"]
    MS["Mastra (DD-14)<br/>observability for PRODUCTION<br/>machine-readable · 5/5"]
    SHARED["Shared design<br/>refuse to hide internal decisions<br/>(OpenHarness logs them ·<br/>Mastra emits them as events)"]
    OH -->|observability axis| MS
    OH -.->|both| SHARED
    MS -.->|both| SHARED
    style OH fill:#0d1b2a,stroke:#5eead4,color:#5eead4,stroke-width:2px
    style MS fill:#0d1b2a,stroke:#5eead4,color:#5eead4,stroke-width:2px
    style SHARED fill:#0d1b2a,stroke:#f0a868,color:#f0a868
```

---

## Diagram 7 — n8n Workflow: Mastra Native Emission (reference pipeline)

**Type**: n8n workflow JSON.
**Purpose**: Provide the n8n workflow that demonstrates native event emission as an inspectable pipeline — the same pattern Module 10 teaches, executable in n8n — and contrast it with a wrapper-instrumented equivalent.
**Reading**:
- The component node emits structured events as part of its run output (`{ result, events[] }`) — the native pattern; a wrapper-only workflow would see only the boundary crossing (input/output) and miss the internal decision events.
- The consumer fan-out (logger, dashboard, alerting, replay) all read the same event stream — property 3 of native emission; no "telemetry says X but logs say Y" gap.
- This is the reference pipeline for the lab: students implement both patterns in Python (07-lab-spec.md) and can compare against this n8n version.

```json
{
  "name": "Mastra Native Emission — DD-14",
  "nodes": [
    { "parameters": { "content": "={{ JSON.stringify({ input: $json.input, component: 'NativeComponent' }) }}", "options": {} }, "id": "in", "name": "1. Component input", "type": "n8n-nodes-base.set", "typeVersion": 3.4, "position": [160, 300] },
    { "parameters": { "content": "={{ JSON.stringify({ result: 'computed output', events: [{ type: 'tool_selected', reason: 'regex match', alternatives_rejected: ['web_search'] }, { type: 'context_pruned', kept: 4, dropped: 2 }, { type: 'stop_condition', reason: 'max_iterations' }] }) }}", "options": {} }, "id": "run", "name": "2. component.run() (native emission)", "type": "n8n-nodes-base.respondToWebhook", "typeVersion": 1, "position": [400, 300], "notesInFlow": true, "notes": "Mastra native pattern: component returns { result, events[] }. Events ARE the contract — internal decisions visible, not just boundary crossings. Compare wrapper pattern: withObservability(agent) sees only input/output, misses tool_selected/context_pruned/stop_condition." },
    { "parameters": { "content": "={{ JSON.stringify($json.events.map(e => ({ sink: 'logger', event: e }))) }}", "options": {} }, "id": "log", "name": "3a. Logger sink", "type": "n8n-nodes-base.set", "typeVersion": 3.4, "position": [640, 180] },
    { "parameters": { "content": "={{ JSON.stringify($json.events.map(e => ({ sink: 'dashboard', event: e }))) }}", "options": {} }, "id": "dash", "name": "3b. Dashboard sink", "type": "n8n-nodes-base.set", "typeVersion": 3.4, "position": [640, 300] },
    { "parameters": { "content": "={{ JSON.stringify($json.events.filter(e => e.type === 'stop_condition').map(e => ({ sink: 'alerting', event: e }))) }}", "options": {} }, "id": "alert", "name": "3c. Alerting sink (stop_condition only)", "type": "n8n-nodes-base.set", "typeVersion": 3.4, "position": [640, 420] },
    { "parameters": { "content": "={{ JSON.stringify({ replay: true, events: $json.events }) }}", "options": {} }, "id": "replay", "name": "3d. Replay sink", "type": "n8n-nodes-base.respondToWebhook", "typeVersion": 1, "position": [880, 300] }
  ],
  "connections": { "1. Component input": { "main": [ [ { "node": "2. component.run() (native emission)", "type": "main", "index": 0 } ] ] }, "2. component.run() (native emission)": { "main": [ [ { "node": "3a. Logger sink", "type": "main", "index": 0 }, { "node": "3b. Dashboard sink", "type": "main", "index": 0 }, { "node": "3c. Alerting sink (stop_condition only)", "type": "main", "index": 0 }, { "node": "3d. Replay sink", "type": "main", "index": 0 } ] ] } },
  "settings": { "executionOrder": "v1" }, "meta": { "templateCreatedBy": "Harness Engineering Master Course — DD-14 Mastra (native pattern reference)" }
}
```
