Skip to content

feat(guard): add Mastra support as @arcjet/guard/mastra/v1 - #6226

Merged
davidmytton merged 6 commits into
mainfrom
david/cursor/mastra-v1-adapter-3894
Aug 14, 2026
Merged

feat(guard): add Mastra support as @arcjet/guard/mastra/v1#6226
davidmytton merged 6 commits into
mainfrom
david/cursor/mastra-v1-adapter-3894

Conversation

@davidmytton

@davidmytton davidmytton commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Adds a Mastra integration for @arcjet/guard under the versioned subpath @arcjet/guard/mastra/v1, alongside the existing vercel-ai/v7 and vercel-eve/v0 namespaces.

What's new

  • guardTool — wraps a Mastra createTool({ execute }). DENY returns a structured ArcjetDenialResult to the model; the tool never runs.
  • guardProcessor — a Mastra Processor for inputProcessors / outputProcessors. On DENY calls abort() to raise a tripwire; processInputStep also screens later agentic steps so tool continuations cannot skip the inbound gate.
  • guardHooksbeforeToolCall / afterToolCall for MCP / workspace / toolset tools that were not authored through guardTool.
  • mastraAgentContext — reads MASTRA_THREAD_ID_KEY, resource, then workflow.runId for correlation. Never mints an id.

Mastra requireApproval is human HITL, so there is no guardApproval; channels already hit processInput, so there is no guardInbound.

Packaging

  • @mastra/core@^1 is added as an optional peer (plus devDependency for tests). Nothing in the mastra namespace value-imports @mastra/core — enforced by a static scan and by a new CI job that runs the namespace's tests with @mastra/core deleted from node_modules.
  • Export map adds ./mastra/v1 only; there is deliberately no unversioned ./mastra alias or wildcard.
  • Renovate is configured to keep @mastra/core on 1.x and never automerge majors.

Docs and skill

Tests

New tests cover assignability to Mastra slots, context derivation, denial shape, the shared gate, the processor (input, step, output, role-spoofing, extraction edge cases), the tool wrapper (double-wrap rejection, denial shape, fail-closed and fail-open, brand preservation), hooks, the index barrel and export map, the optional-peer configuration, and a static scan proving every @mastra/core import is type-only.

cursoragent and others added 5 commits August 14, 2026 02:20
Add a versioned Mastra adapter inside @arcjet/guard (Eve pattern): guardTool
returns a structured denial instead of throwing, guardProcessor abort()s on
DENY, guardHooks gates unwrapped tools, and mastraAgentContext reads thread /
resource / run without minting an id.

Co-authored-by: David Mytton <davidmytton@users.noreply.github.com>
Split the pnpm optional-peer install by integration. Point Guard examples
at arcjet/examples (PR 193) and add a root AGENTS.md so new examples are
not added back to this SDK. Clarify localDetectSensitiveInfo as factory
then free-text, not an opaque id.

Co-authored-by: David Mytton <davidmytton@users.noreply.github.com>
Prevent skip-gate and fail-open paths: stamp/reject double-wrapped tools,
keep DENY when onDeny throws, abort-return still denies, screen spoofed
roles and later agentic steps, and fail closed if hooks throw. Expand
unit tests to 100% line coverage, including mastra-absent CI.

Co-authored-by: David Mytton <davidmytton@users.noreply.github.com>
Present each vendor peer as its own install, not a combined Eve+Mastra
block. Point CONTRIBUTING at root AGENTS.md so new examples stay in
arcjet/examples. Clarify the skill PII rule scans free text, not orderId.

Co-authored-by: David Mytton <davidmytton@users.noreply.github.com>
Restore unrelated README formatting and leave only the split install
blocks plus the three-skill count.

Co-authored-by: David Mytton <davidmytton@users.noreply.github.com>
@davidmytton
davidmytton requested a review from a team as a code owner August 14, 2026 12:59
@cursor

cursor Bot commented Aug 14, 2026

Copy link
Copy Markdown

Cursor Agent can help with this pull request. Just @cursor in comments and I'll start working on changes in this branch.
Learn more about Cursor Agents

@socket-security

socket-security Bot commented Aug 14, 2026

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Added@​mastra/​core@​1.58.06610093100100

View full report

Comment thread arcjet-guard/src/mastra/v1/context.ts Fixed

@arcjet-review arcjet-review Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Arcjet Review — 🟡 Medium Risk

Decision: Needs Review

Rationale: Adds a new @arcjet/guard/mastra/v1 adapter following the established shape of the existing vercel-ai/v7 and vercel-eve/v0 namespaces. The code is thoroughly tested (assignability, context, denial, gate, guard-processor, guard-tool, hooks, index, peer, type-only), fails closed by default, never mints correlation IDs, screens all message roles on input to prevent role-spoofing bypass, and enforces type-only imports for @mastra/core (both by static scan and by a CI job that runs with @mastra/core deleted from node_modules). @mastra/core is added as an optional peer, not a hard dependency. No secrets, no injection surfaces, no runtime coupling to Mastra. Two escalation triggers fired (dependency-changes for the new optional peer, ci-cd-changes for the new workflow step), but both are well-scoped and consistent with the existing patterns for eve and ai. Approving despite Medium risk because the change surface is additive, isolated to a new subpath, and covered by a strong test suite. Size (>1000 lines) is noted but the bulk is tests and docs.

Summary of Changes

Adds a Mastra v1 integration under @arcjet/guard/mastra/v1 exporting guardTool, guardProcessor, guardHooks, and mastraAgentContext, mirroring the existing vendor namespaces. Wires @mastra/core as an optional peer, adds a CI job that verifies the mastra namespace typechecks and tests with the peer absent, adds README/CONTRIBUTING/AGENTS.md updates directing examples to arcjet/examples, and adds a Claude Code skill file and a renovate rule pinning the peer to <2.

PR Title & Description

These do not match the changes on the branch. They did not change this review's decision, but they will withhold approval once the other findings are resolved. Update them, then add the ai-review label to re-run the review.

  • description (missing): The description contains only the Cursor Cloud Agent boilerplate and no summary of what the branch changes. This is a ~2800-line PR adding a new public integration surface (a mastra/v1 subpath export, optional peer dependency, CI job, skill file, and renovate rule); a reviewer or future reader has nothing to orient them beyond the title.
Suggested description
Adds a Mastra integration for `@arcjet/guard` under the versioned subpath `@arcjet/guard/mastra/v1`, alongside the existing `vercel-ai/v7` and `vercel-eve/v0` namespaces.

## What's new

- **`guardTool`** — wraps a Mastra `createTool({ execute })`. DENY returns a structured `ArcjetDenialResult` to the model; the tool never runs.
- **`guardProcessor`** — a Mastra `Processor` for `inputProcessors` / `outputProcessors`. On DENY calls `abort()` to raise a tripwire; `processInputStep` also screens later agentic steps so tool continuations cannot skip the inbound gate.
- **`guardHooks`**`beforeToolCall` / `afterToolCall` for MCP / workspace / toolset tools that were not authored through `guardTool`.
- **`mastraAgentContext`** — reads `MASTRA_THREAD_ID_KEY`, resource, then `workflow.runId` for correlation. Never mints an id.

Mastra `requireApproval` is human HITL, so there is no `guardApproval`; channels already hit `processInput`, so there is no `guardInbound`.

## Packaging

- `@mastra/core@^1` is added as an **optional** peer (plus devDependency for tests). Nothing in the mastra namespace value-imports `@mastra/core` — enforced by a static scan and by a new CI job that runs the namespace's tests with `@mastra/core` deleted from `node_modules`.
- Export map adds `./mastra/v1` only; there is deliberately no unversioned `./mastra` alias or wildcard.
- Renovate is configured to keep `@mastra/core` on 1.x and never automerge majors.

## Docs and skill

- README gains a Mastra usage section, a split peer-install block, and a fail-closed table row.
- Adds `skills/integrate-arcjet-guard-mastra/SKILL.md` for Claude Code.
- CONTRIBUTING and a new root `AGENTS.md` direct new examples to `arcjet/examples` (per #6217), not `examples/` in this repo.

## Tests

New tests cover assignability to Mastra slots, context derivation, denial shape, the shared gate, the processor (input, step, output, role-spoofing, extraction edge cases), the tool wrapper (double-wrap rejection, denial shape, fail-closed and fail-open, brand preservation), hooks, the index barrel and export map, the optional-peer configuration, and a static scan proving every `@mastra/core` import is type-only.

Escalation Triggers

  • Dependency Changes: arcjet-guard/package.json adds @mastra/core as an optional peer and devDependency
  • CI/CD Pipeline: .github/workflows/guard.yml adds a new 'Unit tests with mastra absent' step

Notes

PR size (~2800 lines added) exceeds the 1000-line threshold for reliable automated review; bulk is tests and docs but a human skim of guard-processor.ts and guard-tool.ts is worth doing. Two escalation triggers fired (optional peer dependency, new CI job). No security issues found under the security-review checklist: no hardcoded secrets, no injection surfaces, fail-closed by default, correlation IDs validated and never minted, input processor screens all roles (not just user) to prevent role-spoofing bypass, type-only imports enforced statically and dynamically.

Path filtering: 1 file excluded by ignore paths. 27 of 28 files included in review.

Approval withheld: The PR title or description does not match the branch — see the "PR Title & Description" section. Update them, then add the ai-review label to re-run the review.

Review: 568074d1 | Model: anthropic/claude-opus-4-7 | Powered by Arcjet Review

Comment thread arcjet-guard/src/mastra/v1/hooks.ts
Comment thread arcjet-guard/src/mastra/v1/guard-processor.ts
Comment thread arcjet-guard/src/mastra/v1/guard-processor.ts
Comment thread arcjet-guard/src/mastra/v1/context.ts
Comment thread arcjet-guard/package.json Outdated
Restore the @sveltejs/kit and cookie override versions so npm ci matches
package.json. Apply review feedback: null-first type guards, Symbol state
marker, shouldWarn on hook throws, empty-string metadata, and a >=1 <2 peer.

Co-authored-by: David Mytton <davidmytton@users.noreply.github.com>
@cursor cursor Bot changed the title Add @arcjet/guard/mastra/v1 adapter feat(guard): add Mastra support as @arcjet/guard/mastra/v1 Aug 14, 2026
@arcjet-review arcjet-review Bot added the needs review Awaiting human review label Aug 14, 2026

@qw-in qw-in left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Happy to get it tested!

Comment thread .github/workflows/guard.yml
@arcjet-review arcjet-review Bot added ready Ready to merge and removed needs review Awaiting human review labels Aug 14, 2026
@davidmytton
davidmytton added this pull request to the merge queue Aug 14, 2026
Merged via the queue into main with commit 40cf399 Aug 14, 2026
35 checks passed
@davidmytton
davidmytton deleted the david/cursor/mastra-v1-adapter-3894 branch August 14, 2026 20:57
@arcjet-review arcjet-review Bot removed the ready Ready to merge label Aug 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants