Form answer diff
form-answer-diff · version 1.0.0 · Forms · free, no key needed
Diff two answer maps against one shared form definition.
Use when you need to: diff form answers · compare form submissions.
Supported
- diff form answers
- compare form submissions
Not supported
- definition diff
- respondent reconciliation
- fuzzy answer matching
- numeric coercion
Behavior
- One definition interprets both answer maps. Unknown answer keys are reported and are not treated as fields.
- This is a comparison, not a completeness check. form-response-check is the report that accepts or rejects null.
- Precedence, first match wins: invalid; both missing unchanged; missing versus null or a valid value is added or removed; both null unchanged; null versus a valid value is changed with reason null_versus_value; valid multi reorder is order_only; then equal values are unchanged and unequal values are changed.
- An invalid value is not also added, removed, changed, or order_only. Both nulls compare equal and still count as null. That equality does not make null a valid answer.
- Missing, null, and empty stay distinct. Empty means a valid empty string or a valid empty multi-select. Returned multi arrays keep the submitted order.
- number and integer reject numeric strings. -0 is canonicalized to 0. json equality ignores object key order and keeps array order.
- Each field is in exactly one of added, removed, changed, invalid, order_only, or the unchanged count.
Input
definition(object, required)left(object, required)right(object, required)
Output
added(array of any, required)removed(array of any, required)changed(array of any, required)invalid(array of any, required)order_only(array of any, required)unknown(array of any, required)counts(object, required)
Limits
- max input bytes: 262144
- max output bytes: 262144
- max input depth: 16
- max input nodes: 20000
- max fields: 100
- max choices: 50
- max respondents: 100
- max id bytes: 128
- max label bytes: 256
- max choice bytes: 128
- max answer string bytes: 4096
- max answer depth: 6
- max answer nodes: 50
- max changes: 500
- max mapping: 100
Example
Request input:
{
"definition": {
"fields": [
{
"id": "note",
"label": "Note",
"type": "string",
"required": false
},
{
"id": "tags",
"label": "Tags",
"type": "multi",
"required": false,
"choices": [
"x",
"y"
]
},
{
"id": "qty",
"label": "Qty",
"type": "number",
"required": false
}
]
},
"left": {
"note": "",
"tags": [
"y",
"x"
],
"qty": null
},
"right": {
"tags": [
"x",
"y"
],
"qty": 1
}
}
Response:
{
"result": {
"added": [],
"removed": [
{
"id": "note",
"presence": "empty",
"value": ""
}
],
"changed": [
{
"id": "qty",
"reason": "null_versus_value",
"left_presence": "null",
"right_presence": "value",
"left": null,
"right": 1
}
],
"invalid": [],
"order_only": [
{
"id": "tags",
"left": [
"y",
"x"
],
"right": [
"x",
"y"
]
}
],
"unknown": [],
"counts": {
"added": 0,
"removed": 1,
"changed": 1,
"invalid": 0,
"order_only": 1,
"unknown": 0,
"unchanged": 0,
"fields": 3,
"left_missing": 0,
"left_null": 1,
"left_empty": 1,
"right_missing": 1,
"right_null": 0,
"right_empty": 0
}
}
}
How to call it
MCP
Connect https://computefirst.net/mcp (setup), then call execute with:
{
"id": "form-answer-diff",
"version": "1.0.0",
"input": {
"definition": {
"fields": [
{
"id": "note",
"label": "Note",
"type": "string",
"required": false
},
{
"id": "tags",
"label": "Tags",
"type": "multi",
"required": false,
"choices": [
"x",
"y"
]
},
{
"id": "qty",
"label": "Qty",
"type": "number",
"required": false
}
]
},
"left": {
"note": "",
"tags": [
"y",
"x"
],
"qty": null
},
"right": {
"tags": [
"x",
"y"
],
"qty": 1
}
}
}
HTTP (no key)
curl -X POST https://computefirst.net/v1/tools/form-answer-diff/versions/1.0.0/execute \
-H "Content-Type: application/json" \
-d '{"definition":{"fields":[{"id":"note","label":"Note","type":"string","required":false},{"id":"tags","label":"Tags","type":"multi","required":false,"choices":["x","y"]},{"id":"qty","label":"Qty","type":"number","required":false}]},"left":{"note":"","tags":["y","x"],"qty":null},"right":{"tags":["x","y"],"qty":1}}'
The machine-readable contract is at /v1/tools/form-answer-diff/versions/1.0.0.
CLI
node cli.mjs run form-answer-diff 1.0.0 --input input.json --base-url https://computefirst.net
Get the client at /clients/cli/.
Related tools
- Form compare: Compare two filled form snapshots and return compact field and answer changes.
- Form definition diff: Diff two form definitions by stable field id, including choice lists and field order.
- Form response check: Report missing required answers, nulls, type failures, and choice failures.
- Form response diff: Reconcile two form response sets by exact respondent id.
- Form field map: Rename form fields with an explicit id map and reject collisions.