Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 76 additions & 0 deletions src/content/docs/guards/capture.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,81 @@ export default {
| `occurredAt` / `occurred_at` | Optional timestamp. Defaults to the time of the call. Pre-epoch values cannot be represented and are dropped. |
| `waitUntil` | JavaScript only. Platform hook that keeps the invocation alive until the batch is sent. |

## Capture outcomes

Helpers that wrap an action record `metadata.outcome` on the capture event
they emit. The value is capture and Sequence metadata. It never changes the
decision. `conclusion` remains `ALLOW` or `DENY`. The decision has no
outcome field.

You don't set `outcome`. The helper writes it after your metadata so a
caller key can't overwrite what the helper recorded.

<Tabs syncKey="language">
<TabItem label="JavaScript / TypeScript">

JavaScript `guardTool` and `guardAction` record one of the following
values:

| Value | The action | What it means |
| ----- | ---------- | ------------- |
| `success` | Ran. | The helper executed the action. |
| `error` | Ran, then threw. | The action failed after the check. |
| `denied` | Did not run. | Policy evaluated `DENY`. |
| `unavailable` | Did not run. | Fail-closed. The check was incomplete. |

They don't record `degraded`. When `onGuardError` is `"allow"` and the
action runs without a complete judgment, the event records `success`.

</TabItem>
<TabItem label="Python">

Python checkpoint helpers record one of the following values:

| Value | The action | What policy did |
Comment thread
cursor[bot] marked this conversation as resolved.
Outdated
| ----- | ---------- | --------------- |
| `success` | Ran. | Judged all of it. |
| `degraded` | Ran. `on_guard_error` is `allow`. | Judged it in part or not at all. |
| `error` | Ran, then threw. | Judged it or not. |
| `denied` | Did not run. | Evaluated `DENY`. |
| `unavailable` | Did not run. | Fail-closed. The check was incomplete. |

Comment thread
cursor[bot] marked this conversation as resolved.
`on_guard_error` is `"allow"` or `"deny"`. The default is `"deny"`: an
incomplete check blocks the action and records `unavailable`. If the
action runs and then throws, the event records `error`, even when the
judgment was incomplete.

A `degraded` event uses `decision_id` to tell the two incomplete judgments
apart:

- Present: policy judged the action in part.
- Absent: policy judged none of it. The helper had no decision, a
failed-open decision with an empty id, or an answer it could not read.

An unreadable decision isn't passed into capture. The event emits
without `decision_id`.

The following helpers go through the checkpoint engine, so they record
these outcomes:

- `guard_action` / `guard_action_sync`
- `guard_tool`
- `ArcjetMiddleware`

A direct `capture()` call doesn't set `outcome`. Observe-only
`ArcjetCaptureHandler` and `ArcjetAsyncCaptureHandler` don't go through
the checkpoint engine.

</TabItem>
<TabItem label="Go">

The Go SDK doesn't write `metadata.outcome` on `Capture`. Use `Capture`
to record that an allowed action happened. Outcome classification is not
part of the Go helper surface.

</TabItem>
</Tabs>

## Call `capture()` without a client handle

Passing the client explicitly is the recommended path. When `capture()` is
Expand All @@ -186,6 +261,7 @@ startup and import the free `capture()` function. See <Link.Page href="/testing#

- <Link.Page href="/guards">Agent guards</Link.Page>
- <Link.Page href="/guards/reference">Guard testing and reference</Link.Page>
- <Link.Page href="/guards/langchain">LangChain agent guard</Link.Page>
- <Link.Page href="/testing">Testing Arcjet</Link.Page>
- <Link.Page href="/reference/python#record-what-happened-with-capture">Python SDK capture</Link.Page>
- <Link.Page href="/reference/go#capture">Go SDK capture</Link.Page>
4 changes: 3 additions & 1 deletion src/content/docs/guards/framework-integrations.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,9 @@ Pick the surface that matches what you hold when the effect runs:
- Observe only: `ArcjetCaptureHandler` / `ArcjetAsyncCaptureHandler`.
These cannot deny a call. LangChain ignores callback return values.

For more information about install, helpers, fail-closed behavior, and
`guard_tool` and `ArcjetMiddleware` go through the checkpoint engine, so
their capture events include `metadata.outcome`. For more information
about install, helpers, fail-closed behavior, capture outcomes, and
correlation, see the
<Link.Page href="/guards/langchain">LangChain agent guard</Link.Page>.

Expand Down
8 changes: 8 additions & 0 deletions src/content/docs/guards/langchain.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,14 @@ The core `guard()` call still fails open. It returns `ALLOW`, and
`has_failed_open()` returns `True`. The wrappers that sit around an effect
fail closed.

Checkpoint surfaces go through the checkpoint engine, so the capture
event they emit includes `metadata.outcome`. If the action ran only
because `on_guard_error="allow"` and policy did not judge it fully, the
event records `degraded`. The default records `unavailable` and blocks.
For more information about the five values and how `decision_id`
distinguishes a partial judgment, see
<Link.Page href="/guards/capture#capture-outcomes">Capture outcomes</Link.Page>.

## Correlation

Pass one correlation ID into `ainvoke()` so middleware and guarded tools
Expand Down
6 changes: 4 additions & 2 deletions src/content/docs/guards/reference.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -179,8 +179,10 @@ Metadata is untrusted and is not redacted – do not put secrets or PII in it.

Use `capture()` / `Capture` to record that an allowed action happened. Captures
are visibility data: they never change a conclusion and never set
`hasFailedOpen()`. For options, batching, `flush()`, and serverless `waitUntil`,
see <Link.Page href="/guards/capture">Capture events</Link.Page>.
`hasFailedOpen()`. Python checkpoint helpers and JavaScript wrappers also
write `metadata.outcome` on the event they emit. For options, batching,
`flush()`, serverless `waitUntil`, and the outcome values, see
<Link.Page href="/guards/capture">Capture events</Link.Page>.

## Decisions and policy results

Expand Down
10 changes: 9 additions & 1 deletion src/content/docs/reference/python.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -713,6 +713,12 @@ checkpoint helpers. They fail closed by default
- **Observe only** – `ArcjetCaptureHandler` /
`ArcjetAsyncCaptureHandler`. These cannot deny a call.

Checkpoint helpers that wrap an effect also record `metadata.outcome` on
the capture event. The value is capture and Sequence metadata. It
doesn't change `conclusion`, which remains `ALLOW` or `DENY`. For the
five values and the `degraded` discriminator, see
<Link.Page href="/guards/capture#capture-outcomes">Capture outcomes</Link.Page>.

For install, examples, correlation, and the configure-before-wrap rule,
see the <Link.Page href="/guards/langchain">LangChain agent guard</Link.Page>.

Expand Down Expand Up @@ -933,7 +939,9 @@ href="/guards/reference#metadata">Guard metadata</Link.Page>.
`guard()` decides whether something is allowed.
<Link.Page href="/guards/capture">`capture()`</Link.Page> records that it
happened. It never affects a decision, never raises, and is not awaited even
on the async client.
on the async client. Checkpoint helpers set `metadata.outcome` on the
events they emit. A direct `capture()` call doesn't. See
<Link.Page href="/guards/capture#capture-outcomes">Capture outcomes</Link.Page>.

```py
aj.capture(
Expand Down
4 changes: 3 additions & 1 deletion src/content/docs/testing.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ and the in-memory test client. Guard tests must assert that a denied or
unavailable decision prevents the side effect, not only that Arcjet returned a
particular result. Capture tests record that an allowed action happened, so they
must assert that the application recorded the expected `action` after the side
effect ran. See <Link.Page href="/guards/capture">Capture events</Link.Page>.
effect ran. When you test a Python checkpoint helper, assert
`metadata.outcome` as well. See
<Link.Page href="/guards/capture#capture-outcomes">Capture outcomes</Link.Page>.

## Test with Newman

Expand Down
4 changes: 4 additions & 0 deletions src/content/docs/troubleshooting.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,10 @@ LangChain wrappers do this by default. See
<Link.Page href="/guards/reference#availability-and-fail-behavior">Agent guard availability and fail behavior</Link.Page>
and the <Link.Page href="/guards/langchain">LangChain agent guard</Link.Page>.

Python checkpoint helpers that proceed because `on_guard_error="allow"`
record `metadata.outcome` as `degraded` on the capture event. See
<Link.Page href="/guards/capture#capture-outcomes">Capture outcomes</Link.Page>.

### Arcjet uses 127.0.0.1 when the public IP address is missing in development mode

Arcjet's automatic IP detection expects a valid public IP address to enable
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.