{"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-10ab4387da78c5c4", "name": "Possibly dead Python function: require_api_admin", "shortDescription": {"text": "Possibly dead Python function: require_api_admin"}, "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-d70b809a10a493bc", "name": "Possibly dead Python function: update_season_meta", "shortDescription": {"text": "Possibly dead Python function: update_season_meta"}, "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-7bb5bac59c7f390c", "name": "Possibly dead Python function: update_game_result_meta", "shortDescription": {"text": "Possibly dead Python function: update_game_result_meta"}, "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-df4c2d2b10127d3d", "name": "Possibly dead Python function: update_player_meta", "shortDescription": {"text": "Possibly dead Python function: update_player_meta"}, "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-45d94ab270ec4533", "name": "Possibly dead Python function: load_hooper_meta", "shortDescription": {"text": "Possibly dead Python function: load_hooper_meta"}, "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-d20e9b9a2b8f6a7c", "name": "Possibly dead Python function: compute_contest", "shortDescription": {"text": "Possibly dead Python function: compute_contest"}, "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-229e6f0b64b62bba", "name": "Possibly dead Python function: mark_presented", "shortDescription": {"text": "Possibly dead Python function: mark_presented"}, "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-e3ebeb56427e7f90", "name": "Possibly dead Python function: setup_hook", "shortDescription": {"text": "Possibly dead Python function: setup_hook"}, "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-fbc9e452fd00d3bd", "name": "Possibly dead Python function: generate_newspaper_headlines", "shortDescription": {"text": "Possibly dead Python function: generate_newspaper_headlines"}, "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-4f0d6ccc5a6072b7", "name": "Possibly dead Python function: generate_report_with_prompt", "shortDescription": {"text": "Possibly dead Python function: generate_report_with_prompt"}, "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-b0377ef879f85060", "name": "Stray `console.log` in TS/JS \u2014 static/js/htmx.min.js:1", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 static/js/htmx.min.js:1"}, "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-d63da3583b14afc0", "name": "Dockerfile runs as root: Dockerfile", "shortDescription": {"text": "Dockerfile runs as root: Dockerfile"}, "fullDescription": {"text": "No non-root USER set. Containers running as root expand the blast radius of any vulnerability inside the image."}, "properties": {"scanner": "scanner-primary", "layer": "hardware", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-de3c1f217d72a063", "name": "Docker base image is tag-pinned but not digest-pinned: python:3.12-slim", "shortDescription": {"text": "Docker base image is tag-pinned but not digest-pinned: python:3.12-slim"}, "fullDescription": {"text": "Container tags can be retagged upstream. Pin production base images to a reviewed digest (`image@sha256:...`) when reproducibility and supply-chain integrity matter."}, "properties": {"scanner": "scanner-primary", "layer": "hardware", "severity": "low", "confidence": 1.0}}, {"id": "scanner-87f8318b0d5393f8", "name": "Insecure pattern 'new_function_used' in static/js/htmx.min.js:1", "shortDescription": {"text": "Insecure pattern 'new_function_used' in static/js/htmx.min.js:1"}, "fullDescription": {"text": "Found a known-risky pattern (new_function_used). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-fa524bd2c579768f", "name": "Insecure pattern 'direct_innerhtml_assignment' in static/js/htmx.min.js:1", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in static/js/htmx.min.js:1"}, "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-d1999688d7f90428", "name": "Insecure pattern 'insert_adjacent_html' in static/js/htmx.min.js:1", "shortDescription": {"text": "Insecure pattern 'insert_adjacent_html' in static/js/htmx.min.js:1"}, "fullDescription": {"text": "Found a known-risky pattern (insert_adjacent_html). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-236da8be2d8e7d33", "name": "Insecure pattern 'domparser_html_parse' in static/js/htmx.min.js:1", "shortDescription": {"text": "Insecure pattern 'domparser_html_parse' in static/js/htmx.min.js:1"}, "fullDescription": {"text": "Found a known-risky pattern (domparser_html_parse). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-efaa984d7b9bbd10", "name": "Insecure pattern 'exec_used' in src/pinwheel/core/codegen.py:626", "shortDescription": {"text": "Insecure pattern 'exec_used' in src/pinwheel/core/codegen.py:626"}, "fullDescription": {"text": "Found a known-risky pattern (exec_used). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-06005d6f37ba6e34", "name": "Very large file: tests/test_pages.py (2974 lines)", "shortDescription": {"text": "Very large file: tests/test_pages.py (2974 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-13d81dd72cb32c42", "name": "Very large file: tests/test_governance.py (1955 lines)", "shortDescription": {"text": "Very large file: tests/test_governance.py (1955 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-90b3f5bf893fb879", "name": "Very large file: tests/test_season_lifecycle.py (1499 lines)", "shortDescription": {"text": "Very large file: tests/test_season_lifecycle.py (1499 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-1b0a010647df194c", "name": "Very large file: tests/test_simulation.py (2009 lines)", "shortDescription": {"text": "Very large file: tests/test_simulation.py (2009 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-b4c8ac933a625629", "name": "Very large file: tests/test_discord.py (4550 lines)", "shortDescription": {"text": "Very large file: tests/test_discord.py (4550 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-d2c697ac57287f94", "name": "Very large file: tests/test_commentary.py (2806 lines)", "shortDescription": {"text": "Very large file: tests/test_commentary.py (2806 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-1491554d24420761", "name": "Very large file: tests/test_game_loop.py (2808 lines)", "shortDescription": {"text": "Very large file: tests/test_game_loop.py (2808 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-030b7c46d674b2f6", "name": "Very large file: tests/test_reports.py (2520 lines)", "shortDescription": {"text": "Very large file: tests/test_reports.py (2520 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-3e9fea8361b2e77a", "name": "Very large file: tests/test_effects.py (2866 lines)", "shortDescription": {"text": "Very large file: tests/test_effects.py (2866 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-f1edb8785f9985d5", "name": "Very large file: tests/test_api/test_e2e_workflow.py (1617 lines)", "shortDescription": {"text": "Very large file: tests/test_api/test_e2e_workflow.py (1617 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-c5a9a5d35e5683eb", "name": "Very large file: src/pinwheel/api/pages.py (3410 lines)", "shortDescription": {"text": "Very large file: src/pinwheel/api/pages.py (3410 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-dd938ef45e15ca30", "name": "Very large file: src/pinwheel/db/repository.py (1740 lines)", "shortDescription": {"text": "Very large file: src/pinwheel/db/repository.py (1740 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-0628c650f745ab65", "name": "Very large file: src/pinwheel/core/game_loop.py (3150 lines)", "shortDescription": {"text": "Very large file: src/pinwheel/core/game_loop.py (3150 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-1ec4956e559c965c", "name": "Very large file: src/pinwheel/discord/views.py (1893 lines)", "shortDescription": {"text": "Very large file: src/pinwheel/discord/views.py (1893 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-b6c40414c15060b1", "name": "Very large file: src/pinwheel/discord/bot.py (4743 lines)", "shortDescription": {"text": "Very large file: src/pinwheel/discord/bot.py (4743 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-8dab206e50feee43", "name": "Very large file: src/pinwheel/discord/embeds.py (2020 lines)", "shortDescription": {"text": "Very large file: src/pinwheel/discord/embeds.py (2020 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-98bfad270a6f0066", "name": "Very large file: src/pinwheel/ai/interpreter.py (1390 lines)", "shortDescription": {"text": "Very large file: src/pinwheel/ai/interpreter.py (1390 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-1a88454f47abbead", "name": "Very large file: src/pinwheel/ai/report.py (2839 lines)", "shortDescription": {"text": "Very large file: src/pinwheel/ai/report.py (2839 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-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 161 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 76 placeholder/mock markers across 18 source files. This often means the repo looks complete while core flows still use generated scaffolding or fake data."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-2d0c7b7ab8f8aacf", "name": "Critical user flow still appears backed by mock or placeholder data", "shortDescription": {"text": "Critical user flow still appears backed by mock or placeholder data"}, "fullDescription": {"text": "A payment/auth/admin/order/billing-style flow contains mock, fake, TODO, dummy, or placeholder markers in runtime source. In the Fable corpus this is a high-leverage completeness smell: the app can look finished while the money, identity, or tenant flow is still scaffolded."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-b9088664ace7f748", "name": "Composite production-readiness gap", "shortDescription": {"text": "Composite production-readiness gap"}, "fullDescription": {"text": "Multiple low-cost hardening controls are missing together: license, ci. 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-bea357a6497a2d5d", "name": "Agent authority lacks a verifier contract: CLAUDE.md", "shortDescription": {"text": "Agent authority lacks a verifier contract: CLAUDE.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-e8ab3946ea9e7679", "name": "Agent instruction/config may expose a secret: docs/skills/post-commit/SKILL.md", "shortDescription": {"text": "Agent instruction/config may expose a secret: docs/skills/post-commit/SKILL.md"}, "fullDescription": {"text": "Agent-facing files are routinely pasted into LLM/tool contexts. Move literal tokens, keys, and passwords into a secret manager or document them as placeholders only."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-e725d2ab884fbd49", "name": "Multiple root agent instruction files without precedence", "shortDescription": {"text": "Multiple root agent instruction files without precedence"}, "fullDescription": {"text": "The repo has multiple top-level AI-coder instruction files. Without precedence rules, different agents may follow different policies."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-08599109ae14d82a", "name": "Commented-code block (7 lines) in tests/test_strategy_integration.py:482", "shortDescription": {"text": "Commented-code block (7 lines) in tests/test_strategy_integration.py:482"}, "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-f8152a3410d3e73b", "name": "Legacy-named symbol `interp_v2` in tests/test_scheduler_runner.py:744", "shortDescription": {"text": "Legacy-named symbol `interp_v2` in tests/test_scheduler_runner.py:744"}, "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-91e611f920fd11a9", "name": "Legacy-named symbol `get_proposal_effects_v2` in tests/test_governance.py:17", "shortDescription": {"text": "Legacy-named symbol `get_proposal_effects_v2` in tests/test_governance.py:17"}, "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-b19230a344b5c7e5", "name": "Commented-code block (5 lines) in tests/test_season_lifecycle.py:1098", "shortDescription": {"text": "Commented-code block (5 lines) in tests/test_season_lifecycle.py:1098"}, "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-6003cc4fd39bffef", "name": "Legacy-named symbol `refreshed_old` in tests/test_season.py:499", "shortDescription": {"text": "Legacy-named symbol `refreshed_old` in tests/test_season.py:499"}, "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-50b0c6a38072c415", "name": "Legacy-named symbol `mock_user_v1` in tests/test_auth.py:291", "shortDescription": {"text": "Legacy-named symbol `mock_user_v1` in tests/test_auth.py:291"}, "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-a8783440b46f5ce1", "name": "Legacy-named symbol `governance_legacy` in tests/test_memorial.py:432", "shortDescription": {"text": "Legacy-named symbol `governance_legacy` in tests/test_memorial.py:432"}, "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-b30b0b0ec0fbc5b4", "name": "Legacy-named symbol `action_v1` in tests/test_action_registry.py:263", "shortDescription": {"text": "Legacy-named symbol `action_v1` in tests/test_action_registry.py:263"}, "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-dcca564fdf5df2a4", "name": "Legacy-named symbol `compute_shot_probability_v2` in tests/test_simulation.py:24", "shortDescription": {"text": "Legacy-named symbol `compute_shot_probability_v2` in tests/test_simulation.py:24"}, "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-e82c71ea58b0aab4", "name": "Legacy-named symbol `test_state_returns_copy` in tests/test_codegen.py:216", "shortDescription": {"text": "Legacy-named symbol `test_state_returns_copy` in tests/test_codegen.py:216"}, "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-3d727c55ae2fa5e5", "name": "Legacy-named symbol `test_change_too_old` in tests/test_commentary.py:1938", "shortDescription": {"text": "Legacy-named symbol `test_change_too_old` in tests/test_commentary.py:1938"}, "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-71b6858762bd32ba", "name": "Legacy-named symbol `interpret_proposal_v2` in tests/test_messages_api.py:512", "shortDescription": {"text": "Legacy-named symbol `interpret_proposal_v2` in tests/test_messages_api.py:512"}, "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-0d8f690dcae600e9", "name": "Commented-code block (11 lines) in tests/test_game_loop.py:2079", "shortDescription": {"text": "Commented-code block (11 lines) in tests/test_game_loop.py:2079"}, "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-d6d71e6164e21660", "name": "Commented-code block (6 lines) in tests/test_pages_what_changed.py:445", "shortDescription": {"text": "Commented-code block (6 lines) in tests/test_pages_what_changed.py:445"}, "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-c39969f8808b2e36", "name": "Legacy-named symbol `detect_tier_v2` in tests/test_codegen_integration.py:18", "shortDescription": {"text": "Legacy-named symbol `detect_tier_v2` in tests/test_codegen_integration.py:18"}, "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-6decd2d50d8f8e2e", "name": "Legacy-named symbol `interpret_proposal_v2` in tests/test_deferred_interpreter.py:150", "shortDescription": {"text": "Legacy-named symbol `interpret_proposal_v2` in tests/test_deferred_interpreter.py:150"}, "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-7309533f8871153c", "name": "Legacy-named symbol `detect_tier_v2` in tests/test_effects.py:1609", "shortDescription": {"text": "Legacy-named symbol `detect_tier_v2` in tests/test_effects.py:1609"}, "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-4e28eaea25ff7ce9", "name": "Legacy-named symbol `detect_tier_v2` in tests/test_patch_validation.py:18", "shortDescription": {"text": "Legacy-named symbol `detect_tier_v2` in tests/test_patch_validation.py:18"}, "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-993889e628f6b184", "name": "Legacy-named symbol `effects_v2` in tests/test_expanded_ruleset.py:667", "shortDescription": {"text": "Legacy-named symbol `effects_v2` in tests/test_expanded_ruleset.py:667"}, "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-dfdcd44591dca3ec", "name": "Legacy-named symbol `governance_legacy` in tests/test_narrative.py:987", "shortDescription": {"text": "Legacy-named symbol `governance_legacy` in tests/test_narrative.py:987"}, "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-dd4857dc6ec47262", "name": "Legacy-named symbol `TestNarrationRegistryMatchesLegacy` in tests/test_narrate.py:702", "shortDescription": {"text": "Legacy-named symbol `TestNarrationRegistryMatchesLegacy` in tests/test_narrate.py:702"}, "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-62bdf45f0d3dcf1c", "name": "Legacy-named symbol `effects_v2` in tests/test_api/test_e2e_workflow.py:691", "shortDescription": {"text": "Legacy-named symbol `effects_v2` in tests/test_api/test_e2e_workflow.py:691"}, "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-1096c39b837702fa", "name": "Commented-code block (5 lines) in tests/test_evals/test_eval_dashboard.py:239", "shortDescription": {"text": "Commented-code block (5 lines) in tests/test_evals/test_eval_dashboard.py:239"}, "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-515c79435b85ae7b", "name": "Legacy-named symbol `interpret_proposal_v2` in scripts/resubmit_proposals.py:4", "shortDescription": {"text": "Legacy-named symbol `interpret_proposal_v2` in scripts/resubmit_proposals.py:4"}, "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-f30d1fd84f038e90", "name": "Legacy-named symbol `resubmit_proposals_v2` in scripts/resubmit_proposals_v2.py:9", "shortDescription": {"text": "Legacy-named symbol `resubmit_proposals_v2` in scripts/resubmit_proposals_v2.py:9"}, "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-c100c2b620ccc124", "name": "Legacy-named symbol `governance_legacy` in src/pinwheel/api/pages.py:3345", "shortDescription": {"text": "Legacy-named symbol `governance_legacy` in src/pinwheel/api/pages.py:3345"}, "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-bdb799d25c7c1eb3", "name": "Legacy-named symbol `model_copy` in src/pinwheel/models/game_definition.py:355", "shortDescription": {"text": "Legacy-named symbol `model_copy` in src/pinwheel/models/game_definition.py:355"}, "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-727ddda08edceb67", "name": "Legacy-named symbol `governance_legacy` in src/pinwheel/models/report.py:61", "shortDescription": {"text": "Legacy-named symbol `governance_legacy` in src/pinwheel/models/report.py:61"}, "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-4c1d4c14ab4b680f", "name": "Commented-code block (7 lines) in src/pinwheel/db/models.py:185", "shortDescription": {"text": "Commented-code block (7 lines) in src/pinwheel/db/models.py:185"}, "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-b5bc66a3155676ac", "name": "Legacy-named symbol `compute_shot_probability_v2` in src/pinwheel/core/possession.py:786", "shortDescription": {"text": "Legacy-named symbol `compute_shot_probability_v2` in src/pinwheel/core/possession.py:786"}, "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-cbf7e02eba4b67e5", "name": "Legacy-named symbol `compute_contest_v2` in src/pinwheel/core/scoring.py:57", "shortDescription": {"text": "Legacy-named symbol `compute_contest_v2` in src/pinwheel/core/scoring.py:57"}, "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-00d80d8652f0f47f", "name": "Legacy-named symbol `detect_tier_v2` in src/pinwheel/core/governance.py:179", "shortDescription": {"text": "Legacy-named symbol `detect_tier_v2` in src/pinwheel/core/governance.py:179"}, "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-07f1aeccfeeaabd9", "name": "Commented-code block (8 lines) in src/pinwheel/core/governance.py:6", "shortDescription": {"text": "Commented-code block (8 lines) in src/pinwheel/core/governance.py:6"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-bcf9f0c9d0ca308d", "name": "Commented-code block (5 lines) in src/pinwheel/core/scheduler_runner.py:635", "shortDescription": {"text": "Commented-code block (5 lines) in src/pinwheel/core/scheduler_runner.py:635"}, "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-f8b03b7c10adbd67", "name": "Legacy-named symbol `interpret_proposal_v2` in src/pinwheel/core/deferred_interpreter.py:73", "shortDescription": {"text": "Legacy-named symbol `interpret_proposal_v2` in src/pinwheel/core/deferred_interpreter.py:73"}, "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-c93b91985f0d1399", "name": "Commented-code block (5 lines) in src/pinwheel/core/codegen_pipeline.py:385", "shortDescription": {"text": "Commented-code block (5 lines) in src/pinwheel/core/codegen_pipeline.py:385"}, "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-c13d43a93c1a05c4", "name": "Legacy-named symbol `get_proposal_effects_v2` in src/pinwheel/core/game_loop.py:67", "shortDescription": {"text": "Legacy-named symbol `get_proposal_effects_v2` in src/pinwheel/core/game_loop.py:67"}, "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-1327e7aee5329b03", "name": "Commented-code block (6 lines) in src/pinwheel/core/game_loop.py:1097", "shortDescription": {"text": "Commented-code block (6 lines) in src/pinwheel/core/game_loop.py:1097"}, "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-b70b43430978a474", "name": "Legacy-named symbol `last_old` in src/pinwheel/core/trajectory.py:323", "shortDescription": {"text": "Legacy-named symbol `last_old` in src/pinwheel/core/trajectory.py:323"}, "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-eb74a129f6e1057a", "name": "Legacy-named symbol `governance_legacy` in src/pinwheel/core/memorial.py:396", "shortDescription": {"text": "Legacy-named symbol `governance_legacy` in src/pinwheel/core/memorial.py:396"}, "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-21083f78d8a771d5", "name": "Legacy-named symbol `governance_legacy` in src/pinwheel/core/narrative.py:360", "shortDescription": {"text": "Legacy-named symbol `governance_legacy` in src/pinwheel/core/narrative.py:360"}, "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-b3200b6ecc759c23", "name": "Legacy-named symbol `best_old` in src/pinwheel/core/narrative_standings.py:255", "shortDescription": {"text": "Legacy-named symbol `best_old` in src/pinwheel/core/narrative_standings.py:255"}, "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-ad28d434470a1780", "name": "Legacy-named symbol `interpretation_v2` in src/pinwheel/discord/views.py:49", "shortDescription": {"text": "Legacy-named symbol `interpretation_v2` in src/pinwheel/discord/views.py:49"}, "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-ffda07b340f20895", "name": "Legacy-named symbol `interpret_proposal_v2` in src/pinwheel/discord/bot.py:2184", "shortDescription": {"text": "Legacy-named symbol `interpret_proposal_v2` in src/pinwheel/discord/bot.py:2184"}, "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-96fafed8ee9dc48f", "name": "Commented-code block (5 lines) in src/pinwheel/discord/bot.py:678", "shortDescription": {"text": "Commented-code block (5 lines) in src/pinwheel/discord/bot.py:678"}, "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-f4227e3e7e739b53", "name": "Legacy-named symbol `interpretation_v2` in src/pinwheel/discord/embeds.py:633", "shortDescription": {"text": "Legacy-named symbol `interpretation_v2` in src/pinwheel/discord/embeds.py:633"}, "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-91b72a567006375d", "name": "Legacy-named symbol `interpret_proposal_v2` in src/pinwheel/ai/interpreter.py:8", "shortDescription": {"text": "Legacy-named symbol `interpret_proposal_v2` in src/pinwheel/ai/interpreter.py:8"}, "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-eaf5710aa764792d", "name": "Commented-code block (5 lines) in src/pinwheel/ai/interpreter.py:7", "shortDescription": {"text": "Commented-code block (5 lines) in src/pinwheel/ai/interpreter.py:7"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-c9d60f7c5f4e7cb9", "name": "Legacy-named symbol `governance_legacy` in src/pinwheel/ai/report.py:2636", "shortDescription": {"text": "Legacy-named symbol `governance_legacy` in src/pinwheel/ai/report.py:2636"}, "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-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:\nsrc/pinwheel/api/follow.py:follow_team, src/pinwheel/api/follow.py:unfollow_team\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-cf123d023b1145b7", "name": "FastAPI POST `test_classifier` without auth dependency \u2014 src/pinwheel/api/admin_workbench.py:159", "shortDescription": {"text": "FastAPI POST `test_classifier` without auth dependency \u2014 src/pinwheel/api/admin_workbench.py:159"}, "fullDescription": {"text": "`@router.post` decorator with no `Depends(get_current_user)` or auth-shaped dependency in its signature. Mutating endpoints should require authentication unless explicitly public."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-a0a43963cb6a57b3", "name": "FastAPI POST `update_hooper_bio` without auth dependency \u2014 src/pinwheel/api/pages.py:2543", "shortDescription": {"text": "FastAPI POST `update_hooper_bio` without auth dependency \u2014 src/pinwheel/api/pages.py:2543"}, "fullDescription": {"text": "`@router.post` decorator with no `Depends(get_current_user)` or auth-shaped dependency in its signature. Mutating endpoints should require authentication unless explicitly public."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-7166069a8b199d5e", "name": "FastAPI POST `follow_team` without auth dependency \u2014 src/pinwheel/api/follow.py:31", "shortDescription": {"text": "FastAPI POST `follow_team` without auth dependency \u2014 src/pinwheel/api/follow.py:31"}, "fullDescription": {"text": "`@router.post` decorator with no `Depends(get_current_user)` or auth-shaped dependency in its signature. Mutating endpoints should require authentication unless explicitly public."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-7ba58676a8104d38", "name": "FastAPI DELETE `unfollow_team` without auth dependency \u2014 src/pinwheel/api/follow.py:66", "shortDescription": {"text": "FastAPI DELETE `unfollow_team` without auth dependency \u2014 src/pinwheel/api/follow.py:66"}, "fullDescription": {"text": "`@router.delete` decorator with no `Depends(get_current_user)` or auth-shaped dependency in its signature. Mutating endpoints should require authentication unless explicitly public."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}]}}, "automationDetails": {"id": "repobility/25434"}, "properties": {"repository": "djacobs/Pinwheel", "repoUrl": "https://github.com/djacobs/Pinwheel", "branch": "main"}, "results": [{"ruleId": "scanner-10ab4387da78c5c4", "level": "note", "message": {"text": "Possibly dead Python function: require_api_admin"}, "properties": {"repobilityId": "7813b25229c07ff6", "scanner": "scanner-primary", "fingerprint": "10ab4387da78c5c4", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/pinwheel/auth/deps.py:124"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-d70b809a10a493bc", "level": "note", "message": {"text": "Possibly dead Python function: update_season_meta"}, "properties": {"repobilityId": "83173f4db584a41e", "scanner": "scanner-primary", "fingerprint": "d70b809a10a493bc", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/pinwheel/db/repository.py:1565"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-7bb5bac59c7f390c", "level": "note", "message": {"text": "Possibly dead Python function: update_game_result_meta"}, "properties": {"repobilityId": "0a45018840c81977", "scanner": "scanner-primary", "fingerprint": "7bb5bac59c7f390c", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/pinwheel/db/repository.py:1574"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-df4c2d2b10127d3d", "level": "note", "message": {"text": "Possibly dead Python function: update_player_meta"}, "properties": {"repobilityId": "0b23109806c046b7", "scanner": "scanner-primary", "fingerprint": "df4c2d2b10127d3d", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/pinwheel/db/repository.py:1583"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-45d94ab270ec4533", "level": "note", "message": {"text": "Possibly dead Python function: load_hooper_meta"}, "properties": {"repobilityId": "bb0c18c3e5e61224", "scanner": "scanner-primary", "fingerprint": "45d94ab270ec4533", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/pinwheel/db/repository.py:1720"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-d20e9b9a2b8f6a7c", "level": "note", "message": {"text": "Possibly dead Python function: compute_contest"}, "properties": {"repobilityId": "22fee6d88d936b91", "scanner": "scanner-primary", "fingerprint": "d20e9b9a2b8f6a7c", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/pinwheel/core/scoring.py:50"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-229e6f0b64b62bba", "level": "note", "message": {"text": "Possibly dead Python function: mark_presented"}, "properties": {"repobilityId": "624fa1ac32e69afd", "scanner": "scanner-primary", "fingerprint": "229e6f0b64b62bba", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/pinwheel/core/scheduler_runner.py:743"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-e3ebeb56427e7f90", "level": "note", "message": {"text": "Possibly dead Python function: setup_hook"}, "properties": {"repobilityId": "21ca643157480dac", "scanner": "scanner-primary", "fingerprint": "e3ebeb56427e7f90", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/pinwheel/discord/bot.py:526"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-fbc9e452fd00d3bd", "level": "note", "message": {"text": "Possibly dead Python function: generate_newspaper_headlines"}, "properties": {"repobilityId": "c083f06e79384cfb", "scanner": "scanner-primary", "fingerprint": "fbc9e452fd00d3bd", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/pinwheel/ai/insights.py:680"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-4f0d6ccc5a6072b7", "level": "note", "message": {"text": "Possibly dead Python function: generate_report_with_prompt"}, "properties": {"repobilityId": "0ff94e705cece774", "scanner": "scanner-primary", "fingerprint": "4f0d6ccc5a6072b7", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/pinwheel/ai/report.py:849"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-b0377ef879f85060", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 static/js/htmx.min.js:1"}, "properties": {"repobilityId": "0292e297807e6744", "scanner": "scanner-primary", "fingerprint": "b0377ef879f85060", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-d63da3583b14afc0", "level": "warning", "message": {"text": "Dockerfile runs as root: Dockerfile"}, "properties": {"repobilityId": "a2ed1bd120e507db", "scanner": "scanner-primary", "fingerprint": "d63da3583b14afc0", "layer": "hardware", "severity": "medium", "confidence": 1.0, "tags": ["security", "container"]}}, {"ruleId": "scanner-de3c1f217d72a063", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: python:3.12-slim"}, "properties": {"repobilityId": "308788945d4d68ee", "scanner": "scanner-primary", "fingerprint": "de3c1f217d72a063", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Dockerfile"}, "region": {"startLine": 2}}}]}, {"ruleId": "scanner-de3c1f217d72a063", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: python:3.12-slim"}, "properties": {"repobilityId": "6d409624cc615175", "scanner": "scanner-primary", "fingerprint": "de3c1f217d72a063", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Dockerfile"}, "region": {"startLine": 20}}}]}, {"ruleId": "scanner-87f8318b0d5393f8", "level": "error", "message": {"text": "Insecure pattern 'new_function_used' in static/js/htmx.min.js:1"}, "properties": {"repobilityId": "58809cde9ced05c1", "scanner": "scanner-primary", "fingerprint": "87f8318b0d5393f8", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["owasp", "new_function_used"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "static/js/htmx.min.js"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-fa524bd2c579768f", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in static/js/htmx.min.js:1"}, "properties": {"repobilityId": "f97f3b645c0ccad9", "scanner": "scanner-primary", "fingerprint": "fa524bd2c579768f", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "static/js/htmx.min.js"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-d1999688d7f90428", "level": "warning", "message": {"text": "Insecure pattern 'insert_adjacent_html' in static/js/htmx.min.js:1"}, "properties": {"repobilityId": "3a980f91cc04825a", "scanner": "scanner-primary", "fingerprint": "d1999688d7f90428", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "insert_adjacent_html"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "static/js/htmx.min.js"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-236da8be2d8e7d33", "level": "warning", "message": {"text": "Insecure pattern 'domparser_html_parse' in static/js/htmx.min.js:1"}, "properties": {"repobilityId": "3f9e937aa4795934", "scanner": "scanner-primary", "fingerprint": "236da8be2d8e7d33", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "domparser_html_parse"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "static/js/htmx.min.js"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-efaa984d7b9bbd10", "level": "error", "message": {"text": "Insecure pattern 'exec_used' in src/pinwheel/core/codegen.py:626"}, "properties": {"repobilityId": "5c7548acb7f1bb47", "scanner": "scanner-primary", "fingerprint": "efaa984d7b9bbd10", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["owasp", "exec_used"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/pinwheel/core/codegen.py"}, "region": {"startLine": 626}}}]}, {"ruleId": "scanner-06005d6f37ba6e34", "level": "note", "message": {"text": "Very large file: tests/test_pages.py (2974 lines)"}, "properties": {"repobilityId": "67f2d417d68d599e", "scanner": "scanner-primary", "fingerprint": "06005d6f37ba6e34", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-13d81dd72cb32c42", "level": "note", "message": {"text": "Very large file: tests/test_governance.py (1955 lines)"}, "properties": {"repobilityId": "9bd7c8d90d53a335", "scanner": "scanner-primary", "fingerprint": "13d81dd72cb32c42", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-90b3f5bf893fb879", "level": "note", "message": {"text": "Very large file: tests/test_season_lifecycle.py (1499 lines)"}, "properties": {"repobilityId": "fb478f4911866aa2", "scanner": "scanner-primary", "fingerprint": "90b3f5bf893fb879", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-1b0a010647df194c", "level": "note", "message": {"text": "Very large file: tests/test_simulation.py (2009 lines)"}, "properties": {"repobilityId": "894aa6984fbf2870", "scanner": "scanner-primary", "fingerprint": "1b0a010647df194c", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-b4c8ac933a625629", "level": "note", "message": {"text": "Very large file: tests/test_discord.py (4550 lines)"}, "properties": {"repobilityId": "ad691ae45e044384", "scanner": "scanner-primary", "fingerprint": "b4c8ac933a625629", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-d2c697ac57287f94", "level": "note", "message": {"text": "Very large file: tests/test_commentary.py (2806 lines)"}, "properties": {"repobilityId": "4f77f7da0b11f0a6", "scanner": "scanner-primary", "fingerprint": "d2c697ac57287f94", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-1491554d24420761", "level": "note", "message": {"text": "Very large file: tests/test_game_loop.py (2808 lines)"}, "properties": {"repobilityId": "162f68d77064754b", "scanner": "scanner-primary", "fingerprint": "1491554d24420761", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-030b7c46d674b2f6", "level": "note", "message": {"text": "Very large file: tests/test_reports.py (2520 lines)"}, "properties": {"repobilityId": "7541d606af3089f6", "scanner": "scanner-primary", "fingerprint": "030b7c46d674b2f6", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-3e9fea8361b2e77a", "level": "note", "message": {"text": "Very large file: tests/test_effects.py (2866 lines)"}, "properties": {"repobilityId": "375d9f710e282b96", "scanner": "scanner-primary", "fingerprint": "3e9fea8361b2e77a", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-f1edb8785f9985d5", "level": "note", "message": {"text": "Very large file: tests/test_api/test_e2e_workflow.py (1617 lines)"}, "properties": {"repobilityId": "7fe1789416ec527a", "scanner": "scanner-primary", "fingerprint": "f1edb8785f9985d5", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-c5a9a5d35e5683eb", "level": "note", "message": {"text": "Very large file: src/pinwheel/api/pages.py (3410 lines)"}, "properties": {"repobilityId": "bf94ce86a84b9e71", "scanner": "scanner-primary", "fingerprint": "c5a9a5d35e5683eb", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-dd938ef45e15ca30", "level": "note", "message": {"text": "Very large file: src/pinwheel/db/repository.py (1740 lines)"}, "properties": {"repobilityId": "6b3cad10b0041a36", "scanner": "scanner-primary", "fingerprint": "dd938ef45e15ca30", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-0628c650f745ab65", "level": "note", "message": {"text": "Very large file: src/pinwheel/core/game_loop.py (3150 lines)"}, "properties": {"repobilityId": "4a801c8a4178ea7d", "scanner": "scanner-primary", "fingerprint": "0628c650f745ab65", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-1ec4956e559c965c", "level": "note", "message": {"text": "Very large file: src/pinwheel/discord/views.py (1893 lines)"}, "properties": {"repobilityId": "783a136425c4ba61", "scanner": "scanner-primary", "fingerprint": "1ec4956e559c965c", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-b6c40414c15060b1", "level": "note", "message": {"text": "Very large file: src/pinwheel/discord/bot.py (4743 lines)"}, "properties": {"repobilityId": "5a60a5160d3c6591", "scanner": "scanner-primary", "fingerprint": "b6c40414c15060b1", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-8dab206e50feee43", "level": "note", "message": {"text": "Very large file: src/pinwheel/discord/embeds.py (2020 lines)"}, "properties": {"repobilityId": "f5ff1dd837d8b028", "scanner": "scanner-primary", "fingerprint": "8dab206e50feee43", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-98bfad270a6f0066", "level": "note", "message": {"text": "Very large file: src/pinwheel/ai/interpreter.py (1390 lines)"}, "properties": {"repobilityId": "ecdf5d70b15462ab", "scanner": "scanner-primary", "fingerprint": "98bfad270a6f0066", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-1a88454f47abbead", "level": "note", "message": {"text": "Very large file: src/pinwheel/ai/report.py (2839 lines)"}, "properties": {"repobilityId": "70d046a079b138c2", "scanner": "scanner-primary", "fingerprint": "1a88454f47abbead", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-141b30a41e03817b", "level": "note", "message": {"text": "No license file detected"}, "properties": {"repobilityId": "c70fcd8721c97fdd", "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": "38ca93374f744aa8", "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": "69044c1ec8de0267", "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": "b049839b02a91dc2", "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": "87d60ea684942a99", "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": "5658e7dacef0faec", "scanner": "scanner-primary", "fingerprint": "749d4bc1bd66df5f", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-bea357a6497a2d5d", "level": "warning", "message": {"text": "Agent authority lacks a verifier contract: CLAUDE.md"}, "properties": {"repobilityId": "aae72df3934829ac", "scanner": "scanner-primary", "fingerprint": "bea357a6497a2d5d", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "verification", "claude_instruction"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "CLAUDE.md"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-e8ab3946ea9e7679", "level": "error", "message": {"text": "Agent instruction/config may expose a secret: docs/skills/post-commit/SKILL.md"}, "properties": {"repobilityId": "107756bdfac8c3b5", "scanner": "scanner-primary", "fingerprint": "e8ab3946ea9e7679", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["agent-instructions", "secrets", "skill_file"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docs/skills/post-commit/SKILL.md"}, "region": {"startLine": 20}}}]}, {"ruleId": "scanner-e725d2ab884fbd49", "level": "note", "message": {"text": "Multiple root agent instruction files without precedence"}, "properties": {"repobilityId": "1953db6c89508d22", "scanner": "scanner-primary", "fingerprint": "e725d2ab884fbd49", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["agent-instructions", "governance"]}}, {"ruleId": "scanner-08599109ae14d82a", "level": "none", "message": {"text": "Commented-code block (7 lines) in tests/test_strategy_integration.py:482"}, "properties": {"repobilityId": "00826aa386f27790", "scanner": "scanner-primary", "fingerprint": "08599109ae14d82a", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-f8152a3410d3e73b", "level": "note", "message": {"text": "Legacy-named symbol `interp_v2` in tests/test_scheduler_runner.py:744"}, "properties": {"repobilityId": "93545f6d2b3b892e", "scanner": "scanner-primary", "fingerprint": "f8152a3410d3e73b", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-91e611f920fd11a9", "level": "note", "message": {"text": "Legacy-named symbol `get_proposal_effects_v2` in tests/test_governance.py:17"}, "properties": {"repobilityId": "1c1be35c2def7a41", "scanner": "scanner-primary", "fingerprint": "91e611f920fd11a9", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-b19230a344b5c7e5", "level": "none", "message": {"text": "Commented-code block (5 lines) in tests/test_season_lifecycle.py:1098"}, "properties": {"repobilityId": "e9af4fe5b97112a9", "scanner": "scanner-primary", "fingerprint": "b19230a344b5c7e5", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-6003cc4fd39bffef", "level": "note", "message": {"text": "Legacy-named symbol `refreshed_old` in tests/test_season.py:499"}, "properties": {"repobilityId": "36173a8ea3ca0ddd", "scanner": "scanner-primary", "fingerprint": "6003cc4fd39bffef", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-50b0c6a38072c415", "level": "note", "message": {"text": "Legacy-named symbol `mock_user_v1` in tests/test_auth.py:291"}, "properties": {"repobilityId": "f912aff68c434d51", "scanner": "scanner-primary", "fingerprint": "50b0c6a38072c415", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-a8783440b46f5ce1", "level": "note", "message": {"text": "Legacy-named symbol `governance_legacy` in tests/test_memorial.py:432"}, "properties": {"repobilityId": "8da6a93894124946", "scanner": "scanner-primary", "fingerprint": "a8783440b46f5ce1", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-b30b0b0ec0fbc5b4", "level": "note", "message": {"text": "Legacy-named symbol `action_v1` in tests/test_action_registry.py:263"}, "properties": {"repobilityId": "0f90a8666b70cce2", "scanner": "scanner-primary", "fingerprint": "b30b0b0ec0fbc5b4", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-dcca564fdf5df2a4", "level": "note", "message": {"text": "Legacy-named symbol `compute_shot_probability_v2` in tests/test_simulation.py:24"}, "properties": {"repobilityId": "28c49a32aae6286f", "scanner": "scanner-primary", "fingerprint": "dcca564fdf5df2a4", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-e82c71ea58b0aab4", "level": "note", "message": {"text": "Legacy-named symbol `test_state_returns_copy` in tests/test_codegen.py:216"}, "properties": {"repobilityId": "aa641a3dcb4915b6", "scanner": "scanner-primary", "fingerprint": "e82c71ea58b0aab4", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-3d727c55ae2fa5e5", "level": "note", "message": {"text": "Legacy-named symbol `test_change_too_old` in tests/test_commentary.py:1938"}, "properties": {"repobilityId": "72c054aa6b621c01", "scanner": "scanner-primary", "fingerprint": "3d727c55ae2fa5e5", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-71b6858762bd32ba", "level": "note", "message": {"text": "Legacy-named symbol `interpret_proposal_v2` in tests/test_messages_api.py:512"}, "properties": {"repobilityId": "c385f5efa977047f", "scanner": "scanner-primary", "fingerprint": "71b6858762bd32ba", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-0d8f690dcae600e9", "level": "none", "message": {"text": "Commented-code block (11 lines) in tests/test_game_loop.py:2079"}, "properties": {"repobilityId": "69ba97e5b410da67", "scanner": "scanner-primary", "fingerprint": "0d8f690dcae600e9", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-d6d71e6164e21660", "level": "none", "message": {"text": "Commented-code block (6 lines) in tests/test_pages_what_changed.py:445"}, "properties": {"repobilityId": "4c978262c4c64d6b", "scanner": "scanner-primary", "fingerprint": "d6d71e6164e21660", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-c39969f8808b2e36", "level": "note", "message": {"text": "Legacy-named symbol `detect_tier_v2` in tests/test_codegen_integration.py:18"}, "properties": {"repobilityId": "71e2b2aca83c16c5", "scanner": "scanner-primary", "fingerprint": "c39969f8808b2e36", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-6decd2d50d8f8e2e", "level": "note", "message": {"text": "Legacy-named symbol `interpret_proposal_v2` in tests/test_deferred_interpreter.py:150"}, "properties": {"repobilityId": "7bce5b6d3b07ef02", "scanner": "scanner-primary", "fingerprint": "6decd2d50d8f8e2e", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-7309533f8871153c", "level": "note", "message": {"text": "Legacy-named symbol `detect_tier_v2` in tests/test_effects.py:1609"}, "properties": {"repobilityId": "47f14c6b57453f88", "scanner": "scanner-primary", "fingerprint": "7309533f8871153c", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-4e28eaea25ff7ce9", "level": "note", "message": {"text": "Legacy-named symbol `detect_tier_v2` in tests/test_patch_validation.py:18"}, "properties": {"repobilityId": "d70893458c42c05a", "scanner": "scanner-primary", "fingerprint": "4e28eaea25ff7ce9", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-993889e628f6b184", "level": "note", "message": {"text": "Legacy-named symbol `effects_v2` in tests/test_expanded_ruleset.py:667"}, "properties": {"repobilityId": "a90366902c925257", "scanner": "scanner-primary", "fingerprint": "993889e628f6b184", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-dfdcd44591dca3ec", "level": "note", "message": {"text": "Legacy-named symbol `governance_legacy` in tests/test_narrative.py:987"}, "properties": {"repobilityId": "ceffd51470341ccc", "scanner": "scanner-primary", "fingerprint": "dfdcd44591dca3ec", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-dd4857dc6ec47262", "level": "note", "message": {"text": "Legacy-named symbol `TestNarrationRegistryMatchesLegacy` in tests/test_narrate.py:702"}, "properties": {"repobilityId": "245303021a2d2f08", "scanner": "scanner-primary", "fingerprint": "dd4857dc6ec47262", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-62bdf45f0d3dcf1c", "level": "note", "message": {"text": "Legacy-named symbol `effects_v2` in tests/test_api/test_e2e_workflow.py:691"}, "properties": {"repobilityId": "e0f092a237f9b438", "scanner": "scanner-primary", "fingerprint": "62bdf45f0d3dcf1c", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-1096c39b837702fa", "level": "none", "message": {"text": "Commented-code block (5 lines) in tests/test_evals/test_eval_dashboard.py:239"}, "properties": {"repobilityId": "d2de4e0f1395b565", "scanner": "scanner-primary", "fingerprint": "1096c39b837702fa", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-515c79435b85ae7b", "level": "note", "message": {"text": "Legacy-named symbol `interpret_proposal_v2` in scripts/resubmit_proposals.py:4"}, "properties": {"repobilityId": "aa0f1eafa1d97093", "scanner": "scanner-primary", "fingerprint": "515c79435b85ae7b", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-f30d1fd84f038e90", "level": "note", "message": {"text": "Legacy-named symbol `resubmit_proposals_v2` in scripts/resubmit_proposals_v2.py:9"}, "properties": {"repobilityId": "cbcd5be0f1effbca", "scanner": "scanner-primary", "fingerprint": "f30d1fd84f038e90", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-c100c2b620ccc124", "level": "note", "message": {"text": "Legacy-named symbol `governance_legacy` in src/pinwheel/api/pages.py:3345"}, "properties": {"repobilityId": "e1949acd08fc04ab", "scanner": "scanner-primary", "fingerprint": "c100c2b620ccc124", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-bdb799d25c7c1eb3", "level": "note", "message": {"text": "Legacy-named symbol `model_copy` in src/pinwheel/models/game_definition.py:355"}, "properties": {"repobilityId": "219679072d2eb186", "scanner": "scanner-primary", "fingerprint": "bdb799d25c7c1eb3", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-727ddda08edceb67", "level": "note", "message": {"text": "Legacy-named symbol `governance_legacy` in src/pinwheel/models/report.py:61"}, "properties": {"repobilityId": "0d4981ee7f6c20e1", "scanner": "scanner-primary", "fingerprint": "727ddda08edceb67", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-4c1d4c14ab4b680f", "level": "none", "message": {"text": "Commented-code block (7 lines) in src/pinwheel/db/models.py:185"}, "properties": {"repobilityId": "d0b63af7cee3163f", "scanner": "scanner-primary", "fingerprint": "4c1d4c14ab4b680f", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-b5bc66a3155676ac", "level": "note", "message": {"text": "Legacy-named symbol `compute_shot_probability_v2` in src/pinwheel/core/possession.py:786"}, "properties": {"repobilityId": "0009296166049884", "scanner": "scanner-primary", "fingerprint": "b5bc66a3155676ac", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-cbf7e02eba4b67e5", "level": "note", "message": {"text": "Legacy-named symbol `compute_contest_v2` in src/pinwheel/core/scoring.py:57"}, "properties": {"repobilityId": "66c50ff4b1ead8c7", "scanner": "scanner-primary", "fingerprint": "cbf7e02eba4b67e5", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-00d80d8652f0f47f", "level": "note", "message": {"text": "Legacy-named symbol `detect_tier_v2` in src/pinwheel/core/governance.py:179"}, "properties": {"repobilityId": "1ec31d9a500e8b55", "scanner": "scanner-primary", "fingerprint": "00d80d8652f0f47f", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-07f1aeccfeeaabd9", "level": "none", "message": {"text": "Commented-code block (8 lines) in src/pinwheel/core/governance.py:6"}, "properties": {"repobilityId": "b521f8ad3a6c4000", "scanner": "scanner-primary", "fingerprint": "07f1aeccfeeaabd9", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-bcf9f0c9d0ca308d", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/pinwheel/core/scheduler_runner.py:635"}, "properties": {"repobilityId": "8d81a91fed894716", "scanner": "scanner-primary", "fingerprint": "bcf9f0c9d0ca308d", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-f8b03b7c10adbd67", "level": "note", "message": {"text": "Legacy-named symbol `interpret_proposal_v2` in src/pinwheel/core/deferred_interpreter.py:73"}, "properties": {"repobilityId": "ba5bd60f5b1f2c77", "scanner": "scanner-primary", "fingerprint": "f8b03b7c10adbd67", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-c93b91985f0d1399", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/pinwheel/core/codegen_pipeline.py:385"}, "properties": {"repobilityId": "2582d0a2f8b1fc49", "scanner": "scanner-primary", "fingerprint": "c93b91985f0d1399", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-c13d43a93c1a05c4", "level": "note", "message": {"text": "Legacy-named symbol `get_proposal_effects_v2` in src/pinwheel/core/game_loop.py:67"}, "properties": {"repobilityId": "9a9fe34aa65cdbef", "scanner": "scanner-primary", "fingerprint": "c13d43a93c1a05c4", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-1327e7aee5329b03", "level": "none", "message": {"text": "Commented-code block (6 lines) in src/pinwheel/core/game_loop.py:1097"}, "properties": {"repobilityId": "e5fdd6386d6bcf8a", "scanner": "scanner-primary", "fingerprint": "1327e7aee5329b03", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-b70b43430978a474", "level": "note", "message": {"text": "Legacy-named symbol `last_old` in src/pinwheel/core/trajectory.py:323"}, "properties": {"repobilityId": "764c4381dbb93174", "scanner": "scanner-primary", "fingerprint": "b70b43430978a474", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-eb74a129f6e1057a", "level": "note", "message": {"text": "Legacy-named symbol `governance_legacy` in src/pinwheel/core/memorial.py:396"}, "properties": {"repobilityId": "6e269822f7c86e5f", "scanner": "scanner-primary", "fingerprint": "eb74a129f6e1057a", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-21083f78d8a771d5", "level": "note", "message": {"text": "Legacy-named symbol `governance_legacy` in src/pinwheel/core/narrative.py:360"}, "properties": {"repobilityId": "e8890a494009201a", "scanner": "scanner-primary", "fingerprint": "21083f78d8a771d5", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-b3200b6ecc759c23", "level": "note", "message": {"text": "Legacy-named symbol `best_old` in src/pinwheel/core/narrative_standings.py:255"}, "properties": {"repobilityId": "83a4d47bcf8f7692", "scanner": "scanner-primary", "fingerprint": "b3200b6ecc759c23", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-ad28d434470a1780", "level": "note", "message": {"text": "Legacy-named symbol `interpretation_v2` in src/pinwheel/discord/views.py:49"}, "properties": {"repobilityId": "86040807b95d2db2", "scanner": "scanner-primary", "fingerprint": "ad28d434470a1780", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-ffda07b340f20895", "level": "note", "message": {"text": "Legacy-named symbol `interpret_proposal_v2` in src/pinwheel/discord/bot.py:2184"}, "properties": {"repobilityId": "d7cba786c3a64f63", "scanner": "scanner-primary", "fingerprint": "ffda07b340f20895", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-96fafed8ee9dc48f", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/pinwheel/discord/bot.py:678"}, "properties": {"repobilityId": "00ded86726704516", "scanner": "scanner-primary", "fingerprint": "96fafed8ee9dc48f", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-f4227e3e7e739b53", "level": "note", "message": {"text": "Legacy-named symbol `interpretation_v2` in src/pinwheel/discord/embeds.py:633"}, "properties": {"repobilityId": "bb480f05b608df4e", "scanner": "scanner-primary", "fingerprint": "f4227e3e7e739b53", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-91b72a567006375d", "level": "note", "message": {"text": "Legacy-named symbol `interpret_proposal_v2` in src/pinwheel/ai/interpreter.py:8"}, "properties": {"repobilityId": "ce6ae776bf8dab98", "scanner": "scanner-primary", "fingerprint": "91b72a567006375d", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-eaf5710aa764792d", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/pinwheel/ai/interpreter.py:7"}, "properties": {"repobilityId": "95318fd17b03490e", "scanner": "scanner-primary", "fingerprint": "eaf5710aa764792d", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-c9d60f7c5f4e7cb9", "level": "note", "message": {"text": "Legacy-named symbol `governance_legacy` in src/pinwheel/ai/report.py:2636"}, "properties": {"repobilityId": "e2b54550329fb9ae", "scanner": "scanner-primary", "fingerprint": "c9d60f7c5f4e7cb9", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-2c04133e54348533", "level": "note", "message": {"text": "Near-duplicate function bodies in 2 places"}, "properties": {"repobilityId": "8f4cf36c9087cc51", "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": "3973b276057decb8", "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": "8b4bde1564f629ec", "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": "c15f05245f47f888", "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": "682ec662f4982ee8", "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": "1e4d71f02f0154a6", "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": "cf282e3a05dd19d1", "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": "f4220011f374bb36", "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": "8f9493aa2baec521", "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": "926638b945d2adc2", "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": "6c498a6fcc1f2385", "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": "89e8c08a35ce150f", "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": "901bb8f00046516f", "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": "73f976e560f0ae8f", "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": "f0467b17ae4a281b", "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": "79fe3f351fb4871e", "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": "8c52daadfb1a9d7d", "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": "89c29f7b03b28395", "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": "266587defbb8fa23", "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": "942c92dc6beb281a", "scanner": "scanner-primary", "fingerprint": "2c04133e54348533", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "duplicate", "dry"]}}, {"ruleId": "scanner-cf123d023b1145b7", "level": "error", "message": {"text": "FastAPI POST `test_classifier` without auth dependency \u2014 src/pinwheel/api/admin_workbench.py:159"}, "properties": {"repobilityId": "eccdd7c50bd0e505", "scanner": "scanner-primary", "fingerprint": "cf123d023b1145b7", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.fastapi.unauth_mutation"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/pinwheel/api/admin_workbench.py"}, "region": {"startLine": 159}}}]}, {"ruleId": "scanner-a0a43963cb6a57b3", "level": "error", "message": {"text": "FastAPI POST `update_hooper_bio` without auth dependency \u2014 src/pinwheel/api/pages.py:2543"}, "properties": {"repobilityId": "749973c2ba5b46d7", "scanner": "scanner-primary", "fingerprint": "a0a43963cb6a57b3", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.fastapi.unauth_mutation"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/pinwheel/api/pages.py"}, "region": {"startLine": 2543}}}]}, {"ruleId": "scanner-7166069a8b199d5e", "level": "error", "message": {"text": "FastAPI POST `follow_team` without auth dependency \u2014 src/pinwheel/api/follow.py:31"}, "properties": {"repobilityId": "28ca5b34f3bd1c30", "scanner": "scanner-primary", "fingerprint": "7166069a8b199d5e", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.fastapi.unauth_mutation"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/pinwheel/api/follow.py"}, "region": {"startLine": 31}}}]}, {"ruleId": "scanner-7ba58676a8104d38", "level": "error", "message": {"text": "FastAPI DELETE `unfollow_team` without auth dependency \u2014 src/pinwheel/api/follow.py:66"}, "properties": {"repobilityId": "63ca732bf11ddd8b", "scanner": "scanner-primary", "fingerprint": "7ba58676a8104d38", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.fastapi.unauth_mutation"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/pinwheel/api/follow.py"}, "region": {"startLine": 66}}}]}]}]}