{"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-1a8168f70cb0f9f2", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/LessonDetail.jsx:287", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/LessonDetail.jsx:287"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-8b33c263f006da0b", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/menu.jsx:82", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/menu.jsx:82"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-11b864b42cfbdb2c", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/HomeScreen.jsx:210", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/HomeScreen.jsx:210"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-79aa028c633b36e0", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/stories/StoriesPage.jsx:227", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/stories/StoriesPage.jsx:227"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-9ee1a2ba61619164", "name": "Insecure pattern 'direct_innerhtml_assignment' in src/components/SplashScreen.jsx:25", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in src/components/SplashScreen.jsx:25"}, "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-5352f1a8c51c5ad4", "name": "Insecure pattern 'direct_innerhtml_assignment' in src/components/HomeScreen.jsx:33", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in src/components/HomeScreen.jsx:33"}, "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-662c25e340a32a8b", "name": "Insecure pattern 'direct_innerhtml_assignment' in src/components/learn/Writing/RadicalsWriting.jsx:44", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in src/components/learn/Writing/RadicalsWriting.jsx:44"}, "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-6a65c70d30c337b3", "name": "Insecure pattern 'direct_innerhtml_assignment' in src/components/learn/Writing/HanziWriting.jsx:34", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in src/components/learn/Writing/HanziWriting.jsx:34"}, "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-039f8d551c46f35d", "name": "Insecure pattern 'direct_innerhtml_assignment' in src/components/ui/CharacterSheet.jsx:24", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in src/components/ui/CharacterSheet.jsx:24"}, "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-c1e62c8a8becdce0", "name": "GitHub Action is tag-pinned rather than SHA-pinned", "shortDescription": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "fullDescription": {"text": "actions/checkout@v4 can move without a code change in this repo. Pin third-party actions to a reviewed 40-character commit SHA."}, "properties": {"scanner": "scanner-primary", "layer": "cicd", "severity": "low", "confidence": 1.0}}, {"id": "scanner-11fe6710547243fb", "name": "GitHub Actions workflow grants broad write permissions", "shortDescription": {"text": "GitHub Actions workflow grants broad write permissions"}, "fullDescription": {"text": "CI tokens with write permissions increase blast radius when an action, dependency, or PR workflow is compromised. Prefer job-level least-privilege permissions."}, "properties": {"scanner": "scanner-primary", "layer": "cicd", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-531400895b6515a3", "name": "Very large file: src/locales/en.js (1044 lines)", "shortDescription": {"text": "Very large file: src/locales/en.js (1044 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-6cee91cb8bcea305", "name": "Very large file: src/locales/es.js (1053 lines)", "shortDescription": {"text": "Very large file: src/locales/es.js (1053 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-d03422047650b164", "name": "Very large file: src/locales/pt.js (1027 lines)", "shortDescription": {"text": "Very large file: src/locales/pt.js (1027 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-3fb3eec6f20195ab", "name": "Very large file: src/locales/it.js (1027 lines)", "shortDescription": {"text": "Very large file: src/locales/it.js (1027 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-8f2b0ca61a6103ee", "name": "Very large file: src/locales/fr.js (1042 lines)", "shortDescription": {"text": "Very large file: src/locales/fr.js (1042 lines)"}, "fullDescription": {"text": "Files with >800 lines often hide complexity hotspots and discourage tests."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-6893a6c8b0861585", "name": "Very low test-to-source ratio", "shortDescription": {"text": "Very low test-to-source ratio"}, "fullDescription": {"text": "0 test file(s) for 151 source file(s) (ratio 0.00). Consider adding integration or unit tests for critical paths."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-141b30a41e03817b", "name": "No license file detected", "shortDescription": {"text": "No license file detected"}, "fullDescription": {"text": "No LICENSE/COPYING/NOTICE file was found. Generated repositories often omit licensing, which blocks reuse and automated intake."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-3ab5d313dda8e5f9", "name": "Debug logging residue appears in source files", "shortDescription": {"text": "Debug logging residue appears in source files"}, "fullDescription": {"text": "Found 17 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-11825279136b53a3", "name": "CI is configured but no tests are detected", "shortDescription": {"text": "CI is configured but no tests are detected"}, "fullDescription": {"text": "A CI pipeline exists, but the scan found no test files to gate. Opus labeled this generated-code pattern as config theater: release machinery exists, but it has little behavioral signal."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-b9088664ace7f748", "name": "Composite production-readiness gap", "shortDescription": {"text": "Composite production-readiness gap"}, "fullDescription": {"text": "Multiple low-cost hardening controls are missing together: license, tests. Opus verification showed these co-occurring gaps are a better readiness signal than reading each flag in isolation."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "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, tests. Treat this as a contract gap: the agent is guided, but the generated output is not yet guarded by the controls that make it repeatable."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-ea8f3013f588db25", "name": "Shallow git history limits provenance confidence", "shortDescription": {"text": "Shallow git history limits provenance confidence"}, "fullDescription": {"text": "The repository is a shallow clone. Origin/evolution analysis cannot distinguish fresh generation, imported legacy code, or long-lived human code with high confidence."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-8424db9c75e04ba4", "name": "Very short observed git history", "shortDescription": {"text": "Very short observed git history"}, "fullDescription": {"text": "The repo has multiple source files but two or fewer visible commits. This is not a failure by itself, but it lowers confidence in evolution-based diagnosis."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-76b5aa112eba95df", "name": "Commented-code block (6 lines) in vite.config.js:127", "shortDescription": {"text": "Commented-code block (6 lines) in vite.config.js:127"}, "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-542a8f6e82577669", "name": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/fix-fetch.mjs:5", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/fix-fetch.mjs:5"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-7275e53352e55d5b", "name": "Commented-code block (8 lines) in design_handoff_jade_pop_rojo/jr-shell.jsx:1", "shortDescription": {"text": "Commented-code block (8 lines) in design_handoff_jade_pop_rojo/jr-shell.jsx:1"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-1165c17e826c023e", "name": "Commented-code block (6 lines) in design_handoff_jade_pop_rojo/design-canvas.jsx:2", "shortDescription": {"text": "Commented-code block (6 lines) in design_handoff_jade_pop_rojo/design-canvas.jsx:2"}, "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-dd0cb13f023ff479", "name": "`fetch()` without try/.catch or AbortSignal \u2014 design_handoff_jade_pop_rojo/design-canvas.jsx:128", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 design_handoff_jade_pop_rojo/design-canvas.jsx:128"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-20d1e54e2ff77a1e", "name": "Commented-code block (5 lines) in src/utils/srs.js:7", "shortDescription": {"text": "Commented-code block (5 lines) in src/utils/srs.js: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-4eeeaf779bb076c8", "name": "Commented-code block (5 lines) in src/utils/badges.js:1", "shortDescription": {"text": "Commented-code block (5 lines) in src/utils/badges.js:1"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-d16fc54782bd34d4", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/utils/dataCache.js:32", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/utils/dataCache.js:32"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-e7e1a559d524d635", "name": "Commented-code block (5 lines) in src/utils/gameIntroPrefs.js:1", "shortDescription": {"text": "Commented-code block (5 lines) in src/utils/gameIntroPrefs.js:1"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-ed20fdc8b35ad23b", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/utils/assets.js:8", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/utils/assets.js:8"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-c89becc5500857d5", "name": "Commented-code block (6 lines) in src/utils/storyDifficulty.js:12", "shortDescription": {"text": "Commented-code block (6 lines) in src/utils/storyDifficulty.js:12"}, "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-e921f38c9d373fc5", "name": "Legacy-named symbol `dailyProgress_v1` in src/utils/daily-logic.js:5", "shortDescription": {"text": "Legacy-named symbol `dailyProgress_v1` in src/utils/daily-logic.js:5"}, "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-c128e8134e76ab61", "name": "Commented-code block (5 lines) in src/components/LevelUpHost.jsx:1", "shortDescription": {"text": "Commented-code block (5 lines) in src/components/LevelUpHost.jsx:1"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-5f85ba3507e72ab7", "name": "Commented-code block (6 lines) in src/components/LevelUpModal.jsx:1", "shortDescription": {"text": "Commented-code block (6 lines) in src/components/LevelUpModal.jsx:1"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-63688481b17543f3", "name": "Legacy-named symbol `dailyProgress_v1` in src/components/daily/CharactersDaily.jsx:9", "shortDescription": {"text": "Legacy-named symbol `dailyProgress_v1` in src/components/daily/CharactersDaily.jsx: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-8b231bd737ecd373", "name": "Commented-code block (7 lines) in src/components/stories/Avatars.jsx:8", "shortDescription": {"text": "Commented-code block (7 lines) in src/components/stories/Avatars.jsx:8"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-d365723a5ffd515e", "name": "Commented-code block (5 lines) in src/components/stories/CharacterDisplay.jsx:1", "shortDescription": {"text": "Commented-code block (5 lines) in src/components/stories/CharacterDisplay.jsx:1"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-8bdb6622f6d7e7a4", "name": "Commented-code block (6 lines) in src/components/stories/DialogueBox.jsx:1", "shortDescription": {"text": "Commented-code block (6 lines) in src/components/stories/DialogueBox.jsx:1"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-52c81b79ed437dd2", "name": "Commented-code block (9 lines) in src/components/stories/SceneBackground.jsx:1", "shortDescription": {"text": "Commented-code block (9 lines) in src/components/stories/SceneBackground.jsx:1"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-7444ace79a9d7080", "name": "Commented-code block (8 lines) in src/components/minigames/registry.js:1", "shortDescription": {"text": "Commented-code block (8 lines) in src/components/minigames/registry.js:1"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-96ce83a20ce60ada", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/minigames/TranslationGame.jsx:40", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/minigames/TranslationGame.jsx:40"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-7c1cbcb0d3120d0f", "name": "Commented-code block (6 lines) in src/lib/firebase.js:1", "shortDescription": {"text": "Commented-code block (6 lines) in src/lib/firebase.js:1"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-dd3c1a2d1e6b4539", "name": "Legacy-named symbol `dailyProgress_v1` in src/lib/userStore.js:46", "shortDescription": {"text": "Legacy-named symbol `dailyProgress_v1` in src/lib/userStore.js:46"}, "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-f12fdda626a229b2", "name": "Legacy-named symbol `srs_mode_subtitle_v2` in src/locales/en.js:788", "shortDescription": {"text": "Legacy-named symbol `srs_mode_subtitle_v2` in src/locales/en.js:788"}, "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-75077972b3e1e070", "name": "Legacy-named symbol `srs_mode_subtitle_v2` in src/locales/es.js:793", "shortDescription": {"text": "Legacy-named symbol `srs_mode_subtitle_v2` in src/locales/es.js:793"}, "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-94620a422fd41083", "name": "Legacy-named symbol `srs_mode_subtitle_v2` in src/locales/pt.js:773", "shortDescription": {"text": "Legacy-named symbol `srs_mode_subtitle_v2` in src/locales/pt.js:773"}, "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-69a79da82318ca2d", "name": "Legacy-named symbol `srs_mode_subtitle_v2` in src/locales/it.js:773", "shortDescription": {"text": "Legacy-named symbol `srs_mode_subtitle_v2` in src/locales/it.js:773"}, "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-797f827ab0d00470", "name": "Legacy-named symbol `srs_mode_subtitle_v2` in src/locales/fr.js:788", "shortDescription": {"text": "Legacy-named symbol `srs_mode_subtitle_v2` in src/locales/fr.js:788"}, "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-c9d6ccb470585de6", "name": "Legacy-named symbol `srs_mode_subtitle_v2` in src/locales/de.js:392", "shortDescription": {"text": "Legacy-named symbol `srs_mode_subtitle_v2` in src/locales/de.js:392"}, "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-65c7e70d050b1e04", "name": "Commented-code block (6 lines) in src/context/AuthContext.jsx:1", "shortDescription": {"text": "Commented-code block (6 lines) in src/context/AuthContext.jsx:1"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-319e66a630e14977", "name": "2 env vars used in code but missing from .env.example", "shortDescription": {"text": "2 env vars used in code but missing from .env.example"}, "fullDescription": {"text": "Drift between code and config docs. The first few: `BASE_URL`, `DEV`. Add them (with a placeholder/comment) to .env.example so onboarding doesn't break."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}]}}, "automationDetails": {"id": "repobility/20814"}, "properties": {"repository": "Tantdeboc1/aprende-chino", "repoUrl": "https://github.com/Tantdeboc1/aprende-chino", "branch": "main"}, "results": [{"ruleId": "scanner-1a8168f70cb0f9f2", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/LessonDetail.jsx:287"}, "properties": {"repobilityId": "7e747454e4d7566d", "scanner": "scanner-primary", "fingerprint": "1a8168f70cb0f9f2", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-8b33c263f006da0b", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/menu.jsx:82"}, "properties": {"repobilityId": "34ba0d917d13f31f", "scanner": "scanner-primary", "fingerprint": "8b33c263f006da0b", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-11b864b42cfbdb2c", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/HomeScreen.jsx:210"}, "properties": {"repobilityId": "ed4659fbc35f338e", "scanner": "scanner-primary", "fingerprint": "11b864b42cfbdb2c", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-79aa028c633b36e0", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/stories/StoriesPage.jsx:227"}, "properties": {"repobilityId": "20bcde45b72fd2a6", "scanner": "scanner-primary", "fingerprint": "79aa028c633b36e0", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-9ee1a2ba61619164", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in src/components/SplashScreen.jsx:25"}, "properties": {"repobilityId": "4370a35927806d20", "scanner": "scanner-primary", "fingerprint": "9ee1a2ba61619164", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/components/SplashScreen.jsx"}, "region": {"startLine": 25}}}]}, {"ruleId": "scanner-5352f1a8c51c5ad4", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in src/components/HomeScreen.jsx:33"}, "properties": {"repobilityId": "77cae322da8868d2", "scanner": "scanner-primary", "fingerprint": "5352f1a8c51c5ad4", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/components/HomeScreen.jsx"}, "region": {"startLine": 33}}}]}, {"ruleId": "scanner-662c25e340a32a8b", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in src/components/learn/Writing/RadicalsWriting.jsx:44"}, "properties": {"repobilityId": "4eeef03913e4de37", "scanner": "scanner-primary", "fingerprint": "662c25e340a32a8b", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/components/learn/Writing/RadicalsWriting.jsx"}, "region": {"startLine": 44}}}]}, {"ruleId": "scanner-6a65c70d30c337b3", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in src/components/learn/Writing/HanziWriting.jsx:34"}, "properties": {"repobilityId": "0c860f24badcb02e", "scanner": "scanner-primary", "fingerprint": "6a65c70d30c337b3", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/components/learn/Writing/HanziWriting.jsx"}, "region": {"startLine": 34}}}]}, {"ruleId": "scanner-039f8d551c46f35d", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in src/components/ui/CharacterSheet.jsx:24"}, "properties": {"repobilityId": "ea2a5eb68207eaef", "scanner": "scanner-primary", "fingerprint": "039f8d551c46f35d", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/components/ui/CharacterSheet.jsx"}, "region": {"startLine": 24}}}]}, {"ruleId": "scanner-c1e62c8a8becdce0", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "19eb4268d280af38", "scanner": "scanner-primary", "fingerprint": "c1e62c8a8becdce0", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/deploy-pages.yml"}, "region": {"startLine": 22}}}]}, {"ruleId": "scanner-c1e62c8a8becdce0", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "98317e5fcf652416", "scanner": "scanner-primary", "fingerprint": "c1e62c8a8becdce0", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/deploy-pages.yml"}, "region": {"startLine": 25}}}]}, {"ruleId": "scanner-c1e62c8a8becdce0", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "293d3dbcb67ba2f7", "scanner": "scanner-primary", "fingerprint": "c1e62c8a8becdce0", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/deploy-pages.yml"}, "region": {"startLine": 41}}}]}, {"ruleId": "scanner-c1e62c8a8becdce0", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "4a5232ca5f9d3d6d", "scanner": "scanner-primary", "fingerprint": "c1e62c8a8becdce0", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/deploy-pages.yml"}, "region": {"startLine": 54}}}]}, {"ruleId": "scanner-11fe6710547243fb", "level": "warning", "message": {"text": "GitHub Actions workflow grants broad write permissions"}, "properties": {"repobilityId": "c88f07fd35b9711f", "scanner": "scanner-primary", "fingerprint": "11fe6710547243fb", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "least-privilege"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/deploy-pages.yml"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-531400895b6515a3", "level": "note", "message": {"text": "Very large file: src/locales/en.js (1044 lines)"}, "properties": {"repobilityId": "01d3d4983f5b519e", "scanner": "scanner-primary", "fingerprint": "531400895b6515a3", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-6cee91cb8bcea305", "level": "note", "message": {"text": "Very large file: src/locales/es.js (1053 lines)"}, "properties": {"repobilityId": "c666800b94d07bb3", "scanner": "scanner-primary", "fingerprint": "6cee91cb8bcea305", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-d03422047650b164", "level": "note", "message": {"text": "Very large file: src/locales/pt.js (1027 lines)"}, "properties": {"repobilityId": "031c919832795096", "scanner": "scanner-primary", "fingerprint": "d03422047650b164", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-3fb3eec6f20195ab", "level": "note", "message": {"text": "Very large file: src/locales/it.js (1027 lines)"}, "properties": {"repobilityId": "7220416bd34663a1", "scanner": "scanner-primary", "fingerprint": "3fb3eec6f20195ab", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-8f2b0ca61a6103ee", "level": "note", "message": {"text": "Very large file: src/locales/fr.js (1042 lines)"}, "properties": {"repobilityId": "697fa9403e4693c8", "scanner": "scanner-primary", "fingerprint": "8f2b0ca61a6103ee", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-6893a6c8b0861585", "level": "warning", "message": {"text": "Very low test-to-source ratio"}, "properties": {"repobilityId": "54a7de3f06314bf0", "scanner": "scanner-primary", "fingerprint": "6893a6c8b0861585", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["tests", "coverage"]}}, {"ruleId": "scanner-141b30a41e03817b", "level": "note", "message": {"text": "No license file detected"}, "properties": {"repobilityId": "2af03d4531636160", "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": "fc9bf0db196d5d4a", "scanner": "scanner-primary", "fingerprint": "3ab5d313dda8e5f9", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["debug", "cleanup", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-11825279136b53a3", "level": "warning", "message": {"text": "CI is configured but no tests are detected"}, "properties": {"repobilityId": "1dacab877f12d464", "scanner": "scanner-primary", "fingerprint": "11825279136b53a3", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["tests", "ci", "config-theater", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-b9088664ace7f748", "level": "note", "message": {"text": "Composite production-readiness gap"}, "properties": {"repobilityId": "83e0bd30c4334b26", "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": "0901c5c15bb9872c", "scanner": "scanner-primary", "fingerprint": "749d4bc1bd66df5f", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-ea8f3013f588db25", "level": "note", "message": {"text": "Shallow git history limits provenance confidence"}, "properties": {"repobilityId": "bad9314d74417a34", "scanner": "scanner-primary", "fingerprint": "ea8f3013f588db25", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["provenance", "git-history", "generated-repo-pattern"]}}, {"ruleId": "scanner-8424db9c75e04ba4", "level": "none", "message": {"text": "Very short observed git history"}, "properties": {"repobilityId": "07c8a19089a91722", "scanner": "scanner-primary", "fingerprint": "8424db9c75e04ba4", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["provenance", "git-history", "generated-repo-pattern"]}}, {"ruleId": "scanner-76b5aa112eba95df", "level": "none", "message": {"text": "Commented-code block (6 lines) in vite.config.js:127"}, "properties": {"repobilityId": "7dd35033857559ce", "scanner": "scanner-primary", "fingerprint": "76b5aa112eba95df", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-542a8f6e82577669", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/fix-fetch.mjs:5"}, "properties": {"repobilityId": "c05cb67fc89215f0", "scanner": "scanner-primary", "fingerprint": "542a8f6e82577669", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-7275e53352e55d5b", "level": "none", "message": {"text": "Commented-code block (8 lines) in design_handoff_jade_pop_rojo/jr-shell.jsx:1"}, "properties": {"repobilityId": "59bd09db26907a1c", "scanner": "scanner-primary", "fingerprint": "7275e53352e55d5b", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-1165c17e826c023e", "level": "none", "message": {"text": "Commented-code block (6 lines) in design_handoff_jade_pop_rojo/design-canvas.jsx:2"}, "properties": {"repobilityId": "4d574874424892d8", "scanner": "scanner-primary", "fingerprint": "1165c17e826c023e", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-dd0cb13f023ff479", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 design_handoff_jade_pop_rojo/design-canvas.jsx:128"}, "properties": {"repobilityId": "2b55718a43e0731c", "scanner": "scanner-primary", "fingerprint": "dd0cb13f023ff479", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-20d1e54e2ff77a1e", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/utils/srs.js:7"}, "properties": {"repobilityId": "c2e2c03d415963ff", "scanner": "scanner-primary", "fingerprint": "20d1e54e2ff77a1e", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-4eeeaf779bb076c8", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/utils/badges.js:1"}, "properties": {"repobilityId": "a82867727b832d61", "scanner": "scanner-primary", "fingerprint": "4eeeaf779bb076c8", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-d16fc54782bd34d4", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/utils/dataCache.js:32"}, "properties": {"repobilityId": "7a578356ace3b7e0", "scanner": "scanner-primary", "fingerprint": "d16fc54782bd34d4", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-e7e1a559d524d635", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/utils/gameIntroPrefs.js:1"}, "properties": {"repobilityId": "3a09cfd8305f42c0", "scanner": "scanner-primary", "fingerprint": "e7e1a559d524d635", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-ed20fdc8b35ad23b", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/utils/assets.js:8"}, "properties": {"repobilityId": "23d01b4776a1c913", "scanner": "scanner-primary", "fingerprint": "ed20fdc8b35ad23b", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-c89becc5500857d5", "level": "none", "message": {"text": "Commented-code block (6 lines) in src/utils/storyDifficulty.js:12"}, "properties": {"repobilityId": "e7fc629dac426669", "scanner": "scanner-primary", "fingerprint": "c89becc5500857d5", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-e921f38c9d373fc5", "level": "note", "message": {"text": "Legacy-named symbol `dailyProgress_v1` in src/utils/daily-logic.js:5"}, "properties": {"repobilityId": "051390965b3a8aec", "scanner": "scanner-primary", "fingerprint": "e921f38c9d373fc5", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-c128e8134e76ab61", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/components/LevelUpHost.jsx:1"}, "properties": {"repobilityId": "ea303f5e7b0230c0", "scanner": "scanner-primary", "fingerprint": "c128e8134e76ab61", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-5f85ba3507e72ab7", "level": "none", "message": {"text": "Commented-code block (6 lines) in src/components/LevelUpModal.jsx:1"}, "properties": {"repobilityId": "7eb59f609a057de5", "scanner": "scanner-primary", "fingerprint": "5f85ba3507e72ab7", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-63688481b17543f3", "level": "note", "message": {"text": "Legacy-named symbol `dailyProgress_v1` in src/components/daily/CharactersDaily.jsx:9"}, "properties": {"repobilityId": "e0a2f3c41b72b0e6", "scanner": "scanner-primary", "fingerprint": "63688481b17543f3", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-8b231bd737ecd373", "level": "none", "message": {"text": "Commented-code block (7 lines) in src/components/stories/Avatars.jsx:8"}, "properties": {"repobilityId": "cfe425d1dfbaf0b3", "scanner": "scanner-primary", "fingerprint": "8b231bd737ecd373", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-d365723a5ffd515e", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/components/stories/CharacterDisplay.jsx:1"}, "properties": {"repobilityId": "476d07f9f6079b36", "scanner": "scanner-primary", "fingerprint": "d365723a5ffd515e", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-8bdb6622f6d7e7a4", "level": "none", "message": {"text": "Commented-code block (6 lines) in src/components/stories/DialogueBox.jsx:1"}, "properties": {"repobilityId": "67a6f3684b0e56c6", "scanner": "scanner-primary", "fingerprint": "8bdb6622f6d7e7a4", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-52c81b79ed437dd2", "level": "none", "message": {"text": "Commented-code block (9 lines) in src/components/stories/SceneBackground.jsx:1"}, "properties": {"repobilityId": "ad5b4f506e130a9e", "scanner": "scanner-primary", "fingerprint": "52c81b79ed437dd2", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-7444ace79a9d7080", "level": "none", "message": {"text": "Commented-code block (8 lines) in src/components/minigames/registry.js:1"}, "properties": {"repobilityId": "d8b96143e778bdea", "scanner": "scanner-primary", "fingerprint": "7444ace79a9d7080", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-96ce83a20ce60ada", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/minigames/TranslationGame.jsx:40"}, "properties": {"repobilityId": "355eb03d04f946ae", "scanner": "scanner-primary", "fingerprint": "96ce83a20ce60ada", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-7c1cbcb0d3120d0f", "level": "none", "message": {"text": "Commented-code block (6 lines) in src/lib/firebase.js:1"}, "properties": {"repobilityId": "063efc9c2f507c2e", "scanner": "scanner-primary", "fingerprint": "7c1cbcb0d3120d0f", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-dd3c1a2d1e6b4539", "level": "note", "message": {"text": "Legacy-named symbol `dailyProgress_v1` in src/lib/userStore.js:46"}, "properties": {"repobilityId": "852b246283994cc6", "scanner": "scanner-primary", "fingerprint": "dd3c1a2d1e6b4539", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-f12fdda626a229b2", "level": "note", "message": {"text": "Legacy-named symbol `srs_mode_subtitle_v2` in src/locales/en.js:788"}, "properties": {"repobilityId": "2c8e0380d575f35f", "scanner": "scanner-primary", "fingerprint": "f12fdda626a229b2", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-75077972b3e1e070", "level": "note", "message": {"text": "Legacy-named symbol `srs_mode_subtitle_v2` in src/locales/es.js:793"}, "properties": {"repobilityId": "b2d329fc43314a75", "scanner": "scanner-primary", "fingerprint": "75077972b3e1e070", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-94620a422fd41083", "level": "note", "message": {"text": "Legacy-named symbol `srs_mode_subtitle_v2` in src/locales/pt.js:773"}, "properties": {"repobilityId": "7fea5ee2d9240ca7", "scanner": "scanner-primary", "fingerprint": "94620a422fd41083", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-69a79da82318ca2d", "level": "note", "message": {"text": "Legacy-named symbol `srs_mode_subtitle_v2` in src/locales/it.js:773"}, "properties": {"repobilityId": "1d3b35cdf5317ed4", "scanner": "scanner-primary", "fingerprint": "69a79da82318ca2d", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-797f827ab0d00470", "level": "note", "message": {"text": "Legacy-named symbol `srs_mode_subtitle_v2` in src/locales/fr.js:788"}, "properties": {"repobilityId": "54c4383cef083fd8", "scanner": "scanner-primary", "fingerprint": "797f827ab0d00470", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-c9d6ccb470585de6", "level": "note", "message": {"text": "Legacy-named symbol `srs_mode_subtitle_v2` in src/locales/de.js:392"}, "properties": {"repobilityId": "0c2642c2293a3e4a", "scanner": "scanner-primary", "fingerprint": "c9d6ccb470585de6", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-65c7e70d050b1e04", "level": "none", "message": {"text": "Commented-code block (6 lines) in src/context/AuthContext.jsx:1"}, "properties": {"repobilityId": "139e35b5a9bc985d", "scanner": "scanner-primary", "fingerprint": "65c7e70d050b1e04", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-319e66a630e14977", "level": "none", "message": {"text": "2 env vars used in code but missing from .env.example"}, "properties": {"repobilityId": "d838d1fc5d8231c9", "scanner": "scanner-primary", "fingerprint": "319e66a630e14977", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "config-drift"]}}]}]}