{"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-8844b1cb38dd311e", "name": "Stray `console.log` in TS/JS \u2014 workers/facets-get-users-created-puzzles.js:164", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 workers/facets-get-users-created-puzzles.js:164"}, "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-5e4e752eb7044d46", "name": "Stray `console.log` in TS/JS \u2014 workers/facets-inbox-api.js:417", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 workers/facets-inbox-api.js:417"}, "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-77ccfa0443e50017", "name": "Stray `console.log` in TS/JS \u2014 workers/facets-delete-users-created-puzzle.js:177", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 workers/facets-delete-users-created-puzzle.js: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-eac7b611dfa2633d", "name": "Stray `console.log` in TS/JS \u2014 workers/facets-push-api.js:290", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 workers/facets-push-api.js:290"}, "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-7d47518831e20758", "name": "Stray `console.log` in TS/JS \u2014 workers/facets-check-player-id.js:79", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 workers/facets-check-player-id.js:79"}, "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-123ba1291f2fa62c", "name": "Stray `console.log` in TS/JS \u2014 workers/facets-friends-api.js:304", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 workers/facets-friends-api.js:304"}, "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-978f3181732c3df8", "name": "Stray `console.log` in TS/JS \u2014 workers/facets-save-user-settings.js:154", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 workers/facets-save-user-settings.js:154"}, "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-d46c21a656a44bb0", "name": "Stray `console.log` in TS/JS \u2014 workers/facets-shorturl-api.js:79", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 workers/facets-shorturl-api.js:79"}, "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-00220d2e9268e161", "name": "Stray `console.log` in TS/JS \u2014 workers/deprecated/facets-get-ai-solution.js:114", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 workers/deprecated/facets-get-ai-solution.js:114"}, "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-68fbe710e74a3640", "name": "TODO/FIXME marker in shipping code \u2014 workers/deprecated/facets-save-daily-stats.js:42", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 workers/deprecated/facets-save-daily-stats.js:42"}, "fullDescription": {"text": "Track in /reviews or /issues, not as a code comment that rots.\n\nWhy: Drift control \u2014 shouldn't be the same as Quality TODO scanner.\nRule id: fq.todo-marker"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-25fd19eecf3edfa6", "name": "Stray `console.log` in TS/JS \u2014 public/helpers/console-enhancer.js:53", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 public/helpers/console-enhancer.js:53"}, "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-084ff60e6d1e03f6", "name": "Stray `console.log` in TS/JS \u2014 src/fetch-stats.js:13", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/fetch-stats.js:13"}, "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-f09de46887085727", "name": "Stray `console.log` in TS/JS \u2014 src/sw.js:56", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/sw.js:56"}, "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-9c2767e6450f5a97", "name": "TODO/FIXME marker in shipping code \u2014 src/facets.js:3495", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 src/facets.js:3495"}, "fullDescription": {"text": "Track in /reviews or /issues, not as a code comment that rots.\n\nWhy: Drift control \u2014 shouldn't be the same as Quality TODO scanner.\nRule id: fq.todo-marker"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-47697c1552439bc8", "name": "Stray `console.log` in TS/JS \u2014 src/facets.js:54", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/facets.js:54"}, "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-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-76773e52190952ef", "name": "Insecure pattern 'document_write' in index.html:946", "shortDescription": {"text": "Insecure pattern 'document_write' in index.html:946"}, "fullDescription": {"text": "Found a known-risky pattern (document_write). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "low", "confidence": 1.0}}, {"id": "scanner-5fcae26648cfa1bb", "name": "Insecure pattern 'vue_v_html' in index.html:74", "shortDescription": {"text": "Insecure pattern 'vue_v_html' in index.html:74"}, "fullDescription": {"text": "Found a known-risky pattern (vue_v_html). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-83290ea572901d7e", "name": "Insecure pattern 'cors_wildcard' in workers/facets-puzzle-history-api.js:119", "shortDescription": {"text": "Insecure pattern 'cors_wildcard' in workers/facets-puzzle-history-api.js:119"}, "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-ef9ad9258416c273", "name": "Insecure pattern 'cors_wildcard' in workers/facets-get-users-created-puzzles.js:93", "shortDescription": {"text": "Insecure pattern 'cors_wildcard' in workers/facets-get-users-created-puzzles.js:93"}, "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-4d116b7205243328", "name": "Insecure pattern 'cors_wildcard' in workers/facets-inbox-api.js:639", "shortDescription": {"text": "Insecure pattern 'cors_wildcard' in workers/facets-inbox-api.js:639"}, "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-05bdf37fa3796f53", "name": "Insecure pattern 'cors_wildcard' in workers/facets-delete-users-created-puzzle.js:93", "shortDescription": {"text": "Insecure pattern 'cors_wildcard' in workers/facets-delete-users-created-puzzle.js:93"}, "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-06b4b2e88966cdc4", "name": "Insecure pattern 'cors_wildcard' in workers/facets-push-api.js:371", "shortDescription": {"text": "Insecure pattern 'cors_wildcard' in workers/facets-push-api.js:371"}, "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-ef1247bccb3b974e", "name": "Insecure pattern 'cors_wildcard' in workers/facets-get-global-stats.js:7", "shortDescription": {"text": "Insecure pattern 'cors_wildcard' in workers/facets-get-global-stats.js:7"}, "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-64fba642131a421a", "name": "Insecure pattern 'cors_wildcard' in workers/facets-check-player-id.js:9", "shortDescription": {"text": "Insecure pattern 'cors_wildcard' in workers/facets-check-player-id.js:9"}, "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-ab89986526c76870", "name": "Insecure pattern 'cors_wildcard' in workers/facets-friends-api.js:920", "shortDescription": {"text": "Insecure pattern 'cors_wildcard' in workers/facets-friends-api.js:920"}, "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-15db272f5ae5f121", "name": "Insecure pattern 'cors_wildcard' in workers/facets-save-user-settings.js:89", "shortDescription": {"text": "Insecure pattern 'cors_wildcard' in workers/facets-save-user-settings.js:89"}, "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-4b125f11310543c9", "name": "Insecure pattern 'cors_wildcard' in workers/facets-get-recent-anonymous-games.js:81", "shortDescription": {"text": "Insecure pattern 'cors_wildcard' in workers/facets-get-recent-anonymous-games.js:81"}, "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-3ba5add3c3ec8538", "name": "Insecure pattern 'cors_wildcard' in workers/facets-shorturl-api.js:35", "shortDescription": {"text": "Insecure pattern 'cors_wildcard' in workers/facets-shorturl-api.js:35"}, "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-31e42ad833618ce7", "name": "Insecure pattern 'cors_wildcard' in workers/facets-get-user-settings.js:65", "shortDescription": {"text": "Insecure pattern 'cors_wildcard' in workers/facets-get-user-settings.js:65"}, "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-5ae07ac5993c3d51", "name": "Insecure pattern 'cors_wildcard' in workers/deprecated/facets-get-users-stats.js:39", "shortDescription": {"text": "Insecure pattern 'cors_wildcard' in workers/deprecated/facets-get-users-stats.js:39"}, "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-693788d51bef10d5", "name": "Insecure pattern 'cors_wildcard' in workers/deprecated/facets-get-last-10-daily-games.js:96", "shortDescription": {"text": "Insecure pattern 'cors_wildcard' in workers/deprecated/facets-get-last-10-daily-games.js:96"}, "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-19588e5693db92b1", "name": "Insecure pattern 'cors_wildcard' in workers/deprecated/facets-get-ai-solution.js:8", "shortDescription": {"text": "Insecure pattern 'cors_wildcard' in workers/deprecated/facets-get-ai-solution.js:8"}, "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-f1b0df1271128384", "name": "Insecure pattern 'cors_wildcard' in workers/deprecated/facets-save-daily-stats.js:10", "shortDescription": {"text": "Insecure pattern 'cors_wildcard' in workers/deprecated/facets-save-daily-stats.js:10"}, "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-cf18eab8082cc707", "name": "Insecure pattern 'direct_innerhtml_assignment' in src/fetch-game.js:68", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in src/fetch-game.js:68"}, "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-492c74c8dc2481dd", "name": "Insecure pattern 'local_storage_auth_token' in src/facets.js:2297", "shortDescription": {"text": "Insecure pattern 'local_storage_auth_token' in src/facets.js:2297"}, "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-8ed346220212364a", "name": "Insecure pattern 'direct_innerhtml_assignment' in src/helpers/vue.esm-browser.prod.js:4917", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in src/helpers/vue.esm-browser.prod.js:4917"}, "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-28c4a04bd807da0c", "name": "GitHub Action is tag-pinned rather than SHA-pinned", "shortDescription": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "fullDescription": {"text": "actions/checkout@v5 can move without a code change in this repo. Pin third-party actions to a reviewed 40-character commit SHA."}, "properties": {"scanner": "scanner-primary", "layer": "cicd", "severity": "low", "confidence": 1.0}}, {"id": "scanner-1e62fb269d2f3d19", "name": "Very large file: src/facets.js (6212 lines)", "shortDescription": {"text": "Very large file: src/facets.js (6212 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-ecfcdad6c578f908", "name": "Very large file: src/helpers/vue.esm-browser.prod.js (7522 lines)", "shortDescription": {"text": "Very large file: src/helpers/vue.esm-browser.prod.js (7522 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": "0 test file(s) for 32 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-01f96f71d9907a8c", "name": "README lacks setup or run instructions", "shortDescription": {"text": "README lacks setup or run instructions"}, "fullDescription": {"text": "A README exists, but it does not contain common install/setup/run markers. This matches a frequent generated-code pattern: UI is present, operational handoff is thin."}, "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 44 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-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-11825279136b53a3", "name": "CI is configured but no tests are detected", "shortDescription": {"text": "CI is configured but no tests are detected"}, "fullDescription": {"text": "A CI pipeline exists, but the scan found no test files to gate. Opus labeled this generated-code pattern as config theater: release machinery exists, but it has little behavioral signal."}, "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: tests, operator-readme. 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": "low", "confidence": 1.0}}, {"id": "scanner-749d4bc1bd66df5f", "name": "Agent instructions exist but release-hardening basics are missing", "shortDescription": {"text": "Agent instructions exist but release-hardening basics are missing"}, "fullDescription": {"text": "AI-coder instruction files were found, but the repo is missing tests, operator-readme. Treat this as a contract gap: the agent is guided, but the generated output is not yet guarded by the controls that make it repeatable."}, "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-2f2ddc727656e50b", "name": "Agent authority lacks a verifier contract: .claude/PLAN.md", "shortDescription": {"text": "Agent authority lacks a verifier contract: .claude/PLAN.md"}, "fullDescription": {"text": "This agent instruction grants code or shell authority but does not state the verification gate that decides promotion. The recurring safe pattern is: LLM proposes; deterministic tests/build/security checks verify; only verified code promotes."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-7dbfac0ca60206f3", "name": "`fetch()` without try/.catch or AbortSignal \u2014 workers/facets-puzzle-history-api.js:117", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 workers/facets-puzzle-history-api.js:117"}, "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-902f4c5091328e8d", "name": "`fetch()` without try/.catch or AbortSignal \u2014 workers/facets-get-users-created-puzzles.js:75", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 workers/facets-get-users-created-puzzles.js:75"}, "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-92027b4630777f46", "name": "Commented-code block (8 lines) in workers/facets-inbox-api.js:3", "shortDescription": {"text": "Commented-code block (8 lines) in workers/facets-inbox-api.js:3"}, "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-a3ca2ceeaee0b984", "name": "`fetch()` without try/.catch or AbortSignal \u2014 workers/facets-inbox-api.js:638", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 workers/facets-inbox-api.js:638"}, "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-32178535651837ca", "name": "`fetch()` without try/.catch or AbortSignal \u2014 workers/facets-delete-users-created-puzzle.js:75", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 workers/facets-delete-users-created-puzzle.js:75"}, "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-6eda36fc4ac5d978", "name": "`fetch()` without try/.catch or AbortSignal \u2014 workers/facets-push-api.js:321", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 workers/facets-push-api.js:321"}, "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-446ee2e458d75237", "name": "`fetch()` without try/.catch or AbortSignal \u2014 workers/facets-get-global-stats.js:2", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 workers/facets-get-global-stats.js:2"}, "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-278fe70d3e948454", "name": "`fetch()` without try/.catch or AbortSignal \u2014 workers/facets-check-player-id.js:6", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 workers/facets-check-player-id.js:6"}, "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-9663cbec872e57ad", "name": "Commented-code block (5 lines) in workers/facets-friends-api.js:3", "shortDescription": {"text": "Commented-code block (5 lines) in workers/facets-friends-api.js:3"}, "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-980b4243b411a5f6", "name": "`fetch()` without try/.catch or AbortSignal \u2014 workers/facets-friends-api.js:46", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 workers/facets-friends-api.js:46"}, "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-639faed7cb61be13", "name": "`fetch()` without try/.catch or AbortSignal \u2014 workers/facets-get-created-games.js:5", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 workers/facets-get-created-games.js:5"}, "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-9a3983238d87ef93", "name": "`fetch()` without try/.catch or AbortSignal \u2014 workers/facets-get-recent-anonymous-games.js:7", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 workers/facets-get-recent-anonymous-games.js:7"}, "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-b5a7d492093afbc2", "name": "`fetch()` without try/.catch or AbortSignal \u2014 workers/facets-shorturl-api.js:6", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 workers/facets-shorturl-api.js:6"}, "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-8f7e4463a619a771", "name": "`fetch()` without try/.catch or AbortSignal \u2014 workers/deprecated/facets-get-users-stats.js:7", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 workers/deprecated/facets-get-users-stats.js:7"}, "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-ce40348d7c1a5987", "name": "`fetch()` without try/.catch or AbortSignal \u2014 workers/deprecated/facets-get-last-10-daily-games.js:5", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 workers/deprecated/facets-get-last-10-daily-games.js:5"}, "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-25dcf09245fb841f", "name": "`fetch()` without try/.catch or AbortSignal \u2014 workers/deprecated/facets-get-ai-solution.js:6", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 workers/deprecated/facets-get-ai-solution.js:6"}, "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-1cf00e7cc525643d", "name": "`fetch()` without try/.catch or AbortSignal \u2014 workers/deprecated/facets-save-daily-stats.js:7", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 workers/deprecated/facets-save-daily-stats.js:7"}, "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-ee18443dfa792670", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/fetch-game.js:33", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/fetch-game.js:33"}, "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-4f0ff5bc42ac37de", "name": "Commented-code block (5 lines) in src/facets.js:2280", "shortDescription": {"text": "Commented-code block (5 lines) in src/facets.js:2280"}, "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-e24d273d6d84eb7a", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/facets.js:1552", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/facets.js:1552"}, "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-4694d35eed1b7792", "name": "Commented-code block (6 lines) in src/helpers/api.js:24", "shortDescription": {"text": "Commented-code block (6 lines) in src/helpers/api.js:24"}, "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}}]}}, "automationDetails": {"id": "repobility/22768"}, "properties": {"repository": "wilvoss/facets", "repoUrl": "https://github.com/wilvoss/facets", "branch": "main"}, "results": [{"ruleId": "scanner-8844b1cb38dd311e", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 workers/facets-get-users-created-puzzles.js:164"}, "properties": {"repobilityId": "36136600062948bd", "scanner": "scanner-primary", "fingerprint": "8844b1cb38dd311e", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-5e4e752eb7044d46", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 workers/facets-inbox-api.js:417"}, "properties": {"repobilityId": "f89b1e1c85ab2a2a", "scanner": "scanner-primary", "fingerprint": "5e4e752eb7044d46", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-77ccfa0443e50017", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 workers/facets-delete-users-created-puzzle.js:177"}, "properties": {"repobilityId": "0a5ab976bf7bb533", "scanner": "scanner-primary", "fingerprint": "77ccfa0443e50017", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-eac7b611dfa2633d", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 workers/facets-push-api.js:290"}, "properties": {"repobilityId": "0a5204469ebed93d", "scanner": "scanner-primary", "fingerprint": "eac7b611dfa2633d", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-7d47518831e20758", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 workers/facets-check-player-id.js:79"}, "properties": {"repobilityId": "164cca3a4be0e7eb", "scanner": "scanner-primary", "fingerprint": "7d47518831e20758", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-123ba1291f2fa62c", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 workers/facets-friends-api.js:304"}, "properties": {"repobilityId": "fcdd46d43f173d26", "scanner": "scanner-primary", "fingerprint": "123ba1291f2fa62c", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-978f3181732c3df8", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 workers/facets-save-user-settings.js:154"}, "properties": {"repobilityId": "b891623fc432fd59", "scanner": "scanner-primary", "fingerprint": "978f3181732c3df8", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-d46c21a656a44bb0", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 workers/facets-shorturl-api.js:79"}, "properties": {"repobilityId": "6229cd56237372d5", "scanner": "scanner-primary", "fingerprint": "d46c21a656a44bb0", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-00220d2e9268e161", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 workers/deprecated/facets-get-ai-solution.js:114"}, "properties": {"repobilityId": "a2aeebd184c61233", "scanner": "scanner-primary", "fingerprint": "00220d2e9268e161", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-68fbe710e74a3640", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 workers/deprecated/facets-save-daily-stats.js:42"}, "properties": {"repobilityId": "39022f85333f3069", "scanner": "scanner-primary", "fingerprint": "68fbe710e74a3640", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-25fd19eecf3edfa6", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 public/helpers/console-enhancer.js:53"}, "properties": {"repobilityId": "bc6eed3d06175665", "scanner": "scanner-primary", "fingerprint": "25fd19eecf3edfa6", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-084ff60e6d1e03f6", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/fetch-stats.js:13"}, "properties": {"repobilityId": "6756faec4e70b132", "scanner": "scanner-primary", "fingerprint": "084ff60e6d1e03f6", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-f09de46887085727", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/sw.js:56"}, "properties": {"repobilityId": "4628d2405b8ac2de", "scanner": "scanner-primary", "fingerprint": "f09de46887085727", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-9c2767e6450f5a97", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 src/facets.js:3495"}, "properties": {"repobilityId": "5fca8b6eeef49bf6", "scanner": "scanner-primary", "fingerprint": "9c2767e6450f5a97", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-47697c1552439bc8", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/facets.js:54"}, "properties": {"repobilityId": "5b06a975d64160d8", "scanner": "scanner-primary", "fingerprint": "47697c1552439bc8", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"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-76773e52190952ef", "level": "note", "message": {"text": "Insecure pattern 'document_write' in index.html:946"}, "properties": {"repobilityId": "2884396940812c43", "scanner": "scanner-primary", "fingerprint": "76773e52190952ef", "layer": "security", "severity": "low", "confidence": 1.0, "tags": ["owasp", "document_write"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "index.html"}, "region": {"startLine": 946}}}]}, {"ruleId": "scanner-5fcae26648cfa1bb", "level": "warning", "message": {"text": "Insecure pattern 'vue_v_html' in index.html:74"}, "properties": {"repobilityId": "e113dcd526fea0fe", "scanner": "scanner-primary", "fingerprint": "5fcae26648cfa1bb", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "vue_v_html"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "index.html"}, "region": {"startLine": 74}}}]}, {"ruleId": "scanner-83290ea572901d7e", "level": "warning", "message": {"text": "Insecure pattern 'cors_wildcard' in workers/facets-puzzle-history-api.js:119"}, "properties": {"repobilityId": "98036d6b50f22b2e", "scanner": "scanner-primary", "fingerprint": "83290ea572901d7e", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "cors_wildcard"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "workers/facets-puzzle-history-api.js"}, "region": {"startLine": 119}}}]}, {"ruleId": "scanner-ef9ad9258416c273", "level": "warning", "message": {"text": "Insecure pattern 'cors_wildcard' in workers/facets-get-users-created-puzzles.js:93"}, "properties": {"repobilityId": "72409971c24fc44f", "scanner": "scanner-primary", "fingerprint": "ef9ad9258416c273", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "cors_wildcard"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "workers/facets-get-users-created-puzzles.js"}, "region": {"startLine": 93}}}]}, {"ruleId": "scanner-4d116b7205243328", "level": "warning", "message": {"text": "Insecure pattern 'cors_wildcard' in workers/facets-inbox-api.js:639"}, "properties": {"repobilityId": "7fe28924ee4dcb26", "scanner": "scanner-primary", "fingerprint": "4d116b7205243328", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "cors_wildcard"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "workers/facets-inbox-api.js"}, "region": {"startLine": 639}}}]}, {"ruleId": "scanner-05bdf37fa3796f53", "level": "warning", "message": {"text": "Insecure pattern 'cors_wildcard' in workers/facets-delete-users-created-puzzle.js:93"}, "properties": {"repobilityId": "a3375623f3a8cd33", "scanner": "scanner-primary", "fingerprint": "05bdf37fa3796f53", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "cors_wildcard"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "workers/facets-delete-users-created-puzzle.js"}, "region": {"startLine": 93}}}]}, {"ruleId": "scanner-06b4b2e88966cdc4", "level": "warning", "message": {"text": "Insecure pattern 'cors_wildcard' in workers/facets-push-api.js:371"}, "properties": {"repobilityId": "1ebd990289cd392a", "scanner": "scanner-primary", "fingerprint": "06b4b2e88966cdc4", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "cors_wildcard"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "workers/facets-push-api.js"}, "region": {"startLine": 371}}}]}, {"ruleId": "scanner-ef1247bccb3b974e", "level": "warning", "message": {"text": "Insecure pattern 'cors_wildcard' in workers/facets-get-global-stats.js:7"}, "properties": {"repobilityId": "c9ff48e69f6084eb", "scanner": "scanner-primary", "fingerprint": "ef1247bccb3b974e", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "cors_wildcard"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "workers/facets-get-global-stats.js"}, "region": {"startLine": 7}}}]}, {"ruleId": "scanner-64fba642131a421a", "level": "warning", "message": {"text": "Insecure pattern 'cors_wildcard' in workers/facets-check-player-id.js:9"}, "properties": {"repobilityId": "7b57f712df807da1", "scanner": "scanner-primary", "fingerprint": "64fba642131a421a", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "cors_wildcard"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "workers/facets-check-player-id.js"}, "region": {"startLine": 9}}}]}, {"ruleId": "scanner-ab89986526c76870", "level": "warning", "message": {"text": "Insecure pattern 'cors_wildcard' in workers/facets-friends-api.js:920"}, "properties": {"repobilityId": "e0eda79dada2f40d", "scanner": "scanner-primary", "fingerprint": "ab89986526c76870", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "cors_wildcard"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "workers/facets-friends-api.js"}, "region": {"startLine": 920}}}]}, {"ruleId": "scanner-15db272f5ae5f121", "level": "warning", "message": {"text": "Insecure pattern 'cors_wildcard' in workers/facets-save-user-settings.js:89"}, "properties": {"repobilityId": "72dfd5f79bb69a96", "scanner": "scanner-primary", "fingerprint": "15db272f5ae5f121", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "cors_wildcard"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "workers/facets-save-user-settings.js"}, "region": {"startLine": 89}}}]}, {"ruleId": "scanner-4b125f11310543c9", "level": "warning", "message": {"text": "Insecure pattern 'cors_wildcard' in workers/facets-get-recent-anonymous-games.js:81"}, "properties": {"repobilityId": "485fe091784b7a1b", "scanner": "scanner-primary", "fingerprint": "4b125f11310543c9", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "cors_wildcard"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "workers/facets-get-recent-anonymous-games.js"}, "region": {"startLine": 81}}}]}, {"ruleId": "scanner-3ba5add3c3ec8538", "level": "warning", "message": {"text": "Insecure pattern 'cors_wildcard' in workers/facets-shorturl-api.js:35"}, "properties": {"repobilityId": "55f1a3a4e90b44ac", "scanner": "scanner-primary", "fingerprint": "3ba5add3c3ec8538", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "cors_wildcard"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "workers/facets-shorturl-api.js"}, "region": {"startLine": 35}}}]}, {"ruleId": "scanner-31e42ad833618ce7", "level": "warning", "message": {"text": "Insecure pattern 'cors_wildcard' in workers/facets-get-user-settings.js:65"}, "properties": {"repobilityId": "7a654e8153b469a3", "scanner": "scanner-primary", "fingerprint": "31e42ad833618ce7", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "cors_wildcard"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "workers/facets-get-user-settings.js"}, "region": {"startLine": 65}}}]}, {"ruleId": "scanner-5ae07ac5993c3d51", "level": "warning", "message": {"text": "Insecure pattern 'cors_wildcard' in workers/deprecated/facets-get-users-stats.js:39"}, "properties": {"repobilityId": "8bc416a8cd79385e", "scanner": "scanner-primary", "fingerprint": "5ae07ac5993c3d51", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "cors_wildcard"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "workers/deprecated/facets-get-users-stats.js"}, "region": {"startLine": 39}}}]}, {"ruleId": "scanner-693788d51bef10d5", "level": "warning", "message": {"text": "Insecure pattern 'cors_wildcard' in workers/deprecated/facets-get-last-10-daily-games.js:96"}, "properties": {"repobilityId": "2c1f797ba544c230", "scanner": "scanner-primary", "fingerprint": "693788d51bef10d5", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "cors_wildcard"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "workers/deprecated/facets-get-last-10-daily-games.js"}, "region": {"startLine": 96}}}]}, {"ruleId": "scanner-19588e5693db92b1", "level": "warning", "message": {"text": "Insecure pattern 'cors_wildcard' in workers/deprecated/facets-get-ai-solution.js:8"}, "properties": {"repobilityId": "a9d1841cd455c839", "scanner": "scanner-primary", "fingerprint": "19588e5693db92b1", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "cors_wildcard"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "workers/deprecated/facets-get-ai-solution.js"}, "region": {"startLine": 8}}}]}, {"ruleId": "scanner-f1b0df1271128384", "level": "warning", "message": {"text": "Insecure pattern 'cors_wildcard' in workers/deprecated/facets-save-daily-stats.js:10"}, "properties": {"repobilityId": "5e933a0b3456933b", "scanner": "scanner-primary", "fingerprint": "f1b0df1271128384", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "cors_wildcard"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "workers/deprecated/facets-save-daily-stats.js"}, "region": {"startLine": 10}}}]}, {"ruleId": "scanner-cf18eab8082cc707", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in src/fetch-game.js:68"}, "properties": {"repobilityId": "9af83aeadd1b3bb0", "scanner": "scanner-primary", "fingerprint": "cf18eab8082cc707", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/fetch-game.js"}, "region": {"startLine": 68}}}]}, {"ruleId": "scanner-492c74c8dc2481dd", "level": "warning", "message": {"text": "Insecure pattern 'local_storage_auth_token' in src/facets.js:2297"}, "properties": {"repobilityId": "e2fbd150a0d02270", "scanner": "scanner-primary", "fingerprint": "492c74c8dc2481dd", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "local_storage_auth_token"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/facets.js"}, "region": {"startLine": 2297}}}]}, {"ruleId": "scanner-8ed346220212364a", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in src/helpers/vue.esm-browser.prod.js:4917"}, "properties": {"repobilityId": "d595a3693113f457", "scanner": "scanner-primary", "fingerprint": "8ed346220212364a", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/helpers/vue.esm-browser.prod.js"}, "region": {"startLine": 4917}}}]}, {"ruleId": "scanner-28c4a04bd807da0c", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "e90842e167ad707e", "scanner": "scanner-primary", "fingerprint": "28c4a04bd807da0c", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/deploy.yml"}, "region": {"startLine": 15}}}]}, {"ruleId": "scanner-28c4a04bd807da0c", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "ab9c1269f3f77e87", "scanner": "scanner-primary", "fingerprint": "28c4a04bd807da0c", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/deploy.yml"}, "region": {"startLine": 18}}}]}, {"ruleId": "scanner-28c4a04bd807da0c", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "a9c84d2097773eeb", "scanner": "scanner-primary", "fingerprint": "28c4a04bd807da0c", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/deploy.yml"}, "region": {"startLine": 41}}}]}, {"ruleId": "scanner-1e62fb269d2f3d19", "level": "note", "message": {"text": "Very large file: src/facets.js (6212 lines)"}, "properties": {"repobilityId": "c945359f05a102fc", "scanner": "scanner-primary", "fingerprint": "1e62fb269d2f3d19", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-ecfcdad6c578f908", "level": "note", "message": {"text": "Very large file: src/helpers/vue.esm-browser.prod.js (7522 lines)"}, "properties": {"repobilityId": "82381ceea9a9428d", "scanner": "scanner-primary", "fingerprint": "ecfcdad6c578f908", "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-01f96f71d9907a8c", "level": "note", "message": {"text": "README lacks setup or run instructions"}, "properties": {"repobilityId": "d3e7347174323e3a", "scanner": "scanner-primary", "fingerprint": "01f96f71d9907a8c", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["docs", "readme", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-3ab5d313dda8e5f9", "level": "note", "message": {"text": "Debug logging residue appears in source files"}, "properties": {"repobilityId": "33a0b83432fc1297", "scanner": "scanner-primary", "fingerprint": "3ab5d313dda8e5f9", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["debug", "cleanup", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-2d0c7b7ab8f8aacf", "level": "warning", "message": {"text": "Critical user flow still appears backed by mock or placeholder data"}, "properties": {"repobilityId": "552764ef54380607", "scanner": "scanner-primary", "fingerprint": "2d0c7b7ab8f8aacf", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "critical-flow", "generated-repo-pattern"]}}, {"ruleId": "scanner-11825279136b53a3", "level": "warning", "message": {"text": "CI is configured but no tests are detected"}, "properties": {"repobilityId": "b4330175087ec076", "scanner": "scanner-primary", "fingerprint": "11825279136b53a3", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["tests", "ci", "config-theater", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-b9088664ace7f748", "level": "note", "message": {"text": "Composite production-readiness gap"}, "properties": {"repobilityId": "e705f041bdf0cf6a", "scanner": "scanner-primary", "fingerprint": "b9088664ace7f748", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["production-readiness", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-749d4bc1bd66df5f", "level": "warning", "message": {"text": "Agent instructions exist but release-hardening basics are missing"}, "properties": {"repobilityId": "8cb74b9aed45cf9a", "scanner": "scanner-primary", "fingerprint": "749d4bc1bd66df5f", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-ea8f3013f588db25", "level": "note", "message": {"text": "Shallow git history limits provenance confidence"}, "properties": {"repobilityId": "eaa0ddd9becae7a5", "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": "a9918ebad249de82", "scanner": "scanner-primary", "fingerprint": "8424db9c75e04ba4", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["provenance", "git-history", "generated-repo-pattern"]}}, {"ruleId": "scanner-2f2ddc727656e50b", "level": "warning", "message": {"text": "Agent authority lacks a verifier contract: .claude/PLAN.md"}, "properties": {"repobilityId": "3bb398772ac65c56", "scanner": "scanner-primary", "fingerprint": "2f2ddc727656e50b", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "verification", "claude_instruction"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".claude/PLAN.md"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-7dbfac0ca60206f3", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 workers/facets-puzzle-history-api.js:117"}, "properties": {"repobilityId": "3db22dc1d4c5e06d", "scanner": "scanner-primary", "fingerprint": "7dbfac0ca60206f3", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-902f4c5091328e8d", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 workers/facets-get-users-created-puzzles.js:75"}, "properties": {"repobilityId": "6a2a783c1414dcf5", "scanner": "scanner-primary", "fingerprint": "902f4c5091328e8d", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-92027b4630777f46", "level": "none", "message": {"text": "Commented-code block (8 lines) in workers/facets-inbox-api.js:3"}, "properties": {"repobilityId": "a7cfdf2718f154dc", "scanner": "scanner-primary", "fingerprint": "92027b4630777f46", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-a3ca2ceeaee0b984", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 workers/facets-inbox-api.js:638"}, "properties": {"repobilityId": "7bf64460eddfd535", "scanner": "scanner-primary", "fingerprint": "a3ca2ceeaee0b984", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-32178535651837ca", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 workers/facets-delete-users-created-puzzle.js:75"}, "properties": {"repobilityId": "286f62e85f44c446", "scanner": "scanner-primary", "fingerprint": "32178535651837ca", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-6eda36fc4ac5d978", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 workers/facets-push-api.js:321"}, "properties": {"repobilityId": "c419c5ab4a1626a2", "scanner": "scanner-primary", "fingerprint": "6eda36fc4ac5d978", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-446ee2e458d75237", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 workers/facets-get-global-stats.js:2"}, "properties": {"repobilityId": "c11a37ed751166ac", "scanner": "scanner-primary", "fingerprint": "446ee2e458d75237", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-278fe70d3e948454", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 workers/facets-check-player-id.js:6"}, "properties": {"repobilityId": "c138d26ea3438354", "scanner": "scanner-primary", "fingerprint": "278fe70d3e948454", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-9663cbec872e57ad", "level": "none", "message": {"text": "Commented-code block (5 lines) in workers/facets-friends-api.js:3"}, "properties": {"repobilityId": "44a4160ed7174852", "scanner": "scanner-primary", "fingerprint": "9663cbec872e57ad", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-980b4243b411a5f6", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 workers/facets-friends-api.js:46"}, "properties": {"repobilityId": "a69a404c85139487", "scanner": "scanner-primary", "fingerprint": "980b4243b411a5f6", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-639faed7cb61be13", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 workers/facets-get-created-games.js:5"}, "properties": {"repobilityId": "ab7ae4eeab7ae0b1", "scanner": "scanner-primary", "fingerprint": "639faed7cb61be13", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-9a3983238d87ef93", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 workers/facets-get-recent-anonymous-games.js:7"}, "properties": {"repobilityId": "8ca712c60bb232a8", "scanner": "scanner-primary", "fingerprint": "9a3983238d87ef93", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-b5a7d492093afbc2", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 workers/facets-shorturl-api.js:6"}, "properties": {"repobilityId": "001fdf1824f3f829", "scanner": "scanner-primary", "fingerprint": "b5a7d492093afbc2", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-8f7e4463a619a771", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 workers/deprecated/facets-get-users-stats.js:7"}, "properties": {"repobilityId": "1142132bc32225b0", "scanner": "scanner-primary", "fingerprint": "8f7e4463a619a771", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-ce40348d7c1a5987", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 workers/deprecated/facets-get-last-10-daily-games.js:5"}, "properties": {"repobilityId": "f8f188c0a9d02cb6", "scanner": "scanner-primary", "fingerprint": "ce40348d7c1a5987", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-25dcf09245fb841f", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 workers/deprecated/facets-get-ai-solution.js:6"}, "properties": {"repobilityId": "c1ca229fcf7297e9", "scanner": "scanner-primary", "fingerprint": "25dcf09245fb841f", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-1cf00e7cc525643d", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 workers/deprecated/facets-save-daily-stats.js:7"}, "properties": {"repobilityId": "f4551588951a4870", "scanner": "scanner-primary", "fingerprint": "1cf00e7cc525643d", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-ee18443dfa792670", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/fetch-game.js:33"}, "properties": {"repobilityId": "501df3dbed8e5bfc", "scanner": "scanner-primary", "fingerprint": "ee18443dfa792670", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-4f0ff5bc42ac37de", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/facets.js:2280"}, "properties": {"repobilityId": "4c66b175330afd37", "scanner": "scanner-primary", "fingerprint": "4f0ff5bc42ac37de", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-e24d273d6d84eb7a", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/facets.js:1552"}, "properties": {"repobilityId": "7c8fdece4ea47166", "scanner": "scanner-primary", "fingerprint": "e24d273d6d84eb7a", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-4694d35eed1b7792", "level": "none", "message": {"text": "Commented-code block (6 lines) in src/helpers/api.js:24"}, "properties": {"repobilityId": "545d79a13e18647d", "scanner": "scanner-primary", "fingerprint": "4694d35eed1b7792", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}]}]}