Mastra

Observability Primitives · Deep-Dive DD-14 · Course 1

60 minutes · TypeScript-first SDK · Built-in observability as a first-class primitive · Explicit read/write memory tiers

Two distinctive contributions: native event emission (Module 10 reference, 5/5) and explicit read/write memory separation (Module 4.3 reference, 5/5). The only roster harness where the memory-poisoning defense is structural rather than advisory. The cost: no sandbox, smaller community, and you must build against its primitives to get the observability benefit. 34/60 — the observability-and-memory shape.

Deep-Dives · The Harness Roster

The thesis — observability in the component, not around it

WRAPPER PATTERN (most SDKs)

withObservability(agent, { tracer }). Observability applied externally. Sees boundary crossings only. Can drift out of sync.

NATIVE PATTERN (Mastra)

component.run(input) → { result, events[] }. Observability emitted as part of the contract. Internal decisions visible. Contract cannot drift.

THE CONVERGENCE

DD-21 (Tau) makes the typed event union the observability layer for a teaching harness. Mastra makes native emission the primitive for a production SDK. Same conclusion: events ARE the cross-layer contract.

Observability belongs in the component, not around it. The cost: you must build against Mastra's primitives. Bring your own components and you bring your own observability gap.

What "native" buys you — three properties

PROPERTY 1
Internal decisions visible

A wrapper sees tool calls. A native emitter sees why the tool was chosen, what alternatives were rejected, what was pruned. Span tree vs reasoning trace.

PROPERTY 2
Contract cannot drift

Emission is part of the interface. Events track the component as it evolves — or fail to compile. A wrapper can silently stop recording.

PROPERTY 3
Same stream, every consumer

Logger, dashboard, alerting, replay all read the same events. No "telemetry says X but logs say Y" gap.

The cost. Native only pays off when components are native. Bring your own components (an off-the-shelf LLM wrapper, a custom tool) and the event stream shows a hole wherever your non-native component runs.

The explicit read/write memory boundary — Module 4.3 reference

CONFLATED STORE (most harnesses)

One handle for read and write. Restricting writes means intercepting calls and checking intent — a policy layer bolted onto a unified interface.

MASTRA SPLIT

readMemory(query) and writeMemory(entry) are separate interfaces. Give an agent the read interface, withhold the write interface. The defense is in the type system.

Write-gating becomes interface-level, not policy-level. An agent without the write-memory interface cannot poison memory — not because a policy forbids it, but because there is no handle to call. Compare to CrewAI (DD-12): crew-scoped shared memory means every agent can write, write-gating unavailable by default.

The NemoClaw parallel — two interface-level defenses

NEMOCLAW (DD-09) — credentials

Credentials live outside the sandbox's reach. The sandboxed agent never has a handle to the credentials, so the question of leaking them cannot arise inside the sandbox.

MASTRA (DD-14) — memory writes

Write-memory interface withheld. The agent never has a handle to call writeMemory, so the question of poisoning memory cannot arise in the agent.

Same principle, different layer. Both make a security-relevant decision a type-level (architectural) one rather than an advisory one. The strongest defense is to remove the handle, not to write a policy that says "do not misuse it." NemoClaw at the sandbox layer, Mastra at the memory layer.

Score: 34/60 — the observability-and-memory shape

ModuleScoreNotes
M10 Observability5/5Best built-in observability primitives in the roster — native event emission
M4.3 Write-gating5/5Interface-level, not policy-level — the reference
M4 Memory4/5Explicit read/write tier separation — architecturally clean
M2 Tools3/5SDK-defined surface; not a fixed tool set
M5 Sandbox1/5None — bring your own
M9 Verification1/5None
M11 Security2/5Read/write split is an asset; no sandbox/SECURITY model is a gap
Interpretation. Mastra is the observability-and-memory reference, not the production-readiness reference. Two 5/5 peaks (Module 10, Module 4.3). Pair it with a harness that has the security modules implemented.

The OpenHarness-vs-Mastra observability axis

OPENHARNESS (DD-13) — research

Inspectability-as-product. Human-readable logs. The cleanest mechanism reference for research. Module 10: 4/5 (below 5 only because human-readable over machine-readable).

MASTRA (DD-14) — production

Native event emission. Machine-readable structured events. The production observability reference. Module 10: 5/5.

Same goal (see what the agent did), different objective functions. Research reproducibility (OpenHarness) vs production operability (Mastra). OpenHarness approaches the Mastra standard but does not meet it — the gap that keeps OpenHarness at 4/5 while Mastra is 5/5.

MLSecOps relevance — the two hardest substrates to retrofit

Structural write boundary

Read/write split makes memory-poisoning defense interface-level. An MLSecOps team gets a write boundary that is in the type system, not in a policy layer that can be bypassed or misconfigured.

Intrinsic observability stream

Native event emission means every internal decision is an event a SIEM/alerting layer can consume. No "the agent did something but we cannot see what" gap.

The gap. No sandbox (Module 5: 1/5), no threat model (Module 11: 2/5). The memory and observability assets deserve an explicit security framing to match. Pair Mastra with a harness that has the sandbox and verification modules.

Three better, three to fix

THREE BETTER
  1. Observability as a first-class primitive — built in, not a wrapper. Module 10 reference.
  2. Explicit read/write memory tiers — cleanest abstraction. Module 4.3 reference. Only roster harness where memory-poisoning defense is structural.
  3. TypeScript-first DX — best TS experience in the SDK category.
THREE TO FIX
  1. Add a sandbox — none present; for a production SDK this is a gap (compare DD-11's 7-provider abstraction).
  2. Broaden integrations — fewer than OpenCode/Aider; the observability story deserves more consumers.
  3. Add a SECURITY.md and threat model — the read/write split and native observability are security assets that deserve explicit framing.
The verdict. Build on Mastra when TypeScript + observability + memory safety are your priorities and you are willing to build against its primitives. The observability reference for Module 10. The cleanest memory abstraction for Module 4. The only roster harness where memory-poisoning defense is structural rather than advisory.

Takeaways

  1. Observability belongs in the component, not around it. The wrapper pattern sees boundary crossings; the native pattern sees internal decisions. Mastra is the native-pattern reference for Module 10.
  2. Native buys you three properties — internal decisions visible, contract cannot drift, every consumer gets the same stream. The cost: you must build native to get the benefit.
  3. The read/write memory split makes write-gating interface-level — give the read interface, withhold the write interface. The defense is in the type system.
  4. Mastra's split is structurally identical to NemoClaw's credential isolation — both remove the handle rather than writing a policy. Different layers (memory vs sandbox), one principle.
  5. 34/60 is the observability-and-memory shape, not the production-readiness shape — two 5/5 peaks (Module 10, Module 4.3). Pair Mastra with a harness that has the security modules.

DD-14 is the final deep-dive of Course 1. All 14 deep-dives complete. ↑ Course 1 Index.