{"version": "2.1.0", "$schema": "https://json.schemastore.org/sarif-2.1.0.json", "runs": [{"tool": {"driver": {"name": "Repobility", "informationUri": "https://repobility.com", "rules": [{"id": "scanner-ae991169c19f3ea5", "name": "Possibly dead Python function: load_existing_out", "shortDescription": {"text": "Possibly dead Python function: load_existing_out"}, "fullDescription": {"text": "No callers detected by AST scan in this repo. Could be exported for external callers or a framework handler."}, "properties": {"scanner": "scanner-primary", "layer": "software", "severity": "low", "confidence": 1.0}}, {"id": "scanner-785f76901b86f862", "name": "Possibly dead Python function: get_html_seq1", "shortDescription": {"text": "Possibly dead Python function: get_html_seq1"}, "fullDescription": {"text": "No callers detected by AST scan in this repo. Could be exported for external callers or a framework handler."}, "properties": {"scanner": "scanner-primary", "layer": "software", "severity": "low", "confidence": 1.0}}, {"id": "scanner-0e6edfe6ad426f3b", "name": "Possibly dead Python function: get_html_seq3", "shortDescription": {"text": "Possibly dead Python function: get_html_seq3"}, "fullDescription": {"text": "No callers detected by AST scan in this repo. Could be exported for external callers or a framework handler."}, "properties": {"scanner": "scanner-primary", "layer": "software", "severity": "low", "confidence": 1.0}}, {"id": "scanner-4666cb8c30c2af00", "name": "Possibly dead Python function: get_html_seq4", "shortDescription": {"text": "Possibly dead Python function: get_html_seq4"}, "fullDescription": {"text": "No callers detected by AST scan in this repo. Could be exported for external callers or a framework handler."}, "properties": {"scanner": "scanner-primary", "layer": "software", "severity": "low", "confidence": 1.0}}, {"id": "scanner-a3852530e8c290d3", "name": "Possibly dead Python function: process_lead", "shortDescription": {"text": "Possibly dead Python function: process_lead"}, "fullDescription": {"text": "No callers detected by AST scan in this repo. Could be exported for external callers or a framework handler."}, "properties": {"scanner": "scanner-primary", "layer": "software", "severity": "low", "confidence": 1.0}}, {"id": "scanner-9270480434607bc2", "name": "Possibly dead Python function: ip_of", "shortDescription": {"text": "Possibly dead Python function: ip_of"}, "fullDescription": {"text": "No callers detected by AST scan in this repo. Could be exported for external callers or a framework handler."}, "properties": {"scanner": "scanner-primary", "layer": "software", "severity": "low", "confidence": 1.0}}, {"id": "scanner-f472ef58ba91c1eb", "name": "Possibly dead Python function: template_seq2_relance", "shortDescription": {"text": "Possibly dead Python function: template_seq2_relance"}, "fullDescription": {"text": "No callers detected by AST scan in this repo. Could be exported for external callers or a framework handler."}, "properties": {"scanner": "scanner-primary", "layer": "software", "severity": "low", "confidence": 1.0}}, {"id": "scanner-26103f7cf0c40e0e", "name": "Possibly dead Python function: template_transac_signup", "shortDescription": {"text": "Possibly dead Python function: template_transac_signup"}, "fullDescription": {"text": "No callers detected by AST scan in this repo. Could be exported for external callers or a framework handler."}, "properties": {"scanner": "scanner-primary", "layer": "software", "severity": "low", "confidence": 1.0}}, {"id": "scanner-e9548ef404227dac", "name": "Possibly dead Python function: template_syndics_prospection", "shortDescription": {"text": "Possibly dead Python function: template_syndics_prospection"}, "fullDescription": {"text": "No callers detected by AST scan in this repo. Could be exported for external callers or a framework handler."}, "properties": {"scanner": "scanner-primary", "layer": "software", "severity": "low", "confidence": 1.0}}, {"id": "scanner-bf3e6809daf41aa2", "name": "Possibly dead Python function: template_syndics_hot_relance", "shortDescription": {"text": "Possibly dead Python function: template_syndics_hot_relance"}, "fullDescription": {"text": "No callers detected by AST scan in this repo. Could be exported for external callers or a framework handler."}, "properties": {"scanner": "scanner-primary", "layer": "software", "severity": "low", "confidence": 1.0}}, {"id": "scanner-64ab9e7ff0b94d07", "name": "Possibly dead Python function: template_artisans_seq1_sms", "shortDescription": {"text": "Possibly dead Python function: template_artisans_seq1_sms"}, "fullDescription": {"text": "No callers detected by AST scan in this repo. Could be exported for external callers or a framework handler."}, "properties": {"scanner": "scanner-primary", "layer": "software", "severity": "low", "confidence": 1.0}}, {"id": "scanner-380d39cab122cd10", "name": "Possibly dead Python function: template_artisans_relance_sms", "shortDescription": {"text": "Possibly dead Python function: template_artisans_relance_sms"}, "fullDescription": {"text": "No callers detected by AST scan in this repo. Could be exported for external callers or a framework handler."}, "properties": {"scanner": "scanner-primary", "layer": "software", "severity": "low", "confidence": 1.0}}, {"id": "scanner-e478fe9d6e2de108", "name": "Possibly dead Python function: handle_data", "shortDescription": {"text": "Possibly dead Python function: handle_data"}, "fullDescription": {"text": "No callers detected by AST scan in this repo. Could be exported for external callers or a framework handler."}, "properties": {"scanner": "scanner-primary", "layer": "software", "severity": "low", "confidence": 1.0}}, {"id": "scanner-da612c4f34a08f02", "name": "Possibly dead Python function: extract_between", "shortDescription": {"text": "Possibly dead Python function: extract_between"}, "fullDescription": {"text": "No callers detected by AST scan in this repo. Could be exported for external callers or a framework handler."}, "properties": {"scanner": "scanner-primary", "layer": "software", "severity": "low", "confidence": 1.0}}, {"id": "scanner-9c618cc4428c8d41", "name": "Possibly dead Python function: log_message", "shortDescription": {"text": "Possibly dead Python function: log_message"}, "fullDescription": {"text": "No callers detected by AST scan in this repo. Could be exported for external callers or a framework handler."}, "properties": {"scanner": "scanner-primary", "layer": "software", "severity": "low", "confidence": 1.0}}, {"id": "scanner-882f7c05f5a77016", "name": "Possibly dead Python function: do_POST", "shortDescription": {"text": "Possibly dead Python function: do_POST"}, "fullDescription": {"text": "No callers detected by AST scan in this repo. Could be exported for external callers or a framework handler."}, "properties": {"scanner": "scanner-primary", "layer": "software", "severity": "low", "confidence": 1.0}}, {"id": "scanner-d94902fc903fd94f", "name": "Possibly dead Python function: replacer", "shortDescription": {"text": "Possibly dead Python function: replacer"}, "fullDescription": {"text": "No callers detected by AST scan in this repo. Could be exported for external callers or a framework handler."}, "properties": {"scanner": "scanner-primary", "layer": "software", "severity": "low", "confidence": 1.0}}, {"id": "scanner-ff16728185a3da9e", "name": "Possibly dead Python function: s1", "shortDescription": {"text": "Possibly dead Python function: s1"}, "fullDescription": {"text": "No callers detected by AST scan in this repo. Could be exported for external callers or a framework handler."}, "properties": {"scanner": "scanner-primary", "layer": "software", "severity": "low", "confidence": 1.0}}, {"id": "scanner-bbac12bf6e176442", "name": "Possibly dead Python function: s2", "shortDescription": {"text": "Possibly dead Python function: s2"}, "fullDescription": {"text": "No callers detected by AST scan in this repo. Could be exported for external callers or a framework handler."}, "properties": {"scanner": "scanner-primary", "layer": "software", "severity": "low", "confidence": 1.0}}, {"id": "scanner-75eba4e3bbeb2963", "name": "Possibly dead Python function: s3", "shortDescription": {"text": "Possibly dead Python function: s3"}, "fullDescription": {"text": "No callers detected by AST scan in this repo. Could be exported for external callers or a framework handler."}, "properties": {"scanner": "scanner-primary", "layer": "software", "severity": "low", "confidence": 1.0}}, {"id": "scanner-8b173ed56b4a45d3", "name": "Possibly dead Python function: s4", "shortDescription": {"text": "Possibly dead Python function: s4"}, "fullDescription": {"text": "No callers detected by AST scan in this repo. Could be exported for external callers or a framework handler."}, "properties": {"scanner": "scanner-primary", "layer": "software", "severity": "low", "confidence": 1.0}}, {"id": "scanner-96a60f3f47962265", "name": "Possibly dead Python function: s5", "shortDescription": {"text": "Possibly dead Python function: s5"}, "fullDescription": {"text": "No callers detected by AST scan in this repo. Could be exported for external callers or a framework handler."}, "properties": {"scanner": "scanner-primary", "layer": "software", "severity": "low", "confidence": 1.0}}, {"id": "scanner-a4fa394795377af5", "name": "Possibly dead Python function: s6", "shortDescription": {"text": "Possibly dead Python function: s6"}, "fullDescription": {"text": "No callers detected by AST scan in this repo. Could be exported for external callers or a framework handler."}, "properties": {"scanner": "scanner-primary", "layer": "software", "severity": "low", "confidence": 1.0}}, {"id": "scanner-e60e143915b2f02e", "name": "Possibly dead Python function: s7", "shortDescription": {"text": "Possibly dead Python function: s7"}, "fullDescription": {"text": "No callers detected by AST scan in this repo. Could be exported for external callers or a framework handler."}, "properties": {"scanner": "scanner-primary", "layer": "software", "severity": "low", "confidence": 1.0}}, {"id": "scanner-64b7992e1c48cb03", "name": "Possibly dead Python function: s8", "shortDescription": {"text": "Possibly dead Python function: s8"}, "fullDescription": {"text": "No callers detected by AST scan in this repo. Could be exported for external callers or a framework handler."}, "properties": {"scanner": "scanner-primary", "layer": "software", "severity": "low", "confidence": 1.0}}, {"id": "scanner-34b90404f67b0770", "name": "Possibly dead Python function: s1", "shortDescription": {"text": "Possibly dead Python function: s1"}, "fullDescription": {"text": "No callers detected by AST scan in this repo. Could be exported for external callers or a framework handler."}, "properties": {"scanner": "scanner-primary", "layer": "software", "severity": "low", "confidence": 1.0}}, {"id": "scanner-c34427623a2fb6bf", "name": "Possibly dead Python function: s2", "shortDescription": {"text": "Possibly dead Python function: s2"}, "fullDescription": {"text": "No callers detected by AST scan in this repo. Could be exported for external callers or a framework handler."}, "properties": {"scanner": "scanner-primary", "layer": "software", "severity": "low", "confidence": 1.0}}, {"id": "scanner-92ea45fe5159a334", "name": "Possibly dead Python function: s3", "shortDescription": {"text": "Possibly dead Python function: s3"}, "fullDescription": {"text": "No callers detected by AST scan in this repo. Could be exported for external callers or a framework handler."}, "properties": {"scanner": "scanner-primary", "layer": "software", "severity": "low", "confidence": 1.0}}, {"id": "scanner-1f0547b742f5d1a7", "name": "Possibly dead Python function: s4", "shortDescription": {"text": "Possibly dead Python function: s4"}, "fullDescription": {"text": "No callers detected by AST scan in this repo. Could be exported for external callers or a framework handler."}, "properties": {"scanner": "scanner-primary", "layer": "software", "severity": "low", "confidence": 1.0}}, {"id": "scanner-8d3a2262a3980c62", "name": "Possibly dead Python function: s5", "shortDescription": {"text": "Possibly dead Python function: s5"}, "fullDescription": {"text": "No callers detected by AST scan in this repo. Could be exported for external callers or a framework handler."}, "properties": {"scanner": "scanner-primary", "layer": "software", "severity": "low", "confidence": 1.0}}, {"id": "scanner-63d708313d422248", "name": "Icon-only button without accessible name \u2014 chat-widget.js:296", "shortDescription": {"text": "Icon-only button without accessible name \u2014 chat-widget.js:296"}, "fullDescription": {"text": "A `<button>` whose only child is a single glyph or symbol needs `title=` or `aria-label=` so screen readers (and tooltips on hover) work.\n\nWhy: P3 in CHECKLIST.md \u2014 icon-only buttons skipped a title.\nRule id: fq.button.no-label"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-68324f980e71e148", "name": "Stray `console.log` in TS/JS \u2014 server.js:178", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 server.js:178"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-5eaab42a3ded5539", "name": "Stray `console.log` in TS/JS \u2014 app/supabase/functions/notify-artisans/index.ts:240", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 app/supabase/functions/notify-artisans/index.ts:240"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-bb6e1482fe62aa2b", "name": "Stray `console.log` in TS/JS \u2014 app/supabase/functions/stripe-webhook/index.ts:209", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 app/supabase/functions/stripe-webhook/index.ts:209"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-910ecfec3c62632a", "name": "Stray `console.log` in TS/JS \u2014 app/supabase/functions/notify-client/index.ts:177", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 app/supabase/functions/notify-client/index.ts:177"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-d437beb001ab6eb8", "name": "Stray `console.log` in TS/JS \u2014 supabase/functions/stripe-webhook/index.ts:209", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 supabase/functions/stripe-webhook/index.ts:209"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-995f6a0aea20b428", "name": "Privileged port 9 in use", "shortDescription": {"text": "Privileged port 9 in use"}, "fullDescription": {"text": "Port 9 is privileged (<1024). Make sure the service runs with the right caps or front it with a non-privileged port via a load balancer."}, "properties": {"scanner": "scanner-primary", "layer": "network", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-62c8d97bd93503b8", "name": "Privileged port 30 in use", "shortDescription": {"text": "Privileged port 30 in use"}, "fullDescription": {"text": "Port 30 is privileged (<1024). Make sure the service runs with the right caps or front it with a non-privileged port via a load balancer."}, "properties": {"scanner": "scanner-primary", "layer": "network", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-a95ade1bdd1987a6", "name": "Privileged port 15 in use", "shortDescription": {"text": "Privileged port 15 in use"}, "fullDescription": {"text": "Port 15 is privileged (<1024). Make sure the service runs with the right caps or front it with a non-privileged port via a load balancer."}, "properties": {"scanner": "scanner-primary", "layer": "network", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-9710c8d059e53154", "name": "No frontend routes/components detected", "shortDescription": {"text": "No frontend routes/components detected"}, "fullDescription": {"text": "No React/Vue/Next routes were found. This is fine for backend-only repos."}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-a96fa63778c42f59", "name": "Insecure pattern 'direct_innerhtml_assignment' in ma-demande.html:263", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in ma-demande.html:263"}, "fullDescription": {"text": "Found a known-risky pattern (direct_innerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-5cf6fe6bd8fdc4f1", "name": "Insecure pattern 'direct_innerhtml_assignment' in simulateur-aides.html:780", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in simulateur-aides.html:780"}, "fullDescription": {"text": "Found a known-risky pattern (direct_innerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-7091cc616d691d69", "name": "Insecure pattern 'direct_innerhtml_assignment' in artisan_old_pre_v2.html:1670", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in artisan_old_pre_v2.html:1670"}, "fullDescription": {"text": "Found a known-risky pattern (direct_innerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-8f52e8986b0a0826", "name": "Insecure pattern 'direct_innerhtml_assignment' in chat-widget.js:287", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in chat-widget.js:287"}, "fullDescription": {"text": "Found a known-risky pattern (direct_innerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-86d189487e0d4362", "name": "Insecure pattern 'direct_innerhtml_assignment' in estimateur.html:367", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in estimateur.html:367"}, "fullDescription": {"text": "Found a known-risky pattern (direct_innerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-074f6907445f2415", "name": "Insecure pattern 'cors_wildcard' in server.js:31", "shortDescription": {"text": "Insecure pattern 'cors_wildcard' in server.js:31"}, "fullDescription": {"text": "Found a known-risky pattern (cors_wildcard). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-299df472a5e519ee", "name": "Insecure pattern 'tls_verify_false' in email-agent/enrich_batch_20260420.py:218", "shortDescription": {"text": "Insecure pattern 'tls_verify_false' in email-agent/enrich_batch_20260420.py:218"}, "fullDescription": {"text": "Found a known-risky pattern (tls_verify_false). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-36544ce12490cea0", "name": "Insecure pattern 'tls_verify_false' in email-agent/scrape_syndics_direct.py:184", "shortDescription": {"text": "Insecure pattern 'tls_verify_false' in email-agent/scrape_syndics_direct.py:184"}, "fullDescription": {"text": "Found a known-risky pattern (tls_verify_false). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-f52368eeadfb258d", "name": "Insecure pattern 'direct_innerhtml_assignment' in blog/index.html:193", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in blog/index.html:193"}, "fullDescription": {"text": "Found a known-risky pattern (direct_innerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-cb2db38163fda1c6", "name": "Insecure pattern 'local_storage_auth_token' in js/abtest.js:39", "shortDescription": {"text": "Insecure pattern 'local_storage_auth_token' in js/abtest.js:39"}, "fullDescription": {"text": "Found a known-risky pattern (local_storage_auth_token). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-9980e23403b821ee", "name": "Insecure pattern 'direct_innerhtml_assignment' in app/dashboard.html:351", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in app/dashboard.html:351"}, "fullDescription": {"text": "Found a known-risky pattern (direct_innerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-2d02fc3a02b7deb5", "name": "Insecure pattern 'direct_innerhtml_assignment' in app/login.html:161", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in app/login.html:161"}, "fullDescription": {"text": "Found a known-risky pattern (direct_innerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-4ea1f5398d4d9005", "name": "Insecure pattern 'direct_innerhtml_assignment' in app/documents.html:331", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in app/documents.html:331"}, "fullDescription": {"text": "Found a known-risky pattern (direct_innerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-d49e1930945192ab", "name": "Insecure pattern 'direct_innerhtml_assignment' in app/profile.html:384", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in app/profile.html:384"}, "fullDescription": {"text": "Found a known-risky pattern (direct_innerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-2ae9b327d7e63c82", "name": "Insecure pattern 'direct_innerhtml_assignment' in app/js/chantier.js:213", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in app/js/chantier.js:213"}, "fullDescription": {"text": "Found a known-risky pattern (direct_innerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-1d44c329a2a1887e", "name": "Insecure pattern 'direct_innerhtml_assignment' in social/claude_design_export/v3_scraped/index.html:212", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in social/claude_design_export/v3_scraped/index.html:212"}, "fullDescription": {"text": "Found a known-risky pattern (direct_innerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-9aabc04c71b29f2a", "name": "Insecure pattern 'cors_wildcard' in supabase/functions/_shared/cors.ts:4", "shortDescription": {"text": "Insecure pattern 'cors_wildcard' in supabase/functions/_shared/cors.ts:4"}, "fullDescription": {"text": "Found a known-risky pattern (cors_wildcard). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-4601e3ad3bb28677", "name": "No CI/CD pipelines detected", "shortDescription": {"text": "No CI/CD pipelines detected"}, "fullDescription": {"text": "No GitHub Actions, GitLab CI, or CircleCI configs found. Without CI you can't gate deploys on tests/lints."}, "properties": {"scanner": "scanner-primary", "layer": "cicd", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-9b2f942f95eca675", "name": "Very large file: blog/_batch_viral2.py (961 lines)", "shortDescription": {"text": "Very large file: blog/_batch_viral2.py (961 lines)"}, "fullDescription": {"text": "Files with >800 lines often hide complexity hotspots and discourage tests."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-e9c88c7da80c67e8", "name": "Very large file: blog/_batch_reglementaire_b2c.py (918 lines)", "shortDescription": {"text": "Very large file: blog/_batch_reglementaire_b2c.py (918 lines)"}, "fullDescription": {"text": "Files with >800 lines often hide complexity hotspots and discourage tests."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-9b41da9199d39070", "name": "Very large file: blog/_batch_reglementaire.py (1065 lines)", "shortDescription": {"text": "Very large file: blog/_batch_reglementaire.py (1065 lines)"}, "fullDescription": {"text": "Files with >800 lines often hide complexity hotspots and discourage tests."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-9b5d52fecd221737", "name": "Very large file: blog-pro/_batch8.py (819 lines)", "shortDescription": {"text": "Very large file: blog-pro/_batch8.py (819 lines)"}, "fullDescription": {"text": "Files with >800 lines often hide complexity hotspots and discourage tests."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-6893a6c8b0861585", "name": "Very low test-to-source ratio", "shortDescription": {"text": "Very low test-to-source ratio"}, "fullDescription": {"text": "1 test file(s) for 205 source file(s) (ratio 0.00). Consider adding integration or unit tests for critical paths."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-141b30a41e03817b", "name": "No license file detected", "shortDescription": {"text": "No license file detected"}, "fullDescription": {"text": "No LICENSE/COPYING/NOTICE file was found. Generated repositories often omit licensing, which blocks reuse and automated intake."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-3ab5d313dda8e5f9", "name": "Debug logging residue appears in source files", "shortDescription": {"text": "Debug logging residue appears in source files"}, "fullDescription": {"text": "Found 1733 console/debugger/print-style debug statements in non-test source. This is a common fast-generation residue before production cleanup."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-72b2a6250083a784", "name": "Placeholder or mock-heavy implementation detected", "shortDescription": {"text": "Placeholder or mock-heavy implementation detected"}, "fullDescription": {"text": "Found 42 placeholder/mock markers across 18 source files. This often means the repo looks complete while core flows still use generated scaffolding or fake data."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-2d0c7b7ab8f8aacf", "name": "Critical user flow still appears backed by mock or placeholder data", "shortDescription": {"text": "Critical user flow still appears backed by mock or placeholder data"}, "fullDescription": {"text": "A payment/auth/admin/order/billing-style flow contains mock, fake, TODO, dummy, or placeholder markers in runtime source. In the Fable corpus this is a high-leverage completeness smell: the app can look finished while the money, identity, or tenant flow is still scaffolded."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-b9088664ace7f748", "name": "Composite production-readiness gap", "shortDescription": {"text": "Composite production-readiness gap"}, "fullDescription": {"text": "Multiple low-cost hardening controls are missing together: license, ci, tests. Opus verification showed these co-occurring gaps are a better readiness signal than reading each flag in isolation."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-ea8f3013f588db25", "name": "Shallow git history limits provenance confidence", "shortDescription": {"text": "Shallow git history limits provenance confidence"}, "fullDescription": {"text": "The repository is a shallow clone. Origin/evolution analysis cannot distinguish fresh generation, imported legacy code, or long-lived human code with high confidence."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-8424db9c75e04ba4", "name": "Very short observed git history", "shortDescription": {"text": "Very short observed git history"}, "fullDescription": {"text": "The repo has multiple source files but two or fewer visible commits. This is not a failure by itself, but it lowers confidence in evolution-based diagnosis."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-afcad725f244433c", "name": "Commented-code block (5 lines) in server.js:621", "shortDescription": {"text": "Commented-code block (5 lines) in server.js:621"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-3e35500f63ed6334", "name": "Legacy-named symbol `leads_gmaps_v2` in email-agent/scraper_gmaps_v2.py:13", "shortDescription": {"text": "Legacy-named symbol `leads_gmaps_v2` in email-agent/scraper_gmaps_v2.py:13"}, "fullDescription": {"text": "Names with suffixes like `_old`, `_v1`, `_deprecated` usually indicate replaced-but-not-removed code (typical AI-coder leftover). Confirm and delete, or rename if it's the active version."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-792b5e40903dd22a", "name": "`fetch()` without try/.catch or AbortSignal \u2014 functions/api/chat-notify.js:54", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 functions/api/chat-notify.js:54"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-81f71366c1a0baf5", "name": "`fetch()` without try/.catch or AbortSignal \u2014 functions/api/vapi-webhook.js:80", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 functions/api/vapi-webhook.js:80"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-27d15e2cdc3e51f1", "name": "Commented-code block (5 lines) in js/cro-widgets.js:89", "shortDescription": {"text": "Commented-code block (5 lines) in js/cro-widgets.js:89"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-e4c641560b9cd602", "name": "Commented-code block (5 lines) in js/clarity-init.js:8", "shortDescription": {"text": "Commented-code block (5 lines) in js/clarity-init.js:8"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-0b1b5d64cc88b0f5", "name": "Commented-code block (7 lines) in js/consent.js:8", "shortDescription": {"text": "Commented-code block (7 lines) in js/consent.js:8"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-aefdd6acbcf4472f", "name": "Commented-code block (8 lines) in js/analytics.js:8", "shortDescription": {"text": "Commented-code block (8 lines) in js/analytics.js:8"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-d9a35868723fc8c4", "name": "Legacy-named symbol `hero_headline_v1` in js/abtest.js:6", "shortDescription": {"text": "Legacy-named symbol `hero_headline_v1` in js/abtest.js:6"}, "fullDescription": {"text": "Names with suffixes like `_old`, `_v1`, `_deprecated` usually indicate replaced-but-not-removed code (typical AI-coder leftover). Confirm and delete, or rename if it's the active version."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-1e34d9de1a73ae7a", "name": "Commented-code block (6 lines) in app/sw.js:116", "shortDescription": {"text": "Commented-code block (6 lines) in app/sw.js:116"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-ef30f8cbaecf00e5", "name": "Commented-code block (6 lines) in app/showcase/components.jsx:21", "shortDescription": {"text": "Commented-code block (6 lines) in app/showcase/components.jsx:21"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-773e76de5b158fad", "name": "Commented-code block (6 lines) in app/js/supabase.js:85", "shortDescription": {"text": "Commented-code block (6 lines) in app/js/supabase.js:85"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-9f363f47d23adc94", "name": "`fetch()` without try/.catch or AbortSignal \u2014 app/js/supabase.js:157", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 app/js/supabase.js:157"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-706d901e6b094567", "name": "Commented-code block (9 lines) in app/js/push-helper.js:8", "shortDescription": {"text": "Commented-code block (9 lines) in app/js/push-helper.js:8"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-e30e9208fe28037c", "name": "Commented-code block (5 lines) in app/js/app-menu.js:1", "shortDescription": {"text": "Commented-code block (5 lines) in app/js/app-menu.js:1"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-b024e619128176b0", "name": "Commented-code block (5 lines) in app/supabase/functions/stripe-webhook/index.ts:4", "shortDescription": {"text": "Commented-code block (5 lines) in app/supabase/functions/stripe-webhook/index.ts:4"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-9b69603588f7dd7e", "name": "Commented-code block (6 lines) in app/supabase/functions/notify-admin/index.ts:9", "shortDescription": {"text": "Commented-code block (6 lines) in app/supabase/functions/notify-admin/index.ts:9"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-e677c34fc238dac4", "name": "`fetch()` without try/.catch or AbortSignal \u2014 app/supabase/functions/notify-admin/index.ts:10", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 app/supabase/functions/notify-admin/index.ts:10"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-b1c1ac8b5a450348", "name": "Commented-code block (6 lines) in app/supabase/functions/notify-client-received/index.ts:9", "shortDescription": {"text": "Commented-code block (6 lines) in app/supabase/functions/notify-client-received/index.ts:9"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-e88397a30a25b627", "name": "`fetch()` without try/.catch or AbortSignal \u2014 app/supabase/functions/notify-client-received/index.ts:10", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 app/supabase/functions/notify-client-received/index.ts:10"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-8b43300243cb8cba", "name": "`fetch()` without try/.catch or AbortSignal \u2014 app/supabase/functions/ai-devis/index.ts:104", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 app/supabase/functions/ai-devis/index.ts:104"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-406843eeca194d6e", "name": "Network/subprocess call without timeout or try/except \u2014 social/post_today.py:60", "shortDescription": {"text": "Network/subprocess call without timeout or try/except \u2014 social/post_today.py:60"}, "fullDescription": {"text": "`subprocess.Popen(...)` here lacks both a `timeout=` arg and an enclosing try/except. This is exactly the class of bug that took down our git-clone earlier (HTTP/2 stream cancel surfaced as a fatal). Add a `timeout=` and wrap in try/except, or use a wrapper that retries."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-8a505ca9e245a3c3", "name": "Commented-code block (6 lines) in social/claude_design_export/BatiSpot_v2_extracted/ui_kits/artisan-app/components.jsx:2", "shortDescription": {"text": "Commented-code block (6 lines) in social/claude_design_export/BatiSpot_v2_extracted/ui_kits/artisan-app/components.jsx:21"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-71ca8a384af1c50c", "name": "Commented-code block (6 lines) in leads-machine/cross_majic_ademe.py:58", "shortDescription": {"text": "Commented-code block (6 lines) in leads-machine/cross_majic_ademe.py:58"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-ee045353e8041e17", "name": "Network/subprocess call without timeout or try/except \u2014 agents/run_all.py:28", "shortDescription": {"text": "Network/subprocess call without timeout or try/except \u2014 agents/run_all.py:28"}, "fullDescription": {"text": "`subprocess.run(...)` here lacks both a `timeout=` arg and an enclosing try/except. This is exactly the class of bug that took down our git-clone earlier (HTTP/2 stream cancel surfaced as a fatal). Add a `timeout=` and wrap in try/except, or use a wrapper that retries."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-13640081a679f9df", "name": "Network/subprocess call without timeout or try/except \u2014 agents/blog_autopilot.py:259", "shortDescription": {"text": "Network/subprocess call without timeout or try/except \u2014 agents/blog_autopilot.py:259"}, "fullDescription": {"text": "`subprocess.run(...)` here lacks both a `timeout=` arg and an enclosing try/except. This is exactly the class of bug that took down our git-clone earlier (HTTP/2 stream cancel surfaced as a fatal). Add a `timeout=` and wrap in try/except, or use a wrapper that retries."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-8d6543fb6f3e2bbb", "name": "Network/subprocess call without timeout or try/except \u2014 agents/social/linkedin_poster.py:66", "shortDescription": {"text": "Network/subprocess call without timeout or try/except \u2014 agents/social/linkedin_poster.py:66"}, "fullDescription": {"text": "`requests.get(...)` here lacks both a `timeout=` arg and an enclosing try/except. This is exactly the class of bug that took down our git-clone earlier (HTTP/2 stream cancel surfaced as a fatal). Add a `timeout=` and wrap in try/except, or use a wrapper that retries."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-3139ebdfca2e7355", "name": "`fetch()` without try/.catch or AbortSignal \u2014 supabase/functions/notify-artisan-status/index.ts:19", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 supabase/functions/notify-artisan-status/index.ts:19"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-e08bcbfeedfc5d70", "name": "Commented-code block (5 lines) in supabase/functions/stripe-webhook/index.ts:4", "shortDescription": {"text": "Commented-code block (5 lines) in supabase/functions/stripe-webhook/index.ts:4"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-9b6b2be4e9bb73a9", "name": "Commented-code block (6 lines) in supabase/functions/verify-turnstile/index.ts:7", "shortDescription": {"text": "Commented-code block (6 lines) in supabase/functions/verify-turnstile/index.ts:7"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-3e61170f26f13792", "name": "Commented-code block (7 lines) in supabase/functions/send-push/index.ts:1", "shortDescription": {"text": "Commented-code block (7 lines) in supabase/functions/send-push/index.ts:1"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-c73cccd11c97d305", "name": "Commented-code block (6 lines) in supabase/functions/subscribe-push/index.ts:6", "shortDescription": {"text": "Commented-code block (6 lines) in supabase/functions/subscribe-push/index.ts:6"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-49c98f7cedd9c977", "name": "Near-duplicate function bodies in 4 places", "shortDescription": {"text": "Near-duplicate function bodies in 4 places"}, "fullDescription": {"text": "Functions with the same first-5-line body hash:\nemail-agent/scraper.py:load_existing, agents/forum_scanner.py:load_existing, agents/leboncoin_scanner.py:load_existing, agents/permis_construire.py:load_existing\n\nThis is *the* AI-coder failure mode (4\u00d7 more duplication in vibe-coded repos \u2014 see https://jw.hn/ai-code-hygiene). Consolidate or document why they're separate."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-be46ea126aa5d8dc", "name": "Near-duplicate function bodies in 3 places", "shortDescription": {"text": "Near-duplicate function bodies in 3 places"}, "fullDescription": {"text": "Functions with the same first-5-line body hash:\nemail-agent/scraper_pj_syndics.py:log, email-agent/enrich_website_contact.py:log, email-agent/enrich_mojeek_websites.py:log\n\nThis is *the* AI-coder failure mode (4\u00d7 more duplication in vibe-coded repos \u2014 see https://jw.hn/ai-code-hygiene). Consolidate or document why they're separate."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-0027e313ade46c8f", "name": "Near-duplicate function bodies in 7 places", "shortDescription": {"text": "Near-duplicate function bodies in 7 places"}, "fullDescription": {"text": "Functions with the same first-5-line body hash:\nemail-agent/scraper_pj_syndics.py:normalize_phone, email-agent/scraper_syndics_gestionnaires.py:normalize_phone, email-agent/enricher_v3.py:clean_phone, email-agent/enricher_tel.py:clean_phone\n\nThis is *the* AI-coder failure mode (4\u00d7 more duplication in vibe-coded repos \u2014 see https://jw.hn/ai-code-hygiene). Consolidate or document why they're separate."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-2c04133e54348533", "name": "Near-duplicate function bodies in 2 places", "shortDescription": {"text": "Near-duplicate function bodies in 2 places"}, "fullDescription": {"text": "Functions with the same first-5-line body hash:\nemail-agent/scraper_pj_syndics.py:read_existing, email-agent/scraper_syndics_gestionnaires.py:read_csv\n\nThis is *the* AI-coder failure mode (4\u00d7 more duplication in vibe-coded repos \u2014 see https://jw.hn/ai-code-hygiene). Consolidate or document why they're separate."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-9dad557909b86499", "name": "Near-duplicate function bodies in 10 places", "shortDescription": {"text": "Near-duplicate function bodies in 10 places"}, "fullDescription": {"text": "Functions with the same first-5-line body hash:\nemail-agent/scraper_notaires.py:log, email-agent/scraper_demenageurs.py:log, email-agent/scraper_negoces_btp.py:log, email-agent/scraper_marchands.py:log\n\nThis is *the* AI-coder failure mode (4\u00d7 more duplication in vibe-coded repos \u2014 see https://jw.hn/ai-code-hygiene). Consolidate or document why they're separate."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-380b7cb95b387b9c", "name": "Near-duplicate function bodies in 11 places", "shortDescription": {"text": "Near-duplicate function bodies in 11 places"}, "fullDescription": {"text": "Functions with the same first-5-line body hash:\nemail-agent/scraper_notaires.py:extract_lead, email-agent/scraper_demenageurs.py:extract_lead, email-agent/scraper_negoces_btp.py:extract_lead, email-agent/scraper_marchands.py:extract_lead\n\nThis is *the* AI-coder failure mode (4\u00d7 more duplication in vibe-coded repos \u2014 see https://jw.hn/ai-code-hygiene). Consolidate or document why they're separate."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-33a6b62e30ce7ab4", "name": "Near-duplicate function bodies in 6 places", "shortDescription": {"text": "Near-duplicate function bodies in 6 places"}, "fullDescription": {"text": "Functions with the same first-5-line body hash:\nemail-agent/scrape_admin_biens_emails.py:log, email-agent/enricher_b2b.py:log, email-agent/scrape_agences_websites.py:log, email-agent/scrape_agences_pj_detail.py:log\n\nThis is *the* AI-coder failure mode (4\u00d7 more duplication in vibe-coded repos \u2014 see https://jw.hn/ai-code-hygiene). Consolidate or document why they're separate."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-e6fab797db1a58c7", "name": "Dangling fetch: POST /api/chat-notify (chat-widget.js:341)", "shortDescription": {"text": "Dangling fetch: POST /api/chat-notify (chat-widget.js:341)"}, "fullDescription": {"text": "`chat-widget.js:341` calls `POST /api/chat-notify` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/chat-notify`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-2cb00189348eebc1", "name": "Dangling fetch: POST https://api.brevo.com/v3/smtp/email (functions/api/chat-notify.js:54)", "shortDescription": {"text": "Dangling fetch: POST https://api.brevo.com/v3/smtp/email (functions/api/chat-notify.js:54)"}, "fullDescription": {"text": "`functions/api/chat-notify.js:54` calls `POST https://api.brevo.com/v3/smtp/email` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/api.brevo.com/v3/smtp/email`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-2120fa64daf58d5a", "name": "Dangling fetch: POST https://api.brevo.com/v3/smtp/email (netlify/functions/chat-notify.js:57)", "shortDescription": {"text": "Dangling fetch: POST https://api.brevo.com/v3/smtp/email (netlify/functions/chat-notify.js:57)"}, "fullDescription": {"text": "`netlify/functions/chat-notify.js:57` calls `POST https://api.brevo.com/v3/smtp/email` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/api.brevo.com/v3/smtp/email`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-c1b864c7ceeaea4c", "name": "Dangling fetch: POST https://api.brevo.com/v3/smtp/email (app/supabase/functions/notify-artisans/index.ts:181)", "shortDescription": {"text": "Dangling fetch: POST https://api.brevo.com/v3/smtp/email (app/supabase/functions/notify-artisans/index.ts:181)"}, "fullDescription": {"text": "`app/supabase/functions/notify-artisans/index.ts:181` calls `POST https://api.brevo.com/v3/smtp/email` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/api.brevo.com/v3/smtp/email`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-2e4f3592da81e0c0", "name": "Dangling fetch: POST https://api.brevo.com/v3/smtp/email (app/supabase/functions/stripe-webhook/index.ts:83)", "shortDescription": {"text": "Dangling fetch: POST https://api.brevo.com/v3/smtp/email (app/supabase/functions/stripe-webhook/index.ts:83)"}, "fullDescription": {"text": "`app/supabase/functions/stripe-webhook/index.ts:83` calls `POST https://api.brevo.com/v3/smtp/email` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/api.brevo.com/v3/smtp/email`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-531bfad1666296f6", "name": "Dangling fetch: POST https://api.brevo.com/v3/smtp/email (app/supabase/functions/notify-admin/index.ts:120)", "shortDescription": {"text": "Dangling fetch: POST https://api.brevo.com/v3/smtp/email (app/supabase/functions/notify-admin/index.ts:120)"}, "fullDescription": {"text": "`app/supabase/functions/notify-admin/index.ts:120` calls `POST https://api.brevo.com/v3/smtp/email` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/api.brevo.com/v3/smtp/email`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-4783f6a2f48df9b2", "name": "Dangling fetch: POST https://api.brevo.com/v3/smtp/email (app/supabase/functions/notify-client-received/index.ts:133)", "shortDescription": {"text": "Dangling fetch: POST https://api.brevo.com/v3/smtp/email (app/supabase/functions/notify-client-received/index.ts:133)"}, "fullDescription": {"text": "`app/supabase/functions/notify-client-received/index.ts:133` calls `POST https://api.brevo.com/v3/smtp/email` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/api.brevo.com/v3/smtp/email`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-bf4b9f1319fc31b8", "name": "Dangling fetch: POST https://api.anthropic.com/v1/messages (app/supabase/functions/ai-devis/index.ts:104)", "shortDescription": {"text": "Dangling fetch: POST https://api.anthropic.com/v1/messages (app/supabase/functions/ai-devis/index.ts:104)"}, "fullDescription": {"text": "`app/supabase/functions/ai-devis/index.ts:104` calls `POST https://api.anthropic.com/v1/messages` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/api.anthropic.com/v1/messages`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-ca66ac0417d36f63", "name": "Dangling fetch: POST https://api.brevo.com/v3/smtp/email (app/supabase/functions/notify-client/index.ts:125)", "shortDescription": {"text": "Dangling fetch: POST https://api.brevo.com/v3/smtp/email (app/supabase/functions/notify-client/index.ts:125)"}, "fullDescription": {"text": "`app/supabase/functions/notify-client/index.ts:125` calls `POST https://api.brevo.com/v3/smtp/email` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/api.brevo.com/v3/smtp/email`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-813bf4e0ac0e8356", "name": "Dangling fetch: POST https://api.brevo.com/v3/smtp/email (supabase/functions/notify-artisan-status/index.ts:19)", "shortDescription": {"text": "Dangling fetch: POST https://api.brevo.com/v3/smtp/email (supabase/functions/notify-artisan-status/index.ts:19)"}, "fullDescription": {"text": "`supabase/functions/notify-artisan-status/index.ts:19` calls `POST https://api.brevo.com/v3/smtp/email` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/api.brevo.com/v3/smtp/email`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-70c324508414a42f", "name": "Dangling fetch: POST https://api.brevo.com/v3/smtp/email (supabase/functions/stripe-webhook/index.ts:83)", "shortDescription": {"text": "Dangling fetch: POST https://api.brevo.com/v3/smtp/email (supabase/functions/stripe-webhook/index.ts:83)"}, "fullDescription": {"text": "`supabase/functions/stripe-webhook/index.ts:83` calls `POST https://api.brevo.com/v3/smtp/email` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/api.brevo.com/v3/smtp/email`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-bc12708397ec1473", "name": "Dangling fetch: POST https://challenges.cloudflare.com/turnstile/v0/siteverify (supabase/functions/verify-turnstile/inde", "shortDescription": {"text": "Dangling fetch: POST https://challenges.cloudflare.com/turnstile/v0/siteverify (supabase/functions/verify-turnstile/index.ts:85)"}, "fullDescription": {"text": "`supabase/functions/verify-turnstile/index.ts:85` calls `POST https://challenges.cloudflare.com/turnstile/v0/siteverify` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/challenges.cloudflare.com/turnstile/v0/siteverify`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-5d16331bea0896cb", "name": "Unused endpoint: POST /api/devis", "shortDescription": {"text": "Unused endpoint: POST /api/devis"}, "fullDescription": {"text": "`server.js` declares `POST /api/devis` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-8cfc5990c5256c4d", "name": "Unused endpoint: GET /api/devis", "shortDescription": {"text": "Unused endpoint: GET /api/devis"}, "fullDescription": {"text": "`server.js` declares `GET /api/devis` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-28ba7495fb562454", "name": "Unused endpoint: PATCH /api/devis/:id", "shortDescription": {"text": "Unused endpoint: PATCH /api/devis/:id"}, "fullDescription": {"text": "`server.js` declares `PATCH /api/devis/:id` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-37cf54e98ddb0640", "name": "Unused endpoint: POST /api/partenaires", "shortDescription": {"text": "Unused endpoint: POST /api/partenaires"}, "fullDescription": {"text": "`server.js` declares `POST /api/partenaires` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-89f77744da833f1c", "name": "Unused endpoint: GET /api/partenaires", "shortDescription": {"text": "Unused endpoint: GET /api/partenaires"}, "fullDescription": {"text": "`server.js` declares `GET /api/partenaires` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-7faee4b552a3a400", "name": "Unused endpoint: PATCH /api/partenaires/:id", "shortDescription": {"text": "Unused endpoint: PATCH /api/partenaires/:id"}, "fullDescription": {"text": "`server.js` declares `PATCH /api/partenaires/:id` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-dbee21351d4d8a9d", "name": "Unused endpoint: GET /api/matching", "shortDescription": {"text": "Unused endpoint: GET /api/matching"}, "fullDescription": {"text": "`server.js` declares `GET /api/matching` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-6791a21d1e6f9d7b", "name": "Unused endpoint: GET /api/matching/unmatched", "shortDescription": {"text": "Unused endpoint: GET /api/matching/unmatched"}, "fullDescription": {"text": "`server.js` declares `GET /api/matching/unmatched` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-81d625ac6e569e24", "name": "Unused endpoint: POST /api/matching/devis/:id", "shortDescription": {"text": "Unused endpoint: POST /api/matching/devis/:id"}, "fullDescription": {"text": "`server.js` declares `POST /api/matching/devis/:id` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-58245afa0f95e822", "name": "Unused endpoint: POST /api/matching/auto", "shortDescription": {"text": "Unused endpoint: POST /api/matching/auto"}, "fullDescription": {"text": "`server.js` declares `POST /api/matching/auto` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-f4aae4086adee82c", "name": "Unused endpoint: PATCH /api/matching/:id", "shortDescription": {"text": "Unused endpoint: PATCH /api/matching/:id"}, "fullDescription": {"text": "`server.js` declares `PATCH /api/matching/:id` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-3b37265900e79a8a", "name": "Unused endpoint: GET /api/stats", "shortDescription": {"text": "Unused endpoint: GET /api/stats"}, "fullDescription": {"text": "`server.js` declares `GET /api/stats` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-e83a755eb6a68d43", "name": "Unused endpoint: GET /api/track/open/:trackId", "shortDescription": {"text": "Unused endpoint: GET /api/track/open/:trackId"}, "fullDescription": {"text": "`server.js` declares `GET /api/track/open/:trackId` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-9c8c5f30a2cfc524", "name": "Unused endpoint: GET /api/track/click/:trackId", "shortDescription": {"text": "Unused endpoint: GET /api/track/click/:trackId"}, "fullDescription": {"text": "`server.js` declares `GET /api/track/click/:trackId` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-796454e3b9707cf5", "name": "Unused endpoint: POST /api/track/log", "shortDescription": {"text": "Unused endpoint: POST /api/track/log"}, "fullDescription": {"text": "`server.js` declares `POST /api/track/log` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-3b8d2df21c5db121", "name": "Unused endpoint: POST /api/track/reply", "shortDescription": {"text": "Unused endpoint: POST /api/track/reply"}, "fullDescription": {"text": "`server.js` declares `POST /api/track/reply` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-8fe6b585c3956db9", "name": "Unused endpoint: POST /api/track/stop", "shortDescription": {"text": "Unused endpoint: POST /api/track/stop"}, "fullDescription": {"text": "`server.js` declares `POST /api/track/stop` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-37b1e8fcaa55e10b", "name": "Unused endpoint: GET /api/track/stats", "shortDescription": {"text": "Unused endpoint: GET /api/track/stats"}, "fullDescription": {"text": "`server.js` declares `GET /api/track/stats` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-c5c0be9986e25ec4", "name": "Unused endpoint: GET /api/track/list", "shortDescription": {"text": "Unused endpoint: GET /api/track/list"}, "fullDescription": {"text": "`server.js` declares `GET /api/track/list` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-912e69ac4feaffd3", "name": "Unused endpoint: POST /api/checkout", "shortDescription": {"text": "Unused endpoint: POST /api/checkout"}, "fullDescription": {"text": "`server.js` declares `POST /api/checkout` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}]}}, "automationDetails": {"id": "repobility/21272"}, "properties": {"repository": "thwhkfcbsv-max/batispot", "repoUrl": "https://github.com/thwhkfcbsv-max/batispot", "branch": "main"}, "results": [{"ruleId": "scanner-ae991169c19f3ea5", "level": "note", "message": {"text": "Possibly dead Python function: load_existing_out"}, "properties": {"repobilityId": "4f9db7f0bbbf0771", "scanner": "scanner-primary", "fingerprint": "ae991169c19f3ea5", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "email-agent/scrape_admin_biens_emails.py:130"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-785f76901b86f862", "level": "note", "message": {"text": "Possibly dead Python function: get_html_seq1"}, "properties": {"repobilityId": "1eef166535f020fe", "scanner": "scanner-primary", "fingerprint": "785f76901b86f862", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "email-agent/sender_syndics_brevo.py:106"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-0e6edfe6ad426f3b", "level": "note", "message": {"text": "Possibly dead Python function: get_html_seq3"}, "properties": {"repobilityId": "8b1700e92b4d52f5", "scanner": "scanner-primary", "fingerprint": "0e6edfe6ad426f3b", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "email-agent/sender_syndics_brevo.py:135"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-4666cb8c30c2af00", "level": "note", "message": {"text": "Possibly dead Python function: get_html_seq4"}, "properties": {"repobilityId": "5c20919bcf5520e7", "scanner": "scanner-primary", "fingerprint": "4666cb8c30c2af00", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "email-agent/sender_syndics_brevo.py:173"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-a3852530e8c290d3", "level": "note", "message": {"text": "Possibly dead Python function: process_lead"}, "properties": {"repobilityId": "bddc234e0a713765", "scanner": "scanner-primary", "fingerprint": "a3852530e8c290d3", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "email-agent/scrape_syndics_direct.py:269"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-9270480434607bc2", "level": "note", "message": {"text": "Possibly dead Python function: ip_of"}, "properties": {"repobilityId": "b9d7239ba64d9187", "scanner": "scanner-primary", "fingerprint": "9270480434607bc2", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "email-agent/scrape_fnaim_unis.py:139"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-f472ef58ba91c1eb", "level": "note", "message": {"text": "Possibly dead Python function: template_seq2_relance"}, "properties": {"repobilityId": "e1cf1c232d7b24d0", "scanner": "scanner-primary", "fingerprint": "f472ef58ba91c1eb", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "email-agent/sms_sender_brevo.py:224"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-26103f7cf0c40e0e", "level": "note", "message": {"text": "Possibly dead Python function: template_transac_signup"}, "properties": {"repobilityId": "7972a0d7003ed695", "scanner": "scanner-primary", "fingerprint": "26103f7cf0c40e0e", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "email-agent/sms_sender_brevo.py:233"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-e9548ef404227dac", "level": "note", "message": {"text": "Possibly dead Python function: template_syndics_prospection"}, "properties": {"repobilityId": "b5a095ab06d406ca", "scanner": "scanner-primary", "fingerprint": "e9548ef404227dac", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "email-agent/sms_sender_brevo.py:241"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-bf3e6809daf41aa2", "level": "note", "message": {"text": "Possibly dead Python function: template_syndics_hot_relance"}, "properties": {"repobilityId": "ef5ca310a2902d67", "scanner": "scanner-primary", "fingerprint": "bf3e6809daf41aa2", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "email-agent/sms_sender_brevo.py:250"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-64ab9e7ff0b94d07", "level": "note", "message": {"text": "Possibly dead Python function: template_artisans_seq1_sms"}, "properties": {"repobilityId": "1969adc379a48c66", "scanner": "scanner-primary", "fingerprint": "64ab9e7ff0b94d07", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "email-agent/sms_sender_brevo.py:259"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-380d39cab122cd10", "level": "note", "message": {"text": "Possibly dead Python function: template_artisans_relance_sms"}, "properties": {"repobilityId": "5c598e24b4313026", "scanner": "scanner-primary", "fingerprint": "380d39cab122cd10", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "email-agent/sms_sender_brevo.py:268"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-e478fe9d6e2de108", "level": "note", "message": {"text": "Possibly dead Python function: handle_data"}, "properties": {"repobilityId": "3a673a278f4fc1e6", "scanner": "scanner-primary", "fingerprint": "e478fe9d6e2de108", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "email-agent/scraper_avis_negatifs.py:188"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-da612c4f34a08f02", "level": "note", "message": {"text": "Possibly dead Python function: extract_between"}, "properties": {"repobilityId": "668e9cbb5b97494c", "scanner": "scanner-primary", "fingerprint": "da612c4f34a08f02", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "email-agent/scraper_avis_negatifs.py:199"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-9c618cc4428c8d41", "level": "note", "message": {"text": "Possibly dead Python function: log_message"}, "properties": {"repobilityId": "965f3150b4af5b2e", "scanner": "scanner-primary", "fingerprint": "9c618cc4428c8d41", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "email-agent/vapi/webhook_handler.py:62"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-882f7c05f5a77016", "level": "note", "message": {"text": "Possibly dead Python function: do_POST"}, "properties": {"repobilityId": "53357410ca9379a9", "scanner": "scanner-primary", "fingerprint": "882f7c05f5a77016", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "email-agent/vapi/webhook_handler.py:65"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-d94902fc903fd94f", "level": "note", "message": {"text": "Possibly dead Python function: replacer"}, "properties": {"repobilityId": "4c6d041d83cc4187", "scanner": "scanner-primary", "fingerprint": "d94902fc903fd94f", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/strip_html_hrefs.py:48"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-ff16728185a3da9e", "level": "note", "message": {"text": "Possibly dead Python function: s1"}, "properties": {"repobilityId": "ef2ed292b7c9f4c1", "scanner": "scanner-primary", "fingerprint": "ff16728185a3da9e", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "social/generate_reel_v3.py:520"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-bbac12bf6e176442", "level": "note", "message": {"text": "Possibly dead Python function: s2"}, "properties": {"repobilityId": "9a148ccc04bd8653", "scanner": "scanner-primary", "fingerprint": "bbac12bf6e176442", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "social/generate_reel_v3.py:533"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-75eba4e3bbeb2963", "level": "note", "message": {"text": "Possibly dead Python function: s3"}, "properties": {"repobilityId": "f638f93e10acef4c", "scanner": "scanner-primary", "fingerprint": "75eba4e3bbeb2963", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "social/generate_reel_v3.py:541"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-8b173ed56b4a45d3", "level": "note", "message": {"text": "Possibly dead Python function: s4"}, "properties": {"repobilityId": "e0bf736723cf9762", "scanner": "scanner-primary", "fingerprint": "8b173ed56b4a45d3", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "social/generate_reel_v3.py:556"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-96a60f3f47962265", "level": "note", "message": {"text": "Possibly dead Python function: s5"}, "properties": {"repobilityId": "1efa54f39702a67b", "scanner": "scanner-primary", "fingerprint": "96a60f3f47962265", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "social/generate_reel_v3.py:565"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-a4fa394795377af5", "level": "note", "message": {"text": "Possibly dead Python function: s6"}, "properties": {"repobilityId": "5a25060c3c0f4abc", "scanner": "scanner-primary", "fingerprint": "a4fa394795377af5", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "social/generate_reel_v3.py:393"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-e60e143915b2f02e", "level": "note", "message": {"text": "Possibly dead Python function: s7"}, "properties": {"repobilityId": "e6ce1de944ba890d", "scanner": "scanner-primary", "fingerprint": "e60e143915b2f02e", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "social/generate_reel_v3.py:407"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-64b7992e1c48cb03", "level": "note", "message": {"text": "Possibly dead Python function: s8"}, "properties": {"repobilityId": "1a8e76f6d324b083", "scanner": "scanner-primary", "fingerprint": "64b7992e1c48cb03", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "social/generate_reel_v3.py:416"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-34b90404f67b0770", "level": "note", "message": {"text": "Possibly dead Python function: s1"}, "properties": {"repobilityId": "ef2ed292b7c9f4c1", "scanner": "scanner-primary", "fingerprint": "34b90404f67b0770", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "social/generate_reel_v2.py:432"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-c34427623a2fb6bf", "level": "note", "message": {"text": "Possibly dead Python function: s2"}, "properties": {"repobilityId": "9a148ccc04bd8653", "scanner": "scanner-primary", "fingerprint": "c34427623a2fb6bf", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "social/generate_reel_v2.py:444"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-92ea45fe5159a334", "level": "note", "message": {"text": "Possibly dead Python function: s3"}, "properties": {"repobilityId": "f638f93e10acef4c", "scanner": "scanner-primary", "fingerprint": "92ea45fe5159a334", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "social/generate_reel_v2.py:452"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-1f0547b742f5d1a7", "level": "note", "message": {"text": "Possibly dead Python function: s4"}, "properties": {"repobilityId": "e0bf736723cf9762", "scanner": "scanner-primary", "fingerprint": "1f0547b742f5d1a7", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "social/generate_reel_v2.py:467"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-8d3a2262a3980c62", "level": "note", "message": {"text": "Possibly dead Python function: s5"}, "properties": {"repobilityId": "1efa54f39702a67b", "scanner": "scanner-primary", "fingerprint": "8d3a2262a3980c62", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "social/generate_reel_v2.py:480"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-63d708313d422248", "level": "note", "message": {"text": "Icon-only button without accessible name \u2014 chat-widget.js:296"}, "properties": {"repobilityId": "90462276c2bc4880", "scanner": "scanner-primary", "fingerprint": "63d708313d422248", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.button.no-label"]}}, {"ruleId": "scanner-68324f980e71e148", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 server.js:178"}, "properties": {"repobilityId": "a9deebb5fdc93edc", "scanner": "scanner-primary", "fingerprint": "68324f980e71e148", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-5eaab42a3ded5539", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 app/supabase/functions/notify-artisans/index.ts:240"}, "properties": {"repobilityId": "ce279b73dc1920df", "scanner": "scanner-primary", "fingerprint": "5eaab42a3ded5539", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-bb6e1482fe62aa2b", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 app/supabase/functions/stripe-webhook/index.ts:209"}, "properties": {"repobilityId": "a8084047f49e52a7", "scanner": "scanner-primary", "fingerprint": "bb6e1482fe62aa2b", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-910ecfec3c62632a", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 app/supabase/functions/notify-client/index.ts:177"}, "properties": {"repobilityId": "a2013b7f96540d70", "scanner": "scanner-primary", "fingerprint": "910ecfec3c62632a", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-d437beb001ab6eb8", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 supabase/functions/stripe-webhook/index.ts:209"}, "properties": {"repobilityId": "7c738a141c293866", "scanner": "scanner-primary", "fingerprint": "d437beb001ab6eb8", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-995f6a0aea20b428", "level": "warning", "message": {"text": "Privileged port 9 in use"}, "properties": {"repobilityId": "31590a6ba3409390", "scanner": "scanner-primary", "fingerprint": "995f6a0aea20b428", "layer": "network", "severity": "medium", "confidence": 1.0, "tags": ["security", "ports"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/morning_routine.sh"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-62c8d97bd93503b8", "level": "warning", "message": {"text": "Privileged port 30 in use"}, "properties": {"repobilityId": "54f172e7d16fc662", "scanner": "scanner-primary", "fingerprint": "62c8d97bd93503b8", "layer": "network", "severity": "medium", "confidence": 1.0, "tags": ["security", "ports"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/morning_routine.sh"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-a95ade1bdd1987a6", "level": "warning", "message": {"text": "Privileged port 15 in use"}, "properties": {"repobilityId": "3340f9a170f285cd", "scanner": "scanner-primary", "fingerprint": "a95ade1bdd1987a6", "layer": "network", "severity": "medium", "confidence": 1.0, "tags": ["security", "ports"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/run_daily_enrichment.sh"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-9710c8d059e53154", "level": "none", "message": {"text": "No frontend routes/components detected"}, "properties": {"repobilityId": "44ca61485762e494", "scanner": "scanner-primary", "fingerprint": "9710c8d059e53154", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["coverage"]}}, {"ruleId": "scanner-a96fa63778c42f59", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in ma-demande.html:263"}, "properties": {"repobilityId": "37b21970e2435ab7", "scanner": "scanner-primary", "fingerprint": "a96fa63778c42f59", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "ma-demande.html"}, "region": {"startLine": 263}}}]}, {"ruleId": "scanner-5cf6fe6bd8fdc4f1", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in simulateur-aides.html:780"}, "properties": {"repobilityId": "a1765209b5037cb2", "scanner": "scanner-primary", "fingerprint": "5cf6fe6bd8fdc4f1", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "simulateur-aides.html"}, "region": {"startLine": 780}}}]}, {"ruleId": "scanner-7091cc616d691d69", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in artisan_old_pre_v2.html:1670"}, "properties": {"repobilityId": "6c4f96cb8250f12d", "scanner": "scanner-primary", "fingerprint": "7091cc616d691d69", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "artisan_old_pre_v2.html"}, "region": {"startLine": 1670}}}]}, {"ruleId": "scanner-8f52e8986b0a0826", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in chat-widget.js:287"}, "properties": {"repobilityId": "dae7ff8577caabba", "scanner": "scanner-primary", "fingerprint": "8f52e8986b0a0826", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "chat-widget.js"}, "region": {"startLine": 287}}}]}, {"ruleId": "scanner-86d189487e0d4362", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in estimateur.html:367"}, "properties": {"repobilityId": "35046459e58b770b", "scanner": "scanner-primary", "fingerprint": "86d189487e0d4362", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "estimateur.html"}, "region": {"startLine": 367}}}]}, {"ruleId": "scanner-074f6907445f2415", "level": "warning", "message": {"text": "Insecure pattern 'cors_wildcard' in server.js:31"}, "properties": {"repobilityId": "0d9bca6c0839725e", "scanner": "scanner-primary", "fingerprint": "074f6907445f2415", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "cors_wildcard"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "server.js"}, "region": {"startLine": 31}}}]}, {"ruleId": "scanner-299df472a5e519ee", "level": "error", "message": {"text": "Insecure pattern 'tls_verify_false' in email-agent/enrich_batch_20260420.py:218"}, "properties": {"repobilityId": "dd329c052d9392fe", "scanner": "scanner-primary", "fingerprint": "299df472a5e519ee", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["owasp", "tls_verify_false"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "email-agent/enrich_batch_20260420.py"}, "region": {"startLine": 218}}}]}, {"ruleId": "scanner-36544ce12490cea0", "level": "error", "message": {"text": "Insecure pattern 'tls_verify_false' in email-agent/scrape_syndics_direct.py:184"}, "properties": {"repobilityId": "2630968c0a59bd43", "scanner": "scanner-primary", "fingerprint": "36544ce12490cea0", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["owasp", "tls_verify_false"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "email-agent/scrape_syndics_direct.py"}, "region": {"startLine": 184}}}]}, {"ruleId": "scanner-f52368eeadfb258d", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in blog/index.html:193"}, "properties": {"repobilityId": "c533bafccaac8061", "scanner": "scanner-primary", "fingerprint": "f52368eeadfb258d", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "blog/index.html"}, "region": {"startLine": 193}}}]}, {"ruleId": "scanner-cb2db38163fda1c6", "level": "warning", "message": {"text": "Insecure pattern 'local_storage_auth_token' in js/abtest.js:39"}, "properties": {"repobilityId": "8251a47215b33215", "scanner": "scanner-primary", "fingerprint": "cb2db38163fda1c6", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "local_storage_auth_token"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "js/abtest.js"}, "region": {"startLine": 39}}}]}, {"ruleId": "scanner-9980e23403b821ee", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in app/dashboard.html:351"}, "properties": {"repobilityId": "811d65a59d4ef156", "scanner": "scanner-primary", "fingerprint": "9980e23403b821ee", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/dashboard.html"}, "region": {"startLine": 351}}}]}, {"ruleId": "scanner-2d02fc3a02b7deb5", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in app/login.html:161"}, "properties": {"repobilityId": "b7e05ab49a9b195e", "scanner": "scanner-primary", "fingerprint": "2d02fc3a02b7deb5", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/login.html"}, "region": {"startLine": 161}}}]}, {"ruleId": "scanner-4ea1f5398d4d9005", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in app/documents.html:331"}, "properties": {"repobilityId": "2f70b566368133db", "scanner": "scanner-primary", "fingerprint": "4ea1f5398d4d9005", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/documents.html"}, "region": {"startLine": 331}}}]}, {"ruleId": "scanner-d49e1930945192ab", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in app/profile.html:384"}, "properties": {"repobilityId": "819c467d90386863", "scanner": "scanner-primary", "fingerprint": "d49e1930945192ab", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/profile.html"}, "region": {"startLine": 384}}}]}, {"ruleId": "scanner-2ae9b327d7e63c82", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in app/js/chantier.js:213"}, "properties": {"repobilityId": "08f2e2a7d47f2983", "scanner": "scanner-primary", "fingerprint": "2ae9b327d7e63c82", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/js/chantier.js"}, "region": {"startLine": 213}}}]}, {"ruleId": "scanner-1d44c329a2a1887e", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in social/claude_design_export/v3_scraped/index.html:212"}, "properties": {"repobilityId": "4afc591b0c1a82db", "scanner": "scanner-primary", "fingerprint": "1d44c329a2a1887e", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "social/claude_design_export/v3_scraped/index.html"}, "region": {"startLine": 212}}}]}, {"ruleId": "scanner-9aabc04c71b29f2a", "level": "warning", "message": {"text": "Insecure pattern 'cors_wildcard' in supabase/functions/_shared/cors.ts:4"}, "properties": {"repobilityId": "7c8e268f4e944077", "scanner": "scanner-primary", "fingerprint": "9aabc04c71b29f2a", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "cors_wildcard"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "supabase/functions/_shared/cors.ts"}, "region": {"startLine": 4}}}]}, {"ruleId": "scanner-4601e3ad3bb28677", "level": "warning", "message": {"text": "No CI/CD pipelines detected"}, "properties": {"repobilityId": "c3ee439bce2bc51e", "scanner": "scanner-primary", "fingerprint": "4601e3ad3bb28677", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["coverage"]}}, {"ruleId": "scanner-9b2f942f95eca675", "level": "note", "message": {"text": "Very large file: blog/_batch_viral2.py (961 lines)"}, "properties": {"repobilityId": "803f699fa74e6841", "scanner": "scanner-primary", "fingerprint": "9b2f942f95eca675", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-e9c88c7da80c67e8", "level": "note", "message": {"text": "Very large file: blog/_batch_reglementaire_b2c.py (918 lines)"}, "properties": {"repobilityId": "b3c88fc53dac8e92", "scanner": "scanner-primary", "fingerprint": "e9c88c7da80c67e8", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-9b41da9199d39070", "level": "note", "message": {"text": "Very large file: blog/_batch_reglementaire.py (1065 lines)"}, "properties": {"repobilityId": "4ccec86d10da1a6c", "scanner": "scanner-primary", "fingerprint": "9b41da9199d39070", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-9b5d52fecd221737", "level": "note", "message": {"text": "Very large file: blog-pro/_batch8.py (819 lines)"}, "properties": {"repobilityId": "2d9dde127c7383f3", "scanner": "scanner-primary", "fingerprint": "9b5d52fecd221737", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-6893a6c8b0861585", "level": "warning", "message": {"text": "Very low test-to-source ratio"}, "properties": {"repobilityId": "54a7de3f06314bf0", "scanner": "scanner-primary", "fingerprint": "6893a6c8b0861585", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["tests", "coverage"]}}, {"ruleId": "scanner-141b30a41e03817b", "level": "note", "message": {"text": "No license file detected"}, "properties": {"repobilityId": "a78b58271d66a015", "scanner": "scanner-primary", "fingerprint": "141b30a41e03817b", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["license", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-3ab5d313dda8e5f9", "level": "note", "message": {"text": "Debug logging residue appears in source files"}, "properties": {"repobilityId": "5704bd780627fb06", "scanner": "scanner-primary", "fingerprint": "3ab5d313dda8e5f9", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["debug", "cleanup", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-72b2a6250083a784", "level": "warning", "message": {"text": "Placeholder or mock-heavy implementation detected"}, "properties": {"repobilityId": "ce6f51d06d2b4cfb", "scanner": "scanner-primary", "fingerprint": "72b2a6250083a784", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "incomplete", "generated-repo-pattern"]}}, {"ruleId": "scanner-2d0c7b7ab8f8aacf", "level": "warning", "message": {"text": "Critical user flow still appears backed by mock or placeholder data"}, "properties": {"repobilityId": "4a795e328d5367bf", "scanner": "scanner-primary", "fingerprint": "2d0c7b7ab8f8aacf", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "critical-flow", "generated-repo-pattern"]}}, {"ruleId": "scanner-b9088664ace7f748", "level": "warning", "message": {"text": "Composite production-readiness gap"}, "properties": {"repobilityId": "b44ea0f2428c7e42", "scanner": "scanner-primary", "fingerprint": "b9088664ace7f748", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["production-readiness", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-ea8f3013f588db25", "level": "note", "message": {"text": "Shallow git history limits provenance confidence"}, "properties": {"repobilityId": "37457a1d47bb8841", "scanner": "scanner-primary", "fingerprint": "ea8f3013f588db25", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["provenance", "git-history", "generated-repo-pattern"]}}, {"ruleId": "scanner-8424db9c75e04ba4", "level": "none", "message": {"text": "Very short observed git history"}, "properties": {"repobilityId": "ee24af96f05502f2", "scanner": "scanner-primary", "fingerprint": "8424db9c75e04ba4", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["provenance", "git-history", "generated-repo-pattern"]}}, {"ruleId": "scanner-afcad725f244433c", "level": "none", "message": {"text": "Commented-code block (5 lines) in server.js:621"}, "properties": {"repobilityId": "d725d960f3b1b2ce", "scanner": "scanner-primary", "fingerprint": "afcad725f244433c", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-3e35500f63ed6334", "level": "note", "message": {"text": "Legacy-named symbol `leads_gmaps_v2` in email-agent/scraper_gmaps_v2.py:13"}, "properties": {"repobilityId": "c7d69c74e0a9202f", "scanner": "scanner-primary", "fingerprint": "3e35500f63ed6334", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-792b5e40903dd22a", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 functions/api/chat-notify.js:54"}, "properties": {"repobilityId": "73a2400083b35a46", "scanner": "scanner-primary", "fingerprint": "792b5e40903dd22a", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-81f71366c1a0baf5", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 functions/api/vapi-webhook.js:80"}, "properties": {"repobilityId": "c1da476afa6b5fff", "scanner": "scanner-primary", "fingerprint": "81f71366c1a0baf5", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-27d15e2cdc3e51f1", "level": "none", "message": {"text": "Commented-code block (5 lines) in js/cro-widgets.js:89"}, "properties": {"repobilityId": "b1cde9cf9e3039e9", "scanner": "scanner-primary", "fingerprint": "27d15e2cdc3e51f1", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-e4c641560b9cd602", "level": "none", "message": {"text": "Commented-code block (5 lines) in js/clarity-init.js:8"}, "properties": {"repobilityId": "8c55a0b0c6c03c51", "scanner": "scanner-primary", "fingerprint": "e4c641560b9cd602", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-0b1b5d64cc88b0f5", "level": "none", "message": {"text": "Commented-code block (7 lines) in js/consent.js:8"}, "properties": {"repobilityId": "f8314c2a0fa5f21b", "scanner": "scanner-primary", "fingerprint": "0b1b5d64cc88b0f5", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-aefdd6acbcf4472f", "level": "none", "message": {"text": "Commented-code block (8 lines) in js/analytics.js:8"}, "properties": {"repobilityId": "b9c90b61b8c516a1", "scanner": "scanner-primary", "fingerprint": "aefdd6acbcf4472f", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-d9a35868723fc8c4", "level": "note", "message": {"text": "Legacy-named symbol `hero_headline_v1` in js/abtest.js:6"}, "properties": {"repobilityId": "228cd492ccc81e8f", "scanner": "scanner-primary", "fingerprint": "d9a35868723fc8c4", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-1e34d9de1a73ae7a", "level": "none", "message": {"text": "Commented-code block (6 lines) in app/sw.js:116"}, "properties": {"repobilityId": "99f240b058cfc430", "scanner": "scanner-primary", "fingerprint": "1e34d9de1a73ae7a", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-ef30f8cbaecf00e5", "level": "none", "message": {"text": "Commented-code block (6 lines) in app/showcase/components.jsx:21"}, "properties": {"repobilityId": "f83ac358791a4c49", "scanner": "scanner-primary", "fingerprint": "ef30f8cbaecf00e5", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-773e76de5b158fad", "level": "none", "message": {"text": "Commented-code block (6 lines) in app/js/supabase.js:85"}, "properties": {"repobilityId": "4076b4c5380bc3e4", "scanner": "scanner-primary", "fingerprint": "773e76de5b158fad", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-9f363f47d23adc94", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 app/js/supabase.js:157"}, "properties": {"repobilityId": "ddf9b42a8fadcd4b", "scanner": "scanner-primary", "fingerprint": "9f363f47d23adc94", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-706d901e6b094567", "level": "none", "message": {"text": "Commented-code block (9 lines) in app/js/push-helper.js:8"}, "properties": {"repobilityId": "09af44d30aa3caa2", "scanner": "scanner-primary", "fingerprint": "706d901e6b094567", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-e30e9208fe28037c", "level": "none", "message": {"text": "Commented-code block (5 lines) in app/js/app-menu.js:1"}, "properties": {"repobilityId": "3f024d43bb312620", "scanner": "scanner-primary", "fingerprint": "e30e9208fe28037c", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-b024e619128176b0", "level": "none", "message": {"text": "Commented-code block (5 lines) in app/supabase/functions/stripe-webhook/index.ts:4"}, "properties": {"repobilityId": "83278836bf4b9222", "scanner": "scanner-primary", "fingerprint": "b024e619128176b0", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-9b69603588f7dd7e", "level": "none", "message": {"text": "Commented-code block (6 lines) in app/supabase/functions/notify-admin/index.ts:9"}, "properties": {"repobilityId": "9ceca77c393e2c39", "scanner": "scanner-primary", "fingerprint": "9b69603588f7dd7e", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-e677c34fc238dac4", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 app/supabase/functions/notify-admin/index.ts:10"}, "properties": {"repobilityId": "d1528dc254634a8b", "scanner": "scanner-primary", "fingerprint": "e677c34fc238dac4", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-b1c1ac8b5a450348", "level": "none", "message": {"text": "Commented-code block (6 lines) in app/supabase/functions/notify-client-received/index.ts:9"}, "properties": {"repobilityId": "b093c4aab761077f", "scanner": "scanner-primary", "fingerprint": "b1c1ac8b5a450348", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-e88397a30a25b627", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 app/supabase/functions/notify-client-received/index.ts:10"}, "properties": {"repobilityId": "73cc2cda4780adbc", "scanner": "scanner-primary", "fingerprint": "e88397a30a25b627", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-8b43300243cb8cba", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 app/supabase/functions/ai-devis/index.ts:104"}, "properties": {"repobilityId": "7a4de48d82778840", "scanner": "scanner-primary", "fingerprint": "8b43300243cb8cba", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-406843eeca194d6e", "level": "warning", "message": {"text": "Network/subprocess call without timeout or try/except \u2014 social/post_today.py:60"}, "properties": {"repobilityId": "ff4994ad5d23d162", "scanner": "scanner-primary", "fingerprint": "406843eeca194d6e", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-8a505ca9e245a3c3", "level": "none", "message": {"text": "Commented-code block (6 lines) in social/claude_design_export/BatiSpot_v2_extracted/ui_kits/artisan-app/components.jsx:21"}, "properties": {"repobilityId": "5728ffdce1f217a9", "scanner": "scanner-primary", "fingerprint": "8a505ca9e245a3c3", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-71ca8a384af1c50c", "level": "none", "message": {"text": "Commented-code block (6 lines) in leads-machine/cross_majic_ademe.py:58"}, "properties": {"repobilityId": "94173cc7b44f0e4f", "scanner": "scanner-primary", "fingerprint": "71ca8a384af1c50c", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-ee045353e8041e17", "level": "warning", "message": {"text": "Network/subprocess call without timeout or try/except \u2014 agents/run_all.py:28"}, "properties": {"repobilityId": "4cdbf6a47e6d5b11", "scanner": "scanner-primary", "fingerprint": "ee045353e8041e17", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-13640081a679f9df", "level": "warning", "message": {"text": "Network/subprocess call without timeout or try/except \u2014 agents/blog_autopilot.py:259"}, "properties": {"repobilityId": "0b2a8c971c16e0bc", "scanner": "scanner-primary", "fingerprint": "13640081a679f9df", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-8d6543fb6f3e2bbb", "level": "warning", "message": {"text": "Network/subprocess call without timeout or try/except \u2014 agents/social/linkedin_poster.py:66"}, "properties": {"repobilityId": "06d3cf713e9c70a1", "scanner": "scanner-primary", "fingerprint": "8d6543fb6f3e2bbb", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-3139ebdfca2e7355", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 supabase/functions/notify-artisan-status/index.ts:19"}, "properties": {"repobilityId": "d367f7f703099e99", "scanner": "scanner-primary", "fingerprint": "3139ebdfca2e7355", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-e08bcbfeedfc5d70", "level": "none", "message": {"text": "Commented-code block (5 lines) in supabase/functions/stripe-webhook/index.ts:4"}, "properties": {"repobilityId": "23753eda7bc24217", "scanner": "scanner-primary", "fingerprint": "e08bcbfeedfc5d70", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-9b6b2be4e9bb73a9", "level": "none", "message": {"text": "Commented-code block (6 lines) in supabase/functions/verify-turnstile/index.ts:7"}, "properties": {"repobilityId": "f9814e9c25f0b7ff", "scanner": "scanner-primary", "fingerprint": "9b6b2be4e9bb73a9", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-3e61170f26f13792", "level": "none", "message": {"text": "Commented-code block (7 lines) in supabase/functions/send-push/index.ts:1"}, "properties": {"repobilityId": "0f755d4da56ec234", "scanner": "scanner-primary", "fingerprint": "3e61170f26f13792", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-c73cccd11c97d305", "level": "none", "message": {"text": "Commented-code block (6 lines) in supabase/functions/subscribe-push/index.ts:6"}, "properties": {"repobilityId": "17aa33b7b769a5fc", "scanner": "scanner-primary", "fingerprint": "c73cccd11c97d305", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-49c98f7cedd9c977", "level": "note", "message": {"text": "Near-duplicate function bodies in 4 places"}, "properties": {"repobilityId": "c0d2c21b2855c810", "scanner": "scanner-primary", "fingerprint": "49c98f7cedd9c977", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "duplicate", "dry"]}}, {"ruleId": "scanner-be46ea126aa5d8dc", "level": "note", "message": {"text": "Near-duplicate function bodies in 3 places"}, "properties": {"repobilityId": "897f262cd9eb1daa", "scanner": "scanner-primary", "fingerprint": "be46ea126aa5d8dc", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "duplicate", "dry"]}}, {"ruleId": "scanner-be46ea126aa5d8dc", "level": "note", "message": {"text": "Near-duplicate function bodies in 3 places"}, "properties": {"repobilityId": "5037ad1e921c34ef", "scanner": "scanner-primary", "fingerprint": "be46ea126aa5d8dc", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "duplicate", "dry"]}}, {"ruleId": "scanner-0027e313ade46c8f", "level": "note", "message": {"text": "Near-duplicate function bodies in 7 places"}, "properties": {"repobilityId": "a5588d5f66aa08b0", "scanner": "scanner-primary", "fingerprint": "0027e313ade46c8f", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "duplicate", "dry"]}}, {"ruleId": "scanner-2c04133e54348533", "level": "note", "message": {"text": "Near-duplicate function bodies in 2 places"}, "properties": {"repobilityId": "b225bad88a9839e0", "scanner": "scanner-primary", "fingerprint": "2c04133e54348533", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "duplicate", "dry"]}}, {"ruleId": "scanner-9dad557909b86499", "level": "note", "message": {"text": "Near-duplicate function bodies in 10 places"}, "properties": {"repobilityId": "7b77b11c288c20fe", "scanner": "scanner-primary", "fingerprint": "9dad557909b86499", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "duplicate", "dry"]}}, {"ruleId": "scanner-0027e313ade46c8f", "level": "note", "message": {"text": "Near-duplicate function bodies in 7 places"}, "properties": {"repobilityId": "9a1375bce8ecb2c5", "scanner": "scanner-primary", "fingerprint": "0027e313ade46c8f", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "duplicate", "dry"]}}, {"ruleId": "scanner-380b7cb95b387b9c", "level": "note", "message": {"text": "Near-duplicate function bodies in 11 places"}, "properties": {"repobilityId": "8653a19639e9ba8c", "scanner": "scanner-primary", "fingerprint": "380b7cb95b387b9c", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "duplicate", "dry"]}}, {"ruleId": "scanner-33a6b62e30ce7ab4", "level": "note", "message": {"text": "Near-duplicate function bodies in 6 places"}, "properties": {"repobilityId": "dcbc230c9032ee64", "scanner": "scanner-primary", "fingerprint": "33a6b62e30ce7ab4", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "duplicate", "dry"]}}, {"ruleId": "scanner-2c04133e54348533", "level": "note", "message": {"text": "Near-duplicate function bodies in 2 places"}, "properties": {"repobilityId": "3941d7a6b878bc71", "scanner": "scanner-primary", "fingerprint": "2c04133e54348533", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "duplicate", "dry"]}}, {"ruleId": "scanner-be46ea126aa5d8dc", "level": "note", "message": {"text": "Near-duplicate function bodies in 3 places"}, "properties": {"repobilityId": "9d37aaddbea5fd5d", "scanner": "scanner-primary", "fingerprint": "be46ea126aa5d8dc", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "duplicate", "dry"]}}, {"ruleId": "scanner-2c04133e54348533", "level": "note", "message": {"text": "Near-duplicate function bodies in 2 places"}, "properties": {"repobilityId": "03810b8ea4523cb1", "scanner": "scanner-primary", "fingerprint": "2c04133e54348533", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "duplicate", "dry"]}}, {"ruleId": "scanner-2c04133e54348533", "level": "note", "message": {"text": "Near-duplicate function bodies in 2 places"}, "properties": {"repobilityId": "d2522ac6379e14de", "scanner": "scanner-primary", "fingerprint": "2c04133e54348533", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "duplicate", "dry"]}}, {"ruleId": "scanner-2c04133e54348533", "level": "note", "message": {"text": "Near-duplicate function bodies in 2 places"}, "properties": {"repobilityId": "21ad9619f59a38b3", "scanner": "scanner-primary", "fingerprint": "2c04133e54348533", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "duplicate", "dry"]}}, {"ruleId": "scanner-2c04133e54348533", "level": "note", "message": {"text": "Near-duplicate function bodies in 2 places"}, "properties": {"repobilityId": "a88d8616cf849949", "scanner": "scanner-primary", "fingerprint": "2c04133e54348533", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "duplicate", "dry"]}}, {"ruleId": "scanner-2c04133e54348533", "level": "note", "message": {"text": "Near-duplicate function bodies in 2 places"}, "properties": {"repobilityId": "c67519d96d7927d3", "scanner": "scanner-primary", "fingerprint": "2c04133e54348533", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "duplicate", "dry"]}}, {"ruleId": "scanner-2c04133e54348533", "level": "note", "message": {"text": "Near-duplicate function bodies in 2 places"}, "properties": {"repobilityId": "82d350b389044747", "scanner": "scanner-primary", "fingerprint": "2c04133e54348533", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "duplicate", "dry"]}}, {"ruleId": "scanner-2c04133e54348533", "level": "note", "message": {"text": "Near-duplicate function bodies in 2 places"}, "properties": {"repobilityId": "3a309721bc61d292", "scanner": "scanner-primary", "fingerprint": "2c04133e54348533", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "duplicate", "dry"]}}, {"ruleId": "scanner-2c04133e54348533", "level": "note", "message": {"text": "Near-duplicate function bodies in 2 places"}, "properties": {"repobilityId": "ba1ba2c25a613566", "scanner": "scanner-primary", "fingerprint": "2c04133e54348533", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "duplicate", "dry"]}}, {"ruleId": "scanner-2c04133e54348533", "level": "note", "message": {"text": "Near-duplicate function bodies in 2 places"}, "properties": {"repobilityId": "240ee3a2284bc804", "scanner": "scanner-primary", "fingerprint": "2c04133e54348533", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "duplicate", "dry"]}}, {"ruleId": "scanner-e6fab797db1a58c7", "level": "error", "message": {"text": "Dangling fetch: POST /api/chat-notify (chat-widget.js:341)"}, "properties": {"repobilityId": "a56977c1bbfbb2f9", "scanner": "scanner-primary", "fingerprint": "e6fab797db1a58c7", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-2cb00189348eebc1", "level": "error", "message": {"text": "Dangling fetch: POST https://api.brevo.com/v3/smtp/email (functions/api/chat-notify.js:54)"}, "properties": {"repobilityId": "a59f593b0ad84bd1", "scanner": "scanner-primary", "fingerprint": "2cb00189348eebc1", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-2120fa64daf58d5a", "level": "error", "message": {"text": "Dangling fetch: POST https://api.brevo.com/v3/smtp/email (netlify/functions/chat-notify.js:57)"}, "properties": {"repobilityId": "eb7c8b9ad8a51e99", "scanner": "scanner-primary", "fingerprint": "2120fa64daf58d5a", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-c1b864c7ceeaea4c", "level": "error", "message": {"text": "Dangling fetch: POST https://api.brevo.com/v3/smtp/email (app/supabase/functions/notify-artisans/index.ts:181)"}, "properties": {"repobilityId": "12ab2e73f4eb5bb7", "scanner": "scanner-primary", "fingerprint": "c1b864c7ceeaea4c", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-2e4f3592da81e0c0", "level": "error", "message": {"text": "Dangling fetch: POST https://api.brevo.com/v3/smtp/email (app/supabase/functions/stripe-webhook/index.ts:83)"}, "properties": {"repobilityId": "cb7421b1593748e7", "scanner": "scanner-primary", "fingerprint": "2e4f3592da81e0c0", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-531bfad1666296f6", "level": "error", "message": {"text": "Dangling fetch: POST https://api.brevo.com/v3/smtp/email (app/supabase/functions/notify-admin/index.ts:120)"}, "properties": {"repobilityId": "e334ec3b218c9f75", "scanner": "scanner-primary", "fingerprint": "531bfad1666296f6", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-4783f6a2f48df9b2", "level": "error", "message": {"text": "Dangling fetch: POST https://api.brevo.com/v3/smtp/email (app/supabase/functions/notify-client-received/index.ts:133)"}, "properties": {"repobilityId": "94a29f79caaacf88", "scanner": "scanner-primary", "fingerprint": "4783f6a2f48df9b2", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-bf4b9f1319fc31b8", "level": "error", "message": {"text": "Dangling fetch: POST https://api.anthropic.com/v1/messages (app/supabase/functions/ai-devis/index.ts:104)"}, "properties": {"repobilityId": "2d5b407b212b8897", "scanner": "scanner-primary", "fingerprint": "bf4b9f1319fc31b8", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-ca66ac0417d36f63", "level": "error", "message": {"text": "Dangling fetch: POST https://api.brevo.com/v3/smtp/email (app/supabase/functions/notify-client/index.ts:125)"}, "properties": {"repobilityId": "c02a7abb4e49b968", "scanner": "scanner-primary", "fingerprint": "ca66ac0417d36f63", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-813bf4e0ac0e8356", "level": "error", "message": {"text": "Dangling fetch: POST https://api.brevo.com/v3/smtp/email (supabase/functions/notify-artisan-status/index.ts:19)"}, "properties": {"repobilityId": "f3169c313ae04ab8", "scanner": "scanner-primary", "fingerprint": "813bf4e0ac0e8356", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-70c324508414a42f", "level": "error", "message": {"text": "Dangling fetch: POST https://api.brevo.com/v3/smtp/email (supabase/functions/stripe-webhook/index.ts:83)"}, "properties": {"repobilityId": "ac43a0847f7893c6", "scanner": "scanner-primary", "fingerprint": "70c324508414a42f", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-bc12708397ec1473", "level": "error", "message": {"text": "Dangling fetch: POST https://challenges.cloudflare.com/turnstile/v0/siteverify (supabase/functions/verify-turnstile/index.ts:85)"}, "properties": {"repobilityId": "ae3e5d650b44dfc9", "scanner": "scanner-primary", "fingerprint": "bc12708397ec1473", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-5d16331bea0896cb", "level": "note", "message": {"text": "Unused endpoint: POST /api/devis"}, "properties": {"repobilityId": "0f2ca8cfb221b019", "scanner": "scanner-primary", "fingerprint": "5d16331bea0896cb", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-8cfc5990c5256c4d", "level": "note", "message": {"text": "Unused endpoint: GET /api/devis"}, "properties": {"repobilityId": "eddaf8018bc1c67b", "scanner": "scanner-primary", "fingerprint": "8cfc5990c5256c4d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-28ba7495fb562454", "level": "note", "message": {"text": "Unused endpoint: PATCH /api/devis/:id"}, "properties": {"repobilityId": "c197ecd360003d64", "scanner": "scanner-primary", "fingerprint": "28ba7495fb562454", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-37cf54e98ddb0640", "level": "note", "message": {"text": "Unused endpoint: POST /api/partenaires"}, "properties": {"repobilityId": "6e2f17ca25d02719", "scanner": "scanner-primary", "fingerprint": "37cf54e98ddb0640", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-89f77744da833f1c", "level": "note", "message": {"text": "Unused endpoint: GET /api/partenaires"}, "properties": {"repobilityId": "07e8ff1fd178b847", "scanner": "scanner-primary", "fingerprint": "89f77744da833f1c", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-7faee4b552a3a400", "level": "note", "message": {"text": "Unused endpoint: PATCH /api/partenaires/:id"}, "properties": {"repobilityId": "110bccbc30662d29", "scanner": "scanner-primary", "fingerprint": "7faee4b552a3a400", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-dbee21351d4d8a9d", "level": "note", "message": {"text": "Unused endpoint: GET /api/matching"}, "properties": {"repobilityId": "6eee687b194f78e9", "scanner": "scanner-primary", "fingerprint": "dbee21351d4d8a9d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-6791a21d1e6f9d7b", "level": "note", "message": {"text": "Unused endpoint: GET /api/matching/unmatched"}, "properties": {"repobilityId": "7861b558cf7f25e5", "scanner": "scanner-primary", "fingerprint": "6791a21d1e6f9d7b", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-81d625ac6e569e24", "level": "note", "message": {"text": "Unused endpoint: POST /api/matching/devis/:id"}, "properties": {"repobilityId": "db02e12e8cc6d740", "scanner": "scanner-primary", "fingerprint": "81d625ac6e569e24", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-58245afa0f95e822", "level": "note", "message": {"text": "Unused endpoint: POST /api/matching/auto"}, "properties": {"repobilityId": "214b8233149c9fe0", "scanner": "scanner-primary", "fingerprint": "58245afa0f95e822", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-f4aae4086adee82c", "level": "note", "message": {"text": "Unused endpoint: PATCH /api/matching/:id"}, "properties": {"repobilityId": "3246ad5059a63edf", "scanner": "scanner-primary", "fingerprint": "f4aae4086adee82c", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-3b37265900e79a8a", "level": "note", "message": {"text": "Unused endpoint: GET /api/stats"}, "properties": {"repobilityId": "8735764fed7aaaaa", "scanner": "scanner-primary", "fingerprint": "3b37265900e79a8a", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-e83a755eb6a68d43", "level": "note", "message": {"text": "Unused endpoint: GET /api/track/open/:trackId"}, "properties": {"repobilityId": "ad9112d7a3c50621", "scanner": "scanner-primary", "fingerprint": "e83a755eb6a68d43", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-9c8c5f30a2cfc524", "level": "note", "message": {"text": "Unused endpoint: GET /api/track/click/:trackId"}, "properties": {"repobilityId": "0aeabb0115878320", "scanner": "scanner-primary", "fingerprint": "9c8c5f30a2cfc524", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-796454e3b9707cf5", "level": "note", "message": {"text": "Unused endpoint: POST /api/track/log"}, "properties": {"repobilityId": "fe0e5c34ad112d1d", "scanner": "scanner-primary", "fingerprint": "796454e3b9707cf5", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-3b8d2df21c5db121", "level": "note", "message": {"text": "Unused endpoint: POST /api/track/reply"}, "properties": {"repobilityId": "79fe091d4df483a9", "scanner": "scanner-primary", "fingerprint": "3b8d2df21c5db121", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-8fe6b585c3956db9", "level": "note", "message": {"text": "Unused endpoint: POST /api/track/stop"}, "properties": {"repobilityId": "58402884aa8c3030", "scanner": "scanner-primary", "fingerprint": "8fe6b585c3956db9", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-37b1e8fcaa55e10b", "level": "note", "message": {"text": "Unused endpoint: GET /api/track/stats"}, "properties": {"repobilityId": "2af0bb03a2bc7905", "scanner": "scanner-primary", "fingerprint": "37b1e8fcaa55e10b", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-c5c0be9986e25ec4", "level": "note", "message": {"text": "Unused endpoint: GET /api/track/list"}, "properties": {"repobilityId": "d4978120133009dc", "scanner": "scanner-primary", "fingerprint": "c5c0be9986e25ec4", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-912e69ac4feaffd3", "level": "note", "message": {"text": "Unused endpoint: POST /api/checkout"}, "properties": {"repobilityId": "b36b6286cebf6154", "scanner": "scanner-primary", "fingerprint": "912e69ac4feaffd3", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}]}]}