{"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-bead75b0f9233e05", "name": "No API endpoints detected", "shortDescription": {"text": "No API endpoints detected"}, "fullDescription": {"text": "The scanner did not find FastAPI/Flask/Express/NestJS/GraphQL/gRPC routes. If this repo exposes APIs, the framework may be unsupported."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "info", "confidence": 1.0}}, {"id": "scanner-b2e2c4fa6954398c", "name": "Stray `console.log` in TS/JS \u2014 backend/src/scripts/postBuild.js:28", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/src/scripts/postBuild.js:28"}, "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-33844929fecb3704", "name": "TODO/FIXME marker in shipping code \u2014 storefront/check-env-variables.js:6", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 storefront/check-env-variables.js:6"}, "fullDescription": {"text": "Track in /reviews or /issues, not as a code comment that rots.\n\nWhy: Drift control \u2014 shouldn't be the same as Quality TODO scanner.\nRule id: fq.todo-marker"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-a8c093bb85d4fb6f", "name": "TODO/FIXME marker in shipping code \u2014 storefront/src/modules/layout/components/cart-dropdown/index.tsx:46", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 storefront/src/modules/layout/components/cart-dropdown/index.tsx:46"}, "fullDescription": {"text": "Track in /reviews or /issues, not as a code comment that rots.\n\nWhy: Drift control \u2014 shouldn't be the same as Quality TODO scanner.\nRule id: fq.todo-marker"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-efbe46e1f8c533e3", "name": "TODO/FIXME marker in shipping code \u2014 storefront/src/modules/cart/components/item/index.tsx:45", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 storefront/src/modules/cart/components/item/index.tsx:45"}, "fullDescription": {"text": "Track in /reviews or /issues, not as a code comment that rots.\n\nWhy: Drift control \u2014 shouldn't be the same as Quality TODO scanner.\nRule id: fq.todo-marker"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-64722fd19afd6aad", "name": "`truncate` class without `title=` for hover reveal \u2014 storefront/src/modules/search/components/hit/index.tsx:46", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 storefront/src/modules/search/components/hit/index.tsx:46"}, "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-49c933731ad6bf35", "name": "TODO/FIXME marker in shipping code \u2014 storefront/src/modules/account/components/profile-email/index.tsx:19", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 storefront/src/modules/account/components/profile-email/index.tsx:19"}, "fullDescription": {"text": "Track in /reviews or /issues, not as a code comment that rots.\n\nWhy: Drift control \u2014 shouldn't be the same as Quality TODO scanner.\nRule id: fq.todo-marker"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-4cf7d752e3f1ba84", "name": "TODO/FIXME marker in shipping code \u2014 storefront/src/modules/account/components/profile-password/index.tsx:18", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 storefront/src/modules/account/components/profile-password/index.tsx:18"}, "fullDescription": {"text": "Track in /reviews or /issues, not as a code comment that rots.\n\nWhy: Drift control \u2014 shouldn't be the same as Quality TODO scanner.\nRule id: fq.todo-marker"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-3839671dde4e5dfb", "name": "TODO/FIXME marker in shipping code \u2014 storefront/src/modules/products/components/thumbnail/index.tsx:9", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 storefront/src/modules/products/components/thumbnail/index.tsx:9"}, "fullDescription": {"text": "Track in /reviews or /issues, not as a code comment that rots.\n\nWhy: Drift control \u2014 shouldn't be the same as Quality TODO scanner.\nRule id: fq.todo-marker"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-0f13ed5c704c8a41", "name": "`truncate` class without `title=` for hover reveal \u2014 storefront/src/modules/products/components/product-actions/mobile-a", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 storefront/src/modules/products/components/product-actions/mobile-actions.tsx:106"}, "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-4ad34f4cb40bc827", "name": "TODO/FIXME marker in shipping code \u2014 storefront/src/modules/checkout/components/payment-button/index.tsx:30", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 storefront/src/modules/checkout/components/payment-button/index.tsx:30"}, "fullDescription": {"text": "Track in /reviews or /issues, not as a code comment that rots.\n\nWhy: Drift control \u2014 shouldn't be the same as Quality TODO scanner.\nRule id: fq.todo-marker"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-653ce898d505cd20", "name": "`truncate` class without `title=` for hover reveal \u2014 storefront/src/modules/checkout/components/discount-code/index.tsx:", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 storefront/src/modules/checkout/components/discount-code/index.tsx:116"}, "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-cbd24efe98659f26", "name": "`truncate` class without `title=` for hover reveal \u2014 storefront/src/modules/checkout/components/address-select/index.tsx", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 storefront/src/modules/checkout/components/address-select/index.tsx:44"}, "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-181c4aff5fd85ba9", "name": "Insecure pattern 'node_child_process' in backend/src/scripts/postBuild.js:2", "shortDescription": {"text": "Insecure pattern 'node_child_process' in backend/src/scripts/postBuild.js:2"}, "fullDescription": {"text": "Found a known-risky pattern (node_child_process). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-3e77c6e65dc9e2b8", "name": "GitHub Action is tag-pinned rather than SHA-pinned", "shortDescription": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "fullDescription": {"text": "actions/setup-node@v3 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-6893a6c8b0861585", "name": "Very low test-to-source ratio", "shortDescription": {"text": "Very low test-to-source ratio"}, "fullDescription": {"text": "16 test file(s) for 295 source file(s) (ratio 0.05). Consider adding integration or unit tests for critical paths."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-72b2a6250083a784", "name": "Placeholder or mock-heavy implementation detected", "shortDescription": {"text": "Placeholder or mock-heavy implementation detected"}, "fullDescription": {"text": "Found 33 placeholder/mock markers across 15 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-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-5b91b90efd3004af", "name": "`fetch()` without try/.catch or AbortSignal \u2014 backend/src/scripts/import-woocommerce-catalog.ts:312", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 backend/src/scripts/import-woocommerce-catalog.ts:312"}, "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-38b28a13c00dd92a", "name": "`fetch()` without try/.catch or AbortSignal \u2014 backend/src/modules/email-notifications/services/brevo.ts:171", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 backend/src/modules/email-notifications/services/brevo.ts:171"}, "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-d74c50a6050ad6bb", "name": "Legacy-named symbol `hero__copy` in storefront/src/modules/home/components/hero/hero-copy.tsx:18", "shortDescription": {"text": "Legacy-named symbol `hero__copy` in storefront/src/modules/home/components/hero/hero-copy.tsx: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-bddda3d5a14c7401", "name": "29 env vars used in code but missing from .env.example", "shortDescription": {"text": "29 env vars used in code but missing from .env.example"}, "fullDescription": {"text": "Drift between code and config docs. The first few: `BACKEND_PUBLIC_URL`, `BREVO_FROM`, `CI`, `DEFAULT_REGION`, `MEDUSA_DISABLE_ADMIN`, `MEDUSA_WORKER_MODE`, `MEILISEARCH_ADMIN_KEY`, `MEILISEARCH_API_KEY` + 21 more. Add them (with a placeholder/comment) to .env.example so onboarding doesn't break."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}]}}, "automationDetails": {"id": "repobility/18348"}, "properties": {"repository": "rockyalb/medusajs-2.0-for-railway-boilerplate", "repoUrl": "https://github.com/rockyalb/medusajs-2.0-for-railway-boilerplate", "branch": "main"}, "results": [{"ruleId": "scanner-bead75b0f9233e05", "level": "none", "message": {"text": "No API endpoints detected"}, "properties": {"repobilityId": "0f8bb852027c38f8", "scanner": "scanner-primary", "fingerprint": "bead75b0f9233e05", "layer": "api", "severity": "info", "confidence": 1.0, "tags": ["coverage"]}}, {"ruleId": "scanner-b2e2c4fa6954398c", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/src/scripts/postBuild.js:28"}, "properties": {"repobilityId": "b5f4a28c51e099a4", "scanner": "scanner-primary", "fingerprint": "b2e2c4fa6954398c", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-33844929fecb3704", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 storefront/check-env-variables.js:6"}, "properties": {"repobilityId": "05a4966da46065ef", "scanner": "scanner-primary", "fingerprint": "33844929fecb3704", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-a8c093bb85d4fb6f", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 storefront/src/modules/layout/components/cart-dropdown/index.tsx:46"}, "properties": {"repobilityId": "d76fba60762200b4", "scanner": "scanner-primary", "fingerprint": "a8c093bb85d4fb6f", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-efbe46e1f8c533e3", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 storefront/src/modules/cart/components/item/index.tsx:45"}, "properties": {"repobilityId": "112733384e3ba4b2", "scanner": "scanner-primary", "fingerprint": "efbe46e1f8c533e3", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-64722fd19afd6aad", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 storefront/src/modules/search/components/hit/index.tsx:46"}, "properties": {"repobilityId": "ddff16aab8d9163a", "scanner": "scanner-primary", "fingerprint": "64722fd19afd6aad", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-49c933731ad6bf35", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 storefront/src/modules/account/components/profile-email/index.tsx:19"}, "properties": {"repobilityId": "42e92f2d9889e95e", "scanner": "scanner-primary", "fingerprint": "49c933731ad6bf35", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-4cf7d752e3f1ba84", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 storefront/src/modules/account/components/profile-password/index.tsx:18"}, "properties": {"repobilityId": "a89497173227e447", "scanner": "scanner-primary", "fingerprint": "4cf7d752e3f1ba84", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-3839671dde4e5dfb", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 storefront/src/modules/products/components/thumbnail/index.tsx:9"}, "properties": {"repobilityId": "72c989abe594f980", "scanner": "scanner-primary", "fingerprint": "3839671dde4e5dfb", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-0f13ed5c704c8a41", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 storefront/src/modules/products/components/product-actions/mobile-actions.tsx:106"}, "properties": {"repobilityId": "7ae23477a342170d", "scanner": "scanner-primary", "fingerprint": "0f13ed5c704c8a41", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-4ad34f4cb40bc827", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 storefront/src/modules/checkout/components/payment-button/index.tsx:30"}, "properties": {"repobilityId": "0818577cd86d4fe6", "scanner": "scanner-primary", "fingerprint": "4ad34f4cb40bc827", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-653ce898d505cd20", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 storefront/src/modules/checkout/components/discount-code/index.tsx:116"}, "properties": {"repobilityId": "d5f3ebafbf7b26a2", "scanner": "scanner-primary", "fingerprint": "653ce898d505cd20", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-cbd24efe98659f26", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 storefront/src/modules/checkout/components/address-select/index.tsx:44"}, "properties": {"repobilityId": "eaf718d549c82d93", "scanner": "scanner-primary", "fingerprint": "cbd24efe98659f26", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-181c4aff5fd85ba9", "level": "warning", "message": {"text": "Insecure pattern 'node_child_process' in backend/src/scripts/postBuild.js:2"}, "properties": {"repobilityId": "bc93ac471b7c5a79", "scanner": "scanner-primary", "fingerprint": "181c4aff5fd85ba9", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "node_child_process"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/src/scripts/postBuild.js"}, "region": {"startLine": 2}}}]}, {"ruleId": "scanner-3e77c6e65dc9e2b8", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "c24538e653a9df3e", "scanner": "scanner-primary", "fingerprint": "3e77c6e65dc9e2b8", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "storefront/.github/workflows/test-e2e.yaml"}, "region": {"startLine": 89}}}]}, {"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-72b2a6250083a784", "level": "warning", "message": {"text": "Placeholder or mock-heavy implementation detected"}, "properties": {"repobilityId": "236562e151ed5aa4", "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": "35632979d8beede4", "scanner": "scanner-primary", "fingerprint": "2d0c7b7ab8f8aacf", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "critical-flow", "generated-repo-pattern"]}}, {"ruleId": "scanner-ea8f3013f588db25", "level": "note", "message": {"text": "Shallow git history limits provenance confidence"}, "properties": {"repobilityId": "d7c790b8096b90a7", "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": "3b72e7d1fbff25b3", "scanner": "scanner-primary", "fingerprint": "8424db9c75e04ba4", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["provenance", "git-history", "generated-repo-pattern"]}}, {"ruleId": "scanner-5b91b90efd3004af", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 backend/src/scripts/import-woocommerce-catalog.ts:312"}, "properties": {"repobilityId": "484f83ac748e32c7", "scanner": "scanner-primary", "fingerprint": "5b91b90efd3004af", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-38b28a13c00dd92a", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 backend/src/modules/email-notifications/services/brevo.ts:171"}, "properties": {"repobilityId": "fb798800209e2c16", "scanner": "scanner-primary", "fingerprint": "38b28a13c00dd92a", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-d74c50a6050ad6bb", "level": "note", "message": {"text": "Legacy-named symbol `hero__copy` in storefront/src/modules/home/components/hero/hero-copy.tsx:18"}, "properties": {"repobilityId": "a6f7e55de27f6f5a", "scanner": "scanner-primary", "fingerprint": "d74c50a6050ad6bb", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-bddda3d5a14c7401", "level": "note", "message": {"text": "29 env vars used in code but missing from .env.example"}, "properties": {"repobilityId": "3519a6b4ac1d4f19", "scanner": "scanner-primary", "fingerprint": "bddda3d5a14c7401", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "config-drift"]}}]}]}