{"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-d104698065730b6c", "name": "Possibly dead Python function: hidden_run", "shortDescription": {"text": "Possibly dead Python function: hidden_run"}, "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-bf79adad4f527f83", "name": "Possibly dead Python function: hidden_popen", "shortDescription": {"text": "Possibly dead Python function: hidden_popen"}, "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-bb5324026d660ebc", "name": "Possibly dead Python function: is_systemd_service_active", "shortDescription": {"text": "Possibly dead Python function: is_systemd_service_active"}, "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-42404f28c4224378", "name": "Possibly dead Python function: worker", "shortDescription": {"text": "Possibly dead Python function: worker"}, "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-e83dbfc6f76f1375", "name": "Possibly dead Python function: run_kg_link_mastery", "shortDescription": {"text": "Possibly dead Python function: run_kg_link_mastery"}, "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-4f13d81722c59f19", "name": "Possibly dead Python function: step_weak", "shortDescription": {"text": "Possibly dead Python function: step_weak"}, "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-e446d1d203e1f8b0", "name": "Possibly dead Python function: step_antimodel", "shortDescription": {"text": "Possibly dead Python function: step_antimodel"}, "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-3dc14abbb974fef1", "name": "Possibly dead Python function: step_quality", "shortDescription": {"text": "Possibly dead Python function: step_quality"}, "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-f78974ab9ff339ca", "name": "Possibly dead Python function: run_smoke_tests", "shortDescription": {"text": "Possibly dead Python function: run_smoke_tests"}, "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-ada41286e941ae05", "name": "Possibly dead Python function: deploy_dashboard", "shortDescription": {"text": "Possibly dead Python function: deploy_dashboard"}, "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-e38ffb3f04d74ee9", "name": "Possibly dead Python function: sync_ankiweb", "shortDescription": {"text": "Possibly dead Python function: sync_ankiweb"}, "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-e518cd23af870bcc", "name": "Possibly dead Python function: replace_callout", "shortDescription": {"text": "Possibly dead Python function: replace_callout"}, "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-e50fdf3cf612873a", "name": "Possibly dead Python function: no_cards_record", "shortDescription": {"text": "Possibly dead Python function: no_cards_record"}, "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-36d30752a26e0b87", "name": "Possibly dead Python function: has_text_layer", "shortDescription": {"text": "Possibly dead Python function: has_text_layer"}, "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-e5a791ac37434ab7", "name": "Possibly dead Python function: handle_qa", "shortDescription": {"text": "Possibly dead Python function: handle_qa"}, "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-fd9aad110edf53cf", "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-4c1b1e9643ec1f06", "name": "Possibly dead Python function: do_GET", "shortDescription": {"text": "Possibly dead Python function: do_GET"}, "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-5a39a9122872a4bb", "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-21c42f7d9380cebf", "name": "Possibly dead Python function: judge_one_note", "shortDescription": {"text": "Possibly dead Python function: judge_one_note"}, "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-989e2128ca53b5ca", "name": "Possibly dead Python function: link_l1", "shortDescription": {"text": "Possibly dead Python function: link_l1"}, "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-b4725ed0cf3b6421", "name": "Possibly dead Python function: process_unit", "shortDescription": {"text": "Possibly dead Python function: process_unit"}, "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-59c0f08e1169b39b", "name": "Possibly dead Python function: is_trivial_mechanical", "shortDescription": {"text": "Possibly dead Python function: is_trivial_mechanical"}, "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-28903bd962cff9aa", "name": "Possibly dead Python function: audit_one_node", "shortDescription": {"text": "Possibly dead Python function: audit_one_node"}, "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-f2df328eef9945e7", "name": "Possibly dead Python function: audit_deep_one_node", "shortDescription": {"text": "Possibly dead Python function: audit_deep_one_node"}, "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-1cd523234bdc053b", "name": "Possibly dead Python function: judge_group", "shortDescription": {"text": "Possibly dead Python function: judge_group"}, "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-585a623afc44258e", "name": "Possibly dead Python function: translate_examples", "shortDescription": {"text": "Possibly dead Python function: translate_examples"}, "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-c5daa200464ca472", "name": "Possibly dead Python function: reset_to_zero", "shortDescription": {"text": "Possibly dead Python function: reset_to_zero"}, "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-486a7b6caffdb3a2", "name": "Possibly dead Python function: lookup_free_dict", "shortDescription": {"text": "Possibly dead Python function: lookup_free_dict"}, "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-184b7bea5e548af4", "name": "Possibly dead Python function: lookup_mw_learner", "shortDescription": {"text": "Possibly dead Python function: lookup_mw_learner"}, "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-8d4af49886be79c2", "name": "Icon-only button without accessible name \u2014 _server_deploy/static/pdf/reader.js:2739", "shortDescription": {"text": "Icon-only button without accessible name \u2014 _server_deploy/static/pdf/reader.js:2739"}, "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-b23327875be64f63", "name": "Icon-only button without accessible name \u2014 _server_deploy/static/pdf/reader.src/12-vocab-sentences.js:481", "shortDescription": {"text": "Icon-only button without accessible name \u2014 _server_deploy/static/pdf/reader.src/12-vocab-sentences.js:481"}, "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-2905e0bee152be7b", "name": "Stray `console.log` in TS/JS \u2014 _server_deploy/static/three/three.module.min.js:6", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 _server_deploy/static/three/three.module.min.js:6"}, "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-c1bccc4d8687dde2", "name": "Insecure pattern 'direct_innerhtml_assignment' in dashboard/index.html:742", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in dashboard/index.html:742"}, "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-93efd27d1a81fabf", "name": "Insecure pattern 'direct_innerhtml_assignment' in _client/core/qa_browser.py:1701", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in _client/core/qa_browser.py:1701"}, "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-a5275302ca6dae27", "name": "Insecure pattern 'cors_wildcard' in _client/core/qa_browser.py:2789", "shortDescription": {"text": "Insecure pattern 'cors_wildcard' in _client/core/qa_browser.py:2789"}, "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-72a4f9bb63246b3e", "name": "Insecure pattern 'direct_innerhtml_assignment' in _server_deploy/static/nav.js:193", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in _server_deploy/static/nav.js: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-6349f2f97b06f228", "name": "Insecure pattern 'direct_innerhtml_assignment' in _server_deploy/static/pdf/reader.js:498", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in _server_deploy/static/pdf/reader.js:498"}, "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-57db75bc66518a90", "name": "Insecure pattern 'direct_innerhtml_assignment' in _server_deploy/static/pdf/reader.src/21-misc-ai.js:42", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in _server_deploy/static/pdf/reader.src/21-misc-ai.js:42"}, "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-cc55bb15ad68ad38", "name": "Insecure pattern 'direct_innerhtml_assignment' in _server_deploy/static/pdf/reader.src/17-highlight.js:55", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in _server_deploy/static/pdf/reader.src/17-highlight.js:55"}, "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-f57f7b8ec67a6902", "name": "Insecure pattern 'direct_innerhtml_assignment' in _server_deploy/static/pdf/reader.src/04-render.js:109", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in _server_deploy/static/pdf/reader.src/04-render.js:109"}, "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-4c02d44e247c1720", "name": "Insecure pattern 'direct_innerhtml_assignment' in _server_deploy/static/pdf/reader.src/05-nav.js:8", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in _server_deploy/static/pdf/reader.src/05-nav.js:8"}, "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-b4ad1bb019964f94", "name": "Insecure pattern 'direct_innerhtml_assignment' in _server_deploy/static/pdf/reader.src/07-continuous.js:3", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in _server_deploy/static/pdf/reader.src/07-continuous.js:3"}, "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-5c9f060e3cd0331a", "name": "Insecure pattern 'direct_innerhtml_assignment' in _server_deploy/static/pdf/reader.src/20-result-draft.js:6", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in _server_deploy/static/pdf/reader.src/20-result-draft.js:6"}, "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-99faefbf51de6de5", "name": "Insecure pattern 'direct_innerhtml_assignment' in _server_deploy/static/pdf/reader.src/16-caret-select.js:64", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in _server_deploy/static/pdf/reader.src/16-caret-select.js:64"}, "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-286d2842d1d6830a", "name": "Insecure pattern 'direct_innerhtml_assignment' in _server_deploy/static/pdf/reader.src/03-loader.js:235", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in _server_deploy/static/pdf/reader.src/03-loader.js:235"}, "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-541e96c942d210c5", "name": "Insecure pattern 'direct_innerhtml_assignment' in _server_deploy/static/pdf/reader.src/18-grammar.js:52", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in _server_deploy/static/pdf/reader.src/18-grammar.js:52"}, "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-4ddc6994af6ed81d", "name": "Insecure pattern 'direct_innerhtml_assignment' in _server_deploy/static/pdf/reader.src/19-dict.js:65", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in _server_deploy/static/pdf/reader.src/19-dict.js:65"}, "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-7c9d2ddcfffb7e00", "name": "Insecure pattern 'direct_innerhtml_assignment' in _server_deploy/static/pdf/reader.src/11-search.js:19", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in _server_deploy/static/pdf/reader.src/11-search.js:19"}, "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-032f8d6501e9d56d", "name": "Insecure pattern 'direct_innerhtml_assignment' in _server_deploy/static/pdf/reader.src/08-charlayer.js:56", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in _server_deploy/static/pdf/reader.src/08-charlayer.js:56"}, "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-fec700a3d031fc2e", "name": "Insecure pattern 'direct_innerhtml_assignment' in _server_deploy/static/pdf/reader.src/12-vocab-sentences.js:291", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in _server_deploy/static/pdf/reader.src/12-vocab-sentences.js:291"}, "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-1dfc8bbe93ed5b50", "name": "Insecure pattern 'direct_innerhtml_assignment' in _server_deploy/static/pdf/reader.src/15-phrase-wordpop.js:79", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in _server_deploy/static/pdf/reader.src/15-phrase-wordpop.js:79"}, "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-9c8ec43a1f962ffc", "name": "Insecure pattern 'direct_innerhtml_assignment' in _server_deploy/static/pdf/reader.src/09-ruby.js:8", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in _server_deploy/static/pdf/reader.src/09-ruby.js:8"}, "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-f4ab67d8eea0e59b", "name": "Insecure pattern 'direct_innerhtml_assignment' in _server_deploy/static/pdf/reader.src/23-bookshelf.js:11", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in _server_deploy/static/pdf/reader.src/23-bookshelf.js:11"}, "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-b7d43d27ef4026a8", "name": "Insecure pattern 'direct_innerhtml_assignment' in _server_deploy/static/pdf/reader.src/13-selection.js:202", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in _server_deploy/static/pdf/reader.src/13-selection.js:202"}, "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-73daaa9412ad3d43", "name": "Insecure pattern 'direct_innerhtml_assignment' in _server_deploy/static/pdf/reader.src/14-textlayer-legacy.js:80", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in _server_deploy/static/pdf/reader.src/14-textlayer-legacy.js:80"}, "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-56c39bd510a51890", "name": "Insecure pattern 'direct_innerhtml_assignment' in _server_deploy/history/index.html:936", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in _server_deploy/history/index.html:936"}, "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-63a3793e2b661ded", "name": "Insecure pattern 'direct_innerhtml_assignment' in launchers/\u5386\u53f2\u67e5\u770b.py:142", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in launchers/\u5386\u53f2\u67e5\u770b.py:142"}, "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-0f2d0a5cb2d43789", "name": "Insecure pattern 'direct_outerhtml_assignment' in launchers/\u5386\u53f2\u67e5\u770b.py:202", "shortDescription": {"text": "Insecure pattern 'direct_outerhtml_assignment' in launchers/\u5386\u53f2\u67e5\u770b.py:202"}, "fullDescription": {"text": "Found a known-risky pattern (direct_outerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-c752b3fefa3c05f4", "name": "Insecure pattern 'cors_wildcard' in launchers/\u5386\u53f2\u67e5\u770b.py:296", "shortDescription": {"text": "Insecure pattern 'cors_wildcard' in launchers/\u5386\u53f2\u67e5\u770b.py:296"}, "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-c43c2a480e74993e", "name": "Insecure pattern 'direct_innerhtml_assignment' in launchers/\u622a\u56fe\u95ee\u7b54.py:782", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in launchers/\u622a\u56fe\u95ee\u7b54.py:782"}, "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-609a150083b9a278", "name": "Insecure pattern 'cors_wildcard' in launchers/\u622a\u56fe\u95ee\u7b54.py:1200", "shortDescription": {"text": "Insecure pattern 'cors_wildcard' in launchers/\u622a\u56fe\u95ee\u7b54.py:1200"}, "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-2cd6f0ea2dc13021", "name": "Insecure pattern 'direct_innerhtml_assignment' in history/index.html:124", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in history/index.html:124"}, "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-3172c44b3f82a640", "name": "Insecure pattern 'direct_outerhtml_assignment' in history/index.html:174", "shortDescription": {"text": "Insecure pattern 'direct_outerhtml_assignment' in history/index.html:174"}, "fullDescription": {"text": "Found a known-risky pattern (direct_outerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-9973b587cd0089b1", "name": "Very large file: _client/core/qa_browser.py (3418 lines)", "shortDescription": {"text": "Very large file: _client/core/qa_browser.py (3418 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-b42f94ca8a950669", "name": "Very large file: _client/core/gui.py (1948 lines)", "shortDescription": {"text": "Very large file: _client/core/gui.py (1948 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-a731b2590372c93d", "name": "Very large file: _server_deploy/pdf_reader.py (5707 lines)", "shortDescription": {"text": "Very large file: _server_deploy/pdf_reader.py (5707 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-69b7f77ed032b128", "name": "Very large file: _server_deploy/static/pdf/reader.js (7622 lines)", "shortDescription": {"text": "Very large file: _server_deploy/static/pdf/reader.js (7622 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-0d5bab0ccc4cff99", "name": "Very large file: _server_deploy/static/three/GLTFLoader.js (4725 lines)", "shortDescription": {"text": "Very large file: _server_deploy/static/three/GLTFLoader.js (4725 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-c4964bd75f649851", "name": "Very large file: launchers/\u622a\u56fe\u95ee\u7b54.py (1571 lines)", "shortDescription": {"text": "Very large file: launchers/\u622a\u56fe\u95ee\u7b54.py (1571 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": "5 test file(s) for 152 source file(s) (ratio 0.03). 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 741 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 41 placeholder/mock markers across 11 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. 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 license, ci. 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-05f5478d21665a25", "name": "Agent authority lacks a verifier contract: .claude/skills/pdf-mark.md", "shortDescription": {"text": "Agent authority lacks a verifier contract: .claude/skills/pdf-mark.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-7910530bc2f8dc38", "name": "Agent authority lacks a verifier contract: .claude/skills/\u767b\u8bb0\u65b0\u7b14\u8bb0.md", "shortDescription": {"text": "Agent authority lacks a verifier contract: .claude/skills/\u767b\u8bb0\u65b0\u7b14\u8bb0.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-b8e8475ba8bb912d", "name": "Agent authority lacks a verifier contract: .claude/skills/openai-cli-chat.md", "shortDescription": {"text": "Agent authority lacks a verifier contract: .claude/skills/openai-cli-chat.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-1d0865b06dd19e56", "name": "Agent authority lacks a verifier contract: .claude/skills/claude-quota.md", "shortDescription": {"text": "Agent authority lacks a verifier contract: .claude/skills/claude-quota.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-6639ce3ba76a0320", "name": "Agent authority lacks a verifier contract: .claude/skills/website.md", "shortDescription": {"text": "Agent authority lacks a verifier contract: .claude/skills/website.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-2013d507601d029b", "name": "Network/subprocess call without timeout or try/except \u2014 scripts/register_notes.py:56", "shortDescription": {"text": "Network/subprocess call without timeout or try/except \u2014 scripts/register_notes.py:56"}, "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-29697c4a66e58a42", "name": "Stub function `update` (body is just `pass`/`return`) \u2014 scripts/register_notes.py:468", "shortDescription": {"text": "Stub function `update` (body is just `pass`/`return`) \u2014 scripts/register_notes.py:468"}, "fullDescription": {"text": "Likely an AI scaffold that was never filled in. Remove or implement."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-41efef83219ae056", "name": "Network/subprocess call without timeout or try/except \u2014 scripts/platform_utils.py:13", "shortDescription": {"text": "Network/subprocess call without timeout or try/except \u2014 scripts/platform_utils.py:13"}, "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-b49b44c23d6c4b1b", "name": "Network/subprocess call without timeout or try/except \u2014 scripts/prewarm_pdf.py:25", "shortDescription": {"text": "Network/subprocess call without timeout or try/except \u2014 scripts/prewarm_pdf.py:25"}, "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-1fce2d1cab391f68", "name": "Network/subprocess call without timeout or try/except \u2014 scripts/quick_sync.py:27", "shortDescription": {"text": "Network/subprocess call without timeout or try/except \u2014 scripts/quick_sync.py:27"}, "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-a84ad1cc4645bcf5", "name": "Commented-code block (5 lines) in scripts/find_jeff_videos.py:44", "shortDescription": {"text": "Commented-code block (5 lines) in scripts/find_jeff_videos.py:44"}, "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-e61306696f568e3a", "name": "Network/subprocess call without timeout or try/except \u2014 scripts/daily_anki_status.py:197", "shortDescription": {"text": "Network/subprocess call without timeout or try/except \u2014 scripts/daily_anki_status.py:197"}, "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-e4903607a176b389", "name": "Network/subprocess call without timeout or try/except \u2014 scripts/annotate_note.py:35", "shortDescription": {"text": "Network/subprocess call without timeout or try/except \u2014 scripts/annotate_note.py:35"}, "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-8a290cf533c2604e", "name": "Commented-code block (5 lines) in scripts/embed_ocr_to_pdf.py:207", "shortDescription": {"text": "Commented-code block (5 lines) in scripts/embed_ocr_to_pdf.py:207"}, "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-ad6b3577e1e3692f", "name": "Commented-code block (7 lines) in scripts/export_dashboard.py:102", "shortDescription": {"text": "Commented-code block (7 lines) in scripts/export_dashboard.py:102"}, "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-6072259105b7f1f9", "name": "Legacy-named symbol `_file_hash_legacy` in scripts/cleanup_orphans.py:139", "shortDescription": {"text": "Legacy-named symbol `_file_hash_legacy` in scripts/cleanup_orphans.py:139"}, "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-26fd47d997f462b5", "name": "Legacy-named symbol `_file_hash_legacy` in scripts/note_state.py:44", "shortDescription": {"text": "Legacy-named symbol `_file_hash_legacy` in scripts/note_state.py:44"}, "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-1d0311733125d824", "name": "Network/subprocess call without timeout or try/except \u2014 scripts/book_ocr_watchdog.py:42", "shortDescription": {"text": "Network/subprocess call without timeout or try/except \u2014 scripts/book_ocr_watchdog.py:42"}, "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-bf9a25f1576416b8", "name": "Network/subprocess call without timeout or try/except \u2014 scripts/service_switch.py:75", "shortDescription": {"text": "Network/subprocess call without timeout or try/except \u2014 scripts/service_switch.py:75"}, "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-96849d4e4e072bd6", "name": "Commented-code block (5 lines) in scripts/preprocess_book.py:207", "shortDescription": {"text": "Commented-code block (5 lines) in scripts/preprocess_book.py:207"}, "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-4038b2e66fbcfdd7", "name": "Network/subprocess call without timeout or try/except \u2014 scripts/preprocess_book.py:293", "shortDescription": {"text": "Network/subprocess call without timeout or try/except \u2014 scripts/preprocess_book.py:293"}, "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-7a5a6ba604ae15fb", "name": "Network/subprocess call without timeout or try/except \u2014 scripts/restore_textlayer.py:53", "shortDescription": {"text": "Network/subprocess call without timeout or try/except \u2014 scripts/restore_textlayer.py:53"}, "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-3c919c1211c7dd85", "name": "Network/subprocess call without timeout or try/except \u2014 scripts/cmd_server.py:59", "shortDescription": {"text": "Network/subprocess call without timeout or try/except \u2014 scripts/cmd_server.py:59"}, "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-d80178e547ff16f9", "name": "Network/subprocess call without timeout or try/except \u2014 scripts/optimize_pdf.py:86", "shortDescription": {"text": "Network/subprocess call without timeout or try/except \u2014 scripts/optimize_pdf.py:86"}, "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-50789c1d7487d160", "name": "Network/subprocess call without timeout or try/except \u2014 scripts/ai_client.py:91", "shortDescription": {"text": "Network/subprocess call without timeout or try/except \u2014 scripts/ai_client.py:91"}, "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-9176de346c4f0fc3", "name": "Commented-code block (8 lines) in scripts/anki_status.py:92", "shortDescription": {"text": "Commented-code block (8 lines) in scripts/anki_status.py:92"}, "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-fbd0729769967cc5", "name": "Commented-code block (5 lines) in scripts/kg/link_and_mastery.py:32", "shortDescription": {"text": "Commented-code block (5 lines) in scripts/kg/link_and_mastery.py:32"}, "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-6885a8b7680e4ecb", "name": "Legacy-named symbol `is_trivial_mechanical_legacy` in scripts/kg/auto_archive.py:99", "shortDescription": {"text": "Legacy-named symbol `is_trivial_mechanical_legacy` in scripts/kg/auto_archive.py:99"}, "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-cbe27cb06d4e45fe", "name": "Network/subprocess call without timeout or try/except \u2014 scripts/vocab/build_tanaka_index.py:48", "shortDescription": {"text": "Network/subprocess call without timeout or try/except \u2014 scripts/vocab/build_tanaka_index.py:48"}, "fullDescription": {"text": "`urllib.request.urlretrieve(...)` 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-211abffd687be179", "name": "Network/subprocess call without timeout or try/except \u2014 scripts/vocab/build_kanjidic.py:31", "shortDescription": {"text": "Network/subprocess call without timeout or try/except \u2014 scripts/vocab/build_kanjidic.py:31"}, "fullDescription": {"text": "`urllib.request.urlretrieve(...)` 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-12e83b5380ca4bec", "name": "Network/subprocess call without timeout or try/except \u2014 _client/core/ai_backends.py:119", "shortDescription": {"text": "Network/subprocess call without timeout or try/except \u2014 _client/core/ai_backends.py:119"}, "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-6687f587f1fbd181", "name": "Network/subprocess call without timeout or try/except \u2014 _server_deploy/qa_server.py:136", "shortDescription": {"text": "Network/subprocess call without timeout or try/except \u2014 _server_deploy/qa_server.py:136"}, "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-9fdaae84fe3a2844", "name": "Network/subprocess call without timeout or try/except \u2014 _server_deploy/skilltree.py:524", "shortDescription": {"text": "Network/subprocess call without timeout or try/except \u2014 _server_deploy/skilltree.py:524"}, "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-2ffcbe855f03d978", "name": "Network/subprocess call without timeout or try/except \u2014 _server_deploy/control.py:151", "shortDescription": {"text": "Network/subprocess call without timeout or try/except \u2014 _server_deploy/control.py:151"}, "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-5540e26fbbf0a3c8", "name": "Legacy-named symbol `_gs_old` in _server_deploy/pdf_reader.py:5392", "shortDescription": {"text": "Legacy-named symbol `_gs_old` in _server_deploy/pdf_reader.py:5392"}, "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-baf377a088e9555f", "name": "Commented-code block (6 lines) in _server_deploy/app.py:131", "shortDescription": {"text": "Commented-code block (6 lines) in _server_deploy/app.py:131"}, "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-d8a96be751d27451", "name": "Network/subprocess call without timeout or try/except \u2014 _server_deploy/youtube_speech.py:72", "shortDescription": {"text": "Network/subprocess call without timeout or try/except \u2014 _server_deploy/youtube_speech.py:72"}, "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-5c4db51b77be2ff9", "name": "Commented-code block (5 lines) in _server_deploy/static/pdf/reader.js:1604", "shortDescription": {"text": "Commented-code block (5 lines) in _server_deploy/static/pdf/reader.js:1604"}, "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-b953783157afebca", "name": "`fetch()` without try/.catch or AbortSignal \u2014 _server_deploy/static/pdf/reader.js:35", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 _server_deploy/static/pdf/reader.js:35"}, "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-49420fd197137083", "name": "`fetch()` without try/.catch or AbortSignal \u2014 _server_deploy/static/pdf/reader.src/05-nav.js:206", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 _server_deploy/static/pdf/reader.src/05-nav.js:206"}, "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-79754ad736b12eb9", "name": "Commented-code block (5 lines) in _server_deploy/static/pdf/reader.src/07-continuous.js:83", "shortDescription": {"text": "Commented-code block (5 lines) in _server_deploy/static/pdf/reader.src/07-continuous.js:83"}, "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-a4034190b009c729", "name": "`fetch()` without try/.catch or AbortSignal \u2014 _server_deploy/static/pdf/reader.src/03-loader.js:99", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 _server_deploy/static/pdf/reader.src/03-loader.js:99"}, "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-bf0687f4069a2bb1", "name": "Commented-code block (5 lines) in _server_deploy/static/pdf/reader.src/19-dict.js:260", "shortDescription": {"text": "Commented-code block (5 lines) in _server_deploy/static/pdf/reader.src/19-dict.js:260"}, "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-8e74a4243b8556db", "name": "Commented-code block (5 lines) in _server_deploy/static/pdf/reader.src/15-phrase-wordpop.js:602", "shortDescription": {"text": "Commented-code block (5 lines) in _server_deploy/static/pdf/reader.src/15-phrase-wordpop.js:602"}, "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-f691fcf4229f7e38", "name": "`fetch()` without try/.catch or AbortSignal \u2014 _server_deploy/static/pdf/reader.src/15-phrase-wordpop.js:169", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 _server_deploy/static/pdf/reader.src/15-phrase-wordpop.js:169"}, "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-d66f9029d3078548", "name": "Commented-code block (5 lines) in _server_deploy/static/pdf/reader.src/23-bookshelf.js:1", "shortDescription": {"text": "Commented-code block (5 lines) in _server_deploy/static/pdf/reader.src/23-bookshelf.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-a8e14cf90f130a9d", "name": "`fetch()` without try/.catch or AbortSignal \u2014 _server_deploy/static/pdf/reader.src/01-boot.js:35", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 _server_deploy/static/pdf/reader.src/01-boot.js:35"}, "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-d3a4ce7c68cc2367", "name": "Commented-code block (5 lines) in _server_deploy/static/pdf/reader.src/13-selection.js:88", "shortDescription": {"text": "Commented-code block (5 lines) in _server_deploy/static/pdf/reader.src/13-selection.js:88"}, "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-df4a80b5c885e14e", "name": "Commented-code block (5 lines) in _server_deploy/static/three/GLTFLoader.js:198", "shortDescription": {"text": "Commented-code block (5 lines) in _server_deploy/static/three/GLTFLoader.js:198"}, "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-6b3890400b9a2348", "name": "`fetch()` without try/.catch or AbortSignal \u2014 _server_deploy/static/three/three.module.min.js:6", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 _server_deploy/static/three/three.module.min.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-4650cfd558b7e03a", "name": "Network/subprocess call without timeout or try/except \u2014 launchers/\u622a\u56fe\u95ee\u7b54.py:284", "shortDescription": {"text": "Network/subprocess call without timeout or try/except \u2014 launchers/\u622a\u56fe\u95ee\u7b54.py:284"}, "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-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:\nscripts/annotate_images.py:cmd_scan, scripts/annotate_images.py:cmd_apply\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-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:\n_client/core/qa_browser.py:get_int, _client/core/qa_browser.py:get_int, launchers/\u622a\u56fe\u95ee\u7b54.py:get_int, launchers/\u622a\u56fe\u95ee\u7b54.py:get_int\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-f61fcd81aac4d160", "name": "Flask mutation route `login` without `@login_required` \u2014 webapp/app.py:31", "shortDescription": {"text": "Flask mutation route `login` without `@login_required` \u2014 webapp/app.py:31"}, "fullDescription": {"text": "Flask route declares POST/PUT/DELETE/PATCH methods without an auth decorator. Add `@login_required` (Flask-Login) or equivalent."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-542217ae0032dc51", "name": "Flask mutation route `graph_settings` without `@login_required` \u2014 webapp/app.py:60", "shortDescription": {"text": "Flask mutation route `graph_settings` without `@login_required` \u2014 webapp/app.py:60"}, "fullDescription": {"text": "Flask route declares POST/PUT/DELETE/PATCH methods without an auth decorator. Add `@login_required` (Flask-Login) or equivalent."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-9a95e86355fad0e6", "name": "Flask mutation route `qa_update` without `@login_required` \u2014 webapp/app.py:110", "shortDescription": {"text": "Flask mutation route `qa_update` without `@login_required` \u2014 webapp/app.py:110"}, "fullDescription": {"text": "Flask route declares POST/PUT/DELETE/PATCH methods without an auth decorator. Add `@login_required` (Flask-Login) or equivalent."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-13c0289ee5cea73f", "name": "Flask mutation route `skilltree_delete_book` without `@login_required` \u2014 _server_deploy/skilltree.py:770", "shortDescription": {"text": "Flask mutation route `skilltree_delete_book` without `@login_required` \u2014 _server_deploy/skilltree.py:770"}, "fullDescription": {"text": "Flask route declares POST/PUT/DELETE/PATCH methods without an auth decorator. Add `@login_required` (Flask-Login) or equivalent."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-f2aa95e6f930dae9", "name": "Flask mutation route `skilltree_archive_node` without `@login_required` \u2014 _server_deploy/skilltree.py:845", "shortDescription": {"text": "Flask mutation route `skilltree_archive_node` without `@login_required` \u2014 _server_deploy/skilltree.py:845"}, "fullDescription": {"text": "Flask route declares POST/PUT/DELETE/PATCH methods without an auth decorator. Add `@login_required` (Flask-Login) or equivalent."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-61b29c1e676fa271", "name": "Flask mutation route `skilltree_restore_node` without `@login_required` \u2014 _server_deploy/skilltree.py:891", "shortDescription": {"text": "Flask mutation route `skilltree_restore_node` without `@login_required` \u2014 _server_deploy/skilltree.py:891"}, "fullDescription": {"text": "Flask route declares POST/PUT/DELETE/PATCH methods without an auth decorator. Add `@login_required` (Flask-Login) or equivalent."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-9751ca8d41fa7a66", "name": "Flask mutation route `skilltree_prune_notes` without `@login_required` \u2014 _server_deploy/skilltree.py:935", "shortDescription": {"text": "Flask mutation route `skilltree_prune_notes` without `@login_required` \u2014 _server_deploy/skilltree.py:935"}, "fullDescription": {"text": "Flask route declares POST/PUT/DELETE/PATCH methods without an auth decorator. Add `@login_required` (Flask-Login) or equivalent."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-5d940e976607a2b8", "name": "Flask mutation route `skilltree_build_note` without `@login_required` \u2014 _server_deploy/skilltree.py:995", "shortDescription": {"text": "Flask mutation route `skilltree_build_note` without `@login_required` \u2014 _server_deploy/skilltree.py:995"}, "fullDescription": {"text": "Flask route declares POST/PUT/DELETE/PATCH methods without an auth decorator. Add `@login_required` (Flask-Login) or equivalent."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-4f80964acde0275d", "name": "Flask mutation route `skilltree_toggle_tracked` without `@login_required` \u2014 _server_deploy/skilltree.py:1052", "shortDescription": {"text": "Flask mutation route `skilltree_toggle_tracked` without `@login_required` \u2014 _server_deploy/skilltree.py:1052"}, "fullDescription": {"text": "Flask route declares POST/PUT/DELETE/PATCH methods without an auth decorator. Add `@login_required` (Flask-Login) or equivalent."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-39d445ae54a0e933", "name": "Flask mutation route `skilltree_edit` without `@login_required` \u2014 _server_deploy/skilltree.py:1075", "shortDescription": {"text": "Flask mutation route `skilltree_edit` without `@login_required` \u2014 _server_deploy/skilltree.py:1075"}, "fullDescription": {"text": "Flask route declares POST/PUT/DELETE/PATCH methods without an auth decorator. Add `@login_required` (Flask-Login) or equivalent."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-ad6b55c5ef445d47", "name": "Flask mutation route `control_config` without `@login_required` \u2014 _server_deploy/control.py:217", "shortDescription": {"text": "Flask mutation route `control_config` without `@login_required` \u2014 _server_deploy/control.py:217"}, "fullDescription": {"text": "Flask route declares POST/PUT/DELETE/PATCH methods without an auth decorator. Add `@login_required` (Flask-Login) or equivalent."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-e70a3e7c62a84178", "name": "Flask mutation route `control_trigger` without `@login_required` \u2014 _server_deploy/control.py:335", "shortDescription": {"text": "Flask mutation route `control_trigger` without `@login_required` \u2014 _server_deploy/control.py:335"}, "fullDescription": {"text": "Flask route declares POST/PUT/DELETE/PATCH methods without an auth decorator. Add `@login_required` (Flask-Login) or equivalent."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-d88e2d8cd8445ee9", "name": "Flask mutation route `control_kg_build` without `@login_required` \u2014 _server_deploy/control.py:377", "shortDescription": {"text": "Flask mutation route `control_kg_build` without `@login_required` \u2014 _server_deploy/control.py:377"}, "fullDescription": {"text": "Flask route declares POST/PUT/DELETE/PATCH methods without an auth decorator. Add `@login_required` (Flask-Login) or equivalent."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-7bdbf375ea726a49", "name": "Flask mutation route `login` without `@login_required` \u2014 _server_deploy/app.py:403", "shortDescription": {"text": "Flask mutation route `login` without `@login_required` \u2014 _server_deploy/app.py:403"}, "fullDescription": {"text": "Flask route declares POST/PUT/DELETE/PATCH methods without an auth decorator. Add `@login_required` (Flask-Login) or equivalent."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-df0763164a9a423f", "name": "Flask mutation route `register` without `@login_required` \u2014 _server_deploy/app.py:448", "shortDescription": {"text": "Flask mutation route `register` without `@login_required` \u2014 _server_deploy/app.py:448"}, "fullDescription": {"text": "Flask route declares POST/PUT/DELETE/PATCH methods without an auth decorator. Add `@login_required` (Flask-Login) or equivalent."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-9a4ff4ff4f94e320", "name": "Flask mutation route `graph_settings` without `@login_required` \u2014 _server_deploy/app.py:574", "shortDescription": {"text": "Flask mutation route `graph_settings` without `@login_required` \u2014 _server_deploy/app.py:574"}, "fullDescription": {"text": "Flask route declares POST/PUT/DELETE/PATCH methods without an auth decorator. Add `@login_required` (Flask-Login) or equivalent."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-de03c45cab92592c", "name": "Flask mutation route `nav_links` without `@login_required` \u2014 _server_deploy/app.py:627", "shortDescription": {"text": "Flask mutation route `nav_links` without `@login_required` \u2014 _server_deploy/app.py:627"}, "fullDescription": {"text": "Flask route declares POST/PUT/DELETE/PATCH methods without an auth decorator. Add `@login_required` (Flask-Login) or equivalent."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-f3dc7f6583c836a4", "name": "Flask mutation route `admin_create_invite` without `@login_required` \u2014 _server_deploy/app.py:808", "shortDescription": {"text": "Flask mutation route `admin_create_invite` without `@login_required` \u2014 _server_deploy/app.py:808"}, "fullDescription": {"text": "Flask route declares POST/PUT/DELETE/PATCH methods without an auth decorator. Add `@login_required` (Flask-Login) or equivalent."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-f460848c4ac878df", "name": "Flask mutation route `admin_delete_invite` without `@login_required` \u2014 _server_deploy/app.py:827", "shortDescription": {"text": "Flask mutation route `admin_delete_invite` without `@login_required` \u2014 _server_deploy/app.py:827"}, "fullDescription": {"text": "Flask route declares POST/PUT/DELETE/PATCH methods without an auth decorator. Add `@login_required` (Flask-Login) or equivalent."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-ceb72b57b638cf24", "name": "Flask mutation route `admin_delete_user` without `@login_required` \u2014 _server_deploy/app.py:834", "shortDescription": {"text": "Flask mutation route `admin_delete_user` without `@login_required` \u2014 _server_deploy/app.py:834"}, "fullDescription": {"text": "Flask route declares POST/PUT/DELETE/PATCH methods without an auth decorator. Add `@login_required` (Flask-Login) or equivalent."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-a7bb8138a0eeabda", "name": "Flask mutation route `api_upload` without `@login_required` \u2014 _server_deploy/app.py:875", "shortDescription": {"text": "Flask mutation route `api_upload` without `@login_required` \u2014 _server_deploy/app.py:875"}, "fullDescription": {"text": "Flask route declares POST/PUT/DELETE/PATCH methods without an auth decorator. Add `@login_required` (Flask-Login) or equivalent."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-e1edf93d54db0220", "name": "Flask mutation route `qa_update` without `@login_required` \u2014 _server_deploy/app.py:942", "shortDescription": {"text": "Flask mutation route `qa_update` without `@login_required` \u2014 _server_deploy/app.py:942"}, "fullDescription": {"text": "Flask route declares POST/PUT/DELETE/PATCH methods without an auth decorator. Add `@login_required` (Flask-Login) or equivalent."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-81c5b1f5e9b4efc4", "name": "Dangling fetch: GET /pdf/api/prefs (_server_deploy/static/pdf/reader.js:11)", "shortDescription": {"text": "Dangling fetch: GET /pdf/api/prefs (_server_deploy/static/pdf/reader.js:11)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.js:11` calls `GET /pdf/api/prefs` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/prefs`\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-08f7efbeea7dc095", "name": "Dangling fetch: POST /pdf/api/prefs (_server_deploy/static/pdf/reader.js:35)", "shortDescription": {"text": "Dangling fetch: POST /pdf/api/prefs (_server_deploy/static/pdf/reader.js:35)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.js:35` calls `POST /pdf/api/prefs` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/prefs`\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-861a2cbc51a4d5ad", "name": "Dangling fetch: POST /pdf/api/prefs (_server_deploy/static/pdf/reader.js:50)", "shortDescription": {"text": "Dangling fetch: POST /pdf/api/prefs (_server_deploy/static/pdf/reader.js:50)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.js:50` calls `POST /pdf/api/prefs` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/prefs`\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-f66b9249ac34e028", "name": "Dangling fetch: POST /pdf/api/book-langs (_server_deploy/static/pdf/reader.js:112)", "shortDescription": {"text": "Dangling fetch: POST /pdf/api/book-langs (_server_deploy/static/pdf/reader.js:112)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.js:112` calls `POST /pdf/api/book-langs` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/book-langs`\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-3f86b4bbb213d396", "name": "Dangling fetch: POST /pdf/api/book-crop (_server_deploy/static/pdf/reader.js:530)", "shortDescription": {"text": "Dangling fetch: POST /pdf/api/book-crop (_server_deploy/static/pdf/reader.js:530)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.js:530` calls `POST /pdf/api/book-crop` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/book-crop`\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-fae1d4ec64a31bcb", "name": "Dangling fetch: GET /pdf/api/page-nodes?file=${encodeURIComponent(FILE_REL)}&page=${num} (_server_deploy/static/pdf/read", "shortDescription": {"text": "Dangling fetch: GET /pdf/api/page-nodes?file=${encodeURIComponent(FILE_REL)}&page=${num} (_server_deploy/static/pdf/reader.js:857)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.js:857` calls `GET /pdf/api/page-nodes?file=${encodeURIComponent(FILE_REL)}&page=${num}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/page-nodes`\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-9bb6fd2dc7f457f0", "name": "Dangling fetch: POST /skilltree/${encodeURIComponent(book)}/api/toggle-tracked (_server_deploy/static/pdf/reader.js:890)", "shortDescription": {"text": "Dangling fetch: POST /skilltree/${encodeURIComponent(book)}/api/toggle-tracked (_server_deploy/static/pdf/reader.js:890)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.js:890` calls `POST /skilltree/${encodeURIComponent(book)}/api/toggle-tracked` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/skilltree/<p>/api/toggle-tracked`\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-0090d8b057b37efb", "name": "Dangling fetch: POST /pdf/api/grammar-forget (_server_deploy/static/pdf/reader.js:1031)", "shortDescription": {"text": "Dangling fetch: POST /pdf/api/grammar-forget (_server_deploy/static/pdf/reader.js:1031)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.js:1031` calls `POST /pdf/api/grammar-forget` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/grammar-forget`\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-6ece3a00fdf2ffa8", "name": "Dangling fetch: POST /pdf/api/vocab-anki (_server_deploy/static/pdf/reader.js:1128)", "shortDescription": {"text": "Dangling fetch: POST /pdf/api/vocab-anki (_server_deploy/static/pdf/reader.js:1128)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.js:1128` calls `POST /pdf/api/vocab-anki` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/vocab-anki`\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-04fdc6c58de46ec4", "name": "Dangling fetch: GET /pdf/api/page-overlay?file=${encodeURIComponent(FILE_REL)}&page=${num} (_server_deploy/static/pdf/re", "shortDescription": {"text": "Dangling fetch: GET /pdf/api/page-overlay?file=${encodeURIComponent(FILE_REL)}&page=${num} (_server_deploy/static/pdf/reader.js:1836)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.js:1836` calls `GET /pdf/api/page-overlay?file=${encodeURIComponent(FILE_REL)}&page=${num}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/page-overlay`\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-5e61f3b82d3197f1", "name": "Dangling fetch: POST /pdf/api/translate-sentence (_server_deploy/static/pdf/reader.js:2573)", "shortDescription": {"text": "Dangling fetch: POST /pdf/api/translate-sentence (_server_deploy/static/pdf/reader.js:2573)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.js:2573` calls `POST /pdf/api/translate-sentence` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/translate-sentence`\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-a7d1345a6df8ecee", "name": "Dangling fetch: POST /pdf/api/sentence-dismiss (_server_deploy/static/pdf/reader.js:2604)", "shortDescription": {"text": "Dangling fetch: POST /pdf/api/sentence-dismiss (_server_deploy/static/pdf/reader.js:2604)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.js:2604` calls `POST /pdf/api/sentence-dismiss` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/sentence-dismiss`\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-385ea81cceea0221", "name": "Dangling fetch: POST /pdf/api/translate-sentence (_server_deploy/static/pdf/reader.js:2626)", "shortDescription": {"text": "Dangling fetch: POST /pdf/api/translate-sentence (_server_deploy/static/pdf/reader.js:2626)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.js:2626` calls `POST /pdf/api/translate-sentence` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/translate-sentence`\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-d1fbd94d209cb003", "name": "Dangling fetch: POST /pdf/api/translate-sentence (_server_deploy/static/pdf/reader.js:2780)", "shortDescription": {"text": "Dangling fetch: POST /pdf/api/translate-sentence (_server_deploy/static/pdf/reader.js:2780)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.js:2780` calls `POST /pdf/api/translate-sentence` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/translate-sentence`\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-243b80d88c32b508", "name": "Dangling fetch: GET /pdf/api/phrases (_server_deploy/static/pdf/reader.js:3719)", "shortDescription": {"text": "Dangling fetch: GET /pdf/api/phrases (_server_deploy/static/pdf/reader.js:3719)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.js:3719` calls `GET /pdf/api/phrases` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/phrases`\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-c860a470dcc975e6", "name": "Dangling fetch: GET /pdf/api/phrase-mark (_server_deploy/static/pdf/reader.js:3720)", "shortDescription": {"text": "Dangling fetch: GET /pdf/api/phrase-mark (_server_deploy/static/pdf/reader.js:3720)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.js:3720` calls `GET /pdf/api/phrase-mark` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/phrase-mark`\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-49315288e384b0e6", "name": "Dangling fetch: POST /pdf/api/translate-sentence (_server_deploy/static/pdf/reader.js:3882)", "shortDescription": {"text": "Dangling fetch: POST /pdf/api/translate-sentence (_server_deploy/static/pdf/reader.js:3882)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.js:3882` calls `POST /pdf/api/translate-sentence` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/translate-sentence`\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-0a5e839062687623", "name": "Dangling fetch: GET /pdf/api/phrases (_server_deploy/static/pdf/reader.js:3914)", "shortDescription": {"text": "Dangling fetch: GET /pdf/api/phrases (_server_deploy/static/pdf/reader.js:3914)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.js:3914` calls `GET /pdf/api/phrases` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/phrases`\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-8d23478353a7c437", "name": "Dangling fetch: POST /pdf/api/phrase-mark (_server_deploy/static/pdf/reader.js:4354)", "shortDescription": {"text": "Dangling fetch: POST /pdf/api/phrase-mark (_server_deploy/static/pdf/reader.js:4354)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.js:4354` calls `POST /pdf/api/phrase-mark` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/phrase-mark`\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-25e5d4ac32d3c726", "name": "Dangling fetch: POST /pdf/api/highlights (_server_deploy/static/pdf/reader.js:4826)", "shortDescription": {"text": "Dangling fetch: POST /pdf/api/highlights (_server_deploy/static/pdf/reader.js:4826)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.js:4826` calls `POST /pdf/api/highlights` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/highlights`\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-b7c609fc6c53faef", "name": "Dangling fetch: POST /pdf/api/snippets-to-async (_server_deploy/static/pdf/reader.js:4925)", "shortDescription": {"text": "Dangling fetch: POST /pdf/api/snippets-to-async (_server_deploy/static/pdf/reader.js:4925)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.js:4925` calls `POST /pdf/api/snippets-to-async` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/snippets-to-async`\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-531d113d04df4639", "name": "Dangling fetch: GET /pdf/api/grammar-books (_server_deploy/static/pdf/reader.js:4996)", "shortDescription": {"text": "Dangling fetch: GET /pdf/api/grammar-books (_server_deploy/static/pdf/reader.js:4996)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.js:4996` calls `GET /pdf/api/grammar-books` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/grammar-books`\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-a97e211db4e93ad6", "name": "Dangling fetch: POST /pdf/api/grammar-tracked (_server_deploy/static/pdf/reader.js:5005)", "shortDescription": {"text": "Dangling fetch: POST /pdf/api/grammar-tracked (_server_deploy/static/pdf/reader.js:5005)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.js:5005` calls `POST /pdf/api/grammar-tracked` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/grammar-tracked`\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-9587c09fb5b2e522", "name": "Dangling fetch: GET /pdf/api/grammar-books (_server_deploy/static/pdf/reader.js:5023)", "shortDescription": {"text": "Dangling fetch: GET /pdf/api/grammar-books (_server_deploy/static/pdf/reader.js:5023)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.js:5023` calls `GET /pdf/api/grammar-books` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/grammar-books`\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-d11a21034c73b13d", "name": "Dangling fetch: POST /pdf/api/grammar-analyze (_server_deploy/static/pdf/reader.js:5074)", "shortDescription": {"text": "Dangling fetch: POST /pdf/api/grammar-analyze (_server_deploy/static/pdf/reader.js:5074)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.js:5074` calls `POST /pdf/api/grammar-analyze` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/grammar-analyze`\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-c68ee1b68a2dd94b", "name": "Dangling fetch: POST /pdf/api/grammar-history-save (_server_deploy/static/pdf/reader.js:5128)", "shortDescription": {"text": "Dangling fetch: POST /pdf/api/grammar-history-save (_server_deploy/static/pdf/reader.js:5128)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.js:5128` calls `POST /pdf/api/grammar-history-save` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/grammar-history-save`\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-56e1d71380cd7699", "name": "Dangling fetch: POST /pdf/api/grammar-forget (_server_deploy/static/pdf/reader.js:5299)", "shortDescription": {"text": "Dangling fetch: POST /pdf/api/grammar-forget (_server_deploy/static/pdf/reader.js:5299)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.js:5299` calls `POST /pdf/api/grammar-forget` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/grammar-forget`\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-3bb9fba8613a97ba", "name": "Dangling fetch: POST /pdf/api/snippets-to-async (_server_deploy/static/pdf/reader.js:5333)", "shortDescription": {"text": "Dangling fetch: POST /pdf/api/snippets-to-async (_server_deploy/static/pdf/reader.js:5333)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.js:5333` calls `POST /pdf/api/snippets-to-async` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/snippets-to-async`\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-8c389cc11a98aea1", "name": "Dangling fetch: POST /pdf/api/vocab-mark (_server_deploy/static/pdf/reader.js:5932)", "shortDescription": {"text": "Dangling fetch: POST /pdf/api/vocab-mark (_server_deploy/static/pdf/reader.js:5932)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.js:5932` calls `POST /pdf/api/vocab-mark` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/vocab-mark`\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-19c1d65648981304", "name": "Dangling fetch: POST /pdf/api/vocab-anki (_server_deploy/static/pdf/reader.js:5957)", "shortDescription": {"text": "Dangling fetch: POST /pdf/api/vocab-anki (_server_deploy/static/pdf/reader.js:5957)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.js:5957` calls `POST /pdf/api/vocab-anki` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/vocab-anki`\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-8ff90ec2bcd90802", "name": "Dangling fetch: PATCH /pdf/api/highlights (_server_deploy/static/pdf/reader.js:6058)", "shortDescription": {"text": "Dangling fetch: PATCH /pdf/api/highlights (_server_deploy/static/pdf/reader.js:6058)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.js:6058` calls `PATCH /pdf/api/highlights` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/highlights`\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-5870ee3930dcd2b1", "name": "Dangling fetch: DELETE /pdf/api/highlights (_server_deploy/static/pdf/reader.js:6072)", "shortDescription": {"text": "Dangling fetch: DELETE /pdf/api/highlights (_server_deploy/static/pdf/reader.js:6072)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.js:6072` calls `DELETE /pdf/api/highlights` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/highlights`\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-a3389b2b16327d43", "name": "Dangling fetch: POST /pdf/api/snippets-to-async (_server_deploy/static/pdf/reader.js:6767)", "shortDescription": {"text": "Dangling fetch: POST /pdf/api/snippets-to-async (_server_deploy/static/pdf/reader.js:6767)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.js:6767` calls `POST /pdf/api/snippets-to-async` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/snippets-to-async`\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-533635cd134963df", "name": "Dangling fetch: GET /pdf/api/translate-config (_server_deploy/static/pdf/reader.js:6871)", "shortDescription": {"text": "Dangling fetch: GET /pdf/api/translate-config (_server_deploy/static/pdf/reader.js:6871)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.js:6871` calls `GET /pdf/api/translate-config` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/translate-config`\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-ab4bb7f5d8b5a6ae", "name": "Dangling fetch: POST /pdf/api/translate-config (_server_deploy/static/pdf/reader.js:6929)", "shortDescription": {"text": "Dangling fetch: POST /pdf/api/translate-config (_server_deploy/static/pdf/reader.js:6929)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.js:6929` calls `POST /pdf/api/translate-config` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/translate-config`\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-76e2201933f67e9f", "name": "Dangling fetch: POST /pdf/api/translate-sentence (_server_deploy/static/pdf/reader.js:7152)", "shortDescription": {"text": "Dangling fetch: POST /pdf/api/translate-sentence (_server_deploy/static/pdf/reader.js:7152)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.js:7152` calls `POST /pdf/api/translate-sentence` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/translate-sentence`\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-92184f129429554e", "name": "Dangling fetch: POST /pdf/api/to-note (_server_deploy/static/pdf/reader.js:7313)", "shortDescription": {"text": "Dangling fetch: POST /pdf/api/to-note (_server_deploy/static/pdf/reader.js:7313)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.js:7313` calls `POST /pdf/api/to-note` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/to-note`\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-b770f43d1fa8d610", "name": "Dangling fetch: GET /pdf/api/char-offset?file=${encodeURIComponent(FILE_REL)}&page=${page} (_server_deploy/static/pdf/re", "shortDescription": {"text": "Dangling fetch: GET /pdf/api/char-offset?file=${encodeURIComponent(FILE_REL)}&page=${page} (_server_deploy/static/pdf/reader.js:7354)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.js:7354` calls `GET /pdf/api/char-offset?file=${encodeURIComponent(FILE_REL)}&page=${page}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/char-offset`\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-3db18f0ad1771900", "name": "Dangling fetch: POST /pdf/api/char-offset (_server_deploy/static/pdf/reader.js:7362)", "shortDescription": {"text": "Dangling fetch: POST /pdf/api/char-offset (_server_deploy/static/pdf/reader.js:7362)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.js:7362` calls `POST /pdf/api/char-offset` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/char-offset`\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-931032ed92058957", "name": "Dangling fetch: POST /pdf/api/reocr-page (_server_deploy/static/pdf/reader.js:7415)", "shortDescription": {"text": "Dangling fetch: POST /pdf/api/reocr-page (_server_deploy/static/pdf/reader.js:7415)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.js:7415` calls `POST /pdf/api/reocr-page` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/reocr-page`\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-bd342ad70d33bd5b", "name": "Dangling fetch: POST /pdf/api/reocr-page/clear (_server_deploy/static/pdf/reader.js:7434)", "shortDescription": {"text": "Dangling fetch: POST /pdf/api/reocr-page/clear (_server_deploy/static/pdf/reader.js:7434)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.js:7434` calls `POST /pdf/api/reocr-page/clear` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/reocr-page/clear`\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-7972b649deb0779a", "name": "Dangling fetch: POST /pdf/api/prewarm-async (_server_deploy/static/pdf/reader.js:7493)", "shortDescription": {"text": "Dangling fetch: POST /pdf/api/prewarm-async (_server_deploy/static/pdf/reader.js:7493)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.js:7493` calls `POST /pdf/api/prewarm-async` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/prewarm-async`\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-899fdb970dbf55c3", "name": "Dangling fetch: GET /pdf/api/list-pdfs (_server_deploy/static/pdf/reader.js:7548)", "shortDescription": {"text": "Dangling fetch: GET /pdf/api/list-pdfs (_server_deploy/static/pdf/reader.js:7548)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.js:7548` calls `GET /pdf/api/list-pdfs` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/list-pdfs`\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-03b66cf9b7f98ac4", "name": "Dangling fetch: GET /pdf/api/translate-config (_server_deploy/static/pdf/reader.src/21-misc-ai.js:82)", "shortDescription": {"text": "Dangling fetch: GET /pdf/api/translate-config (_server_deploy/static/pdf/reader.src/21-misc-ai.js:82)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.src/21-misc-ai.js:82` calls `GET /pdf/api/translate-config` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/translate-config`\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-31c2c2a49ac85102", "name": "Dangling fetch: POST /pdf/api/translate-config (_server_deploy/static/pdf/reader.src/21-misc-ai.js:140)", "shortDescription": {"text": "Dangling fetch: POST /pdf/api/translate-config (_server_deploy/static/pdf/reader.src/21-misc-ai.js:140)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.src/21-misc-ai.js:140` calls `POST /pdf/api/translate-config` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/translate-config`\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-5db85d3155bfdbfa", "name": "Dangling fetch: POST /pdf/api/translate-sentence (_server_deploy/static/pdf/reader.src/21-misc-ai.js:363)", "shortDescription": {"text": "Dangling fetch: POST /pdf/api/translate-sentence (_server_deploy/static/pdf/reader.src/21-misc-ai.js:363)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.src/21-misc-ai.js:363` calls `POST /pdf/api/translate-sentence` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/translate-sentence`\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-ed8c04efbc06fa63", "name": "Dangling fetch: POST /pdf/api/to-note (_server_deploy/static/pdf/reader.src/21-misc-ai.js:524)", "shortDescription": {"text": "Dangling fetch: POST /pdf/api/to-note (_server_deploy/static/pdf/reader.src/21-misc-ai.js:524)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.src/21-misc-ai.js:524` calls `POST /pdf/api/to-note` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/to-note`\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-dae3edfcfcc563d0", "name": "Dangling fetch: GET /pdf/api/char-offset?file=${encodeURIComponent(FILE_REL)}&page=${page} (_server_deploy/static/pdf/re", "shortDescription": {"text": "Dangling fetch: GET /pdf/api/char-offset?file=${encodeURIComponent(FILE_REL)}&page=${page} (_server_deploy/static/pdf/reader.src/21-misc-ai.js:565)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.src/21-misc-ai.js:565` calls `GET /pdf/api/char-offset?file=${encodeURIComponent(FILE_REL)}&page=${page}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/char-offset`\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-a6b2d557c7d93013", "name": "Dangling fetch: POST /pdf/api/char-offset (_server_deploy/static/pdf/reader.src/21-misc-ai.js:573)", "shortDescription": {"text": "Dangling fetch: POST /pdf/api/char-offset (_server_deploy/static/pdf/reader.src/21-misc-ai.js:573)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.src/21-misc-ai.js:573` calls `POST /pdf/api/char-offset` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/char-offset`\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-a62a6e22bb0599d7", "name": "Dangling fetch: POST /pdf/api/reocr-page (_server_deploy/static/pdf/reader.src/21-misc-ai.js:626)", "shortDescription": {"text": "Dangling fetch: POST /pdf/api/reocr-page (_server_deploy/static/pdf/reader.src/21-misc-ai.js:626)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.src/21-misc-ai.js:626` calls `POST /pdf/api/reocr-page` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/reocr-page`\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-ae49cb8b6dc00875", "name": "Dangling fetch: POST /pdf/api/reocr-page/clear (_server_deploy/static/pdf/reader.src/21-misc-ai.js:645)", "shortDescription": {"text": "Dangling fetch: POST /pdf/api/reocr-page/clear (_server_deploy/static/pdf/reader.src/21-misc-ai.js:645)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.src/21-misc-ai.js:645` calls `POST /pdf/api/reocr-page/clear` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/reocr-page/clear`\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-5853ef25c86a9034", "name": "Dangling fetch: POST /pdf/api/highlights (_server_deploy/static/pdf/reader.src/17-highlight.js:139)", "shortDescription": {"text": "Dangling fetch: POST /pdf/api/highlights (_server_deploy/static/pdf/reader.src/17-highlight.js:139)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.src/17-highlight.js:139` calls `POST /pdf/api/highlights` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/highlights`\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-082c06aca9668256", "name": "Dangling fetch: POST /pdf/api/snippets-to-async (_server_deploy/static/pdf/reader.src/17-highlight.js:238)", "shortDescription": {"text": "Dangling fetch: POST /pdf/api/snippets-to-async (_server_deploy/static/pdf/reader.src/17-highlight.js:238)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.src/17-highlight.js:238` calls `POST /pdf/api/snippets-to-async` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/snippets-to-async`\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-d9db24f44afbacd8", "name": "Dangling fetch: GET /pdf/api/page-nodes?file=${encodeURIComponent(FILE_REL)}&page=${num} (_server_deploy/static/pdf/read", "shortDescription": {"text": "Dangling fetch: GET /pdf/api/page-nodes?file=${encodeURIComponent(FILE_REL)}&page=${num} (_server_deploy/static/pdf/reader.src/05-nav.js:3)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.src/05-nav.js:3` calls `GET /pdf/api/page-nodes?file=${encodeURIComponent(FILE_REL)}&page=${num}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/page-nodes`\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-b8ba7747fbc7d68a", "name": "Dangling fetch: POST /skilltree/${encodeURIComponent(book)}/api/toggle-tracked (_server_deploy/static/pdf/reader.src/05-", "shortDescription": {"text": "Dangling fetch: POST /skilltree/${encodeURIComponent(book)}/api/toggle-tracked (_server_deploy/static/pdf/reader.src/05-nav.js:36)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.src/05-nav.js:36` calls `POST /skilltree/${encodeURIComponent(book)}/api/toggle-tracked` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/skilltree/<p>/api/toggle-tracked`\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-6a23630291fadd2e", "name": "Dangling fetch: POST /pdf/api/grammar-forget (_server_deploy/static/pdf/reader.src/05-nav.js:177)", "shortDescription": {"text": "Dangling fetch: POST /pdf/api/grammar-forget (_server_deploy/static/pdf/reader.src/05-nav.js:177)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.src/05-nav.js:177` calls `POST /pdf/api/grammar-forget` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/grammar-forget`\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-cb0a7205da933130", "name": "Dangling fetch: POST /pdf/api/vocab-anki (_server_deploy/static/pdf/reader.src/05-nav.js:274)", "shortDescription": {"text": "Dangling fetch: POST /pdf/api/vocab-anki (_server_deploy/static/pdf/reader.src/05-nav.js:274)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.src/05-nav.js:274` calls `POST /pdf/api/vocab-anki` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/vocab-anki`\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-6737485fab171388", "name": "Dangling fetch: POST /pdf/api/snippets-to-async (_server_deploy/static/pdf/reader.src/20-result-draft.js:415)", "shortDescription": {"text": "Dangling fetch: POST /pdf/api/snippets-to-async (_server_deploy/static/pdf/reader.src/20-result-draft.js:415)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.src/20-result-draft.js:415` calls `POST /pdf/api/snippets-to-async` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/snippets-to-async`\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-9ecceb481dde344b", "name": "Dangling fetch: POST /pdf/api/book-crop (_server_deploy/static/pdf/reader.src/03-loader.js:267)", "shortDescription": {"text": "Dangling fetch: POST /pdf/api/book-crop (_server_deploy/static/pdf/reader.src/03-loader.js:267)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.src/03-loader.js:267` calls `POST /pdf/api/book-crop` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/book-crop`\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-d41700f0a4489e79", "name": "Dangling fetch: GET /pdf/api/grammar-books (_server_deploy/static/pdf/reader.src/18-grammar.js:18)", "shortDescription": {"text": "Dangling fetch: GET /pdf/api/grammar-books (_server_deploy/static/pdf/reader.src/18-grammar.js:18)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.src/18-grammar.js:18` calls `GET /pdf/api/grammar-books` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/grammar-books`\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-17819e80952d30cb", "name": "Dangling fetch: POST /pdf/api/grammar-tracked (_server_deploy/static/pdf/reader.src/18-grammar.js:27)", "shortDescription": {"text": "Dangling fetch: POST /pdf/api/grammar-tracked (_server_deploy/static/pdf/reader.src/18-grammar.js:27)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.src/18-grammar.js:27` calls `POST /pdf/api/grammar-tracked` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/grammar-tracked`\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-029308ddd51acf9a", "name": "Dangling fetch: GET /pdf/api/grammar-books (_server_deploy/static/pdf/reader.src/18-grammar.js:45)", "shortDescription": {"text": "Dangling fetch: GET /pdf/api/grammar-books (_server_deploy/static/pdf/reader.src/18-grammar.js:45)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.src/18-grammar.js:45` calls `GET /pdf/api/grammar-books` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/grammar-books`\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-78805bcb439b82cc", "name": "Dangling fetch: POST /pdf/api/grammar-analyze (_server_deploy/static/pdf/reader.src/18-grammar.js:96)", "shortDescription": {"text": "Dangling fetch: POST /pdf/api/grammar-analyze (_server_deploy/static/pdf/reader.src/18-grammar.js:96)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.src/18-grammar.js:96` calls `POST /pdf/api/grammar-analyze` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/grammar-analyze`\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-8bbb686626a09cf3", "name": "Dangling fetch: POST /pdf/api/grammar-history-save (_server_deploy/static/pdf/reader.src/18-grammar.js:150)", "shortDescription": {"text": "Dangling fetch: POST /pdf/api/grammar-history-save (_server_deploy/static/pdf/reader.src/18-grammar.js:150)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.src/18-grammar.js:150` calls `POST /pdf/api/grammar-history-save` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/grammar-history-save`\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-d3d5ed032ce59c71", "name": "Dangling fetch: POST /pdf/api/grammar-forget (_server_deploy/static/pdf/reader.src/18-grammar.js:321)", "shortDescription": {"text": "Dangling fetch: POST /pdf/api/grammar-forget (_server_deploy/static/pdf/reader.src/18-grammar.js:321)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.src/18-grammar.js:321` calls `POST /pdf/api/grammar-forget` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/grammar-forget`\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-995635e478772677", "name": "Dangling fetch: POST /pdf/api/snippets-to-async (_server_deploy/static/pdf/reader.src/18-grammar.js:355)", "shortDescription": {"text": "Dangling fetch: POST /pdf/api/snippets-to-async (_server_deploy/static/pdf/reader.src/18-grammar.js:355)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.src/18-grammar.js:355` calls `POST /pdf/api/snippets-to-async` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/snippets-to-async`\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-1ccea747e33b5408", "name": "Dangling fetch: POST /pdf/api/prewarm-async (_server_deploy/static/pdf/reader.src/22-prewarm.js:40)", "shortDescription": {"text": "Dangling fetch: POST /pdf/api/prewarm-async (_server_deploy/static/pdf/reader.src/22-prewarm.js:40)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.src/22-prewarm.js:40` calls `POST /pdf/api/prewarm-async` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/prewarm-async`\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-a8533f9f574ce413", "name": "Dangling fetch: POST /pdf/api/vocab-mark (_server_deploy/static/pdf/reader.src/19-dict.js:183)", "shortDescription": {"text": "Dangling fetch: POST /pdf/api/vocab-mark (_server_deploy/static/pdf/reader.src/19-dict.js:183)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.src/19-dict.js:183` calls `POST /pdf/api/vocab-mark` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/vocab-mark`\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-c7e73d4b9d8f86d1", "name": "Dangling fetch: POST /pdf/api/vocab-anki (_server_deploy/static/pdf/reader.src/19-dict.js:208)", "shortDescription": {"text": "Dangling fetch: POST /pdf/api/vocab-anki (_server_deploy/static/pdf/reader.src/19-dict.js:208)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.src/19-dict.js:208` calls `POST /pdf/api/vocab-anki` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/vocab-anki`\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-a8cbd7e31e3fe204", "name": "Dangling fetch: PATCH /pdf/api/highlights (_server_deploy/static/pdf/reader.src/19-dict.js:309)", "shortDescription": {"text": "Dangling fetch: PATCH /pdf/api/highlights (_server_deploy/static/pdf/reader.src/19-dict.js:309)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.src/19-dict.js:309` calls `PATCH /pdf/api/highlights` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/highlights`\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-848af11f35af88f0", "name": "Dangling fetch: DELETE /pdf/api/highlights (_server_deploy/static/pdf/reader.src/19-dict.js:323)", "shortDescription": {"text": "Dangling fetch: DELETE /pdf/api/highlights (_server_deploy/static/pdf/reader.src/19-dict.js:323)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.src/19-dict.js:323` calls `DELETE /pdf/api/highlights` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/highlights`\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-d230ed7cfbb08250", "name": "Dangling fetch: GET /pdf/api/page-overlay?file=${encodeURIComponent(FILE_REL)}&page=${num} (_server_deploy/static/pdf/re", "shortDescription": {"text": "Dangling fetch: GET /pdf/api/page-overlay?file=${encodeURIComponent(FILE_REL)}&page=${num} (_server_deploy/static/pdf/reader.src/08-charlayer.js:36)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.src/08-charlayer.js:36` calls `GET /pdf/api/page-overlay?file=${encodeURIComponent(FILE_REL)}&page=${num}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/page-overlay`\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-530f042b04623e5d", "name": "Dangling fetch: POST /pdf/api/translate-sentence (_server_deploy/static/pdf/reader.src/12-vocab-sentences.js:315)", "shortDescription": {"text": "Dangling fetch: POST /pdf/api/translate-sentence (_server_deploy/static/pdf/reader.src/12-vocab-sentences.js:315)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.src/12-vocab-sentences.js:315` calls `POST /pdf/api/translate-sentence` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/translate-sentence`\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-67a67b47eab1200d", "name": "Dangling fetch: POST /pdf/api/sentence-dismiss (_server_deploy/static/pdf/reader.src/12-vocab-sentences.js:346)", "shortDescription": {"text": "Dangling fetch: POST /pdf/api/sentence-dismiss (_server_deploy/static/pdf/reader.src/12-vocab-sentences.js:346)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.src/12-vocab-sentences.js:346` calls `POST /pdf/api/sentence-dismiss` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/sentence-dismiss`\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-2fc796e73621a28e", "name": "Dangling fetch: POST /pdf/api/translate-sentence (_server_deploy/static/pdf/reader.src/12-vocab-sentences.js:368)", "shortDescription": {"text": "Dangling fetch: POST /pdf/api/translate-sentence (_server_deploy/static/pdf/reader.src/12-vocab-sentences.js:368)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.src/12-vocab-sentences.js:368` calls `POST /pdf/api/translate-sentence` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/translate-sentence`\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-7831cb776867b56b", "name": "Dangling fetch: POST /pdf/api/translate-sentence (_server_deploy/static/pdf/reader.src/12-vocab-sentences.js:522)", "shortDescription": {"text": "Dangling fetch: POST /pdf/api/translate-sentence (_server_deploy/static/pdf/reader.src/12-vocab-sentences.js:522)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.src/12-vocab-sentences.js:522` calls `POST /pdf/api/translate-sentence` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/translate-sentence`\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-42ba525fd3c88ceb", "name": "Dangling fetch: GET /pdf/api/phrases (_server_deploy/static/pdf/reader.src/15-phrase-wordpop.js:6)", "shortDescription": {"text": "Dangling fetch: GET /pdf/api/phrases (_server_deploy/static/pdf/reader.src/15-phrase-wordpop.js:6)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.src/15-phrase-wordpop.js:6` calls `GET /pdf/api/phrases` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/phrases`\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-ba45f97a2195842f", "name": "Dangling fetch: GET /pdf/api/phrase-mark (_server_deploy/static/pdf/reader.src/15-phrase-wordpop.js:7)", "shortDescription": {"text": "Dangling fetch: GET /pdf/api/phrase-mark (_server_deploy/static/pdf/reader.src/15-phrase-wordpop.js:7)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.src/15-phrase-wordpop.js:7` calls `GET /pdf/api/phrase-mark` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/phrase-mark`\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-4cab32bf010ad66a", "name": "Dangling fetch: POST /pdf/api/translate-sentence (_server_deploy/static/pdf/reader.src/15-phrase-wordpop.js:169)", "shortDescription": {"text": "Dangling fetch: POST /pdf/api/translate-sentence (_server_deploy/static/pdf/reader.src/15-phrase-wordpop.js:169)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.src/15-phrase-wordpop.js:169` calls `POST /pdf/api/translate-sentence` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/translate-sentence`\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-252207797c6055e0", "name": "Dangling fetch: GET /pdf/api/phrases (_server_deploy/static/pdf/reader.src/15-phrase-wordpop.js:201)", "shortDescription": {"text": "Dangling fetch: GET /pdf/api/phrases (_server_deploy/static/pdf/reader.src/15-phrase-wordpop.js:201)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.src/15-phrase-wordpop.js:201` calls `GET /pdf/api/phrases` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/phrases`\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-95a5fcf05c0d7217", "name": "Dangling fetch: POST /pdf/api/phrase-mark (_server_deploy/static/pdf/reader.src/15-phrase-wordpop.js:641)", "shortDescription": {"text": "Dangling fetch: POST /pdf/api/phrase-mark (_server_deploy/static/pdf/reader.src/15-phrase-wordpop.js:641)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.src/15-phrase-wordpop.js:641` calls `POST /pdf/api/phrase-mark` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/phrase-mark`\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-b99f24511a9c73a7", "name": "Dangling fetch: GET /pdf/api/list-pdfs (_server_deploy/static/pdf/reader.src/23-bookshelf.js:38)", "shortDescription": {"text": "Dangling fetch: GET /pdf/api/list-pdfs (_server_deploy/static/pdf/reader.src/23-bookshelf.js:38)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.src/23-bookshelf.js:38` calls `GET /pdf/api/list-pdfs` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/list-pdfs`\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-d8f41f40c5bcd93b", "name": "Dangling fetch: GET /pdf/api/prefs (_server_deploy/static/pdf/reader.src/01-boot.js:11)", "shortDescription": {"text": "Dangling fetch: GET /pdf/api/prefs (_server_deploy/static/pdf/reader.src/01-boot.js:11)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.src/01-boot.js:11` calls `GET /pdf/api/prefs` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/prefs`\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-e664881ee724dd8e", "name": "Dangling fetch: POST /pdf/api/prefs (_server_deploy/static/pdf/reader.src/01-boot.js:35)", "shortDescription": {"text": "Dangling fetch: POST /pdf/api/prefs (_server_deploy/static/pdf/reader.src/01-boot.js:35)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.src/01-boot.js:35` calls `POST /pdf/api/prefs` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/prefs`\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-5bac588cf6da9d46", "name": "Dangling fetch: POST /pdf/api/prefs (_server_deploy/static/pdf/reader.src/01-boot.js:50)", "shortDescription": {"text": "Dangling fetch: POST /pdf/api/prefs (_server_deploy/static/pdf/reader.src/01-boot.js:50)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.src/01-boot.js:50` calls `POST /pdf/api/prefs` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/prefs`\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-1304129e73d04852", "name": "Dangling fetch: POST /pdf/api/book-langs (_server_deploy/static/pdf/reader.src/01-boot.js:112)", "shortDescription": {"text": "Dangling fetch: POST /pdf/api/book-langs (_server_deploy/static/pdf/reader.src/01-boot.js:112)"}, "fullDescription": {"text": "`_server_deploy/static/pdf/reader.src/01-boot.js:112` calls `POST /pdf/api/book-langs` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/pdf/api/book-langs`\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-4c7ad61ba1b23915", "name": "Unused endpoint: ANY /login", "shortDescription": {"text": "Unused endpoint: ANY /login"}, "fullDescription": {"text": "`webapp/app.py` declares `ANY /login` 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-c9e449c3b9e73b73", "name": "Unused endpoint: ANY /logout", "shortDescription": {"text": "Unused endpoint: ANY /logout"}, "fullDescription": {"text": "`webapp/app.py` declares `ANY /logout` 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-742bb54617573d9c", "name": "Unused endpoint: ANY /dashboard/", "shortDescription": {"text": "Unused endpoint: ANY /dashboard/"}, "fullDescription": {"text": "`webapp/app.py` declares `ANY /dashboard/` 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-95fc94040ca18a0a", "name": "Unused endpoint: ANY /dashboard/<path:filename>", "shortDescription": {"text": "Unused endpoint: ANY /dashboard/<path:filename>"}, "fullDescription": {"text": "`webapp/app.py` declares `ANY /dashboard/<path:filename>` 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-7d40d28394f87c42", "name": "Unused endpoint: ANY /dashboard/graph-settings.json", "shortDescription": {"text": "Unused endpoint: ANY /dashboard/graph-settings.json"}, "fullDescription": {"text": "`webapp/app.py` declares `ANY /dashboard/graph-settings.json` 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-b39cbaaec68ddbe2", "name": "Unused endpoint: ANY /private/", "shortDescription": {"text": "Unused endpoint: ANY /private/"}, "fullDescription": {"text": "`webapp/app.py` declares `ANY /private/` 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-0db99ac2c44c605c", "name": "Unused endpoint: ANY /private/<path:filename>", "shortDescription": {"text": "Unused endpoint: ANY /private/<path:filename>"}, "fullDescription": {"text": "`webapp/app.py` declares `ANY /private/<path:filename>` 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-14c3471b25b0a373", "name": "Unused endpoint: ANY /history/", "shortDescription": {"text": "Unused endpoint: ANY /history/"}, "fullDescription": {"text": "`webapp/app.py` declares `ANY /history/` 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-73d2f563392095b9", "name": "Unused endpoint: ANY /history/<path:filename>", "shortDescription": {"text": "Unused endpoint: ANY /history/<path:filename>"}, "fullDescription": {"text": "`webapp/app.py` declares `ANY /history/<path:filename>` 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-fd4119dbce791524", "name": "Unused endpoint: ANY /qa/", "shortDescription": {"text": "Unused endpoint: ANY /qa/"}, "fullDescription": {"text": "`webapp/app.py` declares `ANY /qa/` 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-74c5b1f5f1fe71fe", "name": "Unused endpoint: ANY /qa", "shortDescription": {"text": "Unused endpoint: ANY /qa"}, "fullDescription": {"text": "`webapp/app.py` declares `ANY /qa` 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-2c0ca82b4f50febc", "name": "Unused endpoint: ANY /qa/update", "shortDescription": {"text": "Unused endpoint: ANY /qa/update"}, "fullDescription": {"text": "`webapp/app.py` declares `ANY /qa/update` 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-f3a803c245ace4f1", "name": "Unused endpoint: ANY /skilltree/", "shortDescription": {"text": "Unused endpoint: ANY /skilltree/"}, "fullDescription": {"text": "`_server_deploy/skilltree.py` declares `ANY /skilltree/` 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-887a8d4a21192e2f", "name": "Unused endpoint: ANY /skilltree/api/books-meta", "shortDescription": {"text": "Unused endpoint: ANY /skilltree/api/books-meta"}, "fullDescription": {"text": "`_server_deploy/skilltree.py` declares `ANY /skilltree/api/books-meta` 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-6e3e6555829513c6", "name": "Unused endpoint: ANY /skilltree/<book>/api/delete", "shortDescription": {"text": "Unused endpoint: ANY /skilltree/<book>/api/delete"}, "fullDescription": {"text": "`_server_deploy/skilltree.py` declares `ANY /skilltree/<book>/api/delete` 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-cdf85d002fd4189c", "name": "Unused endpoint: ANY /skilltree/<book>/", "shortDescription": {"text": "Unused endpoint: ANY /skilltree/<book>/"}, "fullDescription": {"text": "`_server_deploy/skilltree.py` declares `ANY /skilltree/<book>/` 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-4d54bb883bf04a1f", "name": "Unused endpoint: ANY /skilltree/<book>/data.json", "shortDescription": {"text": "Unused endpoint: ANY /skilltree/<book>/data.json"}, "fullDescription": {"text": "`_server_deploy/skilltree.py` declares `ANY /skilltree/<book>/data.json` 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-72ba6997481b404b", "name": "Unused endpoint: ANY /skilltree/<book>/pdf", "shortDescription": {"text": "Unused endpoint: ANY /skilltree/<book>/pdf"}, "fullDescription": {"text": "`_server_deploy/skilltree.py` declares `ANY /skilltree/<book>/pdf` 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-da97d8b5b83a45f4", "name": "Unused endpoint: ANY /skilltree/<book>/api/archive-node", "shortDescription": {"text": "Unused endpoint: ANY /skilltree/<book>/api/archive-node"}, "fullDescription": {"text": "`_server_deploy/skilltree.py` declares `ANY /skilltree/<book>/api/archive-node` 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-81a09bd9fe723db6", "name": "Unused endpoint: ANY /skilltree/<book>/api/restore-node", "shortDescription": {"text": "Unused endpoint: ANY /skilltree/<book>/api/restore-node"}, "fullDescription": {"text": "`_server_deploy/skilltree.py` declares `ANY /skilltree/<book>/api/restore-node` 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-2af24535a1907e15", "name": "Unused endpoint: ANY /skilltree/<book>/api/prune-notes", "shortDescription": {"text": "Unused endpoint: ANY /skilltree/<book>/api/prune-notes"}, "fullDescription": {"text": "`_server_deploy/skilltree.py` declares `ANY /skilltree/<book>/api/prune-notes` 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-bff1c0a78508b3df", "name": "Unused endpoint: ANY /skilltree/<book>/api/build-note", "shortDescription": {"text": "Unused endpoint: ANY /skilltree/<book>/api/build-note"}, "fullDescription": {"text": "`_server_deploy/skilltree.py` declares `ANY /skilltree/<book>/api/build-note` 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-b0044f6359a26ad1", "name": "Unused endpoint: ANY /skilltree/<book>/api/build-note-status/<job_id>", "shortDescription": {"text": "Unused endpoint: ANY /skilltree/<book>/api/build-note-status/<job_id>"}, "fullDescription": {"text": "`_server_deploy/skilltree.py` declares `ANY /skilltree/<book>/api/build-note-status/<job_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-8695dc03943d38b4", "name": "Unused endpoint: ANY /skilltree/<book>/api/toggle-tracked", "shortDescription": {"text": "Unused endpoint: ANY /skilltree/<book>/api/toggle-tracked"}, "fullDescription": {"text": "`_server_deploy/skilltree.py` declares `ANY /skilltree/<book>/api/toggle-tracked` 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-9249feb9c8622971", "name": "Unused endpoint: ANY /skilltree/<book>/api/edit", "shortDescription": {"text": "Unused endpoint: ANY /skilltree/<book>/api/edit"}, "fullDescription": {"text": "`_server_deploy/skilltree.py` declares `ANY /skilltree/<book>/api/edit` 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-af9f841b7fd2738a", "name": "Unused endpoint: ANY /control/api/status", "shortDescription": {"text": "Unused endpoint: ANY /control/api/status"}, "fullDescription": {"text": "`_server_deploy/control.py` declares `ANY /control/api/status` 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-dc14284155645c62", "name": "Unused endpoint: ANY /control/api/config/schema", "shortDescription": {"text": "Unused endpoint: ANY /control/api/config/schema"}, "fullDescription": {"text": "`_server_deploy/control.py` declares `ANY /control/api/config/schema` 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-e53fb451093c1f14", "name": "Unused endpoint: ANY /control/api/ipad-config", "shortDescription": {"text": "Unused endpoint: ANY /control/api/ipad-config"}, "fullDescription": {"text": "`_server_deploy/control.py` declares `ANY /control/api/ipad-config` 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-a85458142cd2eee8", "name": "Unused endpoint: ANY /control/api/config", "shortDescription": {"text": "Unused endpoint: ANY /control/api/config"}, "fullDescription": {"text": "`_server_deploy/control.py` declares `ANY /control/api/config` 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-5dd8c5b22ba36b9b", "name": "Unused endpoint: ANY /control/api/quota-log", "shortDescription": {"text": "Unused endpoint: ANY /control/api/quota-log"}, "fullDescription": {"text": "`_server_deploy/control.py` declares `ANY /control/api/quota-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-0ef899087fd974db", "name": "Unused endpoint: ANY /control/api/quota-now", "shortDescription": {"text": "Unused endpoint: ANY /control/api/quota-now"}, "fullDescription": {"text": "`_server_deploy/control.py` declares `ANY /control/api/quota-now` 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-735286cfb4c23a2f", "name": "Unused endpoint: ANY /control/api/trigger-log", "shortDescription": {"text": "Unused endpoint: ANY /control/api/trigger-log"}, "fullDescription": {"text": "`_server_deploy/control.py` declares `ANY /control/api/trigger-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-8e3fde3e12101a78", "name": "Unused endpoint: ANY /control/api/trigger/<action>", "shortDescription": {"text": "Unused endpoint: ANY /control/api/trigger/<action>"}, "fullDescription": {"text": "`_server_deploy/control.py` declares `ANY /control/api/trigger/<action>` 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-10c583a35f2fcfd2", "name": "Unused endpoint: ANY /control/api/kg-build", "shortDescription": {"text": "Unused endpoint: ANY /control/api/kg-build"}, "fullDescription": {"text": "`_server_deploy/control.py` declares `ANY /control/api/kg-build` 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-a34a227529e9c691", "name": "Unused endpoint: ANY /control/api/kg-build-log", "shortDescription": {"text": "Unused endpoint: ANY /control/api/kg-build-log"}, "fullDescription": {"text": "`_server_deploy/control.py` declares `ANY /control/api/kg-build-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-1a6d91f2236825bf", "name": "Unused endpoint: ANY /", "shortDescription": {"text": "Unused endpoint: ANY /"}, "fullDescription": {"text": "`_server_deploy/pdf_reader.py` declares `ANY /` 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-1c1a12faddca1602", "name": "Unused endpoint: ANY /api/cache-stats", "shortDescription": {"text": "Unused endpoint: ANY /api/cache-stats"}, "fullDescription": {"text": "`_server_deploy/pdf_reader.py` declares `ANY /api/cache-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-d87d1b555a41341a", "name": "Unused endpoint: ANY /api/ping", "shortDescription": {"text": "Unused endpoint: ANY /api/ping"}, "fullDescription": {"text": "`_server_deploy/pdf_reader.py` declares `ANY /api/ping` 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-96bd846c5bb348a1", "name": "Unused endpoint: ANY /api/book-meta", "shortDescription": {"text": "Unused endpoint: ANY /api/book-meta"}, "fullDescription": {"text": "`_server_deploy/pdf_reader.py` declares `ANY /api/book-meta` 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-a9034de58c8021f6", "name": "Unused endpoint: ANY /api/prefs", "shortDescription": {"text": "Unused endpoint: ANY /api/prefs"}, "fullDescription": {"text": "`_server_deploy/pdf_reader.py` declares `ANY /api/prefs` 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-eba3d61a670b6f09", "name": "Unused endpoint: ANY /sw.js", "shortDescription": {"text": "Unused endpoint: ANY /sw.js"}, "fullDescription": {"text": "`_server_deploy/pdf_reader.py` declares `ANY /sw.js` 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-98cabcde8e0f6e0b", "name": "Unused endpoint: ANY /api/page-image", "shortDescription": {"text": "Unused endpoint: ANY /api/page-image"}, "fullDescription": {"text": "`_server_deploy/pdf_reader.py` declares `ANY /api/page-image` 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-6730c7fbe7462299", "name": "Unused endpoint: ANY /view", "shortDescription": {"text": "Unused endpoint: ANY /view"}, "fullDescription": {"text": "`_server_deploy/pdf_reader.py` declares `ANY /view` 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-5a0fd9b8173954cb", "name": "Unused endpoint: ANY /file/<path:rel>", "shortDescription": {"text": "Unused endpoint: ANY /file/<path:rel>"}, "fullDescription": {"text": "`_server_deploy/pdf_reader.py` declares `ANY /file/<path:rel>` 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-51d39b63af99fec6", "name": "Unused endpoint: ANY /api/list-pdfs", "shortDescription": {"text": "Unused endpoint: ANY /api/list-pdfs"}, "fullDescription": {"text": "`_server_deploy/pdf_reader.py` declares `ANY /api/list-pdfs` 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-0514763ee6953fe0", "name": "Unused endpoint: ANY /api/preprocess-status", "shortDescription": {"text": "Unused endpoint: ANY /api/preprocess-status"}, "fullDescription": {"text": "`_server_deploy/pdf_reader.py` declares `ANY /api/preprocess-status` 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-1b3332c2b5c6a2f7", "name": "Unused endpoint: ANY /api/preprocess-async", "shortDescription": {"text": "Unused endpoint: ANY /api/preprocess-async"}, "fullDescription": {"text": "`_server_deploy/pdf_reader.py` declares `ANY /api/preprocess-async` 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-b5596d346605445a", "name": "Unused endpoint: ANY /api/prewarm-async", "shortDescription": {"text": "Unused endpoint: ANY /api/prewarm-async"}, "fullDescription": {"text": "`_server_deploy/pdf_reader.py` declares `ANY /api/prewarm-async` 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-510b59c77515f28b", "name": "Unused endpoint: ANY /api/prewarm-status", "shortDescription": {"text": "Unused endpoint: ANY /api/prewarm-status"}, "fullDescription": {"text": "`_server_deploy/pdf_reader.py` declares `ANY /api/prewarm-status` 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-b542c74c50152ca8", "name": "Unused endpoint: ANY /api/compress-async", "shortDescription": {"text": "Unused endpoint: ANY /api/compress-async"}, "fullDescription": {"text": "`_server_deploy/pdf_reader.py` declares `ANY /api/compress-async` 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/24768"}, "properties": {"repository": "bwicarus/obsidian-claudecode-skills", "repoUrl": "https://github.com/bwicarus/obsidian-claudecode-skills", "branch": "main"}, "results": [{"ruleId": "scanner-d104698065730b6c", "level": "note", "message": {"text": "Possibly dead Python function: hidden_run"}, "properties": {"repobilityId": "ce59697c10001992", "scanner": "scanner-primary", "fingerprint": "d104698065730b6c", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/platform_utils.py:41"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-bf79adad4f527f83", "level": "note", "message": {"text": "Possibly dead Python function: hidden_popen"}, "properties": {"repobilityId": "5d626efc93eb288d", "scanner": "scanner-primary", "fingerprint": "bf79adad4f527f83", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/platform_utils.py:50"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-bb5324026d660ebc", "level": "note", "message": {"text": "Possibly dead Python function: is_systemd_service_active"}, "properties": {"repobilityId": "9cdb8743048ccdd6", "scanner": "scanner-primary", "fingerprint": "bb5324026d660ebc", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/platform_utils.py:56"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-42404f28c4224378", "level": "note", "message": {"text": "Possibly dead Python function: worker"}, "properties": {"repobilityId": "fbe2b50200068803", "scanner": "scanner-primary", "fingerprint": "42404f28c4224378", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/google_vision_ocr.py:192"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-e83dbfc6f76f1375", "level": "note", "message": {"text": "Possibly dead Python function: run_kg_link_mastery"}, "properties": {"repobilityId": "029b841b74d36518", "scanner": "scanner-primary", "fingerprint": "e83dbfc6f76f1375", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/daily_anki_status.py:204"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-4f13d81722c59f19", "level": "note", "message": {"text": "Possibly dead Python function: step_weak"}, "properties": {"repobilityId": "8ce8ce330a2a4ec2", "scanner": "scanner-primary", "fingerprint": "4f13d81722c59f19", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/daily_anki_status.py:313"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-e446d1d203e1f8b0", "level": "note", "message": {"text": "Possibly dead Python function: step_antimodel"}, "properties": {"repobilityId": "526d6fc7c7199303", "scanner": "scanner-primary", "fingerprint": "e446d1d203e1f8b0", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/daily_anki_status.py:321"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-3dc14abbb974fef1", "level": "note", "message": {"text": "Possibly dead Python function: step_quality"}, "properties": {"repobilityId": "51ef6cdb444dc539", "scanner": "scanner-primary", "fingerprint": "3dc14abbb974fef1", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/daily_anki_status.py:328"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-f78974ab9ff339ca", "level": "note", "message": {"text": "Possibly dead Python function: run_smoke_tests"}, "properties": {"repobilityId": "5a02d9ef1b4cd3c2", "scanner": "scanner-primary", "fingerprint": "f78974ab9ff339ca", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/daily_anki_status.py:339"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-ada41286e941ae05", "level": "note", "message": {"text": "Possibly dead Python function: deploy_dashboard"}, "properties": {"repobilityId": "db834589d58c7076", "scanner": "scanner-primary", "fingerprint": "ada41286e941ae05", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/daily_anki_status.py:356"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-e38ffb3f04d74ee9", "level": "note", "message": {"text": "Possibly dead Python function: sync_ankiweb"}, "properties": {"repobilityId": "111871b6ff7d2c22", "scanner": "scanner-primary", "fingerprint": "e38ffb3f04d74ee9", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/daily_anki_status.py:365"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-e518cd23af870bcc", "level": "note", "message": {"text": "Possibly dead Python function: replace_callout"}, "properties": {"repobilityId": "4008a2b15476dd5e", "scanner": "scanner-primary", "fingerprint": "e518cd23af870bcc", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/annotate_note.py:122"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-e50fdf3cf612873a", "level": "note", "message": {"text": "Possibly dead Python function: no_cards_record"}, "properties": {"repobilityId": "bdf5354fb9083319", "scanner": "scanner-primary", "fingerprint": "e50fdf3cf612873a", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/anki_from_note.py:535"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-36d30752a26e0b87", "level": "note", "message": {"text": "Possibly dead Python function: has_text_layer"}, "properties": {"repobilityId": "8c8392601c1b9138", "scanner": "scanner-primary", "fingerprint": "36d30752a26e0b87", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/preprocess_book.py:46"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-e5a791ac37434ab7", "level": "note", "message": {"text": "Possibly dead Python function: handle_qa"}, "properties": {"repobilityId": "d7d132f3cb267aca", "scanner": "scanner-primary", "fingerprint": "e5a791ac37434ab7", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/cmd_server.py:127"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-fd9aad110edf53cf", "level": "note", "message": {"text": "Possibly dead Python function: log_message"}, "properties": {"repobilityId": "965f3150b4af5b2e", "scanner": "scanner-primary", "fingerprint": "fd9aad110edf53cf", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/cmd_server.py:163"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-4c1b1e9643ec1f06", "level": "note", "message": {"text": "Possibly dead Python function: do_GET"}, "properties": {"repobilityId": "2d943bb45e4f13bd", "scanner": "scanner-primary", "fingerprint": "4c1b1e9643ec1f06", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/cmd_server.py:191"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-5a39a9122872a4bb", "level": "note", "message": {"text": "Possibly dead Python function: do_POST"}, "properties": {"repobilityId": "53357410ca9379a9", "scanner": "scanner-primary", "fingerprint": "5a39a9122872a4bb", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/cmd_server.py:200"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-21c42f7d9380cebf", "level": "note", "message": {"text": "Possibly dead Python function: judge_one_note"}, "properties": {"repobilityId": "2f9e709abff44b3d", "scanner": "scanner-primary", "fingerprint": "21c42f7d9380cebf", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/kg/link_with_ai.py:142"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-989e2128ca53b5ca", "level": "note", "message": {"text": "Possibly dead Python function: link_l1"}, "properties": {"repobilityId": "7070c7f0b9b80451", "scanner": "scanner-primary", "fingerprint": "989e2128ca53b5ca", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/kg/link_and_mastery.py:71"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-b4725ed0cf3b6421", "level": "note", "message": {"text": "Possibly dead Python function: process_unit"}, "properties": {"repobilityId": "98936705d3937492", "scanner": "scanner-primary", "fingerprint": "b4725ed0cf3b6421", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/kg/build_grammar_nodes.py:275"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-59c0f08e1169b39b", "level": "note", "message": {"text": "Possibly dead Python function: is_trivial_mechanical"}, "properties": {"repobilityId": "61c1041110340d61", "scanner": "scanner-primary", "fingerprint": "59c0f08e1169b39b", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/kg/auto_archive.py:115"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-28903bd962cff9aa", "level": "note", "message": {"text": "Possibly dead Python function: audit_one_node"}, "properties": {"repobilityId": "22e11fa47409f2f1", "scanner": "scanner-primary", "fingerprint": "28903bd962cff9aa", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/kg/audit_kg.py:233"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-f2df328eef9945e7", "level": "note", "message": {"text": "Possibly dead Python function: audit_deep_one_node"}, "properties": {"repobilityId": "40e9428a2186202e", "scanner": "scanner-primary", "fingerprint": "f2df328eef9945e7", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/kg/audit_kg.py:299"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-1cd523234bdc053b", "level": "note", "message": {"text": "Possibly dead Python function: judge_group"}, "properties": {"repobilityId": "a232e88d728c1522", "scanner": "scanner-primary", "fingerprint": "1cd523234bdc053b", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/kg/merge_nodes.py:101"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-585a623afc44258e", "level": "note", "message": {"text": "Possibly dead Python function: translate_examples"}, "properties": {"repobilityId": "c5f1667359097045", "scanner": "scanner-primary", "fingerprint": "585a623afc44258e", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/vocab/translate.py:299"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-c5daa200464ca472", "level": "note", "message": {"text": "Possibly dead Python function: reset_to_zero"}, "properties": {"repobilityId": "83f95d18c6a0086b", "scanner": "scanner-primary", "fingerprint": "c5daa200464ca472", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/vocab/paragraph_exposure.py:249"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-486a7b6caffdb3a2", "level": "note", "message": {"text": "Possibly dead Python function: lookup_free_dict"}, "properties": {"repobilityId": "9e04cc956dbaeec0", "scanner": "scanner-primary", "fingerprint": "486a7b6caffdb3a2", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/vocab/dict_sources.py:235"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-184b7bea5e548af4", "level": "note", "message": {"text": "Possibly dead Python function: lookup_mw_learner"}, "properties": {"repobilityId": "1176b842f9a110af", "scanner": "scanner-primary", "fingerprint": "184b7bea5e548af4", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/vocab/dict_sources.py:317"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-8d4af49886be79c2", "level": "note", "message": {"text": "Icon-only button without accessible name \u2014 _server_deploy/static/pdf/reader.js:2739"}, "properties": {"repobilityId": "ee01d8888445dca0", "scanner": "scanner-primary", "fingerprint": "8d4af49886be79c2", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.button.no-label"]}}, {"ruleId": "scanner-b23327875be64f63", "level": "note", "message": {"text": "Icon-only button without accessible name \u2014 _server_deploy/static/pdf/reader.src/12-vocab-sentences.js:481"}, "properties": {"repobilityId": "739e8a4e4edaed22", "scanner": "scanner-primary", "fingerprint": "b23327875be64f63", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.button.no-label"]}}, {"ruleId": "scanner-2905e0bee152be7b", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 _server_deploy/static/three/three.module.min.js:6"}, "properties": {"repobilityId": "b3d6da442d99cdc4", "scanner": "scanner-primary", "fingerprint": "2905e0bee152be7b", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-c1bccc4d8687dde2", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in dashboard/index.html:742"}, "properties": {"repobilityId": "1d59152a7617eeef", "scanner": "scanner-primary", "fingerprint": "c1bccc4d8687dde2", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "dashboard/index.html"}, "region": {"startLine": 742}}}]}, {"ruleId": "scanner-93efd27d1a81fabf", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in _client/core/qa_browser.py:1701"}, "properties": {"repobilityId": "53a94668de24f901", "scanner": "scanner-primary", "fingerprint": "93efd27d1a81fabf", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "_client/core/qa_browser.py"}, "region": {"startLine": 1701}}}]}, {"ruleId": "scanner-a5275302ca6dae27", "level": "warning", "message": {"text": "Insecure pattern 'cors_wildcard' in _client/core/qa_browser.py:2789"}, "properties": {"repobilityId": "69bdb32efa2e37a0", "scanner": "scanner-primary", "fingerprint": "a5275302ca6dae27", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "cors_wildcard"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "_client/core/qa_browser.py"}, "region": {"startLine": 2789}}}]}, {"ruleId": "scanner-72a4f9bb63246b3e", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in _server_deploy/static/nav.js:193"}, "properties": {"repobilityId": "3a1df0635d6dbfee", "scanner": "scanner-primary", "fingerprint": "72a4f9bb63246b3e", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "_server_deploy/static/nav.js"}, "region": {"startLine": 193}}}]}, {"ruleId": "scanner-6349f2f97b06f228", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in _server_deploy/static/pdf/reader.js:498"}, "properties": {"repobilityId": "524f4e33b1322f45", "scanner": "scanner-primary", "fingerprint": "6349f2f97b06f228", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "_server_deploy/static/pdf/reader.js"}, "region": {"startLine": 498}}}]}, {"ruleId": "scanner-57db75bc66518a90", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in _server_deploy/static/pdf/reader.src/21-misc-ai.js:42"}, "properties": {"repobilityId": "16b162e0836eeaf1", "scanner": "scanner-primary", "fingerprint": "57db75bc66518a90", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "_server_deploy/static/pdf/reader.src/21-misc-ai.js"}, "region": {"startLine": 42}}}]}, {"ruleId": "scanner-cc55bb15ad68ad38", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in _server_deploy/static/pdf/reader.src/17-highlight.js:55"}, "properties": {"repobilityId": "b13cb00ac3eb45a0", "scanner": "scanner-primary", "fingerprint": "cc55bb15ad68ad38", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "_server_deploy/static/pdf/reader.src/17-highlight.js"}, "region": {"startLine": 55}}}]}, {"ruleId": "scanner-f57f7b8ec67a6902", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in _server_deploy/static/pdf/reader.src/04-render.js:109"}, "properties": {"repobilityId": "4bca36daab0bb907", "scanner": "scanner-primary", "fingerprint": "f57f7b8ec67a6902", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "_server_deploy/static/pdf/reader.src/04-render.js"}, "region": {"startLine": 109}}}]}, {"ruleId": "scanner-4c02d44e247c1720", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in _server_deploy/static/pdf/reader.src/05-nav.js:8"}, "properties": {"repobilityId": "3ecef76f22ba0ec7", "scanner": "scanner-primary", "fingerprint": "4c02d44e247c1720", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "_server_deploy/static/pdf/reader.src/05-nav.js"}, "region": {"startLine": 8}}}]}, {"ruleId": "scanner-b4ad1bb019964f94", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in _server_deploy/static/pdf/reader.src/07-continuous.js:3"}, "properties": {"repobilityId": "cdb9f34f659d56c9", "scanner": "scanner-primary", "fingerprint": "b4ad1bb019964f94", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "_server_deploy/static/pdf/reader.src/07-continuous.js"}, "region": {"startLine": 3}}}]}, {"ruleId": "scanner-5c9f060e3cd0331a", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in _server_deploy/static/pdf/reader.src/20-result-draft.js:6"}, "properties": {"repobilityId": "02dd0a16a43ac80a", "scanner": "scanner-primary", "fingerprint": "5c9f060e3cd0331a", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "_server_deploy/static/pdf/reader.src/20-result-draft.js"}, "region": {"startLine": 6}}}]}, {"ruleId": "scanner-99faefbf51de6de5", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in _server_deploy/static/pdf/reader.src/16-caret-select.js:64"}, "properties": {"repobilityId": "3a02c1989eaa8999", "scanner": "scanner-primary", "fingerprint": "99faefbf51de6de5", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "_server_deploy/static/pdf/reader.src/16-caret-select.js"}, "region": {"startLine": 64}}}]}, {"ruleId": "scanner-286d2842d1d6830a", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in _server_deploy/static/pdf/reader.src/03-loader.js:235"}, "properties": {"repobilityId": "189354ec7448de6a", "scanner": "scanner-primary", "fingerprint": "286d2842d1d6830a", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "_server_deploy/static/pdf/reader.src/03-loader.js"}, "region": {"startLine": 235}}}]}, {"ruleId": "scanner-541e96c942d210c5", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in _server_deploy/static/pdf/reader.src/18-grammar.js:52"}, "properties": {"repobilityId": "b030051d8fe781bd", "scanner": "scanner-primary", "fingerprint": "541e96c942d210c5", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "_server_deploy/static/pdf/reader.src/18-grammar.js"}, "region": {"startLine": 52}}}]}, {"ruleId": "scanner-4ddc6994af6ed81d", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in _server_deploy/static/pdf/reader.src/19-dict.js:65"}, "properties": {"repobilityId": "ea21c34103c8629d", "scanner": "scanner-primary", "fingerprint": "4ddc6994af6ed81d", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "_server_deploy/static/pdf/reader.src/19-dict.js"}, "region": {"startLine": 65}}}]}, {"ruleId": "scanner-7c9d2ddcfffb7e00", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in _server_deploy/static/pdf/reader.src/11-search.js:19"}, "properties": {"repobilityId": "6e98a75c9284fe48", "scanner": "scanner-primary", "fingerprint": "7c9d2ddcfffb7e00", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "_server_deploy/static/pdf/reader.src/11-search.js"}, "region": {"startLine": 19}}}]}, {"ruleId": "scanner-032f8d6501e9d56d", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in _server_deploy/static/pdf/reader.src/08-charlayer.js:56"}, "properties": {"repobilityId": "9c503942ce40b979", "scanner": "scanner-primary", "fingerprint": "032f8d6501e9d56d", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "_server_deploy/static/pdf/reader.src/08-charlayer.js"}, "region": {"startLine": 56}}}]}, {"ruleId": "scanner-fec700a3d031fc2e", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in _server_deploy/static/pdf/reader.src/12-vocab-sentences.js:291"}, "properties": {"repobilityId": "c37462da0a9ebec4", "scanner": "scanner-primary", "fingerprint": "fec700a3d031fc2e", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "_server_deploy/static/pdf/reader.src/12-vocab-sentences.js"}, "region": {"startLine": 291}}}]}, {"ruleId": "scanner-1dfc8bbe93ed5b50", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in _server_deploy/static/pdf/reader.src/15-phrase-wordpop.js:79"}, "properties": {"repobilityId": "b8cdbbea2dd38c0b", "scanner": "scanner-primary", "fingerprint": "1dfc8bbe93ed5b50", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "_server_deploy/static/pdf/reader.src/15-phrase-wordpop.js"}, "region": {"startLine": 79}}}]}, {"ruleId": "scanner-9c8ec43a1f962ffc", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in _server_deploy/static/pdf/reader.src/09-ruby.js:8"}, "properties": {"repobilityId": "bf420c45d68f9000", "scanner": "scanner-primary", "fingerprint": "9c8ec43a1f962ffc", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "_server_deploy/static/pdf/reader.src/09-ruby.js"}, "region": {"startLine": 8}}}]}, {"ruleId": "scanner-f4ab67d8eea0e59b", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in _server_deploy/static/pdf/reader.src/23-bookshelf.js:11"}, "properties": {"repobilityId": "39d1708a47c5a38f", "scanner": "scanner-primary", "fingerprint": "f4ab67d8eea0e59b", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "_server_deploy/static/pdf/reader.src/23-bookshelf.js"}, "region": {"startLine": 11}}}]}, {"ruleId": "scanner-b7d43d27ef4026a8", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in _server_deploy/static/pdf/reader.src/13-selection.js:202"}, "properties": {"repobilityId": "d00e2e7353f55b33", "scanner": "scanner-primary", "fingerprint": "b7d43d27ef4026a8", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "_server_deploy/static/pdf/reader.src/13-selection.js"}, "region": {"startLine": 202}}}]}, {"ruleId": "scanner-73daaa9412ad3d43", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in _server_deploy/static/pdf/reader.src/14-textlayer-legacy.js:80"}, "properties": {"repobilityId": "b2e4090aa1c86a15", "scanner": "scanner-primary", "fingerprint": "73daaa9412ad3d43", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "_server_deploy/static/pdf/reader.src/14-textlayer-legacy.js"}, "region": {"startLine": 80}}}]}, {"ruleId": "scanner-56c39bd510a51890", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in _server_deploy/history/index.html:936"}, "properties": {"repobilityId": "ad876025c03c7256", "scanner": "scanner-primary", "fingerprint": "56c39bd510a51890", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "_server_deploy/history/index.html"}, "region": {"startLine": 936}}}]}, {"ruleId": "scanner-63a3793e2b661ded", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in launchers/\u5386\u53f2\u67e5\u770b.py:142"}, "properties": {"repobilityId": "58cb1b581944c497", "scanner": "scanner-primary", "fingerprint": "63a3793e2b661ded", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "launchers/\u5386\u53f2\u67e5\u770b.py"}, "region": {"startLine": 142}}}]}, {"ruleId": "scanner-0f2d0a5cb2d43789", "level": "warning", "message": {"text": "Insecure pattern 'direct_outerhtml_assignment' in launchers/\u5386\u53f2\u67e5\u770b.py:202"}, "properties": {"repobilityId": "3f6c276edbd918b2", "scanner": "scanner-primary", "fingerprint": "0f2d0a5cb2d43789", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_outerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "launchers/\u5386\u53f2\u67e5\u770b.py"}, "region": {"startLine": 202}}}]}, {"ruleId": "scanner-c752b3fefa3c05f4", "level": "warning", "message": {"text": "Insecure pattern 'cors_wildcard' in launchers/\u5386\u53f2\u67e5\u770b.py:296"}, "properties": {"repobilityId": "e080a5b8aa3a2c0f", "scanner": "scanner-primary", "fingerprint": "c752b3fefa3c05f4", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "cors_wildcard"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "launchers/\u5386\u53f2\u67e5\u770b.py"}, "region": {"startLine": 296}}}]}, {"ruleId": "scanner-c43c2a480e74993e", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in launchers/\u622a\u56fe\u95ee\u7b54.py:782"}, "properties": {"repobilityId": "b8282427f0324fed", "scanner": "scanner-primary", "fingerprint": "c43c2a480e74993e", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "launchers/\u622a\u56fe\u95ee\u7b54.py"}, "region": {"startLine": 782}}}]}, {"ruleId": "scanner-609a150083b9a278", "level": "warning", "message": {"text": "Insecure pattern 'cors_wildcard' in launchers/\u622a\u56fe\u95ee\u7b54.py:1200"}, "properties": {"repobilityId": "39be29adf9e25937", "scanner": "scanner-primary", "fingerprint": "609a150083b9a278", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "cors_wildcard"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "launchers/\u622a\u56fe\u95ee\u7b54.py"}, "region": {"startLine": 1200}}}]}, {"ruleId": "scanner-2cd6f0ea2dc13021", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in history/index.html:124"}, "properties": {"repobilityId": "14edeb7fe006b480", "scanner": "scanner-primary", "fingerprint": "2cd6f0ea2dc13021", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "history/index.html"}, "region": {"startLine": 124}}}]}, {"ruleId": "scanner-3172c44b3f82a640", "level": "warning", "message": {"text": "Insecure pattern 'direct_outerhtml_assignment' in history/index.html:174"}, "properties": {"repobilityId": "1dcae98bd8943add", "scanner": "scanner-primary", "fingerprint": "3172c44b3f82a640", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_outerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "history/index.html"}, "region": {"startLine": 174}}}]}, {"ruleId": "scanner-9973b587cd0089b1", "level": "note", "message": {"text": "Very large file: _client/core/qa_browser.py (3418 lines)"}, "properties": {"repobilityId": "f09fe4be87076fb8", "scanner": "scanner-primary", "fingerprint": "9973b587cd0089b1", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-b42f94ca8a950669", "level": "note", "message": {"text": "Very large file: _client/core/gui.py (1948 lines)"}, "properties": {"repobilityId": "12792a82206045a3", "scanner": "scanner-primary", "fingerprint": "b42f94ca8a950669", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-a731b2590372c93d", "level": "note", "message": {"text": "Very large file: _server_deploy/pdf_reader.py (5707 lines)"}, "properties": {"repobilityId": "be84086178fa416b", "scanner": "scanner-primary", "fingerprint": "a731b2590372c93d", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-69b7f77ed032b128", "level": "note", "message": {"text": "Very large file: _server_deploy/static/pdf/reader.js (7622 lines)"}, "properties": {"repobilityId": "2875305f7e484cff", "scanner": "scanner-primary", "fingerprint": "69b7f77ed032b128", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-0d5bab0ccc4cff99", "level": "note", "message": {"text": "Very large file: _server_deploy/static/three/GLTFLoader.js (4725 lines)"}, "properties": {"repobilityId": "aa77fa0d5758e98b", "scanner": "scanner-primary", "fingerprint": "0d5bab0ccc4cff99", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-c4964bd75f649851", "level": "note", "message": {"text": "Very large file: launchers/\u622a\u56fe\u95ee\u7b54.py (1571 lines)"}, "properties": {"repobilityId": "38f7c99aebc7fbfe", "scanner": "scanner-primary", "fingerprint": "c4964bd75f649851", "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": "16a03bde7d52e681", "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": "9bfd6ea461a1e4b6", "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": "c4ccefb4eee57dfb", "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": "3fb6ffc7d2b7376b", "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": "note", "message": {"text": "Composite production-readiness gap"}, "properties": {"repobilityId": "8b4f8c103583321c", "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": "f415d08b31cfae7f", "scanner": "scanner-primary", "fingerprint": "749d4bc1bd66df5f", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-05f5478d21665a25", "level": "warning", "message": {"text": "Agent authority lacks a verifier contract: .claude/skills/pdf-mark.md"}, "properties": {"repobilityId": "e003e15bcd700543", "scanner": "scanner-primary", "fingerprint": "05f5478d21665a25", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "verification", "claude_instruction"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".claude/skills/pdf-mark.md"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-7910530bc2f8dc38", "level": "warning", "message": {"text": "Agent authority lacks a verifier contract: .claude/skills/\u767b\u8bb0\u65b0\u7b14\u8bb0.md"}, "properties": {"repobilityId": "48786b651b5fa7ba", "scanner": "scanner-primary", "fingerprint": "7910530bc2f8dc38", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "verification", "claude_instruction"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".claude/skills/\u767b\u8bb0\u65b0\u7b14\u8bb0.md"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-b8e8475ba8bb912d", "level": "warning", "message": {"text": "Agent authority lacks a verifier contract: .claude/skills/openai-cli-chat.md"}, "properties": {"repobilityId": "640fe3c4c3460008", "scanner": "scanner-primary", "fingerprint": "b8e8475ba8bb912d", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "verification", "claude_instruction"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".claude/skills/openai-cli-chat.md"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-1d0865b06dd19e56", "level": "warning", "message": {"text": "Agent authority lacks a verifier contract: .claude/skills/claude-quota.md"}, "properties": {"repobilityId": "0588c6b634995624", "scanner": "scanner-primary", "fingerprint": "1d0865b06dd19e56", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "verification", "claude_instruction"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".claude/skills/claude-quota.md"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-6639ce3ba76a0320", "level": "warning", "message": {"text": "Agent authority lacks a verifier contract: .claude/skills/website.md"}, "properties": {"repobilityId": "89757f8f14380461", "scanner": "scanner-primary", "fingerprint": "6639ce3ba76a0320", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "verification", "claude_instruction"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".claude/skills/website.md"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-2013d507601d029b", "level": "warning", "message": {"text": "Network/subprocess call without timeout or try/except \u2014 scripts/register_notes.py:56"}, "properties": {"repobilityId": "0a893899f26d33ca", "scanner": "scanner-primary", "fingerprint": "2013d507601d029b", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-29697c4a66e58a42", "level": "note", "message": {"text": "Stub function `update` (body is just `pass`/`return`) \u2014 scripts/register_notes.py:468"}, "properties": {"repobilityId": "2083e5c9fdb42904", "scanner": "scanner-primary", "fingerprint": "29697c4a66e58a42", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "empty-handler", "dead-code"]}}, {"ruleId": "scanner-41efef83219ae056", "level": "warning", "message": {"text": "Network/subprocess call without timeout or try/except \u2014 scripts/platform_utils.py:13"}, "properties": {"repobilityId": "f80a4090737041ea", "scanner": "scanner-primary", "fingerprint": "41efef83219ae056", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-b49b44c23d6c4b1b", "level": "warning", "message": {"text": "Network/subprocess call without timeout or try/except \u2014 scripts/prewarm_pdf.py:25"}, "properties": {"repobilityId": "e12797a22acc777e", "scanner": "scanner-primary", "fingerprint": "b49b44c23d6c4b1b", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-1fce2d1cab391f68", "level": "warning", "message": {"text": "Network/subprocess call without timeout or try/except \u2014 scripts/quick_sync.py:27"}, "properties": {"repobilityId": "bcac514ff5196985", "scanner": "scanner-primary", "fingerprint": "1fce2d1cab391f68", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-a84ad1cc4645bcf5", "level": "none", "message": {"text": "Commented-code block (5 lines) in scripts/find_jeff_videos.py:44"}, "properties": {"repobilityId": "042a9a2ffe928a4e", "scanner": "scanner-primary", "fingerprint": "a84ad1cc4645bcf5", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-e61306696f568e3a", "level": "warning", "message": {"text": "Network/subprocess call without timeout or try/except \u2014 scripts/daily_anki_status.py:197"}, "properties": {"repobilityId": "6fb141dcf23835f4", "scanner": "scanner-primary", "fingerprint": "e61306696f568e3a", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-e4903607a176b389", "level": "warning", "message": {"text": "Network/subprocess call without timeout or try/except \u2014 scripts/annotate_note.py:35"}, "properties": {"repobilityId": "42df40e7bff123f9", "scanner": "scanner-primary", "fingerprint": "e4903607a176b389", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-8a290cf533c2604e", "level": "none", "message": {"text": "Commented-code block (5 lines) in scripts/embed_ocr_to_pdf.py:207"}, "properties": {"repobilityId": "bebe9bd7d31b7a6c", "scanner": "scanner-primary", "fingerprint": "8a290cf533c2604e", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-ad6b3577e1e3692f", "level": "none", "message": {"text": "Commented-code block (7 lines) in scripts/export_dashboard.py:102"}, "properties": {"repobilityId": "c99ca998ca6eb0a0", "scanner": "scanner-primary", "fingerprint": "ad6b3577e1e3692f", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-6072259105b7f1f9", "level": "note", "message": {"text": "Legacy-named symbol `_file_hash_legacy` in scripts/cleanup_orphans.py:139"}, "properties": {"repobilityId": "ad5eec7c48af06dc", "scanner": "scanner-primary", "fingerprint": "6072259105b7f1f9", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-26fd47d997f462b5", "level": "note", "message": {"text": "Legacy-named symbol `_file_hash_legacy` in scripts/note_state.py:44"}, "properties": {"repobilityId": "a73685c44e9a4518", "scanner": "scanner-primary", "fingerprint": "26fd47d997f462b5", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-1d0311733125d824", "level": "warning", "message": {"text": "Network/subprocess call without timeout or try/except \u2014 scripts/book_ocr_watchdog.py:42"}, "properties": {"repobilityId": "e7746ffda5c298ed", "scanner": "scanner-primary", "fingerprint": "1d0311733125d824", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-bf9a25f1576416b8", "level": "warning", "message": {"text": "Network/subprocess call without timeout or try/except \u2014 scripts/service_switch.py:75"}, "properties": {"repobilityId": "ed20cea6c47bbea5", "scanner": "scanner-primary", "fingerprint": "bf9a25f1576416b8", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-96849d4e4e072bd6", "level": "none", "message": {"text": "Commented-code block (5 lines) in scripts/preprocess_book.py:207"}, "properties": {"repobilityId": "d20b80062bceb82e", "scanner": "scanner-primary", "fingerprint": "96849d4e4e072bd6", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-4038b2e66fbcfdd7", "level": "warning", "message": {"text": "Network/subprocess call without timeout or try/except \u2014 scripts/preprocess_book.py:293"}, "properties": {"repobilityId": "e3c2e6eeb2644fe0", "scanner": "scanner-primary", "fingerprint": "4038b2e66fbcfdd7", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-7a5a6ba604ae15fb", "level": "warning", "message": {"text": "Network/subprocess call without timeout or try/except \u2014 scripts/restore_textlayer.py:53"}, "properties": {"repobilityId": "dd5d4a92aacbd7af", "scanner": "scanner-primary", "fingerprint": "7a5a6ba604ae15fb", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-3c919c1211c7dd85", "level": "warning", "message": {"text": "Network/subprocess call without timeout or try/except \u2014 scripts/cmd_server.py:59"}, "properties": {"repobilityId": "977cbc21530ff4e2", "scanner": "scanner-primary", "fingerprint": "3c919c1211c7dd85", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-d80178e547ff16f9", "level": "warning", "message": {"text": "Network/subprocess call without timeout or try/except \u2014 scripts/optimize_pdf.py:86"}, "properties": {"repobilityId": "c9a545af9e7d84eb", "scanner": "scanner-primary", "fingerprint": "d80178e547ff16f9", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-50789c1d7487d160", "level": "warning", "message": {"text": "Network/subprocess call without timeout or try/except \u2014 scripts/ai_client.py:91"}, "properties": {"repobilityId": "d9727d98d3a9ad63", "scanner": "scanner-primary", "fingerprint": "50789c1d7487d160", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-9176de346c4f0fc3", "level": "none", "message": {"text": "Commented-code block (8 lines) in scripts/anki_status.py:92"}, "properties": {"repobilityId": "36e65e279e7f19db", "scanner": "scanner-primary", "fingerprint": "9176de346c4f0fc3", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-fbd0729769967cc5", "level": "none", "message": {"text": "Commented-code block (5 lines) in scripts/kg/link_and_mastery.py:32"}, "properties": {"repobilityId": "2adcb6c76c9e1c85", "scanner": "scanner-primary", "fingerprint": "fbd0729769967cc5", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-6885a8b7680e4ecb", "level": "note", "message": {"text": "Legacy-named symbol `is_trivial_mechanical_legacy` in scripts/kg/auto_archive.py:99"}, "properties": {"repobilityId": "404f464af6bbc6d5", "scanner": "scanner-primary", "fingerprint": "6885a8b7680e4ecb", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-cbe27cb06d4e45fe", "level": "warning", "message": {"text": "Network/subprocess call without timeout or try/except \u2014 scripts/vocab/build_tanaka_index.py:48"}, "properties": {"repobilityId": "d6f8fc966ce2c1ad", "scanner": "scanner-primary", "fingerprint": "cbe27cb06d4e45fe", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-211abffd687be179", "level": "warning", "message": {"text": "Network/subprocess call without timeout or try/except \u2014 scripts/vocab/build_kanjidic.py:31"}, "properties": {"repobilityId": "fa7f8df6daf70c05", "scanner": "scanner-primary", "fingerprint": "211abffd687be179", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-12e83b5380ca4bec", "level": "warning", "message": {"text": "Network/subprocess call without timeout or try/except \u2014 _client/core/ai_backends.py:119"}, "properties": {"repobilityId": "752fcbdd901714e6", "scanner": "scanner-primary", "fingerprint": "12e83b5380ca4bec", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-6687f587f1fbd181", "level": "warning", "message": {"text": "Network/subprocess call without timeout or try/except \u2014 _server_deploy/qa_server.py:136"}, "properties": {"repobilityId": "3962b1712ca1404d", "scanner": "scanner-primary", "fingerprint": "6687f587f1fbd181", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-9fdaae84fe3a2844", "level": "warning", "message": {"text": "Network/subprocess call without timeout or try/except \u2014 _server_deploy/skilltree.py:524"}, "properties": {"repobilityId": "42b23bda0235254d", "scanner": "scanner-primary", "fingerprint": "9fdaae84fe3a2844", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-2ffcbe855f03d978", "level": "warning", "message": {"text": "Network/subprocess call without timeout or try/except \u2014 _server_deploy/control.py:151"}, "properties": {"repobilityId": "23d3b7b56aa01aba", "scanner": "scanner-primary", "fingerprint": "2ffcbe855f03d978", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-5540e26fbbf0a3c8", "level": "note", "message": {"text": "Legacy-named symbol `_gs_old` in _server_deploy/pdf_reader.py:5392"}, "properties": {"repobilityId": "a48d8cbb3ac32cd6", "scanner": "scanner-primary", "fingerprint": "5540e26fbbf0a3c8", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-baf377a088e9555f", "level": "none", "message": {"text": "Commented-code block (6 lines) in _server_deploy/app.py:131"}, "properties": {"repobilityId": "f4f1af673c4efecc", "scanner": "scanner-primary", "fingerprint": "baf377a088e9555f", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-d8a96be751d27451", "level": "warning", "message": {"text": "Network/subprocess call without timeout or try/except \u2014 _server_deploy/youtube_speech.py:72"}, "properties": {"repobilityId": "d0888e2696353a58", "scanner": "scanner-primary", "fingerprint": "d8a96be751d27451", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-5c4db51b77be2ff9", "level": "none", "message": {"text": "Commented-code block (5 lines) in _server_deploy/static/pdf/reader.js:1604"}, "properties": {"repobilityId": "420a56e73701f540", "scanner": "scanner-primary", "fingerprint": "5c4db51b77be2ff9", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-b953783157afebca", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 _server_deploy/static/pdf/reader.js:35"}, "properties": {"repobilityId": "e660a2ac906f95dd", "scanner": "scanner-primary", "fingerprint": "b953783157afebca", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-49420fd197137083", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 _server_deploy/static/pdf/reader.src/05-nav.js:206"}, "properties": {"repobilityId": "5b329d80406107e7", "scanner": "scanner-primary", "fingerprint": "49420fd197137083", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-79754ad736b12eb9", "level": "none", "message": {"text": "Commented-code block (5 lines) in _server_deploy/static/pdf/reader.src/07-continuous.js:83"}, "properties": {"repobilityId": "2fc7b0f5e779d750", "scanner": "scanner-primary", "fingerprint": "79754ad736b12eb9", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-a4034190b009c729", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 _server_deploy/static/pdf/reader.src/03-loader.js:99"}, "properties": {"repobilityId": "bfa398d2f53210b2", "scanner": "scanner-primary", "fingerprint": "a4034190b009c729", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-bf0687f4069a2bb1", "level": "none", "message": {"text": "Commented-code block (5 lines) in _server_deploy/static/pdf/reader.src/19-dict.js:260"}, "properties": {"repobilityId": "3300a517f02737a8", "scanner": "scanner-primary", "fingerprint": "bf0687f4069a2bb1", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-8e74a4243b8556db", "level": "none", "message": {"text": "Commented-code block (5 lines) in _server_deploy/static/pdf/reader.src/15-phrase-wordpop.js:602"}, "properties": {"repobilityId": "2812602ee35972c9", "scanner": "scanner-primary", "fingerprint": "8e74a4243b8556db", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-f691fcf4229f7e38", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 _server_deploy/static/pdf/reader.src/15-phrase-wordpop.js:169"}, "properties": {"repobilityId": "37299f8828a31849", "scanner": "scanner-primary", "fingerprint": "f691fcf4229f7e38", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-d66f9029d3078548", "level": "none", "message": {"text": "Commented-code block (5 lines) in _server_deploy/static/pdf/reader.src/23-bookshelf.js:1"}, "properties": {"repobilityId": "c87bf548aa268d0a", "scanner": "scanner-primary", "fingerprint": "d66f9029d3078548", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-a8e14cf90f130a9d", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 _server_deploy/static/pdf/reader.src/01-boot.js:35"}, "properties": {"repobilityId": "d8515f30226ba993", "scanner": "scanner-primary", "fingerprint": "a8e14cf90f130a9d", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-d3a4ce7c68cc2367", "level": "none", "message": {"text": "Commented-code block (5 lines) in _server_deploy/static/pdf/reader.src/13-selection.js:88"}, "properties": {"repobilityId": "3efe76db45dc8eb2", "scanner": "scanner-primary", "fingerprint": "d3a4ce7c68cc2367", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-df4a80b5c885e14e", "level": "none", "message": {"text": "Commented-code block (5 lines) in _server_deploy/static/three/GLTFLoader.js:198"}, "properties": {"repobilityId": "36aad68231ccf7d8", "scanner": "scanner-primary", "fingerprint": "df4a80b5c885e14e", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-6b3890400b9a2348", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 _server_deploy/static/three/three.module.min.js:6"}, "properties": {"repobilityId": "adf05dc3073b55d7", "scanner": "scanner-primary", "fingerprint": "6b3890400b9a2348", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-4650cfd558b7e03a", "level": "warning", "message": {"text": "Network/subprocess call without timeout or try/except \u2014 launchers/\u622a\u56fe\u95ee\u7b54.py:284"}, "properties": {"repobilityId": "ceba53c83b57a73d", "scanner": "scanner-primary", "fingerprint": "4650cfd558b7e03a", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-2c04133e54348533", "level": "note", "message": {"text": "Near-duplicate function bodies in 2 places"}, "properties": {"repobilityId": "12eef6a226bf9212", "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": "248318ae5b9b61d1", "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": "81385d464ea262fc", "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": "385a6a8f7485ddf9", "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": "85e303cb111122a3", "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": "590245f6ea6b10d3", "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": "b9e29fff5743fea3", "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": "18ff8a9a34fab06c", "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": "c163c50a8e6687ff", "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": "d6300b4b1208e953", "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": "bbb383c2a8087fed", "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": "c59f53ebe699fa65", "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": "94ddd237495e8ebf", "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": "3fac50417eb1a11c", "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": "51d87d1dcdb7e4d3", "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": "5d6557705d9a5204", "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": "f8012c436e686298", "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": "7e7b00b93375a8e1", "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": "869fa1aa2419aec2", "scanner": "scanner-primary", "fingerprint": "2c04133e54348533", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "duplicate", "dry"]}}, {"ruleId": "scanner-49c98f7cedd9c977", "level": "note", "message": {"text": "Near-duplicate function bodies in 4 places"}, "properties": {"repobilityId": "064cef92a231e4a0", "scanner": "scanner-primary", "fingerprint": "49c98f7cedd9c977", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "duplicate", "dry"]}}, {"ruleId": "scanner-f61fcd81aac4d160", "level": "error", "message": {"text": "Flask mutation route `login` without `@login_required` \u2014 webapp/app.py:31"}, "properties": {"repobilityId": "cd287bd58a0d2729", "scanner": "scanner-primary", "fingerprint": "f61fcd81aac4d160", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.flask.unauth_route"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "webapp/app.py"}, "region": {"startLine": 31}}}]}, {"ruleId": "scanner-542217ae0032dc51", "level": "error", "message": {"text": "Flask mutation route `graph_settings` without `@login_required` \u2014 webapp/app.py:60"}, "properties": {"repobilityId": "8424e529226b3379", "scanner": "scanner-primary", "fingerprint": "542217ae0032dc51", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.flask.unauth_route"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "webapp/app.py"}, "region": {"startLine": 60}}}]}, {"ruleId": "scanner-9a95e86355fad0e6", "level": "error", "message": {"text": "Flask mutation route `qa_update` without `@login_required` \u2014 webapp/app.py:110"}, "properties": {"repobilityId": "5167a66b8b1fcd13", "scanner": "scanner-primary", "fingerprint": "9a95e86355fad0e6", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.flask.unauth_route"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "webapp/app.py"}, "region": {"startLine": 110}}}]}, {"ruleId": "scanner-13c0289ee5cea73f", "level": "error", "message": {"text": "Flask mutation route `skilltree_delete_book` without `@login_required` \u2014 _server_deploy/skilltree.py:770"}, "properties": {"repobilityId": "3d2b27f6850e6657", "scanner": "scanner-primary", "fingerprint": "13c0289ee5cea73f", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.flask.unauth_route"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "_server_deploy/skilltree.py"}, "region": {"startLine": 770}}}]}, {"ruleId": "scanner-f2aa95e6f930dae9", "level": "error", "message": {"text": "Flask mutation route `skilltree_archive_node` without `@login_required` \u2014 _server_deploy/skilltree.py:845"}, "properties": {"repobilityId": "e0c2db953fcbd6c1", "scanner": "scanner-primary", "fingerprint": "f2aa95e6f930dae9", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.flask.unauth_route"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "_server_deploy/skilltree.py"}, "region": {"startLine": 845}}}]}, {"ruleId": "scanner-61b29c1e676fa271", "level": "error", "message": {"text": "Flask mutation route `skilltree_restore_node` without `@login_required` \u2014 _server_deploy/skilltree.py:891"}, "properties": {"repobilityId": "c1bc11e0712df2f7", "scanner": "scanner-primary", "fingerprint": "61b29c1e676fa271", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.flask.unauth_route"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "_server_deploy/skilltree.py"}, "region": {"startLine": 891}}}]}, {"ruleId": "scanner-9751ca8d41fa7a66", "level": "error", "message": {"text": "Flask mutation route `skilltree_prune_notes` without `@login_required` \u2014 _server_deploy/skilltree.py:935"}, "properties": {"repobilityId": "72d44ab60e9fa83b", "scanner": "scanner-primary", "fingerprint": "9751ca8d41fa7a66", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.flask.unauth_route"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "_server_deploy/skilltree.py"}, "region": {"startLine": 935}}}]}, {"ruleId": "scanner-5d940e976607a2b8", "level": "error", "message": {"text": "Flask mutation route `skilltree_build_note` without `@login_required` \u2014 _server_deploy/skilltree.py:995"}, "properties": {"repobilityId": "1d89006d6181bfa8", "scanner": "scanner-primary", "fingerprint": "5d940e976607a2b8", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.flask.unauth_route"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "_server_deploy/skilltree.py"}, "region": {"startLine": 995}}}]}, {"ruleId": "scanner-4f80964acde0275d", "level": "error", "message": {"text": "Flask mutation route `skilltree_toggle_tracked` without `@login_required` \u2014 _server_deploy/skilltree.py:1052"}, "properties": {"repobilityId": "7c004ba1b9f79709", "scanner": "scanner-primary", "fingerprint": "4f80964acde0275d", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.flask.unauth_route"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "_server_deploy/skilltree.py"}, "region": {"startLine": 1052}}}]}, {"ruleId": "scanner-39d445ae54a0e933", "level": "error", "message": {"text": "Flask mutation route `skilltree_edit` without `@login_required` \u2014 _server_deploy/skilltree.py:1075"}, "properties": {"repobilityId": "7fe041643d63ef59", "scanner": "scanner-primary", "fingerprint": "39d445ae54a0e933", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.flask.unauth_route"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "_server_deploy/skilltree.py"}, "region": {"startLine": 1075}}}]}, {"ruleId": "scanner-ad6b55c5ef445d47", "level": "error", "message": {"text": "Flask mutation route `control_config` without `@login_required` \u2014 _server_deploy/control.py:217"}, "properties": {"repobilityId": "199e19a069469bcf", "scanner": "scanner-primary", "fingerprint": "ad6b55c5ef445d47", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.flask.unauth_route"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "_server_deploy/control.py"}, "region": {"startLine": 217}}}]}, {"ruleId": "scanner-e70a3e7c62a84178", "level": "error", "message": {"text": "Flask mutation route `control_trigger` without `@login_required` \u2014 _server_deploy/control.py:335"}, "properties": {"repobilityId": "5df8a4179e26a1a7", "scanner": "scanner-primary", "fingerprint": "e70a3e7c62a84178", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.flask.unauth_route"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "_server_deploy/control.py"}, "region": {"startLine": 335}}}]}, {"ruleId": "scanner-d88e2d8cd8445ee9", "level": "error", "message": {"text": "Flask mutation route `control_kg_build` without `@login_required` \u2014 _server_deploy/control.py:377"}, "properties": {"repobilityId": "713614f961784291", "scanner": "scanner-primary", "fingerprint": "d88e2d8cd8445ee9", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.flask.unauth_route"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "_server_deploy/control.py"}, "region": {"startLine": 377}}}]}, {"ruleId": "scanner-7bdbf375ea726a49", "level": "error", "message": {"text": "Flask mutation route `login` without `@login_required` \u2014 _server_deploy/app.py:403"}, "properties": {"repobilityId": "e8e5ba031f559acf", "scanner": "scanner-primary", "fingerprint": "7bdbf375ea726a49", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.flask.unauth_route"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "_server_deploy/app.py"}, "region": {"startLine": 403}}}]}, {"ruleId": "scanner-df0763164a9a423f", "level": "error", "message": {"text": "Flask mutation route `register` without `@login_required` \u2014 _server_deploy/app.py:448"}, "properties": {"repobilityId": "04784e79e47d5c8b", "scanner": "scanner-primary", "fingerprint": "df0763164a9a423f", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.flask.unauth_route"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "_server_deploy/app.py"}, "region": {"startLine": 448}}}]}, {"ruleId": "scanner-9a4ff4ff4f94e320", "level": "error", "message": {"text": "Flask mutation route `graph_settings` without `@login_required` \u2014 _server_deploy/app.py:574"}, "properties": {"repobilityId": "de66edebaf74fb11", "scanner": "scanner-primary", "fingerprint": "9a4ff4ff4f94e320", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.flask.unauth_route"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "_server_deploy/app.py"}, "region": {"startLine": 574}}}]}, {"ruleId": "scanner-de03c45cab92592c", "level": "error", "message": {"text": "Flask mutation route `nav_links` without `@login_required` \u2014 _server_deploy/app.py:627"}, "properties": {"repobilityId": "54d2df6ced0fb439", "scanner": "scanner-primary", "fingerprint": "de03c45cab92592c", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.flask.unauth_route"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "_server_deploy/app.py"}, "region": {"startLine": 627}}}]}, {"ruleId": "scanner-f3dc7f6583c836a4", "level": "error", "message": {"text": "Flask mutation route `admin_create_invite` without `@login_required` \u2014 _server_deploy/app.py:808"}, "properties": {"repobilityId": "cccd209f61797a69", "scanner": "scanner-primary", "fingerprint": "f3dc7f6583c836a4", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.flask.unauth_route"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "_server_deploy/app.py"}, "region": {"startLine": 808}}}]}, {"ruleId": "scanner-f460848c4ac878df", "level": "error", "message": {"text": "Flask mutation route `admin_delete_invite` without `@login_required` \u2014 _server_deploy/app.py:827"}, "properties": {"repobilityId": "11416686da4ebb66", "scanner": "scanner-primary", "fingerprint": "f460848c4ac878df", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.flask.unauth_route"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "_server_deploy/app.py"}, "region": {"startLine": 827}}}]}, {"ruleId": "scanner-ceb72b57b638cf24", "level": "error", "message": {"text": "Flask mutation route `admin_delete_user` without `@login_required` \u2014 _server_deploy/app.py:834"}, "properties": {"repobilityId": "07d09db917a9a83f", "scanner": "scanner-primary", "fingerprint": "ceb72b57b638cf24", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.flask.unauth_route"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "_server_deploy/app.py"}, "region": {"startLine": 834}}}]}, {"ruleId": "scanner-a7bb8138a0eeabda", "level": "error", "message": {"text": "Flask mutation route `api_upload` without `@login_required` \u2014 _server_deploy/app.py:875"}, "properties": {"repobilityId": "425d9ae87f1d59dc", "scanner": "scanner-primary", "fingerprint": "a7bb8138a0eeabda", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.flask.unauth_route"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "_server_deploy/app.py"}, "region": {"startLine": 875}}}]}, {"ruleId": "scanner-e1edf93d54db0220", "level": "error", "message": {"text": "Flask mutation route `qa_update` without `@login_required` \u2014 _server_deploy/app.py:942"}, "properties": {"repobilityId": "60d6d6ae16a710b3", "scanner": "scanner-primary", "fingerprint": "e1edf93d54db0220", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.flask.unauth_route"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "_server_deploy/app.py"}, "region": {"startLine": 942}}}]}, {"ruleId": "scanner-81c5b1f5e9b4efc4", "level": "error", "message": {"text": "Dangling fetch: GET /pdf/api/prefs (_server_deploy/static/pdf/reader.js:11)"}, "properties": {"repobilityId": "57c3070eda0e4c90", "scanner": "scanner-primary", "fingerprint": "81c5b1f5e9b4efc4", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-08f7efbeea7dc095", "level": "error", "message": {"text": "Dangling fetch: POST /pdf/api/prefs (_server_deploy/static/pdf/reader.js:35)"}, "properties": {"repobilityId": "7b13b8d3efedf484", "scanner": "scanner-primary", "fingerprint": "08f7efbeea7dc095", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-861a2cbc51a4d5ad", "level": "error", "message": {"text": "Dangling fetch: POST /pdf/api/prefs (_server_deploy/static/pdf/reader.js:50)"}, "properties": {"repobilityId": "5dc20b16287faed5", "scanner": "scanner-primary", "fingerprint": "861a2cbc51a4d5ad", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-f66b9249ac34e028", "level": "error", "message": {"text": "Dangling fetch: POST /pdf/api/book-langs (_server_deploy/static/pdf/reader.js:112)"}, "properties": {"repobilityId": "f1341c33e74c687e", "scanner": "scanner-primary", "fingerprint": "f66b9249ac34e028", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-3f86b4bbb213d396", "level": "error", "message": {"text": "Dangling fetch: POST /pdf/api/book-crop (_server_deploy/static/pdf/reader.js:530)"}, "properties": {"repobilityId": "d38f10fa46ebda17", "scanner": "scanner-primary", "fingerprint": "3f86b4bbb213d396", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-fae1d4ec64a31bcb", "level": "error", "message": {"text": "Dangling fetch: GET /pdf/api/page-nodes?file=${encodeURIComponent(FILE_REL)}&page=${num} (_server_deploy/static/pdf/reader.js:857)"}, "properties": {"repobilityId": "bbbc40ff5323f36f", "scanner": "scanner-primary", "fingerprint": "fae1d4ec64a31bcb", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-9bb6fd2dc7f457f0", "level": "error", "message": {"text": "Dangling fetch: POST /skilltree/${encodeURIComponent(book)}/api/toggle-tracked (_server_deploy/static/pdf/reader.js:890)"}, "properties": {"repobilityId": "d052a266ab942415", "scanner": "scanner-primary", "fingerprint": "9bb6fd2dc7f457f0", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-0090d8b057b37efb", "level": "error", "message": {"text": "Dangling fetch: POST /pdf/api/grammar-forget (_server_deploy/static/pdf/reader.js:1031)"}, "properties": {"repobilityId": "e8da797b10e06b8c", "scanner": "scanner-primary", "fingerprint": "0090d8b057b37efb", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-6ece3a00fdf2ffa8", "level": "error", "message": {"text": "Dangling fetch: POST /pdf/api/vocab-anki (_server_deploy/static/pdf/reader.js:1128)"}, "properties": {"repobilityId": "cceec431903042ea", "scanner": "scanner-primary", "fingerprint": "6ece3a00fdf2ffa8", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-04fdc6c58de46ec4", "level": "error", "message": {"text": "Dangling fetch: GET /pdf/api/page-overlay?file=${encodeURIComponent(FILE_REL)}&page=${num} (_server_deploy/static/pdf/reader.js:1836)"}, "properties": {"repobilityId": "685da16e30d3c651", "scanner": "scanner-primary", "fingerprint": "04fdc6c58de46ec4", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-5e61f3b82d3197f1", "level": "error", "message": {"text": "Dangling fetch: POST /pdf/api/translate-sentence (_server_deploy/static/pdf/reader.js:2573)"}, "properties": {"repobilityId": "a88b405b2ca5cc9c", "scanner": "scanner-primary", "fingerprint": "5e61f3b82d3197f1", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-a7d1345a6df8ecee", "level": "error", "message": {"text": "Dangling fetch: POST /pdf/api/sentence-dismiss (_server_deploy/static/pdf/reader.js:2604)"}, "properties": {"repobilityId": "5bbdd8f44d6af6f7", "scanner": "scanner-primary", "fingerprint": "a7d1345a6df8ecee", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-385ea81cceea0221", "level": "error", "message": {"text": "Dangling fetch: POST /pdf/api/translate-sentence (_server_deploy/static/pdf/reader.js:2626)"}, "properties": {"repobilityId": "e0679b8b2b8ea65b", "scanner": "scanner-primary", "fingerprint": "385ea81cceea0221", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-d1fbd94d209cb003", "level": "error", "message": {"text": "Dangling fetch: POST /pdf/api/translate-sentence (_server_deploy/static/pdf/reader.js:2780)"}, "properties": {"repobilityId": "dd6d4437c49c6db7", "scanner": "scanner-primary", "fingerprint": "d1fbd94d209cb003", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-243b80d88c32b508", "level": "error", "message": {"text": "Dangling fetch: GET /pdf/api/phrases (_server_deploy/static/pdf/reader.js:3719)"}, "properties": {"repobilityId": "1011d69b3d5f6b0d", "scanner": "scanner-primary", "fingerprint": "243b80d88c32b508", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-c860a470dcc975e6", "level": "error", "message": {"text": "Dangling fetch: GET /pdf/api/phrase-mark (_server_deploy/static/pdf/reader.js:3720)"}, "properties": {"repobilityId": "34c80abe92cc6dec", "scanner": "scanner-primary", "fingerprint": "c860a470dcc975e6", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-49315288e384b0e6", "level": "error", "message": {"text": "Dangling fetch: POST /pdf/api/translate-sentence (_server_deploy/static/pdf/reader.js:3882)"}, "properties": {"repobilityId": "a53e212c8446d085", "scanner": "scanner-primary", "fingerprint": "49315288e384b0e6", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-0a5e839062687623", "level": "error", "message": {"text": "Dangling fetch: GET /pdf/api/phrases (_server_deploy/static/pdf/reader.js:3914)"}, "properties": {"repobilityId": "a2cbc8bbf2a8b419", "scanner": "scanner-primary", "fingerprint": "0a5e839062687623", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-8d23478353a7c437", "level": "error", "message": {"text": "Dangling fetch: POST /pdf/api/phrase-mark (_server_deploy/static/pdf/reader.js:4354)"}, "properties": {"repobilityId": "48eaa630b45640ee", "scanner": "scanner-primary", "fingerprint": "8d23478353a7c437", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-25e5d4ac32d3c726", "level": "error", "message": {"text": "Dangling fetch: POST /pdf/api/highlights (_server_deploy/static/pdf/reader.js:4826)"}, "properties": {"repobilityId": "95d3f0a3775331b9", "scanner": "scanner-primary", "fingerprint": "25e5d4ac32d3c726", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-b7c609fc6c53faef", "level": "error", "message": {"text": "Dangling fetch: POST /pdf/api/snippets-to-async (_server_deploy/static/pdf/reader.js:4925)"}, "properties": {"repobilityId": "8c09e7d4a5d334f2", "scanner": "scanner-primary", "fingerprint": "b7c609fc6c53faef", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-531d113d04df4639", "level": "error", "message": {"text": "Dangling fetch: GET /pdf/api/grammar-books (_server_deploy/static/pdf/reader.js:4996)"}, "properties": {"repobilityId": "0a29ee51e9abea35", "scanner": "scanner-primary", "fingerprint": "531d113d04df4639", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-a97e211db4e93ad6", "level": "error", "message": {"text": "Dangling fetch: POST /pdf/api/grammar-tracked (_server_deploy/static/pdf/reader.js:5005)"}, "properties": {"repobilityId": "33c7391877b0b781", "scanner": "scanner-primary", "fingerprint": "a97e211db4e93ad6", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-9587c09fb5b2e522", "level": "error", "message": {"text": "Dangling fetch: GET /pdf/api/grammar-books (_server_deploy/static/pdf/reader.js:5023)"}, "properties": {"repobilityId": "c15c89500d43723c", "scanner": "scanner-primary", "fingerprint": "9587c09fb5b2e522", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-d11a21034c73b13d", "level": "error", "message": {"text": "Dangling fetch: POST /pdf/api/grammar-analyze (_server_deploy/static/pdf/reader.js:5074)"}, "properties": {"repobilityId": "d533da645232fcd3", "scanner": "scanner-primary", "fingerprint": "d11a21034c73b13d", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-c68ee1b68a2dd94b", "level": "error", "message": {"text": "Dangling fetch: POST /pdf/api/grammar-history-save (_server_deploy/static/pdf/reader.js:5128)"}, "properties": {"repobilityId": "8f338771fdfed91f", "scanner": "scanner-primary", "fingerprint": "c68ee1b68a2dd94b", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-56e1d71380cd7699", "level": "error", "message": {"text": "Dangling fetch: POST /pdf/api/grammar-forget (_server_deploy/static/pdf/reader.js:5299)"}, "properties": {"repobilityId": "3842ec4f16054ce5", "scanner": "scanner-primary", "fingerprint": "56e1d71380cd7699", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-3bb9fba8613a97ba", "level": "error", "message": {"text": "Dangling fetch: POST /pdf/api/snippets-to-async (_server_deploy/static/pdf/reader.js:5333)"}, "properties": {"repobilityId": "e1ab19cefcfc2721", "scanner": "scanner-primary", "fingerprint": "3bb9fba8613a97ba", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-8c389cc11a98aea1", "level": "error", "message": {"text": "Dangling fetch: POST /pdf/api/vocab-mark (_server_deploy/static/pdf/reader.js:5932)"}, "properties": {"repobilityId": "bb7bd3817c50ac85", "scanner": "scanner-primary", "fingerprint": "8c389cc11a98aea1", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-19c1d65648981304", "level": "error", "message": {"text": "Dangling fetch: POST /pdf/api/vocab-anki (_server_deploy/static/pdf/reader.js:5957)"}, "properties": {"repobilityId": "fea7e007a1b03cfc", "scanner": "scanner-primary", "fingerprint": "19c1d65648981304", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-8ff90ec2bcd90802", "level": "error", "message": {"text": "Dangling fetch: PATCH /pdf/api/highlights (_server_deploy/static/pdf/reader.js:6058)"}, "properties": {"repobilityId": "590b40c03272aa39", "scanner": "scanner-primary", "fingerprint": "8ff90ec2bcd90802", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-5870ee3930dcd2b1", "level": "error", "message": {"text": "Dangling fetch: DELETE /pdf/api/highlights (_server_deploy/static/pdf/reader.js:6072)"}, "properties": {"repobilityId": "ea1ff2ed9ce65340", "scanner": "scanner-primary", "fingerprint": "5870ee3930dcd2b1", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-a3389b2b16327d43", "level": "error", "message": {"text": "Dangling fetch: POST /pdf/api/snippets-to-async (_server_deploy/static/pdf/reader.js:6767)"}, "properties": {"repobilityId": "610902f479650c88", "scanner": "scanner-primary", "fingerprint": "a3389b2b16327d43", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-533635cd134963df", "level": "error", "message": {"text": "Dangling fetch: GET /pdf/api/translate-config (_server_deploy/static/pdf/reader.js:6871)"}, "properties": {"repobilityId": "81cbb1b36510a67b", "scanner": "scanner-primary", "fingerprint": "533635cd134963df", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-ab4bb7f5d8b5a6ae", "level": "error", "message": {"text": "Dangling fetch: POST /pdf/api/translate-config (_server_deploy/static/pdf/reader.js:6929)"}, "properties": {"repobilityId": "910f685ffffc2b78", "scanner": "scanner-primary", "fingerprint": "ab4bb7f5d8b5a6ae", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-76e2201933f67e9f", "level": "error", "message": {"text": "Dangling fetch: POST /pdf/api/translate-sentence (_server_deploy/static/pdf/reader.js:7152)"}, "properties": {"repobilityId": "f46b0ea9e88e736d", "scanner": "scanner-primary", "fingerprint": "76e2201933f67e9f", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-92184f129429554e", "level": "error", "message": {"text": "Dangling fetch: POST /pdf/api/to-note (_server_deploy/static/pdf/reader.js:7313)"}, "properties": {"repobilityId": "9a0577d8065af827", "scanner": "scanner-primary", "fingerprint": "92184f129429554e", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-b770f43d1fa8d610", "level": "error", "message": {"text": "Dangling fetch: GET /pdf/api/char-offset?file=${encodeURIComponent(FILE_REL)}&page=${page} (_server_deploy/static/pdf/reader.js:7354)"}, "properties": {"repobilityId": "3da168c473df23c4", "scanner": "scanner-primary", "fingerprint": "b770f43d1fa8d610", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-3db18f0ad1771900", "level": "error", "message": {"text": "Dangling fetch: POST /pdf/api/char-offset (_server_deploy/static/pdf/reader.js:7362)"}, "properties": {"repobilityId": "4a64bdabf0c45cc6", "scanner": "scanner-primary", "fingerprint": "3db18f0ad1771900", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-931032ed92058957", "level": "error", "message": {"text": "Dangling fetch: POST /pdf/api/reocr-page (_server_deploy/static/pdf/reader.js:7415)"}, "properties": {"repobilityId": "5a0f58256c96a874", "scanner": "scanner-primary", "fingerprint": "931032ed92058957", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-bd342ad70d33bd5b", "level": "error", "message": {"text": "Dangling fetch: POST /pdf/api/reocr-page/clear (_server_deploy/static/pdf/reader.js:7434)"}, "properties": {"repobilityId": "edf0cfd82197d4e4", "scanner": "scanner-primary", "fingerprint": "bd342ad70d33bd5b", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-7972b649deb0779a", "level": "error", "message": {"text": "Dangling fetch: POST /pdf/api/prewarm-async (_server_deploy/static/pdf/reader.js:7493)"}, "properties": {"repobilityId": "c2958f8060b8346a", "scanner": "scanner-primary", "fingerprint": "7972b649deb0779a", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-899fdb970dbf55c3", "level": "error", "message": {"text": "Dangling fetch: GET /pdf/api/list-pdfs (_server_deploy/static/pdf/reader.js:7548)"}, "properties": {"repobilityId": "9f0b84a09e0645a5", "scanner": "scanner-primary", "fingerprint": "899fdb970dbf55c3", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-03b66cf9b7f98ac4", "level": "error", "message": {"text": "Dangling fetch: GET /pdf/api/translate-config (_server_deploy/static/pdf/reader.src/21-misc-ai.js:82)"}, "properties": {"repobilityId": "9ea945447de7aebb", "scanner": "scanner-primary", "fingerprint": "03b66cf9b7f98ac4", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-31c2c2a49ac85102", "level": "error", "message": {"text": "Dangling fetch: POST /pdf/api/translate-config (_server_deploy/static/pdf/reader.src/21-misc-ai.js:140)"}, "properties": {"repobilityId": "b5784332e70ed094", "scanner": "scanner-primary", "fingerprint": "31c2c2a49ac85102", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-5db85d3155bfdbfa", "level": "error", "message": {"text": "Dangling fetch: POST /pdf/api/translate-sentence (_server_deploy/static/pdf/reader.src/21-misc-ai.js:363)"}, "properties": {"repobilityId": "87d010b6f17b5f65", "scanner": "scanner-primary", "fingerprint": "5db85d3155bfdbfa", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-ed8c04efbc06fa63", "level": "error", "message": {"text": "Dangling fetch: POST /pdf/api/to-note (_server_deploy/static/pdf/reader.src/21-misc-ai.js:524)"}, "properties": {"repobilityId": "9bf7114a89b1a16f", "scanner": "scanner-primary", "fingerprint": "ed8c04efbc06fa63", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-dae3edfcfcc563d0", "level": "error", "message": {"text": "Dangling fetch: GET /pdf/api/char-offset?file=${encodeURIComponent(FILE_REL)}&page=${page} (_server_deploy/static/pdf/reader.src/21-misc-ai.js:565)"}, "properties": {"repobilityId": "607708dcd17a99c3", "scanner": "scanner-primary", "fingerprint": "dae3edfcfcc563d0", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-a6b2d557c7d93013", "level": "error", "message": {"text": "Dangling fetch: POST /pdf/api/char-offset (_server_deploy/static/pdf/reader.src/21-misc-ai.js:573)"}, "properties": {"repobilityId": "32d3c3ded2419a23", "scanner": "scanner-primary", "fingerprint": "a6b2d557c7d93013", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-a62a6e22bb0599d7", "level": "error", "message": {"text": "Dangling fetch: POST /pdf/api/reocr-page (_server_deploy/static/pdf/reader.src/21-misc-ai.js:626)"}, "properties": {"repobilityId": "cfff22fe62322f1b", "scanner": "scanner-primary", "fingerprint": "a62a6e22bb0599d7", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-ae49cb8b6dc00875", "level": "error", "message": {"text": "Dangling fetch: POST /pdf/api/reocr-page/clear (_server_deploy/static/pdf/reader.src/21-misc-ai.js:645)"}, "properties": {"repobilityId": "26bfab48a5873248", "scanner": "scanner-primary", "fingerprint": "ae49cb8b6dc00875", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-5853ef25c86a9034", "level": "error", "message": {"text": "Dangling fetch: POST /pdf/api/highlights (_server_deploy/static/pdf/reader.src/17-highlight.js:139)"}, "properties": {"repobilityId": "eb9c397a87f9c643", "scanner": "scanner-primary", "fingerprint": "5853ef25c86a9034", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-082c06aca9668256", "level": "error", "message": {"text": "Dangling fetch: POST /pdf/api/snippets-to-async (_server_deploy/static/pdf/reader.src/17-highlight.js:238)"}, "properties": {"repobilityId": "0d72186e3dba8f08", "scanner": "scanner-primary", "fingerprint": "082c06aca9668256", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-d9db24f44afbacd8", "level": "error", "message": {"text": "Dangling fetch: GET /pdf/api/page-nodes?file=${encodeURIComponent(FILE_REL)}&page=${num} (_server_deploy/static/pdf/reader.src/05-nav.js:3)"}, "properties": {"repobilityId": "293cf0f83e90cbb1", "scanner": "scanner-primary", "fingerprint": "d9db24f44afbacd8", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-b8ba7747fbc7d68a", "level": "error", "message": {"text": "Dangling fetch: POST /skilltree/${encodeURIComponent(book)}/api/toggle-tracked (_server_deploy/static/pdf/reader.src/05-nav.js:36)"}, "properties": {"repobilityId": "bb273ea473f00ff3", "scanner": "scanner-primary", "fingerprint": "b8ba7747fbc7d68a", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-6a23630291fadd2e", "level": "error", "message": {"text": "Dangling fetch: POST /pdf/api/grammar-forget (_server_deploy/static/pdf/reader.src/05-nav.js:177)"}, "properties": {"repobilityId": "f25c221c39554a7f", "scanner": "scanner-primary", "fingerprint": "6a23630291fadd2e", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-cb0a7205da933130", "level": "error", "message": {"text": "Dangling fetch: POST /pdf/api/vocab-anki (_server_deploy/static/pdf/reader.src/05-nav.js:274)"}, "properties": {"repobilityId": "1fe635d4a9718847", "scanner": "scanner-primary", "fingerprint": "cb0a7205da933130", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-6737485fab171388", "level": "error", "message": {"text": "Dangling fetch: POST /pdf/api/snippets-to-async (_server_deploy/static/pdf/reader.src/20-result-draft.js:415)"}, "properties": {"repobilityId": "30484175ffdac91a", "scanner": "scanner-primary", "fingerprint": "6737485fab171388", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-9ecceb481dde344b", "level": "error", "message": {"text": "Dangling fetch: POST /pdf/api/book-crop (_server_deploy/static/pdf/reader.src/03-loader.js:267)"}, "properties": {"repobilityId": "64f796452d1b87c9", "scanner": "scanner-primary", "fingerprint": "9ecceb481dde344b", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-d41700f0a4489e79", "level": "error", "message": {"text": "Dangling fetch: GET /pdf/api/grammar-books (_server_deploy/static/pdf/reader.src/18-grammar.js:18)"}, "properties": {"repobilityId": "0f86b4a1bb43aacc", "scanner": "scanner-primary", "fingerprint": "d41700f0a4489e79", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-17819e80952d30cb", "level": "error", "message": {"text": "Dangling fetch: POST /pdf/api/grammar-tracked (_server_deploy/static/pdf/reader.src/18-grammar.js:27)"}, "properties": {"repobilityId": "1706934d163459dc", "scanner": "scanner-primary", "fingerprint": "17819e80952d30cb", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-029308ddd51acf9a", "level": "error", "message": {"text": "Dangling fetch: GET /pdf/api/grammar-books (_server_deploy/static/pdf/reader.src/18-grammar.js:45)"}, "properties": {"repobilityId": "dc0a050d2c84b623", "scanner": "scanner-primary", "fingerprint": "029308ddd51acf9a", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-78805bcb439b82cc", "level": "error", "message": {"text": "Dangling fetch: POST /pdf/api/grammar-analyze (_server_deploy/static/pdf/reader.src/18-grammar.js:96)"}, "properties": {"repobilityId": "643bb8afac724bbc", "scanner": "scanner-primary", "fingerprint": "78805bcb439b82cc", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-8bbb686626a09cf3", "level": "error", "message": {"text": "Dangling fetch: POST /pdf/api/grammar-history-save (_server_deploy/static/pdf/reader.src/18-grammar.js:150)"}, "properties": {"repobilityId": "4937e1065b4991de", "scanner": "scanner-primary", "fingerprint": "8bbb686626a09cf3", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-d3d5ed032ce59c71", "level": "error", "message": {"text": "Dangling fetch: POST /pdf/api/grammar-forget (_server_deploy/static/pdf/reader.src/18-grammar.js:321)"}, "properties": {"repobilityId": "125532d898aebe33", "scanner": "scanner-primary", "fingerprint": "d3d5ed032ce59c71", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-995635e478772677", "level": "error", "message": {"text": "Dangling fetch: POST /pdf/api/snippets-to-async (_server_deploy/static/pdf/reader.src/18-grammar.js:355)"}, "properties": {"repobilityId": "29135735dbf17fb4", "scanner": "scanner-primary", "fingerprint": "995635e478772677", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-1ccea747e33b5408", "level": "error", "message": {"text": "Dangling fetch: POST /pdf/api/prewarm-async (_server_deploy/static/pdf/reader.src/22-prewarm.js:40)"}, "properties": {"repobilityId": "4962968ff0bb614a", "scanner": "scanner-primary", "fingerprint": "1ccea747e33b5408", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-a8533f9f574ce413", "level": "error", "message": {"text": "Dangling fetch: POST /pdf/api/vocab-mark (_server_deploy/static/pdf/reader.src/19-dict.js:183)"}, "properties": {"repobilityId": "ee561940ad5ec268", "scanner": "scanner-primary", "fingerprint": "a8533f9f574ce413", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-c7e73d4b9d8f86d1", "level": "error", "message": {"text": "Dangling fetch: POST /pdf/api/vocab-anki (_server_deploy/static/pdf/reader.src/19-dict.js:208)"}, "properties": {"repobilityId": "577eb68637ea1ce2", "scanner": "scanner-primary", "fingerprint": "c7e73d4b9d8f86d1", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-a8cbd7e31e3fe204", "level": "error", "message": {"text": "Dangling fetch: PATCH /pdf/api/highlights (_server_deploy/static/pdf/reader.src/19-dict.js:309)"}, "properties": {"repobilityId": "668612d912f99ae3", "scanner": "scanner-primary", "fingerprint": "a8cbd7e31e3fe204", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-848af11f35af88f0", "level": "error", "message": {"text": "Dangling fetch: DELETE /pdf/api/highlights (_server_deploy/static/pdf/reader.src/19-dict.js:323)"}, "properties": {"repobilityId": "d3dcdbb9e8092c29", "scanner": "scanner-primary", "fingerprint": "848af11f35af88f0", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-d230ed7cfbb08250", "level": "error", "message": {"text": "Dangling fetch: GET /pdf/api/page-overlay?file=${encodeURIComponent(FILE_REL)}&page=${num} (_server_deploy/static/pdf/reader.src/08-charlayer.js:36)"}, "properties": {"repobilityId": "3306f0e3230411e1", "scanner": "scanner-primary", "fingerprint": "d230ed7cfbb08250", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-530f042b04623e5d", "level": "error", "message": {"text": "Dangling fetch: POST /pdf/api/translate-sentence (_server_deploy/static/pdf/reader.src/12-vocab-sentences.js:315)"}, "properties": {"repobilityId": "66749e80d9b0c5ae", "scanner": "scanner-primary", "fingerprint": "530f042b04623e5d", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-67a67b47eab1200d", "level": "error", "message": {"text": "Dangling fetch: POST /pdf/api/sentence-dismiss (_server_deploy/static/pdf/reader.src/12-vocab-sentences.js:346)"}, "properties": {"repobilityId": "2ce17fd8f3d0dc7d", "scanner": "scanner-primary", "fingerprint": "67a67b47eab1200d", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-2fc796e73621a28e", "level": "error", "message": {"text": "Dangling fetch: POST /pdf/api/translate-sentence (_server_deploy/static/pdf/reader.src/12-vocab-sentences.js:368)"}, "properties": {"repobilityId": "7957e60ee281b0c5", "scanner": "scanner-primary", "fingerprint": "2fc796e73621a28e", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-7831cb776867b56b", "level": "error", "message": {"text": "Dangling fetch: POST /pdf/api/translate-sentence (_server_deploy/static/pdf/reader.src/12-vocab-sentences.js:522)"}, "properties": {"repobilityId": "c8ef1c86e6e5b125", "scanner": "scanner-primary", "fingerprint": "7831cb776867b56b", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-42ba525fd3c88ceb", "level": "error", "message": {"text": "Dangling fetch: GET /pdf/api/phrases (_server_deploy/static/pdf/reader.src/15-phrase-wordpop.js:6)"}, "properties": {"repobilityId": "0ad77335d863081a", "scanner": "scanner-primary", "fingerprint": "42ba525fd3c88ceb", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-ba45f97a2195842f", "level": "error", "message": {"text": "Dangling fetch: GET /pdf/api/phrase-mark (_server_deploy/static/pdf/reader.src/15-phrase-wordpop.js:7)"}, "properties": {"repobilityId": "c9c785040ad61745", "scanner": "scanner-primary", "fingerprint": "ba45f97a2195842f", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-4cab32bf010ad66a", "level": "error", "message": {"text": "Dangling fetch: POST /pdf/api/translate-sentence (_server_deploy/static/pdf/reader.src/15-phrase-wordpop.js:169)"}, "properties": {"repobilityId": "28f7a3c09a495732", "scanner": "scanner-primary", "fingerprint": "4cab32bf010ad66a", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-252207797c6055e0", "level": "error", "message": {"text": "Dangling fetch: GET /pdf/api/phrases (_server_deploy/static/pdf/reader.src/15-phrase-wordpop.js:201)"}, "properties": {"repobilityId": "04e51de7dff2e557", "scanner": "scanner-primary", "fingerprint": "252207797c6055e0", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-95a5fcf05c0d7217", "level": "error", "message": {"text": "Dangling fetch: POST /pdf/api/phrase-mark (_server_deploy/static/pdf/reader.src/15-phrase-wordpop.js:641)"}, "properties": {"repobilityId": "3edabc3d40813020", "scanner": "scanner-primary", "fingerprint": "95a5fcf05c0d7217", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-b99f24511a9c73a7", "level": "error", "message": {"text": "Dangling fetch: GET /pdf/api/list-pdfs (_server_deploy/static/pdf/reader.src/23-bookshelf.js:38)"}, "properties": {"repobilityId": "de5d920764cc5221", "scanner": "scanner-primary", "fingerprint": "b99f24511a9c73a7", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-d8f41f40c5bcd93b", "level": "error", "message": {"text": "Dangling fetch: GET /pdf/api/prefs (_server_deploy/static/pdf/reader.src/01-boot.js:11)"}, "properties": {"repobilityId": "55593938b7297a7b", "scanner": "scanner-primary", "fingerprint": "d8f41f40c5bcd93b", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-e664881ee724dd8e", "level": "error", "message": {"text": "Dangling fetch: POST /pdf/api/prefs (_server_deploy/static/pdf/reader.src/01-boot.js:35)"}, "properties": {"repobilityId": "b5063fd12d8ea7c1", "scanner": "scanner-primary", "fingerprint": "e664881ee724dd8e", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-5bac588cf6da9d46", "level": "error", "message": {"text": "Dangling fetch: POST /pdf/api/prefs (_server_deploy/static/pdf/reader.src/01-boot.js:50)"}, "properties": {"repobilityId": "e410e9ebbdfe2254", "scanner": "scanner-primary", "fingerprint": "5bac588cf6da9d46", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-1304129e73d04852", "level": "error", "message": {"text": "Dangling fetch: POST /pdf/api/book-langs (_server_deploy/static/pdf/reader.src/01-boot.js:112)"}, "properties": {"repobilityId": "1b50f9368a1fecbc", "scanner": "scanner-primary", "fingerprint": "1304129e73d04852", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-4c7ad61ba1b23915", "level": "note", "message": {"text": "Unused endpoint: ANY /login"}, "properties": {"repobilityId": "7129802a7b2d0f6d", "scanner": "scanner-primary", "fingerprint": "4c7ad61ba1b23915", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-c9e449c3b9e73b73", "level": "note", "message": {"text": "Unused endpoint: ANY /logout"}, "properties": {"repobilityId": "369f8ac13d1e079f", "scanner": "scanner-primary", "fingerprint": "c9e449c3b9e73b73", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-742bb54617573d9c", "level": "note", "message": {"text": "Unused endpoint: ANY /dashboard/"}, "properties": {"repobilityId": "0b3d7ed1e1b1af71", "scanner": "scanner-primary", "fingerprint": "742bb54617573d9c", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-95fc94040ca18a0a", "level": "note", "message": {"text": "Unused endpoint: ANY /dashboard/<path:filename>"}, "properties": {"repobilityId": "59e671e24d71b58f", "scanner": "scanner-primary", "fingerprint": "95fc94040ca18a0a", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-7d40d28394f87c42", "level": "note", "message": {"text": "Unused endpoint: ANY /dashboard/graph-settings.json"}, "properties": {"repobilityId": "6738f0584dff6d73", "scanner": "scanner-primary", "fingerprint": "7d40d28394f87c42", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-b39cbaaec68ddbe2", "level": "note", "message": {"text": "Unused endpoint: ANY /private/"}, "properties": {"repobilityId": "4218700bab768ee3", "scanner": "scanner-primary", "fingerprint": "b39cbaaec68ddbe2", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-0db99ac2c44c605c", "level": "note", "message": {"text": "Unused endpoint: ANY /private/<path:filename>"}, "properties": {"repobilityId": "4bf78be31d9603e9", "scanner": "scanner-primary", "fingerprint": "0db99ac2c44c605c", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-14c3471b25b0a373", "level": "note", "message": {"text": "Unused endpoint: ANY /history/"}, "properties": {"repobilityId": "1642c2148281c6eb", "scanner": "scanner-primary", "fingerprint": "14c3471b25b0a373", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-73d2f563392095b9", "level": "note", "message": {"text": "Unused endpoint: ANY /history/<path:filename>"}, "properties": {"repobilityId": "bfd77164f8dbd80a", "scanner": "scanner-primary", "fingerprint": "73d2f563392095b9", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-fd4119dbce791524", "level": "note", "message": {"text": "Unused endpoint: ANY /qa/"}, "properties": {"repobilityId": "16c7799b6e9344d5", "scanner": "scanner-primary", "fingerprint": "fd4119dbce791524", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-74c5b1f5f1fe71fe", "level": "note", "message": {"text": "Unused endpoint: ANY /qa"}, "properties": {"repobilityId": "55a1a658153a71ce", "scanner": "scanner-primary", "fingerprint": "74c5b1f5f1fe71fe", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-2c0ca82b4f50febc", "level": "note", "message": {"text": "Unused endpoint: ANY /qa/update"}, "properties": {"repobilityId": "4341d16054d96ba5", "scanner": "scanner-primary", "fingerprint": "2c0ca82b4f50febc", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-f3a803c245ace4f1", "level": "note", "message": {"text": "Unused endpoint: ANY /skilltree/"}, "properties": {"repobilityId": "91473edbb3e887dc", "scanner": "scanner-primary", "fingerprint": "f3a803c245ace4f1", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-887a8d4a21192e2f", "level": "note", "message": {"text": "Unused endpoint: ANY /skilltree/api/books-meta"}, "properties": {"repobilityId": "9fb267ee0a26817e", "scanner": "scanner-primary", "fingerprint": "887a8d4a21192e2f", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-6e3e6555829513c6", "level": "note", "message": {"text": "Unused endpoint: ANY /skilltree/<book>/api/delete"}, "properties": {"repobilityId": "080fc20abecc6656", "scanner": "scanner-primary", "fingerprint": "6e3e6555829513c6", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-cdf85d002fd4189c", "level": "note", "message": {"text": "Unused endpoint: ANY /skilltree/<book>/"}, "properties": {"repobilityId": "6867619dde4e0285", "scanner": "scanner-primary", "fingerprint": "cdf85d002fd4189c", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-4d54bb883bf04a1f", "level": "note", "message": {"text": "Unused endpoint: ANY /skilltree/<book>/data.json"}, "properties": {"repobilityId": "e9245df5a46d5074", "scanner": "scanner-primary", "fingerprint": "4d54bb883bf04a1f", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-72ba6997481b404b", "level": "note", "message": {"text": "Unused endpoint: ANY /skilltree/<book>/pdf"}, "properties": {"repobilityId": "6da802852d07d31c", "scanner": "scanner-primary", "fingerprint": "72ba6997481b404b", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-da97d8b5b83a45f4", "level": "note", "message": {"text": "Unused endpoint: ANY /skilltree/<book>/api/archive-node"}, "properties": {"repobilityId": "fb644e6f627fc5fd", "scanner": "scanner-primary", "fingerprint": "da97d8b5b83a45f4", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-81a09bd9fe723db6", "level": "note", "message": {"text": "Unused endpoint: ANY /skilltree/<book>/api/restore-node"}, "properties": {"repobilityId": "49f68a823665271f", "scanner": "scanner-primary", "fingerprint": "81a09bd9fe723db6", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-2af24535a1907e15", "level": "note", "message": {"text": "Unused endpoint: ANY /skilltree/<book>/api/prune-notes"}, "properties": {"repobilityId": "e247fa80a7398cce", "scanner": "scanner-primary", "fingerprint": "2af24535a1907e15", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-bff1c0a78508b3df", "level": "note", "message": {"text": "Unused endpoint: ANY /skilltree/<book>/api/build-note"}, "properties": {"repobilityId": "15abfecc018280ba", "scanner": "scanner-primary", "fingerprint": "bff1c0a78508b3df", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-b0044f6359a26ad1", "level": "note", "message": {"text": "Unused endpoint: ANY /skilltree/<book>/api/build-note-status/<job_id>"}, "properties": {"repobilityId": "020b880e130e3c11", "scanner": "scanner-primary", "fingerprint": "b0044f6359a26ad1", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-8695dc03943d38b4", "level": "note", "message": {"text": "Unused endpoint: ANY /skilltree/<book>/api/toggle-tracked"}, "properties": {"repobilityId": "4f10d5b650816447", "scanner": "scanner-primary", "fingerprint": "8695dc03943d38b4", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-9249feb9c8622971", "level": "note", "message": {"text": "Unused endpoint: ANY /skilltree/<book>/api/edit"}, "properties": {"repobilityId": "10fa057095825d48", "scanner": "scanner-primary", "fingerprint": "9249feb9c8622971", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-af9f841b7fd2738a", "level": "note", "message": {"text": "Unused endpoint: ANY /control/api/status"}, "properties": {"repobilityId": "a89f9888111cbdfa", "scanner": "scanner-primary", "fingerprint": "af9f841b7fd2738a", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-dc14284155645c62", "level": "note", "message": {"text": "Unused endpoint: ANY /control/api/config/schema"}, "properties": {"repobilityId": "75e61e0d964bab1f", "scanner": "scanner-primary", "fingerprint": "dc14284155645c62", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-e53fb451093c1f14", "level": "note", "message": {"text": "Unused endpoint: ANY /control/api/ipad-config"}, "properties": {"repobilityId": "a8e582d143f6d5a5", "scanner": "scanner-primary", "fingerprint": "e53fb451093c1f14", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-a85458142cd2eee8", "level": "note", "message": {"text": "Unused endpoint: ANY /control/api/config"}, "properties": {"repobilityId": "fbe769fd6d00f729", "scanner": "scanner-primary", "fingerprint": "a85458142cd2eee8", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-5dd8c5b22ba36b9b", "level": "note", "message": {"text": "Unused endpoint: ANY /control/api/quota-log"}, "properties": {"repobilityId": "9ff13aa70511e0b8", "scanner": "scanner-primary", "fingerprint": "5dd8c5b22ba36b9b", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-0ef899087fd974db", "level": "note", "message": {"text": "Unused endpoint: ANY /control/api/quota-now"}, "properties": {"repobilityId": "a9f59725647cac8d", "scanner": "scanner-primary", "fingerprint": "0ef899087fd974db", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-735286cfb4c23a2f", "level": "note", "message": {"text": "Unused endpoint: ANY /control/api/trigger-log"}, "properties": {"repobilityId": "076709e2a107d4a6", "scanner": "scanner-primary", "fingerprint": "735286cfb4c23a2f", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-8e3fde3e12101a78", "level": "note", "message": {"text": "Unused endpoint: ANY /control/api/trigger/<action>"}, "properties": {"repobilityId": "07bbb86086be23c2", "scanner": "scanner-primary", "fingerprint": "8e3fde3e12101a78", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-10c583a35f2fcfd2", "level": "note", "message": {"text": "Unused endpoint: ANY /control/api/kg-build"}, "properties": {"repobilityId": "421c28b6a21245b4", "scanner": "scanner-primary", "fingerprint": "10c583a35f2fcfd2", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-a34a227529e9c691", "level": "note", "message": {"text": "Unused endpoint: ANY /control/api/kg-build-log"}, "properties": {"repobilityId": "741ad013ce22153b", "scanner": "scanner-primary", "fingerprint": "a34a227529e9c691", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-1a6d91f2236825bf", "level": "note", "message": {"text": "Unused endpoint: ANY /"}, "properties": {"repobilityId": "7382229ae2d8cb17", "scanner": "scanner-primary", "fingerprint": "1a6d91f2236825bf", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-1c1a12faddca1602", "level": "note", "message": {"text": "Unused endpoint: ANY /api/cache-stats"}, "properties": {"repobilityId": "433f208787a7cd48", "scanner": "scanner-primary", "fingerprint": "1c1a12faddca1602", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-d87d1b555a41341a", "level": "note", "message": {"text": "Unused endpoint: ANY /api/ping"}, "properties": {"repobilityId": "1527a1eef4e95ac7", "scanner": "scanner-primary", "fingerprint": "d87d1b555a41341a", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-96bd846c5bb348a1", "level": "note", "message": {"text": "Unused endpoint: ANY /api/book-meta"}, "properties": {"repobilityId": "dd8922e8eb698d8a", "scanner": "scanner-primary", "fingerprint": "96bd846c5bb348a1", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-a9034de58c8021f6", "level": "note", "message": {"text": "Unused endpoint: ANY /api/prefs"}, "properties": {"repobilityId": "2f449b948168f6e2", "scanner": "scanner-primary", "fingerprint": "a9034de58c8021f6", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-eba3d61a670b6f09", "level": "note", "message": {"text": "Unused endpoint: ANY /sw.js"}, "properties": {"repobilityId": "28ce45a0f86aebc2", "scanner": "scanner-primary", "fingerprint": "eba3d61a670b6f09", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-98cabcde8e0f6e0b", "level": "note", "message": {"text": "Unused endpoint: ANY /api/page-image"}, "properties": {"repobilityId": "780dafad1f5b6654", "scanner": "scanner-primary", "fingerprint": "98cabcde8e0f6e0b", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-6730c7fbe7462299", "level": "note", "message": {"text": "Unused endpoint: ANY /view"}, "properties": {"repobilityId": "a15a9ec0b96a5cb6", "scanner": "scanner-primary", "fingerprint": "6730c7fbe7462299", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-5a0fd9b8173954cb", "level": "note", "message": {"text": "Unused endpoint: ANY /file/<path:rel>"}, "properties": {"repobilityId": "a196f408ffd3ba76", "scanner": "scanner-primary", "fingerprint": "5a0fd9b8173954cb", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-51d39b63af99fec6", "level": "note", "message": {"text": "Unused endpoint: ANY /api/list-pdfs"}, "properties": {"repobilityId": "da7dd62361d234d2", "scanner": "scanner-primary", "fingerprint": "51d39b63af99fec6", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-0514763ee6953fe0", "level": "note", "message": {"text": "Unused endpoint: ANY /api/preprocess-status"}, "properties": {"repobilityId": "3d42c53e3ffbf11e", "scanner": "scanner-primary", "fingerprint": "0514763ee6953fe0", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-1b3332c2b5c6a2f7", "level": "note", "message": {"text": "Unused endpoint: ANY /api/preprocess-async"}, "properties": {"repobilityId": "b6173be630a3d788", "scanner": "scanner-primary", "fingerprint": "1b3332c2b5c6a2f7", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-b5596d346605445a", "level": "note", "message": {"text": "Unused endpoint: ANY /api/prewarm-async"}, "properties": {"repobilityId": "c1310e2db1b260a2", "scanner": "scanner-primary", "fingerprint": "b5596d346605445a", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-510b59c77515f28b", "level": "note", "message": {"text": "Unused endpoint: ANY /api/prewarm-status"}, "properties": {"repobilityId": "feec9745506cbeec", "scanner": "scanner-primary", "fingerprint": "510b59c77515f28b", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-b542c74c50152ca8", "level": "note", "message": {"text": "Unused endpoint: ANY /api/compress-async"}, "properties": {"repobilityId": "8c8c9eae138d70a1", "scanner": "scanner-primary", "fingerprint": "b542c74c50152ca8", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}]}]}