The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"name": "LAB 04 - Lastenheft Delta Check - Inspectable",
"nodes": [
{
"parameters": {
"content": "# LAB 04: Lastenheft-Deltas sichtbar machen\n\n**Buyer:** Leitung Engineering / Technischer Vertrieb\n\n**Problem:** Kundenanforderungen und interne Standards werden seitenweise verglichen. Abweichungen, Widerspr\u00fcche und fehlende Angaben m\u00fcssen mit Quelle belegbar bleiben.\n\n**Result:** Eine pr\u00fcfbare Anforderungsmatrix mit Seite, Delta, Risiko und offenen Fragen statt eines unverbundenen Text-Summaries.\n\nInput \u2192 contract \u2192 idempotency \u2192 context \u2192 deterministic rules \u2192 exception \u2192 human decision \u2192 draft.",
"width": 840,
"height": 300,
"color": 2
},
"id": "b5370576-b637-4709-a337-0250b43703e3",
"name": "Note 01 - Business Flow",
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
-1240,
-720
]
},
{
"parameters": {
"content": "# Contract and evidence\n\n- Six synthetic cases: happy, review, stop, duplicate, dependency failure and invalid payload.\n- Source references stay attached to findings.\n- Missing critical facts are never inferred.\n- Correlation and idempotency keys are created before any adapter boundary.",
"width": 840,
"height": 300,
"color": 4
},
"id": "8401c36f-8301-41dc-a601-c6958501c502",
"name": "Note 02 - Contract & Evidence",
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
-300,
-720
]
},
{
"parameters": {
"content": "# Reliability controls\n\n- Atomic claim is represented by a deterministic test double.\n- Duplicate delivery returns the previous outcome.\n- Only transient failures enter a bounded retry envelope.\n- Retry budget: 3 attempts; no unbounded loop.\n- Invalid data enters a redacted repair queue.",
"width": 840,
"height": 300,
"color": 3
},
"id": "e0b77b5f-dfb7-49cc-a2b7-7e85e1b77cf2",
"name": "Note 03 - Reliability Controls",
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
660,
-720
]
},
{
"parameters": {
"content": "# Domain guardrails\n\nContext: Anforderungs- und Standardmatrix (mocked adapter).\n\nThe workflow classifies each case as review-ready, review-required or stopped. Domain rules\u2014not an LLM prompt\u2014own the stop decision.",
"width": 840,
"height": 300,
"color": 5
},
"id": "571744f5-5617-4362-a517-41cf5417403c",
"name": "Note 04 - Domain Guardrails",
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
1640,
-720
]
},
{
"parameters": {
"content": "# Human-controlled decision\n\nOwner: Engineering.\n\nApprove, reject or request information. The approval is version-bound. The external adapter is visible but disabled; every test run reports zero external writes.",
"width": 840,
"height": 300,
"color": 6
},
"id": "87d3aa82-88d3-4c15-a5d3-a75c86d3a8ef",
"name": "Note 05 - Human Boundary",
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
2640,
-720
]
},
{
"parameters": {
"content": "# Test matrix\n\n1. Nominal input reaches review-ready.\n2. Recoverable deviation explains its evidence.\n3. Critical ambiguity stops.\n4. Replay is idempotent.\n5. Dependency outage schedules bounded retry.\n6. Invalid contract is redacted and quarantined.\n\nStatus: Synthetic Demo \u00b7 Built and testable \u00b7 not customer validated.",
"width": 900,
"height": 340,
"color": 7
},
"id": "2b076be6-2c07-4d79-a907-68c02a076a53",
"name": "Note 06 - Test Matrix",
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
3640,
-720
]
},
{
"parameters": {},
"id": "22f38796-23f3-4929-a0f3-847021f38603",
"name": "Manual Test Start",
"type": "n8n-nodes-base.manualTrigger",
"typeVersion": 1,
"position": [
-1240,
0
]
},
{
"parameters": {
"jsCode": "const fixtures = [{\"id\":\"bounded-delta\",\"label\":\"Klare Abweichungen\",\"kind\":\"happy\",\"input\":{\"eventId\":\"LST-DEMO-4001\",\"customerSpec\":\"Lastenheft_Musterlinie.pdf\",\"internalStandard\":\"Werksstandard_WS-04.pdf\",\"requirements\":[{\"id\":\"R-12\",\"text\":\"Taktzeit \u2264 18 s\",\"page\":8,\"standard\":\"\u2264 20 s\",\"state\":\"delta\"},{\"id\":\"R-27\",\"text\":\"Profinet-Schnittstelle\",\"page\":14,\"standard\":\"Profinet vorgesehen\",\"state\":\"match\"},{\"id\":\"R-41\",\"text\":\"Schaltschrank IP54\",\"page\":22,\"standard\":\"IP54\",\"state\":\"match\"}],\"evidence\":[{\"source\":\"Lastenheft_Musterlinie.pdf\",\"page\":8,\"field\":\"R-12\"}]}},{\"id\":\"missing-acceptance\",\"label\":\"Abnahmekriterium fehlt\",\"kind\":\"edge\",\"input\":{\"eventId\":\"LST-DEMO-4002\",\"customerSpec\":\"Lastenheft_Pr\u00fcfzelle.pdf\",\"internalStandard\":\"Werksstandard_WS-04.pdf\",\"requirements\":[{\"id\":\"R-08\",\"text\":\"Hohe Pr\u00fcfgenauigkeit\",\"page\":6,\"standard\":\"Messunsicherheit angeben\",\"state\":\"missing-measure\"},{\"id\":\"R-19\",\"text\":\"CSV-Export\",\"page\":11,\"standard\":\"CSV oder OPC UA\",\"state\":\"match\"}],\"evidence\":[{\"source\":\"Lastenheft_Pr\u00fcfzelle.pdf\",\"page\":6,\"field\":\"R-08\"}]}},{\"id\":\"contradiction\",\"label\":\"Widerspr\u00fcchliche Taktzeit\",\"kind\":\"error\",\"input\":{\"eventId\":\"LST-DEMO-4003\",\"customerSpec\":\"Lastenheft_Linie7.pdf\",\"internalStandard\":\"Werksstandard_WS-04.pdf\",\"requirements\":[{\"id\":\"R-03\",\"text\":\"Taktzeit 12 s\",\"page\":3,\"standard\":\"\u2264 20 s\",\"state\":\"contradiction\",\"conflictsWith\":\"R-44: Taktzeit 15 s auf Seite 28\"}],\"evidence\":[{\"source\":\"Lastenheft_Linie7.pdf\",\"page\":3,\"field\":\"R-03\"},{\"source\":\"Lastenheft_Linie7.pdf\",\"page\":28,\"field\":\"R-44\"}]}},{\"id\":\"bounded-delta-replay\",\"label\":\"Doppelte Zustellung\",\"kind\":\"duplicate\",\"input\":{\"eventId\":\"LST-DEMO-4001\",\"customerSpec\":\"Lastenheft_Musterlinie.pdf\",\"internalStandard\":\"Werksstandard_WS-04.pdf\",\"requirements\":[{\"id\":\"R-12\",\"text\":\"Taktzeit \u2264 18 s\",\"page\":8,\"standard\":\"\u2264 20 s\",\"state\":\"delta\"},{\"id\":\"R-27\",\"text\":\"Profinet-Schnittstelle\",\"page\":14,\"standard\":\"Profinet vorgesehen\",\"state\":\"match\"},{\"id\":\"R-41\",\"text\":\"Schaltschrank IP54\",\"page\":22,\"standard\":\"IP54\",\"state\":\"match\"}],\"evidence\":[{\"source\":\"Lastenheft_Musterlinie.pdf\",\"page\":8,\"field\":\"R-12\"}]}},{\"id\":\"bounded-delta-dependency\",\"label\":\"Tempor\u00e4rer Adapterfehler\",\"kind\":\"dependency\",\"input\":{\"eventId\":\"LST-DEMO-4001-DEP\",\"customerSpec\":\"Lastenheft_Musterlinie.pdf\",\"internalStandard\":\"Werksstandard_WS-04.pdf\",\"requirements\":[{\"id\":\"R-12\",\"text\":\"Taktzeit \u2264 18 s\",\"page\":8,\"standard\":\"\u2264 20 s\",\"state\":\"delta\"},{\"id\":\"R-27\",\"text\":\"Profinet-Schnittstelle\",\"page\":14,\"standard\":\"Profinet vorgesehen\",\"state\":\"match\"},{\"id\":\"R-41\",\"text\":\"Schaltschrank IP54\",\"page\":22,\"standard\":\"IP54\",\"state\":\"match\"}],\"evidence\":[{\"source\":\"Lastenheft_Musterlinie.pdf\",\"page\":8,\"field\":\"R-12\"}],\"adapterAvailable\":false,\"retryAttempt\":1}},{\"id\":\"bounded-delta-invalid\",\"label\":\"Ung\u00fcltiger Eingangsvertrag\",\"kind\":\"invalid\",\"input\":{\"eventId\":null,\"customerSpec\":\"Lastenheft_Musterlinie.pdf\",\"internalStandard\":\"Werksstandard_WS-04.pdf\",\"requirements\":[{\"id\":\"R-12\",\"text\":\"Taktzeit \u2264 18 s\",\"page\":8,\"standard\":\"\u2264 20 s\",\"state\":\"delta\"},{\"id\":\"R-27\",\"text\":\"Profinet-Schnittstelle\",\"page\":14,\"standard\":\"Profinet vorgesehen\",\"state\":\"match\"},{\"id\":\"R-41\",\"text\":\"Schaltschrank IP54\",\"page\":22,\"standard\":\"IP54\",\"state\":\"match\"}],\"evidence\":[{\"source\":\"Lastenheft_Musterlinie.pdf\",\"page\":8,\"field\":\"R-12\"}]}}];\nreturn fixtures.map((fixture) => ({ json: { workflowId: 'spec-delta', evidenceType: 'Synthetic Demo', ...fixture } }));"
},
"id": "6a294a4f-6929-48bc-ac29-4d756b294be2",
"name": "Load 6 Synthetic Test Cases",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-1020,
0
]
},
{
"parameters": {
"jsCode": "return items.map((item, index) => ({ json: {\n workflowId: item.json.workflowId,\n workflowTitle: \"Lastenheft Delta Check\",\n implementationStatus: 'Built and testable',\n adapterStatus: 'Mocked adapter',\n evidenceType: item.json.evidenceType,\n scenario: item.json.id,\n scenarioLabel: item.json.label,\n fixtureKind: item.json.kind,\n sourceType: \"Kundenlastenheft + interner Standard\",\n sourceInput: item.json.input,\n correlationId: item.json.input?.eventId ?? `INVALID-LST-${String(index + 1).padStart(2, '0')}`,\n idempotencyKey: item.json.input?.eventId ?? null,\n retry: { attempt: Number(item.json.input?.retryAttempt ?? 0), maxAttempts: 3, policy: 'transient_only' },\n adapter: { name: \"Anforderungs- und Standardmatrix\", mode: 'mock', available: item.json.kind !== 'dependency', writesPerformed: 0 },\n processing: [],\n audit: [{ state: 'INPUT_RECEIVED', detail: item.json.id, at: '2026-08-13T12:00:00.000Z' }]\n} }));"
},
"id": "652d3699-642d-4506-a32d-3373622d31e0",
"name": "Normalize Intake Envelope",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-800,
0
]
},
{
"parameters": {
"jsCode": "return items.map((item) => {\n const missing = [];\n if (!item.json.sourceInput || typeof item.json.sourceInput !== 'object') missing.push('sourceInput');\n if (!item.json.sourceInput?.eventId) missing.push('eventId');\n return { json: { ...item.json, validation: { valid: missing.length === 0, missing, schema: 'LST_INTAKE_V1' }, audit: [...item.json.audit, { state: 'CONTRACT_VALIDATED', detail: missing.length ? missing.join(',') : 'valid', at: '2026-08-13T12:00:10.000Z' }] } };\n});"
},
"id": "9b77b08c-9c77-421f-ad77-b3b29e77b545",
"name": "Validate Required Contract",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-580,
0
]
},
{
"parameters": {
"mode": "expression",
"numberOutputs": 2,
"output": "={{ $json.validation.valid ? 0 : 1 }}"
},
"id": "b4979208-b597-439b-a697-952eb79796c1",
"name": "Route Contract Status",
"type": "n8n-nodes-base.switch",
"typeVersion": 3.4,
"position": [
-360,
0
]
},
{
"parameters": {
"jsCode": "return items.map((item) => ({ json: { ...item.json, status: 'INVALID_INPUT', errorClass: 'business_validation', retryable: false, exceptions: [{ code: 'INVALID_CONTRACT', severity: 'stop', message: `Missing: ${item.json.validation.missing.join(', ')}` }], externalWritePerformed: false } }));"
},
"id": "0ee29e56-0fe2-4fe9-ace2-9b300de29cc3",
"name": "Classify Validation Error",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-100,
500
]
},
{
"parameters": {
"jsCode": "return items.map((item) => ({ json: { ...item.json, sourceInput: { redacted: true, sourceType: item.json.sourceType }, redaction: { applied: true, retained: ['correlationId', 'scenario', 'errorClass'] } } }));"
},
"id": "915d5f91-905d-4dfe-af5d-5c6b8e5d5ad8",
"name": "Redact Invalid Payload",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
140,
500
]
},
{
"parameters": {
"jsCode": "return items.map((item) => ({ json: { ...item.json, audit: [...item.json.audit, { state: 'MANUAL_DATA_REPAIR', detail: 'invalid_contract', at: '2026-08-13T12:00:20.000Z' }] } }));"
},
"id": "b032e797-af32-4604-a232-eabdb132e92a",
"name": "Audit Validation Failure",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
380,
500
]
},
{
"parameters": {},
"id": "08f6c9ac-09f6-4b3f-aaf6-ccd20bf6ce65",
"name": "Terminal - Manual Data Repair",
"type": "n8n-nodes-base.noOp",
"typeVersion": 1,
"position": [
620,
500
]
},
{
"parameters": {
"jsCode": "const claimed = new Set();\nreturn items.map((item) => {\n const key = item.json.idempotencyKey;\n const duplicate = item.json.fixtureKind === 'duplicate' || claimed.has(key);\n if (!duplicate) claimed.add(key);\n return { json: { ...item.json, idempotency: { key, claimed: !duplicate, duplicate, store: 'atomic_test_double' }, audit: [...item.json.audit, { state: duplicate ? 'DUPLICATE_DETECTED' : 'IDEMPOTENCY_CLAIMED', detail: key, at: '2026-08-13T12:00:30.000Z' }] } };\n});"
},
"id": "7d780e20-7e78-4fb3-af78-1146807812d9",
"name": "Claim Idempotency Key [MOCK]",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-100,
0
]
},
{
"parameters": {
"mode": "expression",
"numberOutputs": 2,
"output": "={{ $json.idempotency.duplicate ? 1 : 0 }}"
},
"id": "c7c7c64d-c6c7-44ba-a5c7-c327c4c7c194",
"name": "Route Replay Status",
"type": "n8n-nodes-base.switch",
"typeVersion": 3.4,
"position": [
140,
0
]
},
{
"parameters": {
"jsCode": "return items.map((item) => ({ json: { ...item.json, status: 'DUPLICATE_REPLAY', previousOutcome: { status: 'READY_FOR_REVIEW', reference: item.json.idempotencyKey }, externalWritePerformed: false } }));"
},
"id": "c741b936-c841-4ac9-a541-b610c641b7a3",
"name": "Load Previous Outcome [MOCK]",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
380,
280
]
},
{
"parameters": {
"jsCode": "return items.map((item) => ({ json: { ...item.json, audit: [...item.json.audit, { state: 'REPLAY_SAFE_RETURN', detail: 'no_second_processing', at: '2026-08-13T12:00:40.000Z' }] } }));"
},
"id": "13e1c475-12e1-42e2-a1e1-c14f10e1bfbc",
"name": "Audit Duplicate Delivery",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
620,
280
]
},
{
"parameters": {},
"id": "98ca57c2-99ca-4955-a6ca-549c97ca562f",
"name": "Terminal - Replay Safe",
"type": "n8n-nodes-base.noOp",
"typeVersion": 1,
"position": [
860,
280
]
},
{
"parameters": {
"jsCode": "return items.map((item) => ({ json: { ...item.json, contextLookup: { source: \"Anforderungs- und Standardmatrix\", status: item.json.adapter.available ? 'available' : 'unavailable', synthetic: true }, audit: [...item.json.audit, { state: 'CONTEXT_LOOKUP', detail: item.json.adapter.available ? 'ok' : '503_test_double', at: '2026-08-13T12:00:50.000Z' }] } }));"
},
"id": "1d507351-1c50-41be-ab50-702b1a506e98",
"name": "Load Anforderungs- und Standardmatrix [MOCK]",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
380,
0
]
},
{
"parameters": {
"mode": "expression",
"numberOutputs": 2,
"output": "={{ $json.adapter.available ? 0 : 1 }}"
},
"id": "a1918273-a091-40e0-a391-8599a2918406",
"name": "Route Dependency Health",
"type": "n8n-nodes-base.switch",
"typeVersion": 3.4,
"position": [
620,
0
]
},
{
"parameters": {
"jsCode": "return items.map((item) => ({ json: { ...item.json, status: 'DEPENDENCY_UNAVAILABLE', errorClass: 'external_transient', retryable: true, retry: { ...item.json.retry, attempt: item.json.retry.attempt || 1 }, externalWritePerformed: false } }));"
},
"id": "f48e84e6-f58e-4679-a28e-81c0f38e8353",
"name": "Classify Transient Dependency Failure",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
860,
500
]
},
{
"parameters": {
"mode": "expression",
"numberOutputs": 2,
"output": "={{ $json.retry.retryable === false || $json.retry.attempt >= $json.retry.maxAttempts ? 1 : 0 }}"
},
"id": "62cf3c18-63cf-4dab-a4cf-3f3e65cf40d1",
"name": "Route Retry Budget",
"type": "n8n-nodes-base.switch",
"typeVersion": 3.4,
"position": [
1100,
500
]
},
{
"parameters": {
"jsCode": "return items.map((item) => ({ json: { ...item.json, retry: { ...item.json.retry, nextAttempt: item.json.retry.attempt + 1, backoffSeconds: Math.min(60, 2 ** item.json.retry.attempt) + 1, jitterPolicy: 'deterministic_test_value' } } }));"
},
"id": "8d41f372-8e41-4505-ab41-f04c8c41f1df",
"name": "Plan Backoff + Jitter",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1340,
420
]
},
{
"parameters": {
"jsCode": "return items.map((item) => ({ json: { ...item.json, retryEnvelope: { correlationId: item.json.correlationId, idempotencyKey: item.json.idempotencyKey, nextAttempt: item.json.retry.nextAttempt, payloadRedacted: true }, audit: [...item.json.audit, { state: 'RETRY_SCHEDULED', detail: `attempt_${item.json.retry.nextAttempt}`, at: '2026-08-13T12:01:00.000Z' }] } }));"
},
"id": "dbddf4bf-dadd-432c-addd-f7e5dcddf652",
"name": "Persist Retry Envelope [MOCK]",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1580,
420
]
},
{
"parameters": {},
"id": "2c35d34d-2b35-41ba-aa35-d0272935ce94",
"name": "Terminal - Bounded Retry Queue",
"type": "n8n-nodes-base.noOp",
"typeVersion": 1,
"position": [
1820,
420
]
},
{
"parameters": {
"jsCode": "return items.map((item) => ({ json: { ...item.json, status: 'TERMINAL_DEPENDENCY_FAILURE', incident: { severity: 'high', correlationId: item.json.correlationId, errorClass: item.json.errorClass, payloadIncluded: false }, externalWritePerformed: false } }));"
},
"id": "3ef01274-3ff0-4407-a0f0-159a41f0172d",
"name": "Build Redacted Technical Incident",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1340,
620
]
},
{
"parameters": {},
"id": "6f083a8d-6e08-48fa-ad08-37676c0835d4",
"name": "Terminal - Operator Action",
"type": "n8n-nodes-base.noOp",
"typeVersion": 1,
"position": [
1580,
620
]
},
{
"parameters": {
"jsCode": "return items.map((item) => ({ json: { ...item.json, processing: [...(item.json.processing ?? []), { order: 1, step: \"Dokumente segmentieren und Seitenanker erhalten\", status: 'completed', sourceBound: true }], audit: [...item.json.audit, { state: 'DOMAIN_STAGE_1', detail: \"Dokumente segmentieren und Seitenanker erhalten\", at: '2026-08-13T12:00:00.000Z' }] } }));"
},
"id": "78bfaedc-79bf-406f-aabf-b2027bbfb395",
"name": "Dokumente segmentieren und Seitenanker erhalten",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
860,
0
]
},
{
"parameters": {
"jsCode": "return items.map((item) => ({ json: { ...item.json, processing: [...(item.json.processing ?? []), { order: 2, step: \"Anforderungen kanonisch normalisieren\", status: 'completed', sourceBound: true }], audit: [...item.json.audit, { state: 'DOMAIN_STAGE_2', detail: \"Anforderungen kanonisch normalisieren\", at: '2026-08-13T12:01:00.000Z' }] } }));"
},
"id": "9a27b191-9927-4ffe-a827-ae6b9727acd8",
"name": "Anforderungen kanonisch normalisieren",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1100,
0
]
},
{
"parameters": {
"jsCode": "return items.map((item) => ({ json: { ...item.json, processing: [...(item.json.processing ?? []), { order: 3, step: \"Interne Standards zuordnen [MOCK]\", status: 'completed', sourceBound: true }], audit: [...item.json.audit, { state: 'DOMAIN_STAGE_3', detail: \"Interne Standards zuordnen [MOCK]\", at: '2026-08-13T12:02:00.000Z' }] } }));"
},
"id": "b25d008a-b35d-421d-a05c-fd64b15cfef7",
"name": "Interne Standards zuordnen [MOCK]",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1340,
0
]
},
{
"parameters": {
"jsCode": "return items.map((item) => ({ json: { ...item.json, processing: [...(item.json.processing ?? []), { order: 4, step: \"Deltas, L\u00fccken und Widerspr\u00fcche klassifizieren\", status: 'completed', sourceBound: true }], audit: [...item.json.audit, { state: 'DOMAIN_STAGE_4', detail: \"Deltas, L\u00fccken und Widerspr\u00fcche klassifizieren\", at: '2026-08-13T12:03:00.000Z' }] } }));"
},
"id": "aaac4c57-a9ac-4ac4-acac-4f7dabac4dea",
"name": "Deltas, L\u00fccken und Widerspr\u00fcche klassifizieren",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1580,
0
]
},
{
"parameters": {
"jsCode": "return items.map((item) => {\n const input = item.json.sourceInput ?? {};\n const issues = [];\n const signals = [];\n const issue = (code, severity, message, evidence = []) => ({ code, severity, message, evidence });\n \nconst requirements = Array.isArray(input.requirements) ? input.requirements : [];\nif (requirements.some((row) => row.state === 'contradiction')) issues.push(issue('CONTRADICTORY_REQUIREMENT', 'stop', 'Widerspr\u00fcchliche Anforderungen d\u00fcrfen nicht still konsolidiert werden.', requirements.filter((row) => row.state === 'contradiction').map((row) => row.id)));\nif (requirements.some((row) => row.state === 'missing-measure')) issues.push(issue('ACCEPTANCE_CRITERION_MISSING', 'review', 'Messbares Abnahmekriterium fehlt.', requirements.filter((row) => row.state === 'missing-measure').map((row) => row.id)));\nsignals.push(...requirements.filter((row) => row.state === 'delta').map((row) => `delta:${row.id}`));\n const status = issues.some((entry) => entry.severity === 'stop')\n ? 'STOPPED_FOR_REVIEW'\n : issues.some((entry) => entry.severity === 'review')\n ? 'REVIEW_REQUIRED'\n : 'READY_FOR_REVIEW';\n return { json: {\n ...item.json,\n decision: { status, derivedBy: 'deterministic_guardrails', humanRequired: true },\n exceptions: issues,\n signals,\n audit: [...item.json.audit, { state: 'GUARDRAILS_EVALUATED', detail: status, at: '2026-08-13T12:05:00.000Z' }]\n } };\n});"
},
"id": "4e84fe24-4f84-4fb7-a085-014a518502dd",
"name": "Evaluate Deterministic Guardrails",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1820,
0
]
},
{
"parameters": {
"mode": "expression",
"numberOutputs": 3,
"output": "={{ ({ READY_FOR_REVIEW: 0, REVIEW_REQUIRED: 1, STOPPED_FOR_REVIEW: 2 })[$json.decision.status] ?? 2 }}"
},
"id": "953f8490-963f-4623-a73f-87b6983f8949",
"name": "Route Business Outcome",
"type": "n8n-nodes-base.switch",
"typeVersion": 3.4,
"position": [
2060,
0
]
},
{
"parameters": {
"jsCode": "return items.map((item) => ({ json: { ...item.json, route: 'ready', reviewMessage: 'Pr\u00fcfung vollst\u00e4ndig; fachliche Freigabe bleibt erforderlich.' } }));"
},
"id": "8fc008cd-8ec0-473a-adc0-05a78cc00414",
"name": "Prepare Review-Ready Candidate",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
2300,
-180
]
},
{
"parameters": {
"jsCode": "return items.map((item) => ({ json: { ...item.json, route: 'review', reviewMessage: 'Abweichung mit Quelle und empfohlener R\u00fcckfrage vorbereitet.' } }));"
},
"id": "037e8107-027e-4f74-a57e-842d047e829a",
"name": "Explain Review Exceptions",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
2300,
0
]
},
{
"parameters": {
"jsCode": "return items.map((item) => ({ json: { ...item.json, route: 'stopped', reviewMessage: 'Kritischer Stop: keine automatische Fortsetzung.' } }));"
},
"id": "ee453cba-ef45-4e4d-ac45-3994ed453b27",
"name": "Quarantine Critical Case",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
2300,
180
]
},
{
"parameters": {
"jsCode": "return items.map((item) => ({ json: { ...item.json, humanDecision: { state: 'pending', owner: \"Engineering\", allowed: ['approve', 'reject', 'request_information'], approvalVersion: `${item.json.correlationId}:v1` }, externalWritePerformed: false, audit: [...item.json.audit, { state: 'HUMAN_REVIEW_PENDING', detail: item.json.decision.status, at: '2026-08-13T12:06:00.000Z' }] } }));"
},
"id": "99501deb-9850-4c58-ab50-21119a501f7e",
"name": "Human Decision Required",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
2560,
0
]
},
{
"parameters": {
"jsCode": "return items.map((item) => ({ json: { ...item.json, preparedOutput: { target: \"Review-Matrix\", mode: 'draft_only', sourceEvent: item.json.correlationId, status: item.json.decision.status, exceptionCodes: item.json.exceptions.map((entry) => entry.code), approvalVersion: item.json.humanDecision.approvalVersion }, adapter: { ...item.json.adapter, writesPerformed: 0 } } }));"
},
"id": "5ef499a1-5df4-480e-acf4-967b5bf494e8",
"name": "Build Review-Matrix Draft",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
2800,
0
]
},
{
"parameters": {
"mode": "expression",
"numberOutputs": 3,
"output": "={{ ({ pending: 0, approved: 1, rejected: 2 })[$json.humanDecision.state] ?? 0 }}"
},
"id": "b4c6f0eb-b3c6-4f58-a6c6-f411b5c6f27e",
"name": "Route Human Decision",
"type": "n8n-nodes-base.switch",
"typeVersion": 3.4,
"position": [
3040,
0
]
},
{
"parameters": {
"jsCode": "return items.map((item) => ({ json: { ...item.json, terminalState: 'PENDING_HUMAN_REVIEW', queue: { owner: item.json.humanDecision.owner, synthetic: true }, externalWritePerformed: false } }));"
},
"id": "be976ccb-bd97-4b38-a097-6ff1bf976e5e",
"name": "Queue for Owner Review [MOCK]",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
3280,
-160
]
},
{
"parameters": {
"method": "POST",
"url": "https://example.invalid/test-adapter",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Idempotency-Key",
"value": "={{ $json.idempotencyKey }}"
}
]
},
"sendBody": true,
"contentType": "raw",
"rawContentType": "application/json",
"body": "={{ JSON.stringify($json.preparedOutput) }}",
"options": {
"timeout": 5000
}
},
"id": "09371fbc-0a37-414f-ab37-22e20c372475",
"name": "[DISABLED] Review-Matrix Test Adapter",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
3280,
0
],
"disabled": true,
"onError": "stopWorkflow",
"notes": "Intentionally disabled. Assign a test credential and test endpoint only in a future approved integration goal."
},
{
"parameters": {
"jsCode": "return items.map((item) => ({ json: { ...item.json, terminalState: 'REJECTED_BY_HUMAN', preparedOutput: null, externalWritePerformed: false } }));"
},
"id": "b08ea868-b18e-49fb-a28e-ab8eb38ead21",
"name": "Close Rejected Draft",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
3280,
160
]
},
{
"parameters": {
"jsCode": "return items.map((item) => ({ json: { ...item.json, externalWritePerformed: false, adapter: { ...item.json.adapter, writesPerformed: 0 }, audit: [...item.json.audit, { state: item.json.terminalState ?? 'ADAPTER_DRY_RUN', detail: 'zero_external_writes', at: '2026-08-13T12:07:00.000Z' }] } }));"
},
"id": "7e0fbbdc-7f0f-4d6f-a00f-bf02810fc095",
"name": "Append Final Audit Event [MOCK]",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
3540,
0
]
},
{
"parameters": {},
"id": "841ea1e5-831e-4052-a21e-9ebf811e9d2c",
"name": "Terminal - Inspectable Review Package",
"type": "n8n-nodes-base.noOp",
"typeVersion": 1,
"position": [
3800,
0
]
}
],
"connections": {
"Manual Test Start": {
"main": [
[
{
"node": "Load 6 Synthetic Test Cases",
"type": "main",
"index": 0
}
]
]
},
"Load 6 Synthetic Test Cases": {
"main": [
[
{
"node": "Normalize Intake Envelope",
"type": "main",
"index": 0
}
]
]
},
"Normalize Intake Envelope": {
"main": [
[
{
"node": "Validate Required Contract",
"type": "main",
"index": 0
}
]
]
},
"Validate Required Contract": {
"main": [
[
{
"node": "Route Contract Status",
"type": "main",
"index": 0
}
]
]
},
"Route Contract Status": {
"main": [
[
{
"node": "Claim Idempotency Key [MOCK]",
"type": "main",
"index": 0
}
],
[
{
"node": "Classify Validation Error",
"type": "main",
"index": 0
}
]
]
},
"Classify Validation Error": {
"main": [
[
{
"node": "Redact Invalid Payload",
"type": "main",
"index": 0
}
]
]
},
"Redact Invalid Payload": {
"main": [
[
{
"node": "Audit Validation Failure",
"type": "main",
"index": 0
}
]
]
},
"Audit Validation Failure": {
"main": [
[
{
"node": "Terminal - Manual Data Repair",
"type": "main",
"index": 0
}
]
]
},
"Claim Idempotency Key [MOCK]": {
"main": [
[
{
"node": "Route Replay Status",
"type": "main",
"index": 0
}
]
]
},
"Route Replay Status": {
"main": [
[
{
"node": "Load Anforderungs- und Standardmatrix [MOCK]",
"type": "main",
"index": 0
}
],
[
{
"node": "Load Previous Outcome [MOCK]",
"type": "main",
"index": 0
}
]
]
},
"Load Previous Outcome [MOCK]": {
"main": [
[
{
"node": "Audit Duplicate Delivery",
"type": "main",
"index": 0
}
]
]
},
"Audit Duplicate Delivery": {
"main": [
[
{
"node": "Terminal - Replay Safe",
"type": "main",
"index": 0
}
]
]
},
"Load Anforderungs- und Standardmatrix [MOCK]": {
"main": [
[
{
"node": "Route Dependency Health",
"type": "main",
"index": 0
}
]
]
},
"Route Dependency Health": {
"main": [
[
{
"node": "Dokumente segmentieren und Seitenanker erhalten",
"type": "main",
"index": 0
}
],
[
{
"node": "Classify Transient Dependency Failure",
"type": "main",
"index": 0
}
]
]
},
"Classify Transient Dependency Failure": {
"main": [
[
{
"node": "Route Retry Budget",
"type": "main",
"index": 0
}
]
]
},
"Route Retry Budget": {
"main": [
[
{
"node": "Plan Backoff + Jitter",
"type": "main",
"index": 0
}
],
[
{
"node": "Build Redacted Technical Incident",
"type": "main",
"index": 0
}
]
]
},
"Plan Backoff + Jitter": {
"main": [
[
{
"node": "Persist Retry Envelope [MOCK]",
"type": "main",
"index": 0
}
]
]
},
"Persist Retry Envelope [MOCK]": {
"main": [
[
{
"node": "Terminal - Bounded Retry Queue",
"type": "main",
"index": 0
}
]
]
},
"Build Redacted Technical Incident": {
"main": [
[
{
"node": "Terminal - Operator Action",
"type": "main",
"index": 0
}
]
]
},
"Dokumente segmentieren und Seitenanker erhalten": {
"main": [
[
{
"node": "Anforderungen kanonisch normalisieren",
"type": "main",
"index": 0
}
]
]
},
"Anforderungen kanonisch normalisieren": {
"main": [
[
{
"node": "Interne Standards zuordnen [MOCK]",
"type": "main",
"index": 0
}
]
]
},
"Interne Standards zuordnen [MOCK]": {
"main": [
[
{
"node": "Deltas, L\u00fccken und Widerspr\u00fcche klassifizieren",
"type": "main",
"index": 0
}
]
]
},
"Deltas, L\u00fccken und Widerspr\u00fcche klassifizieren": {
"main": [
[
{
"node": "Evaluate Deterministic Guardrails",
"type": "main",
"index": 0
}
]
]
},
"Evaluate Deterministic Guardrails": {
"main": [
[
{
"node": "Route Business Outcome",
"type": "main",
"index": 0
}
]
]
},
"Route Business Outcome": {
"main": [
[
{
"node": "Prepare Review-Ready Candidate",
"type": "main",
"index": 0
}
],
[
{
"node": "Explain Review Exceptions",
"type": "main",
"index": 0
}
],
[
{
"node": "Quarantine Critical Case",
"type": "main",
"index": 0
}
]
]
},
"Prepare Review-Ready Candidate": {
"main": [
[
{
"node": "Human Decision Required",
"type": "main",
"index": 0
}
]
]
},
"Explain Review Exceptions": {
"main": [
[
{
"node": "Human Decision Required",
"type": "main",
"index": 0
}
]
]
},
"Quarantine Critical Case": {
"main": [
[
{
"node": "Human Decision Required",
"type": "main",
"index": 0
}
]
]
},
"Human Decision Required": {
"main": [
[
{
"node": "Build Review-Matrix Draft",
"type": "main",
"index": 0
}
]
]
},
"Build Review-Matrix Draft": {
"main": [
[
{
"node": "Route Human Decision",
"type": "main",
"index": 0
}
]
]
},
"Route Human Decision": {
"main": [
[
{
"node": "Queue for Owner Review [MOCK]",
"type": "main",
"index": 0
}
],
[
{
"node": "[DISABLED] Review-Matrix Test Adapter",
"type": "main",
"index": 0
}
],
[
{
"node": "Close Rejected Draft",
"type": "main",
"index": 0
}
]
]
},
"Queue for Owner Review [MOCK]": {
"main": [
[
{
"node": "Append Final Audit Event [MOCK]",
"type": "main",
"index": 0
}
]
]
},
"[DISABLED] Review-Matrix Test Adapter": {
"main": [
[
{
"node": "Append Final Audit Event [MOCK]",
"type": "main",
"index": 0
}
]
]
},
"Close Rejected Draft": {
"main": [
[
{
"node": "Append Final Audit Event [MOCK]",
"type": "main",
"index": 0
}
]
]
},
"Append Final Audit Event [MOCK]": {
"main": [
[
{
"node": "Terminal - Inspectable Review Package",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {
"executionOrder": "v1",
"saveManualExecutions": true,
"saveExecutionProgress": true,
"executionTimeout": 300
},
"versionId": "79cc7595-78cc-4402-a7cc-726f76cc70dc",
"meta": {
"templateCredsSetupCompleted": false,
"syntheticOnly": true,
"portfolioProof": "inspectable-v2"
},
"tags": []
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
LAB 04 - Lastenheft Delta Check - Inspectable. Uses httpRequest. Event-driven trigger; 46 nodes.
Source: https://github.com/hugomenz/automation-portfolio/blob/main/n8n/workflows/lastenheft-delta-check.workflow.json — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
This workflow listens for an “Approved” label on a Trello card, reads the AI draft bookkeeping JSON from card comments, and posts the corresponding transaction to Xero. It then adds a Xero deep link b
02_LLM_Pipeline v1.0. Uses executeWorkflowTrigger, httpRequest, seaTable. Event-driven trigger; 65 nodes.
This workflow allows you to import any workflow from a file or another n8n instance and map the credentials easily. A multi-form setup guides you through the entire process At the beginning you have t
[n8n] Advanced URL Parsing and Shortening Workflow - Switchy.io Integration. Uses splitInBatches, stickyNote, httpRequest, html. Event-driven trigger; 56 nodes.
[](https://youtu.be/c7yCZhmMjtI)