Diff a before/after JSON write for deletes, null-vs-omit and emptied arrays against protected paths

$0.005 USDC per call · Agent infrastructure · POST /api/v1/mutation-intent · Id mutation-intent

Compares the JSON document an agent read (before) with the one it is about to write (after) and lists every change by JSON Pointer: removed members, null turned into omitted (and the reverse), arrays emptied or shrunk, objects emptied, type changes. Fails when a change touches a protected path or is destructive and not listed in allowDestructive; use it before a PUT, PATCH or bulk update. Arrays are compared by index, so a reorder shows as element changes. Does not know the API's semantics for omitted fields (use update-dialect) and does not judge whether a non-destructive change is wanted.

What you get

Catches the PUT that silently wipes a field or an array the agent never meant to touch.

Call it

Send the JSON body below to https://agents.writerslogic.com/api/v1/mutation-intent. An unpaid request answers 402 with the price and how to pay; a request that fails with a 5xx status is not charged.

curl -i -X POST https://agents.writerslogic.com/api/v1/mutation-intent \
  -H 'content-type: application/json' \
  -d '{"before":{"name":"Ada","tags":["a","b"],"phone":null},"after":{"name":"Ada","tags":[]},"protectedPaths":["/name"],"allowDestructive":[]}'

Input

FieldTypeRequiredDescription
beforeanyyesJSON value as last read.
afteranyyesJSON value about to be written.
protectedPathsarray<string; length 0..300>; max 100 itemsnoJSON Pointers that must not change at all; a "*" token matches any one key or index.
allowDestructivearray<string; length 0..300>; max 100 itemsnoJSON Pointers ("*" wildcard) under which deletes, emptied containers and type changes are intended.

Example request body

{
  "before": {
    "name": "Ada",
    "tags": [
      "a",
      "b"
    ],
    "phone": null
  },
  "after": {
    "name": "Ada",
    "tags": []
  },
  "protectedPaths": [
    "/name"
  ],
  "allowDestructive": []
}

Result

The response is { "data": ..., "_provenance": ... }. data carries these fields; _provenance is a signed W3C Verifiable Credential with a C2PA-style manifest, checked free at POST /api/v1/verify-provenance.

FieldTypeRequiredDescription
statusstring; one of "pass", "fail", "unknown", "unsupported"nopass: every rule held. fail: a rule was violated (see witnesses). unknown: the input lacks the evidence to decide. unsupported: outside what this engine covers. Missing evidence is never a pass.
changesarray<object>noAt most 200 changes in document order.
changeCountintegernoTotal changes found, which can exceed the number listed.
truncatedbooleanno
protectedHitsintegerno
unintendedDestructiveintegerno
witnessesarray<object>no
versionsobjectnoEvery semantic dependency of this answer (engine, tables and their as-of dates, tokenizer, calendar, rounding profile).
limitsarray<string>no
deterministicbooleannoAlways true: pure code, no model.

Pay and connect

Available through: x402 (USDC on Base), MCP. MCP clients reach it through the execution-safety-kit package.

Machine-readable