{"data":{"mergeApproved":false,"results":{"diff-gatekeeper":{"verdict":"fail","verdictReason":"2 blocking findings: SQL statement built by interpolating values into a template literal (src/users.ts:11); Unquoted interpolation of req.params.id produces invalid SQL for any id that is not a plain number. (src/users.ts:11)","mergeApproved":false,"riskScore":65,"status":"complete","nextStep":"Do not merge. Fix SAST-01 at src/users.ts:11: Restores the parameterized query so the id value is passed as a bound parameter instead of being interpolated into the SQL string, preventing SQL injection. Then re-run on the updated diff.","topFindings":[{"rank":1,"id":"SAST-01","kind":"security","severity":"high","file":"src/users.ts","line":11,"title":"SQL statement built by interpolating values into a template literal","fix":"Restores the parameterized query so the id value is passed as a bound parameter instead of being interpolated into the SQL string, preventing SQL injection.","blocking":true},{"rank":2,"id":"BUG-01","kind":"bug","severity":"high","file":"src/users.ts","line":11,"title":"Unquoted interpolation of req.params.id produces invalid SQL for any id that is not a plain number.","fix":"Fix the defect described and add a regression test.","blocking":true},{"rank":3,"id":"BC-01","kind":"breaking_change","severity":"medium","file":"src/users.ts","line":11,"title":"The id was previously bound as a parameter, so any value was safely compared.","fix":"Restore the previous contract, or version the change and update consumers.","blocking":false}],"annotations":[{"path":"src/users.ts","start_line":11,"end_line":11,"annotation_level":"failure","title":"SAST-01 SQL statement built by interpolating values into a template literal","message":"SQL statement built by interpolating values into a template literal A value containing SQL syntax changes the statement, enabling data theft or modification. Fix: Restores the parameterized query so the id value is passed as a bound parameter instead of being interpolated into the SQL string, preventing SQL injection."},{"path":"src/users.ts","start_line":11,"end_line":11,"annotation_level":"failure","title":"BUG-01 Unquoted interpolation of req.params.id produces invalid SQL for any id that is not a plain number.","message":"Unquoted interpolation of req.params.id produces invalid SQL for any id that is not a plain number. UUID values such as 123e4567-... cause syntax errors, and values like 'abc' are parsed as column identifiers. Malformed input now throws database errors that can leak schema details through unhandled error responses. The parameterized form handled these inputs correctly. Fix: Fix the defect described and add a regression test."},{"path":"src/users.ts","start_line":11,"end_line":11,"annotation_level":"warning","title":"BC-01 The id was previously bound as a parameter, so any value was safely compared.","message":"The id was previously bound as a parameter, so any value was safely compared. It is now spliced unquoted into the SQL text. Lookups with UUID or other string ids now fail with a SQL syntax or unknown-column error instead of returning a row or null. The failure mode changes from an empty result to a thrown database error, typically a 500. Fix: Restore the previous contract, or version the change and update consumers."}],"sarif":{"$schema":"https://raw.githubusercontent.com/oasis-tcs/sarif-spec/main/sarif-2.1/schema/sarif-schema-2.1.0.json","version":"2.1.0","runs":[{"tool":{"driver":{"name":"writerslogic-diff-gatekeeper","version":"1.0.0","semanticVersion":"1.0.0","informationUri":"https://agents.writerslogic.com","rules":[{"id":"diff/security","name":"security","shortDescription":{"text":"Security flaw in added code"},"defaultConfiguration":{"level":"error"},"properties":{"tags":["security","code-review"],"security-severity":"8.0"}},{"id":"diff/bug","name":"bug","shortDescription":{"text":"Likely bug in added code"},"defaultConfiguration":{"level":"error"},"properties":{"tags":["security","code-review"],"security-severity":"8.0"}},{"id":"diff/breaking_change","name":"breaking_change","shortDescription":{"text":"Silent breaking change"},"defaultConfiguration":{"level":"warning"},"properties":{"tags":["security","code-review"],"security-severity":"5.5"}}]}},"results":[{"ruleId":"diff/security","ruleIndex":0,"level":"error","message":{"text":"SQL statement built by interpolating values into a template literal. SQL statement built by interpolating values into a template literal A value containing SQL syntax changes the statement, enabling data theft or modification. Fix: Restores the parameterized query so the id value is passed as a bound parameter instead of being interpolated into the SQL string, preventing SQL injection."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/users.ts","uriBaseId":"%SRCROOT%"},"region":{"startLine":11}}}],"partialFingerprints":{"primaryLocationLineHash/v1":"SAST-01"},"properties":{"severity":"high","source":"rule","blocking":true}},{"ruleId":"diff/bug","ruleIndex":1,"level":"error","message":{"text":"Unquoted interpolation of req.params.id produces invalid SQL for any id that is not a plain number.. Unquoted interpolation of req.params.id produces invalid SQL for any id that is not a plain number. UUID values such as 123e4567-... cause syntax errors, and values like 'abc' are parsed as column identifiers. Malformed input now throws database errors that can leak schema details through unhandled error responses. The parameterized form handled these inputs correctly. Fix: Fix the defect described and add a regression test."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/users.ts","uriBaseId":"%SRCROOT%"},"region":{"startLine":11}}}],"partialFingerprints":{"primaryLocationLineHash/v1":"BUG-01"},"properties":{"severity":"high","source":"model","blocking":true}},{"ruleId":"diff/breaking_change","ruleIndex":2,"level":"warning","message":{"text":"The id was previously bound as a parameter, so any value was safely compared.. The id was previously bound as a parameter, so any value was safely compared. It is now spliced unquoted into the SQL text. Lookups with UUID or other string ids now fail with a SQL syntax or unknown-column error instead of returning a row or null. The failure mode changes from an empty result to a thrown database error, typically a 500. Fix: Restore the previous contract, or version the change and update consumers."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/users.ts","uriBaseId":"%SRCROOT%"},"region":{"startLine":11}}}],"partialFingerprints":{"primaryLocationLineHash/v1":"BC-01"},"properties":{"severity":"medium","source":"model","blocking":false}}]}]},"modelRiskScore":92,"blockers":["high SAST-01 in src/users.ts","high BUG-01 in src/users.ts"],"summary":"The diff replaces a parameterized query in findUser with a template-string interpolation of req.params.id. This is a regression with no stated purpose. The SQL injection is already reported by the scanner (sql-template-interpolation, src/users.ts:11), so it is not repeated as a separate finding. The change also breaks behavior for non-numeric ids.","intent_alignment":"No context was provided, so the intent is unknown. The diff makes a functionally unnecessary change that removes parameter binding and the safety it gave. It looks like an unrelated or regressive edit rather than a fix.","breakingChanges":[{"id":"BC-01","file":"src/users.ts","location":"findUser, line 11","severity":"medium","description":"The id was previously bound as a parameter, so any value was safely compared. It is now spliced unquoted into the SQL text. Lookups with UUID or other string ids now fail with a SQL syntax or unknown-column error instead of returning a row or null. The failure mode changes from an empty result to a thrown database error, typically a 500.","affected_consumers":"Any caller or route using findUser with non-integer ids (UUIDs, slugs, or malformed input), and API clients that expect a 404 or empty result for unknown ids.","source":"model","grounded":true}],"securityFlaws":[{"id":"SAST-01","file":"src/users.ts","line":11,"category":"sql_injection","severity":"high","description":"SQL statement built by interpolating values into a template literal","exploit_scenario":"A value containing SQL syntax changes the statement, enabling data theft or modification.","source":"rule","grounded":true}],"bugs":[{"id":"BUG-01","file":"src/users.ts","line":11,"category":"logic_error","severity":"high","description":"Unquoted interpolation of req.params.id produces invalid SQL for any id that is not a plain number. UUID values such as 123e4567-... cause syntax errors, and values like 'abc' are parsed as column identifiers. Malformed input now throws database errors that can leak schema details through unhandled error responses. The parameterized form handled these inputs correctly.","source":"model","grounded":true}],"dependencyRisks":{"scanner":[],"model":[]},"secretsDetected":[],"suggestedPatches":[{"finding_id":"SAST-01","file":"src/users.ts","original_code":"  const id = req.params.id;\n  return db.query(`SELECT * FROM users WHERE id = ${id}`);","corrected_code":"  const id = req.params.id;\n  return db.query('SELECT * FROM users WHERE id = $1', [id]);","explanation":"Restores the parameterized query so the id value is passed as a bound parameter instead of being interpolated into the SQL string, preventing SQL injection.","also_fixes":["BUG-01"]}],"stats":{"filesChanged":1,"linesAdded":2,"diffTruncatedForModel":false,"modelChunks":1,"unreviewed":[],"sastPartialLines":0,"sastPartial":[],"ungroundedFindings":0}},"unicode-safety-gate":{"verdict":"pass","verdictReason":"no findings","riskScore":0,"status":"complete","nextStep":"No adversarial Unicode found in the scanned input.","topFindings":[],"source":{"kind":"diff"},"mode":"diff","summary":{"total":0,"returned":0,"truncated":false,"bySeverity":{"critical":0,"high":0,"medium":0,"low":0},"byRule":{"USC001":0,"USC002":0,"USC003":0,"USC004":0,"USC005":0,"USC006":0,"USC007":0,"USC008":0,"USC009":0,"USC010":0,"USC011":0,"USC012":0,"USC013":0,"USC014":0,"USC015":0,"USC016":0,"USC017":0,"USC018":0,"USC019":0},"blocking":0,"filesScanned":1,"filesSkipped":0},"findings":[],"sarif":{"$schema":"https://raw.githubusercontent.com/oasis-tcs/sarif-spec/main/sarif-2.1/schema/sarif-schema-2.1.0.json","version":"2.1.0","runs":[{"tool":{"driver":{"name":"unicode-safety-check","version":"3.0.0","semanticVersion":"3.0.0","informationUri":"https://github.com/dcondrey/unicode-safety-check","rules":[{"id":"USC001","name":"bidi-control","shortDescription":{"text":"Bidirectional control character"},"helpUri":"https://github.com/dcondrey/unicode-safety-check#what-it-detects","defaultConfiguration":{"level":"error"},"properties":{"tags":["security","unicode","supply-chain"],"security-severity":"9.5"}},{"id":"USC002","name":"invisible-format","shortDescription":{"text":"Invisible formatting character"},"helpUri":"https://github.com/dcondrey/unicode-safety-check#what-it-detects","defaultConfiguration":{"level":"error"},"properties":{"tags":["security","unicode","supply-chain"],"security-severity":"9.5"}},{"id":"USC003","name":"mixed-script","shortDescription":{"text":"Mixed-script identifier"},"helpUri":"https://github.com/dcondrey/unicode-safety-check#what-it-detects","defaultConfiguration":{"level":"error"},"properties":{"tags":["security","unicode","supply-chain"],"security-severity":"8.0"}},{"id":"USC004","name":"confusable-collision","shortDescription":{"text":"Confusable identifier collision"},"helpUri":"https://github.com/dcondrey/unicode-safety-check#what-it-detects","defaultConfiguration":{"level":"error"},"properties":{"tags":["security","unicode","supply-chain"],"security-severity":"8.0"}},{"id":"USC005","name":"suspicious-spacing","shortDescription":{"text":"Suspicious spacing character"},"helpUri":"https://github.com/dcondrey/unicode-safety-check#what-it-detects","defaultConfiguration":{"level":"warning"},"properties":{"tags":["security","unicode","supply-chain"],"security-severity":"5.5"}},{"id":"USC006","name":"normalization-drift","shortDescription":{"text":"Normalization-unstable text"},"helpUri":"https://github.com/dcondrey/unicode-safety-check#what-it-detects","defaultConfiguration":{"level":"warning"},"properties":{"tags":["security","unicode","supply-chain"],"security-severity":"5.5"}},{"id":"USC007","name":"control-character","shortDescription":{"text":"Disallowed control character"},"helpUri":"https://github.com/dcondrey/unicode-safety-check#what-it-detects","defaultConfiguration":{"level":"error"},"properties":{"tags":["security","unicode","supply-chain"],"security-severity":"9.5"}},{"id":"USC008","name":"invalid-encoding","shortDescription":{"text":"Invalid UTF-8 encoding"},"helpUri":"https://github.com/dcondrey/unicode-safety-check#what-it-detects","defaultConfiguration":{"level":"error"},"properties":{"tags":["security","unicode","supply-chain"],"security-severity":"9.5"}},{"id":"USC009","name":"misplaced-bom","shortDescription":{"text":"Misplaced byte-order mark"},"helpUri":"https://github.com/dcondrey/unicode-safety-check#what-it-detects","defaultConfiguration":{"level":"error"},"properties":{"tags":["security","unicode","supply-chain"],"security-severity":"9.5"}},{"id":"USC010","name":"variation-selector","shortDescription":{"text":"Suspicious variation selector sequence"},"helpUri":"https://github.com/dcondrey/unicode-safety-check#what-it-detects","defaultConfiguration":{"level":"error"},"properties":{"tags":["security","unicode","supply-chain"],"security-severity":"9.5"}},{"id":"USC011","name":"private-use","shortDescription":{"text":"Private Use Area code point"},"helpUri":"https://github.com/dcondrey/unicode-safety-check#what-it-detects","defaultConfiguration":{"level":"error"},"properties":{"tags":["security","unicode","supply-chain"],"security-severity":"9.5"}},{"id":"USC012","name":"tag-character","shortDescription":{"text":"Tag character (payload encoding)"},"helpUri":"https://github.com/dcondrey/unicode-safety-check#what-it-detects","defaultConfiguration":{"level":"error"},"properties":{"tags":["security","unicode","supply-chain"],"security-severity":"9.5"}},{"id":"USC013","name":"deprecated-format","shortDescription":{"text":"Deprecated format character"},"helpUri":"https://github.com/dcondrey/unicode-safety-check#what-it-detects","defaultConfiguration":{"level":"error"},"properties":{"tags":["security","unicode","supply-chain"],"security-severity":"9.5"}},{"id":"USC014","name":"annotation-anchor","shortDescription":{"text":"Interlinear annotation anchor"},"helpUri":"https://github.com/dcondrey/unicode-safety-check#what-it-detects","defaultConfiguration":{"level":"error"},"properties":{"tags":["security","unicode","supply-chain"],"security-severity":"9.5"}},{"id":"USC015","name":"bidi-pairing","shortDescription":{"text":"Unbalanced bidi control pairing"},"helpUri":"https://github.com/dcondrey/unicode-safety-check#what-it-detects","defaultConfiguration":{"level":"error"},"properties":{"tags":["security","unicode","supply-chain"],"security-severity":"9.5"}},{"id":"USC016","name":"default-ignorable","shortDescription":{"text":"Default-ignorable code point"},"helpUri":"https://github.com/dcondrey/unicode-safety-check#what-it-detects","defaultConfiguration":{"level":"error"},"properties":{"tags":["security","unicode","supply-chain"],"security-severity":"8.0"}},{"id":"USC017","name":"homoglyph","shortDescription":{"text":"Homoglyph character"},"helpUri":"https://github.com/dcondrey/unicode-safety-check#what-it-detects","defaultConfiguration":{"level":"error"},"properties":{"tags":["security","unicode","supply-chain"],"security-severity":"8.0"}},{"id":"USC018","name":"mixed-line-endings","shortDescription":{"text":"Mixed line endings"},"helpUri":"https://github.com/dcondrey/unicode-safety-check#what-it-detects","defaultConfiguration":{"level":"warning"},"properties":{"tags":["security","unicode","supply-chain"],"security-severity":"5.5"}},{"id":"USC019","name":"non-ascii-identifier","shortDescription":{"text":"Non-ASCII in identifier (policy violation)"},"helpUri":"https://github.com/dcondrey/unicode-safety-check#what-it-detects","defaultConfiguration":{"level":"warning"},"properties":{"tags":["security","unicode","supply-chain"],"security-severity":"5.5"}}]}},"columnKind":"unicodeCodePoints","results":[]}]},"skipped":[],"warnings":[],"explanations":[],"llm":"skipped","deterministic":{"engine":"unicode-safety-check 3.0.0, rules USC001-USC019 (github.com/dcondrey/unicode-safety-check, rust/)","findings":0,"verdictBasis":"block: any critical finding, or a high finding in a code/config file; warn: any other finding (including high findings in .md/.txt/.html/.css/.xml/.csv files); pass: no findings","notes":["USC008 (invalid UTF-8) is detected as an unpaired surrogate only: request bodies are decoded before scanning","diff mode scans added lines only; context lines feed the tokenizer state; USC018 (mixed line endings) is not evaluated"]}}},"deterministic":false},"_provenance":{"version":"writerslogic-provenance/1","issuer":"did:web:agents.writerslogic.com","verify":{"endpoint":"POST /api/v1/verify-provenance","did":"did:web:agents.writerslogic.com"},"manifest":{"format":"application/json","instance_id":"xmp:iid:327843e7-b0c9-4632-bd11-acd86cb6c663","claim_generator_info":[{"name":"WritersLogic x402 Agent Hub","version":"2.0.0"}],"title":"Pre-merge Review Pack","assertions":[{"label":"c2pa.actions.v2","data":{"actions":[{"action":"c2pa.created","when":"2026-11-06T17:56:53.694Z","softwareAgent":{"name":"writerslogic-agent-hub/pre-merge-review","version":"2.0.0"},"digitalSourceType":"http://cv.iptc.org/newscodes/digitalsourcetype/trainedAlgorithmicMedia","parameters":{"endpoint":"POST /api/v1/bundles/pre-merge-review","inputDigest":{"alg":"sha256","hash":"d57fe008fff0758aea0c2025fc48607efab9140dd986a01bef311d4c57bc5fee","canonicalization":"JCS"}}}]}},{"label":"c2pa.hash.data","data":{"alg":"sha256","hash":"29e1d314846f88424aa7809b138c4f491e2c9b6257876e6003694a6769c38920","name":"jcs-canonical-json(data)"}}]},"credential":{"@context":["https://www.w3.org/ns/credentials/v2"],"id":"urn:uuid:ceab7e83-1015-419e-977e-e2b61c297eaa","type":["VerifiableCredential","AgentOutputCredential"],"issuer":"did:web:agents.writerslogic.com","validFrom":"2026-11-06T17:56:53.694Z","credentialSubject":{"id":"urn:sha256:29e1d314846f88424aa7809b138c4f491e2c9b6257876e6003694a6769c38920","agent":"pre-merge-review","endpoint":"POST /api/v1/bundles/pre-merge-review","outputDigest":{"alg":"sha256","value":"29e1d314846f88424aa7809b138c4f491e2c9b6257876e6003694a6769c38920","canonicalization":"JCS"},"inputDigest":{"alg":"sha256","value":"d57fe008fff0758aea0c2025fc48607efab9140dd986a01bef311d4c57bc5fee","canonicalization":"JCS"},"manifestDigest":{"alg":"sha256","value":"c5b3d03699bb441163b72308ddf641450d61f5efd182303d715636e20cb91dce","canonicalization":"JCS"},"ingredients":[],"payment":{"scheme":"api-key","network":"eip155:8453","payer":"sample"}},"proof":{"type":"DataIntegrityProof","cryptosuite":"eddsa-jcs-2022","created":"2026-11-06T17:56:53.694Z","verificationMethod":"did:web:agents.writerslogic.com#key-1","proofPurpose":"assertionMethod","proofValue":"z2DdeBsAuFzkYRKSM3snTCE47z91nZYgfPSTxAZ2PGp11EjKtijwJ5PTfp2j783HvoGbfjsTMHZ7mYVizaEWKqm2c"}},"ethSignature":{"type":"EIP-191","signer":"did:pkh:eip155:8453:0x3DBd42560cA7a7E448A2c7DfC9E785526189411f","address":"0x3DBd42560cA7a7E448A2c7DfC9E785526189411f","message":"writerslogic-provenance:c48814f2e79afc17d58e54265ac0cb7a3dd413b46ad612b5651e174d2a6536cf","signature":"0xc354bffeb50446d53da9e52b6a560293a441049102cf7855e86bb45253ea94464a9a6c28437de1e50c057f230de9d5206b83b07deab7e56ee579967c4818f9101b"}}}