{"id":"diff-gatekeeper","title":"PR / Dependency Breaking-Change & Exploit Gatekeeper","description":"Merge gate for a pull request: pass/warn/fail verdict, 0-100 risk score, the top findings with file:line and a fix, drop-in patches, GitHub Checks annotations and a SARIF 2.1.0 log. Accepts a raw unified diff, a GitHub PR, commit or compare URL, or per-file patches. Deterministic scanners (secrets, SQL and command injection, weak crypto, risky package.json changes) run beside a model review for bugs, race conditions and silent API breaks, and every model finding must point at a line inside the diff or it is marked ungrounded and never blocks. Large diffs are reviewed in up to 4 parts and anything beyond is reported as unreviewed. A review aid, not a replacement for tests or human review.","roi":"A CI-ready merge gate: stops a leaked secret, an injection bug or a silent API break before it ships, and hands the author the file, line and fix.","audience":"developer","channels":["x402","mcp","rapidapi","apify"],"endpoint":{"method":"POST","url":"https://agents.writerslogic.com/api/v1/gatekeep-diff","path":"/api/v1/gatekeep-diff","contentType":"application/json"},"price":{"amount":"0.50","currency":"USDC","network":"base","perCall":true,"failedCallsCharged":false},"inputSchema":{"type":"object","additionalProperties":false,"properties":{"gitDiff":{"type":"string","minLength":1,"maxLength":300000,"description":"Raw unified diff (git diff output). Provide exactly one of gitDiff, prUrl or files."},"prUrl":{"type":"string","minLength":20,"maxLength":300,"description":"Alternative to gitDiff: a public GitHub pull request, commit or compare URL (github.com/owner/repo/pull/123). Its .diff is downloaded; a diff over 300,000 characters is cut at a file boundary and the rest reported as unreviewed."},"files":{"type":"array","maxItems":300,"description":"Alternative to gitDiff: changed files with their patch hunks, as returned by GitHub's pull request files API.","items":{"type":"object","additionalProperties":false,"required":["path","patch"],"properties":{"path":{"type":"string","minLength":1,"maxLength":500},"patch":{"type":"string","maxLength":300000},"status":{"type":"string","enum":["added","modified","removed","renamed"]},"previousPath":{"type":"string","maxLength":500}}}},"packageJsonDiff":{"type":"string","maxLength":50000},"context":{"type":"string","maxLength":4000,"description":"What the PR is supposed to do."}}},"resultSchema":{"type":"object","properties":{"summary":{"type":"string"},"intent_alignment":{"type":"string","description":"Does the diff do what the context says, and anything it does beyond that."},"breakingChanges":{"type":"array","items":{"type":"object","additionalProperties":false,"required":["id","file","location","severity","description","affected_consumers","grounded","source"],"properties":{"id":{"type":"string","description":"BC-01, BC-02..."},"file":{"type":"string"},"location":{"type":"string"},"severity":{"type":"string","enum":["critical","high","medium","low"]},"description":{"type":"string"},"affected_consumers":{"type":"string"},"grounded":{"type":"boolean","description":"False when the file or line is not in the diff; ungrounded findings never block."},"source":{"type":"string","enum":["model","rule"]}}}},"securityFlaws":{"type":"array","items":{"type":"object","additionalProperties":false,"required":["id","file","line","category","severity","description","exploit_scenario","grounded","source"],"properties":{"id":{"type":"string","description":"SEC-01, SEC-02..."},"file":{"type":"string"},"line":{"type":"integer"},"category":{"type":"string","enum":["sql_injection","nosql_injection","command_injection","xss","ssrf","path_traversal","authz_bypass","secret_exposure","insecure_crypto","deserialization","supply_chain","other"]},"severity":{"type":"string","enum":["critical","high","medium","low"]},"description":{"type":"string"},"exploit_scenario":{"type":"string"},"grounded":{"type":"boolean","description":"False when the file or line is not in the diff; ungrounded findings never block."},"source":{"type":"string","enum":["model","rule"]}}}},"bugs":{"type":"array","items":{"type":"object","additionalProperties":false,"required":["id","file","line","category","severity","description","grounded","source"],"properties":{"id":{"type":"string","description":"BUG-01, BUG-02..."},"file":{"type":"string"},"line":{"type":"integer"},"category":{"type":"string","enum":["race_condition","state_mutation","error_handling","logic_error","resource_leak","null_handling","performance","other"]},"severity":{"type":"string","enum":["critical","high","medium","low"]},"description":{"type":"string"},"grounded":{"type":"boolean","description":"False when the file or line is not in the diff; ungrounded findings never block."},"source":{"type":"string","enum":["model","rule"]}}}},"dependency_risks":{"type":"array","items":{"type":"object","additionalProperties":false,"required":["package","risk","severity"],"properties":{"package":{"type":"string"},"risk":{"type":"string"},"severity":{"type":"string","enum":["critical","high","medium","low"]}}}},"riskScore":{"type":"integer","description":"0-100 overall merge risk."},"verdict":{"type":"string","enum":["fail","warn","pass","inconclusive"],"description":"fail: a secret or a grounded critical or high finding blocks the merge. inconclusive: part of the diff was not reviewed. warn: only non-blocking findings. pass: none."},"verdictReason":{"type":"string"},"status":{"type":"string","enum":["complete","partial"],"description":"partial when part of the diff was not reviewed or an over-long added line was pattern-scanned only in part; the result is still signed."},"nextStep":{"type":"string"},"topFindings":{"type":"array","items":{"type":"object","description":"Up to 5, most severe first: rank, id, kind (secret, security, bug, breaking_change, dependency), severity, file, line, title, fix, blocking."}},"annotations":{"type":"array","items":{"type":"object","description":"GitHub Checks API annotations: path, start_line, end_line, annotation_level (failure, warning, notice), title, message."}},"sarif":{"type":"object","description":"SARIF 2.1.0 log of every grounded finding at its file and line; uploads to GitHub code scanning as-is."},"mergeApproved":{"type":"boolean","description":"True when no secret and no grounded critical or high finding was found and the whole diff was reviewed."},"modelRiskScore":{"type":"integer","description":"The model's own 0-100 estimate; advisory. riskScore is computed from grounded findings (critical 40, high 20, medium 8, low 2, capped at 100) with scanner floors."},"blockers":{"type":"array","items":{"type":"string"}},"dependencyRisks":{"type":"object"},"secretsDetected":{"type":"array","items":{"type":"object"}},"suggestedPatches":{"type":"array","items":{"type":"object","additionalProperties":false,"required":["finding_id","file","original_code","corrected_code","explanation"],"properties":{"finding_id":{"type":"string"},"file":{"type":"string"},"original_code":{"type":"string","description":"The exact lines from the diff being replaced."},"corrected_code":{"type":"string","description":"Drop-in replacement code."},"explanation":{"type":"string"},"also_fixes":{"type":"array","items":{"type":"string"},"description":"Other finding ids this same patch resolves."}}}},"stats":{"type":"object"}},"required":["summary","intent_alignment","breakingChanges","securityFlaws","bugs","riskScore","verdict","verdictReason","status","nextStep","topFindings","annotations","sarif","mergeApproved","modelRiskScore","blockers","dependencyRisks","secretsDetected","suggestedPatches","stats"]},"outputSchema":{"type":"object","properties":{"data":{"type":"object","properties":{"summary":{"type":"string"},"intent_alignment":{"type":"string","description":"Does the diff do what the context says, and anything it does beyond that."},"breakingChanges":{"type":"array","items":{"type":"object","additionalProperties":false,"required":["id","file","location","severity","description","affected_consumers","grounded","source"],"properties":{"id":{"type":"string","description":"BC-01, BC-02..."},"file":{"type":"string"},"location":{"type":"string"},"severity":{"type":"string","enum":["critical","high","medium","low"]},"description":{"type":"string"},"affected_consumers":{"type":"string"},"grounded":{"type":"boolean","description":"False when the file or line is not in the diff; ungrounded findings never block."},"source":{"type":"string","enum":["model","rule"]}}}},"securityFlaws":{"type":"array","items":{"type":"object","additionalProperties":false,"required":["id","file","line","category","severity","description","exploit_scenario","grounded","source"],"properties":{"id":{"type":"string","description":"SEC-01, SEC-02..."},"file":{"type":"string"},"line":{"type":"integer"},"category":{"type":"string","enum":["sql_injection","nosql_injection","command_injection","xss","ssrf","path_traversal","authz_bypass","secret_exposure","insecure_crypto","deserialization","supply_chain","other"]},"severity":{"type":"string","enum":["critical","high","medium","low"]},"description":{"type":"string"},"exploit_scenario":{"type":"string"},"grounded":{"type":"boolean","description":"False when the file or line is not in the diff; ungrounded findings never block."},"source":{"type":"string","enum":["model","rule"]}}}},"bugs":{"type":"array","items":{"type":"object","additionalProperties":false,"required":["id","file","line","category","severity","description","grounded","source"],"properties":{"id":{"type":"string","description":"BUG-01, BUG-02..."},"file":{"type":"string"},"line":{"type":"integer"},"category":{"type":"string","enum":["race_condition","state_mutation","error_handling","logic_error","resource_leak","null_handling","performance","other"]},"severity":{"type":"string","enum":["critical","high","medium","low"]},"description":{"type":"string"},"grounded":{"type":"boolean","description":"False when the file or line is not in the diff; ungrounded findings never block."},"source":{"type":"string","enum":["model","rule"]}}}},"dependency_risks":{"type":"array","items":{"type":"object","additionalProperties":false,"required":["package","risk","severity"],"properties":{"package":{"type":"string"},"risk":{"type":"string"},"severity":{"type":"string","enum":["critical","high","medium","low"]}}}},"riskScore":{"type":"integer","description":"0-100 overall merge risk."},"verdict":{"type":"string","enum":["fail","warn","pass","inconclusive"],"description":"fail: a secret or a grounded critical or high finding blocks the merge. inconclusive: part of the diff was not reviewed. warn: only non-blocking findings. pass: none."},"verdictReason":{"type":"string"},"status":{"type":"string","enum":["complete","partial"],"description":"partial when part of the diff was not reviewed or an over-long added line was pattern-scanned only in part; the result is still signed."},"nextStep":{"type":"string"},"topFindings":{"type":"array","items":{"type":"object","description":"Up to 5, most severe first: rank, id, kind (secret, security, bug, breaking_change, dependency), severity, file, line, title, fix, blocking."}},"annotations":{"type":"array","items":{"type":"object","description":"GitHub Checks API annotations: path, start_line, end_line, annotation_level (failure, warning, notice), title, message."}},"sarif":{"type":"object","description":"SARIF 2.1.0 log of every grounded finding at its file and line; uploads to GitHub code scanning as-is."},"mergeApproved":{"type":"boolean","description":"True when no secret and no grounded critical or high finding was found and the whole diff was reviewed."},"modelRiskScore":{"type":"integer","description":"The model's own 0-100 estimate; advisory. riskScore is computed from grounded findings (critical 40, high 20, medium 8, low 2, capped at 100) with scanner floors."},"blockers":{"type":"array","items":{"type":"string"}},"dependencyRisks":{"type":"object"},"secretsDetected":{"type":"array","items":{"type":"object"}},"suggestedPatches":{"type":"array","items":{"type":"object","additionalProperties":false,"required":["finding_id","file","original_code","corrected_code","explanation"],"properties":{"finding_id":{"type":"string"},"file":{"type":"string"},"original_code":{"type":"string","description":"The exact lines from the diff being replaced."},"corrected_code":{"type":"string","description":"Drop-in replacement code."},"explanation":{"type":"string"},"also_fixes":{"type":"array","items":{"type":"string"},"description":"Other finding ids this same patch resolves."}}}},"stats":{"type":"object"}},"required":["summary","intent_alignment","breakingChanges","securityFlaws","bugs","riskScore","verdict","verdictReason","status","nextStep","topFindings","annotations","sarif","mergeApproved","modelRiskScore","blockers","dependencyRisks","secretsDetected","suggestedPatches","stats"]},"_provenance":{"type":"object","description":"C2PA-aligned manifest and W3C VC 2.0 (eddsa-jcs-2022) issued by the hub DID; verify at POST /api/v1/verify-provenance"}},"required":["data","_provenance"]},"example":{"gitDiff":"diff --git a/src/users.ts b/src/users.ts\n--- a/src/users.ts\n+++ b/src/users.ts\n@@ -10,3 +10,4 @@ export async function findUser(db, req) {\n-  return db.query('SELECT * FROM users WHERE id = $1', [req.params.id]);\n+  const id = req.params.id;\n+  return db.query(`SELECT * FROM users WHERE id = ${id}`);\n }\n","context":"Refactor user lookup for readability."},"openapiOperation":{"operationId":"diff_gatekeeper","summary":"PR / Dependency Breaking-Change & Exploit Gatekeeper","description":"Merge gate for a pull request: pass/warn/fail verdict, 0-100 risk score, the top findings with file:line and a fix, drop-in patches, GitHub Checks annotations and a SARIF 2.1.0 log. Accepts a raw unified diff, a GitHub PR, commit or compare URL, or per-file patches. Deterministic scanners (secrets, SQL and command injection, weak crypto, risky package.json changes) run beside a model review for bugs, race conditions and silent API breaks, and every model finding must point at a line inside the diff or it is marked ungrounded and never blocks. Large diffs are reviewed in up to 4 parts and anything beyond is reported as unreviewed. A review aid, not a replacement for tests or human review.\n\nPrice: 0.50 USDC on Base (x402).","x-x402-price-usdc":"0.50","x-x402-amount":"500000","x-payment-info":{"protocols":["x402"],"price":{"mode":"fixed","currency":"USD","amount":"0.50"}},"x-audience":"developer","x-sample-url":"https://agents.writerslogic.com/api/v1/samples/diff-gatekeeper","security":[{"x402":[]},{"apiKey":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"gitDiff":{"type":"string","minLength":1,"maxLength":300000,"description":"Raw unified diff (git diff output). Provide exactly one of gitDiff, prUrl or files."},"prUrl":{"type":"string","minLength":20,"maxLength":300,"description":"Alternative to gitDiff: a public GitHub pull request, commit or compare URL (github.com/owner/repo/pull/123). Its .diff is downloaded; a diff over 300,000 characters is cut at a file boundary and the rest reported as unreviewed."},"files":{"type":"array","maxItems":300,"description":"Alternative to gitDiff: changed files with their patch hunks, as returned by GitHub's pull request files API.","items":{"type":"object","additionalProperties":false,"required":["path","patch"],"properties":{"path":{"type":"string","minLength":1,"maxLength":500},"patch":{"type":"string","maxLength":300000},"status":{"type":"string","enum":["added","modified","removed","renamed"]},"previousPath":{"type":"string","maxLength":500}}}},"packageJsonDiff":{"type":"string","maxLength":50000},"context":{"type":"string","maxLength":4000,"description":"What the PR is supposed to do."}}},"example":{"gitDiff":"diff --git a/src/users.ts b/src/users.ts\n--- a/src/users.ts\n+++ b/src/users.ts\n@@ -10,3 +10,4 @@ export async function findUser(db, req) {\n-  return db.query('SELECT * FROM users WHERE id = $1', [req.params.id]);\n+  const id = req.params.id;\n+  return db.query(`SELECT * FROM users WHERE id = ${id}`);\n }\n","context":"Refactor user lookup for readability."}}}},"responses":{"200":{"description":"Paid result with provenance","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"summary":{"type":"string"},"intent_alignment":{"type":"string","description":"Does the diff do what the context says, and anything it does beyond that."},"breakingChanges":{"type":"array","items":{"type":"object","additionalProperties":false,"required":["id","file","location","severity","description","affected_consumers","grounded","source"],"properties":{"id":{"type":"string","description":"BC-01, BC-02..."},"file":{"type":"string"},"location":{"type":"string"},"severity":{"type":"string","enum":["critical","high","medium","low"]},"description":{"type":"string"},"affected_consumers":{"type":"string"},"grounded":{"type":"boolean","description":"False when the file or line is not in the diff; ungrounded findings never block."},"source":{"type":"string","enum":["model","rule"]}}}},"securityFlaws":{"type":"array","items":{"type":"object","additionalProperties":false,"required":["id","file","line","category","severity","description","exploit_scenario","grounded","source"],"properties":{"id":{"type":"string","description":"SEC-01, SEC-02..."},"file":{"type":"string"},"line":{"type":"integer"},"category":{"type":"string","enum":["sql_injection","nosql_injection","command_injection","xss","ssrf","path_traversal","authz_bypass","secret_exposure","insecure_crypto","deserialization","supply_chain","other"]},"severity":{"type":"string","enum":["critical","high","medium","low"]},"description":{"type":"string"},"exploit_scenario":{"type":"string"},"grounded":{"type":"boolean","description":"False when the file or line is not in the diff; ungrounded findings never block."},"source":{"type":"string","enum":["model","rule"]}}}},"bugs":{"type":"array","items":{"type":"object","additionalProperties":false,"required":["id","file","line","category","severity","description","grounded","source"],"properties":{"id":{"type":"string","description":"BUG-01, BUG-02..."},"file":{"type":"string"},"line":{"type":"integer"},"category":{"type":"string","enum":["race_condition","state_mutation","error_handling","logic_error","resource_leak","null_handling","performance","other"]},"severity":{"type":"string","enum":["critical","high","medium","low"]},"description":{"type":"string"},"grounded":{"type":"boolean","description":"False when the file or line is not in the diff; ungrounded findings never block."},"source":{"type":"string","enum":["model","rule"]}}}},"dependency_risks":{"type":"array","items":{"type":"object","additionalProperties":false,"required":["package","risk","severity"],"properties":{"package":{"type":"string"},"risk":{"type":"string"},"severity":{"type":"string","enum":["critical","high","medium","low"]}}}},"riskScore":{"type":"integer","description":"0-100 overall merge risk."},"verdict":{"type":"string","enum":["fail","warn","pass","inconclusive"],"description":"fail: a secret or a grounded critical or high finding blocks the merge. inconclusive: part of the diff was not reviewed. warn: only non-blocking findings. pass: none."},"verdictReason":{"type":"string"},"status":{"type":"string","enum":["complete","partial"],"description":"partial when part of the diff was not reviewed or an over-long added line was pattern-scanned only in part; the result is still signed."},"nextStep":{"type":"string"},"topFindings":{"type":"array","items":{"type":"object","description":"Up to 5, most severe first: rank, id, kind (secret, security, bug, breaking_change, dependency), severity, file, line, title, fix, blocking."}},"annotations":{"type":"array","items":{"type":"object","description":"GitHub Checks API annotations: path, start_line, end_line, annotation_level (failure, warning, notice), title, message."}},"sarif":{"type":"object","description":"SARIF 2.1.0 log of every grounded finding at its file and line; uploads to GitHub code scanning as-is."},"mergeApproved":{"type":"boolean","description":"True when no secret and no grounded critical or high finding was found and the whole diff was reviewed."},"modelRiskScore":{"type":"integer","description":"The model's own 0-100 estimate; advisory. riskScore is computed from grounded findings (critical 40, high 20, medium 8, low 2, capped at 100) with scanner floors."},"blockers":{"type":"array","items":{"type":"string"}},"dependencyRisks":{"type":"object"},"secretsDetected":{"type":"array","items":{"type":"object"}},"suggestedPatches":{"type":"array","items":{"type":"object","additionalProperties":false,"required":["finding_id","file","original_code","corrected_code","explanation"],"properties":{"finding_id":{"type":"string"},"file":{"type":"string"},"original_code":{"type":"string","description":"The exact lines from the diff being replaced."},"corrected_code":{"type":"string","description":"Drop-in replacement code."},"explanation":{"type":"string"},"also_fixes":{"type":"array","items":{"type":"string"},"description":"Other finding ids this same patch resolves."}}}},"stats":{"type":"object"}},"required":["summary","intent_alignment","breakingChanges","securityFlaws","bugs","riskScore","verdict","verdictReason","status","nextStep","topFindings","annotations","sarif","mergeApproved","modelRiskScore","blockers","dependencyRisks","secretsDetected","suggestedPatches","stats"]},"_provenance":{"type":"object","description":"C2PA-aligned manifest and W3C VC 2.0 (eddsa-jcs-2022) issued by the hub DID; verify at POST /api/v1/verify-provenance"}},"required":["data","_provenance"]}}}},"400":{"description":"Invalid request (no payment consumed)","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string"}}}}}},"401":{"description":"Invalid X-API-KEY","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string"}}}}}},"402":{"description":"Payment required or invalid","content":{"application/json":{"schema":{"type":"object","description":"x402 v2 PaymentRequired (also base64 in the PAYMENT-REQUIRED header)","properties":{"x402Version":{"type":"integer"},"error":{"type":"string"},"code":{"type":"string"},"resource":{"type":"object"},"accepts":{"type":"array","items":{"type":"object"}},"extensions":{"type":"object"}}}}}},"502":{"description":"Upstream failure; the payment is released or not settled","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string"}}}}}}}},"links":{"docs":"https://agents.writerslogic.com/docs/diff-gatekeeper/","docsJson":"https://agents.writerslogic.com/docs/diff-gatekeeper.json","sample":"https://agents.writerslogic.com/api/v1/samples/diff-gatekeeper","openapi":"https://agents.writerslogic.com/openapi.json","catalog":"https://agents.writerslogic.com/api/v1/catalog","verifyProvenance":"https://agents.writerslogic.com/api/v1/verify-provenance","index":"https://agents.writerslogic.com/docs/index.json"}}