{"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-2cec1a40b72e7f5a", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/app/components/AlertsFeed.tsx:130", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/app/components/AlertsFeed.tsx:130"}, "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-41b5b85108942621", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/app/components/PerfectSetupPanel.tsx:64", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/app/components/PerfectSetupPanel.tsx:64"}, "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-1ad2359eba443296", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/app/components/StrategyPanel.tsx:352", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/app/components/StrategyPanel.tsx:352"}, "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-0b41d202825ef984", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/app/components/OrderFlowPanel.tsx:311", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/app/components/OrderFlowPanel.tsx:311"}, "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-95acca98f9eae516", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/app/components/layout/CollapsibleZone.tsx:125", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/app/components/layout/CollapsibleZone.tsx:125"}, "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-c7792d802c9d45d0", "name": "Privileged port 1000 in use", "shortDescription": {"text": "Privileged port 1000 in use"}, "fullDescription": {"text": "Port 1000 is privileged (<1024). Make sure the service runs with the right caps or front it with a non-privileged port via a load balancer."}, "properties": {"scanner": "scanner-primary", "layer": "network", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-2803fc8c698c51da", "name": "Privileged port 23 in use", "shortDescription": {"text": "Privileged port 23 in use"}, "fullDescription": {"text": "Port 23 is privileged (<1024). Make sure the service runs with the right caps or front it with a non-privileged port via a load balancer."}, "properties": {"scanner": "scanner-primary", "layer": "network", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-eb97324a5d23465c", "name": "Privileged port 45 in use", "shortDescription": {"text": "Privileged port 45 in use"}, "fullDescription": {"text": "Port 45 is privileged (<1024). Make sure the service runs with the right caps or front it with a non-privileged port via a load balancer."}, "properties": {"scanner": "scanner-primary", "layer": "network", "severity": "medium", "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-1d3b59b4fdc509d8", "name": "Docker base image is tag-pinned but not digest-pinned: eclipse-temurin:21-jdk-alpine", "shortDescription": {"text": "Docker base image is tag-pinned but not digest-pinned: eclipse-temurin:21-jdk-alpine"}, "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-b6f9f00ae20c8b2a", "name": "Docker base image is tag-pinned but not digest-pinned: eclipse-temurin:21-jre-alpine", "shortDescription": {"text": "Docker base image is tag-pinned but not digest-pinned: eclipse-temurin:21-jre-alpine"}, "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-042b3183f25da3f0", "name": "Docker base image is tag-pinned but not digest-pinned: node:20-bookworm-slim", "shortDescription": {"text": "Docker base image is tag-pinned but not digest-pinned: node:20-bookworm-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-aa5acaa49eb8315b", "name": "Containers defined but no K8s/orchestration manifest found", "shortDescription": {"text": "Containers defined but no K8s/orchestration manifest found"}, "fullDescription": {"text": "Repo has Dockerfiles/compose but no Kubernetes/Nomad manifests. If the target deployment is K8s, the manifests may live in a separate ops repo."}, "properties": {"scanner": "scanner-primary", "layer": "hardware", "severity": "low", "confidence": 1.0}}, {"id": "scanner-6372cebde0220094", "name": "No auth library detected", "shortDescription": {"text": "No auth library detected"}, "fullDescription": {"text": "The scanner did not find any standard auth library (JWT, OAuth, NextAuth, Auth0, etc.). The repo has auth/admin/session surface indicators, so auth may live in custom code, in a separate service, or be missing."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-fb5499c7d427188f", "name": "GitHub Action is tag-pinned rather than SHA-pinned", "shortDescription": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "fullDescription": {"text": "actions/download-artifact@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-140a18765640d799", "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-71795b8805794525", "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-28c4a04bd807da0c", "name": "GitHub Action is tag-pinned rather than SHA-pinned", "shortDescription": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "fullDescription": {"text": "actions/upload-artifact@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-ad6701f0a8405e22", "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-6ba9bfab5f283202", "name": "GitHub Action is tag-pinned rather than SHA-pinned", "shortDescription": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "fullDescription": {"text": "actions/cache@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-cc593ce1ac07958f", "name": "Very large file: frontend/app/lib/api.ts (2290 lines)", "shortDescription": {"text": "Very large file: frontend/app/lib/api.ts (2290 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-1767df28daf201c0", "name": "Very large file: src/test/java/com/riskdesk/application/execution/DefaultOrderRouterTest.java (1334 lines)", "shortDescription": {"text": "Very large file: src/test/java/com/riskdesk/application/execution/DefaultOrderRouterTest.java (1334 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-1ecf962e9df6ba72", "name": "Very large file: src/test/java/com/riskdesk/application/service/strategy/WtxExecutionBridgeTest.java (1618 lines)", "shortDescription": {"text": "Very large file: src/test/java/com/riskdesk/application/service/strategy/WtxExecutionBridgeTest.java (1618 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-2ddc48d74a104666", "name": "Very large file: src/main/java/com/riskdesk/infrastructure/marketdata/ibkr/IbGatewayNativeClient.java (2397 lines)", "shortDescription": {"text": "Very large file: src/main/java/com/riskdesk/infrastructure/marketdata/ibkr/IbGatewayNativeClient.java (2397 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-1c70ab2666856584", "name": "Very large file: src/main/java/com/riskdesk/application/execution/DefaultOrderRouter.java (992 lines)", "shortDescription": {"text": "Very large file: src/main/java/com/riskdesk/application/execution/DefaultOrderRouter.java (992 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-d03a5c6a0ebc3e9c", "name": "Very large file: src/main/java/com/riskdesk/application/service/OrderFlowOrchestrator.java (1717 lines)", "shortDescription": {"text": "Very large file: src/main/java/com/riskdesk/application/service/OrderFlowOrchestrator.java (1717 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-42ff47ded277f009", "name": "Very large file: src/main/java/com/riskdesk/application/service/MentorSignalReviewService.java (1962 lines)", "shortDescription": {"text": "Very large file: src/main/java/com/riskdesk/application/service/MentorSignalReviewService.java (1962 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-e52811d884317905", "name": "Very large file: src/main/java/com/riskdesk/application/service/strategy/WtxStrategyService.java (1047 lines)", "shortDescription": {"text": "Very large file: src/main/java/com/riskdesk/application/service/strategy/WtxStrategyService.java (1047 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-008f19b9f8c1bff0", "name": "Very large file: src/main/java/com/riskdesk/application/service/strategy/WtxExecutionBridge.java (1347 lines)", "shortDescription": {"text": "Very large file: src/main/java/com/riskdesk/application/service/strategy/WtxExecutionBridge.java (1347 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-ea3b5e389d8c9c0f", "name": "Low test-to-source ratio", "shortDescription": {"text": "Low test-to-source ratio"}, "fullDescription": {"text": "12 tests / 70 src (ratio 0.17)."}, "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-72b2a6250083a784", "name": "Placeholder or mock-heavy implementation detected", "shortDescription": {"text": "Placeholder or mock-heavy implementation detected"}, "fullDescription": {"text": "Found 40 placeholder/mock markers across 22 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-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. 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-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-68668c0ecdd87d9d", "name": "Commented-code block (5 lines) in frontend/app/components/WtxStrategyPanel.tsx:156", "shortDescription": {"text": "Commented-code block (5 lines) in frontend/app/components/WtxStrategyPanel.tsx:156"}, "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-26e67e0388713a67", "name": "Commented-code block (6 lines) in frontend/app/components/Dashboard.tsx:133", "shortDescription": {"text": "Commented-code block (6 lines) in frontend/app/components/Dashboard.tsx:133"}, "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-b0ceb9e5fef1b12f", "name": "Commented-code block (5 lines) in frontend/app/components/TickChart.tsx:206", "shortDescription": {"text": "Commented-code block (5 lines) in frontend/app/components/TickChart.tsx:206"}, "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-6369885c762d2156", "name": "Commented-code block (5 lines) in frontend/app/components/OrderFlowPanel.tsx:820", "shortDescription": {"text": "Commented-code block (5 lines) in frontend/app/components/OrderFlowPanel.tsx:820"}, "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-68f6ffa42c0f0fec", "name": "Commented-code block (6 lines) in frontend/app/components/quant/Quant7GatesSimulationPanel.tsx:30", "shortDescription": {"text": "Commented-code block (6 lines) in frontend/app/components/quant/Quant7GatesSimulationPanel.tsx:30"}, "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-c729cecaa5558831", "name": "Commented-code block (8 lines) in frontend/app/lib/api.ts:1324", "shortDescription": {"text": "Commented-code block (8 lines) in frontend/app/lib/api.ts:1324"}, "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-e0cbdfdc0c9fc4fd", "name": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/app/lib/api.ts:271", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/app/lib/api.ts:271"}, "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-e594977230ee0816", "name": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/app/hooks/useRollover.ts:91", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/app/hooks/useRollover.ts:91"}, "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-7b8b81c1de4c62f6", "name": "Commented-code block (5 lines) in frontend/app/hooks/useOrderFlow.ts:398", "shortDescription": {"text": "Commented-code block (5 lines) in frontend/app/hooks/useOrderFlow.ts:398"}, "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-1b5a76780c3df9aa", "name": "1 env vars used in code but missing from .env.example", "shortDescription": {"text": "1 env vars used in code but missing from .env.example"}, "fullDescription": {"text": "Drift between code and config docs. The first few: `RISKDESK_DB_URL`. 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}}, {"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:\nauto_trader/auto_trader/live/ibkr_client.py:connection_from_env, auto_trader/auto_trader/live/ibkr_client.py:connect\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}}]}}, "automationDetails": {"id": "repobility/19874"}, "properties": {"repository": "SmailNilson/riskdesk2", "repoUrl": "https://github.com/SmailNilson/riskdesk2", "branch": "main"}, "results": [{"ruleId": "scanner-2cec1a40b72e7f5a", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/app/components/AlertsFeed.tsx:130"}, "properties": {"repobilityId": "1864ff61b71f48a5", "scanner": "scanner-primary", "fingerprint": "2cec1a40b72e7f5a", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-41b5b85108942621", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/app/components/PerfectSetupPanel.tsx:64"}, "properties": {"repobilityId": "a90c286bc3b46a2b", "scanner": "scanner-primary", "fingerprint": "41b5b85108942621", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-1ad2359eba443296", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/app/components/StrategyPanel.tsx:352"}, "properties": {"repobilityId": "5f90336b60188584", "scanner": "scanner-primary", "fingerprint": "1ad2359eba443296", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-0b41d202825ef984", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/app/components/OrderFlowPanel.tsx:311"}, "properties": {"repobilityId": "a813c87ea7b88ead", "scanner": "scanner-primary", "fingerprint": "0b41d202825ef984", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-95acca98f9eae516", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/app/components/layout/CollapsibleZone.tsx:125"}, "properties": {"repobilityId": "f2dc579b7202e87b", "scanner": "scanner-primary", "fingerprint": "95acca98f9eae516", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-c7792d802c9d45d0", "level": "warning", "message": {"text": "Privileged port 1000 in use"}, "properties": {"repobilityId": "5ac9fc9372cfe169", "scanner": "scanner-primary", "fingerprint": "c7792d802c9d45d0", "layer": "network", "severity": "medium", "confidence": 1.0, "tags": ["security", "ports"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "infra/gcp/refresh-runtime-on-vm.sh"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-2803fc8c698c51da", "level": "warning", "message": {"text": "Privileged port 23 in use"}, "properties": {"repobilityId": "a1230e3dfc4becfa", "scanner": "scanner-primary", "fingerprint": "2803fc8c698c51da", "layer": "network", "severity": "medium", "confidence": 1.0, "tags": ["security", "ports"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "infra/gcp/render-secrets-env.sh"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-eb97324a5d23465c", "level": "warning", "message": {"text": "Privileged port 45 in use"}, "properties": {"repobilityId": "73cf64d92574d41c", "scanner": "scanner-primary", "fingerprint": "eb97324a5d23465c", "layer": "network", "severity": "medium", "confidence": 1.0, "tags": ["security", "ports"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "infra/gcp/render-secrets-env.sh"}, "region": {"startLine": 1}}}]}, {"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-1d3b59b4fdc509d8", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: eclipse-temurin:21-jdk-alpine"}, "properties": {"repobilityId": "a2c2c15669e636f7", "scanner": "scanner-primary", "fingerprint": "1d3b59b4fdc509d8", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Dockerfile"}, "region": {"startLine": 7}}}]}, {"ruleId": "scanner-b6f9f00ae20c8b2a", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: eclipse-temurin:21-jre-alpine"}, "properties": {"repobilityId": "46a5c4b4236ae5ed", "scanner": "scanner-primary", "fingerprint": "b6f9f00ae20c8b2a", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Dockerfile"}, "region": {"startLine": 21}}}]}, {"ruleId": "scanner-042b3183f25da3f0", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: node:20-bookworm-slim"}, "properties": {"repobilityId": "56926f1ec1316d52", "scanner": "scanner-primary", "fingerprint": "042b3183f25da3f0", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/Dockerfile"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-042b3183f25da3f0", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: node:20-bookworm-slim"}, "properties": {"repobilityId": "b2c3f9aaffbbaa19", "scanner": "scanner-primary", "fingerprint": "042b3183f25da3f0", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/Dockerfile"}, "region": {"startLine": 7}}}]}, {"ruleId": "scanner-042b3183f25da3f0", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: node:20-bookworm-slim"}, "properties": {"repobilityId": "fada2f08833ee077", "scanner": "scanner-primary", "fingerprint": "042b3183f25da3f0", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/Dockerfile"}, "region": {"startLine": 24}}}]}, {"ruleId": "scanner-aa5acaa49eb8315b", "level": "note", "message": {"text": "Containers defined but no K8s/orchestration manifest found"}, "properties": {"repobilityId": "b230ea9b68736081", "scanner": "scanner-primary", "fingerprint": "aa5acaa49eb8315b", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["coverage", "deployment"]}}, {"ruleId": "scanner-6372cebde0220094", "level": "warning", "message": {"text": "No auth library detected"}, "properties": {"repobilityId": "a5b6035a5bbf8054", "scanner": "scanner-primary", "fingerprint": "6372cebde0220094", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["coverage", "auth"]}}, {"ruleId": "scanner-fb5499c7d427188f", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "a7d0ece9d5b1d629", "scanner": "scanner-primary", "fingerprint": "fb5499c7d427188f", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/tag-and-deploy.yml"}, "region": {"startLine": 151}}}]}, {"ruleId": "scanner-fb5499c7d427188f", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "1866fadcf3a5adf6", "scanner": "scanner-primary", "fingerprint": "fb5499c7d427188f", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/tag-and-deploy.yml"}, "region": {"startLine": 211}}}]}, {"ruleId": "scanner-140a18765640d799", "level": "warning", "message": {"text": "GitHub Actions workflow grants broad write permissions"}, "properties": {"repobilityId": "6a207556a196e01c", "scanner": "scanner-primary", "fingerprint": "140a18765640d799", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "least-privilege"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/tag-and-deploy.yml"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-71795b8805794525", "level": "warning", "message": {"text": "GitHub Actions workflow grants broad write permissions"}, "properties": {"repobilityId": "d1cb53cbf4b6ea2c", "scanner": "scanner-primary", "fingerprint": "71795b8805794525", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "least-privilege"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/deploy-only.yml"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-28c4a04bd807da0c", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "253c1285516d15dc", "scanner": "scanner-primary", "fingerprint": "28c4a04bd807da0c", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/deploy.yml"}, "region": {"startLine": 41}}}]}, {"ruleId": "scanner-28c4a04bd807da0c", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "2d1c807dcf85dd93", "scanner": "scanner-primary", "fingerprint": "28c4a04bd807da0c", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/deploy.yml"}, "region": {"startLine": 85}}}]}, {"ruleId": "scanner-28c4a04bd807da0c", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "a996444fe9d8260b", "scanner": "scanner-primary", "fingerprint": "28c4a04bd807da0c", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/deploy.yml"}, "region": {"startLine": 141}}}]}, {"ruleId": "scanner-ad6701f0a8405e22", "level": "warning", "message": {"text": "GitHub Actions workflow grants broad write permissions"}, "properties": {"repobilityId": "8384c23520d55657", "scanner": "scanner-primary", "fingerprint": "ad6701f0a8405e22", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "least-privilege"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/deploy.yml"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-6ba9bfab5f283202", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "18a7e8b29eb8f70d", "scanner": "scanner-primary", "fingerprint": "6ba9bfab5f283202", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/build.yml"}, "region": {"startLine": 44}}}]}, {"ruleId": "scanner-cc593ce1ac07958f", "level": "note", "message": {"text": "Very large file: frontend/app/lib/api.ts (2290 lines)"}, "properties": {"repobilityId": "4164482c04407387", "scanner": "scanner-primary", "fingerprint": "cc593ce1ac07958f", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-1767df28daf201c0", "level": "note", "message": {"text": "Very large file: src/test/java/com/riskdesk/application/execution/DefaultOrderRouterTest.java (1334 lines)"}, "properties": {"repobilityId": "ee1501720ce0bf3a", "scanner": "scanner-primary", "fingerprint": "1767df28daf201c0", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-1ecf962e9df6ba72", "level": "note", "message": {"text": "Very large file: src/test/java/com/riskdesk/application/service/strategy/WtxExecutionBridgeTest.java (1618 lines)"}, "properties": {"repobilityId": "bc17fc26cc5e28ce", "scanner": "scanner-primary", "fingerprint": "1ecf962e9df6ba72", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-2ddc48d74a104666", "level": "note", "message": {"text": "Very large file: src/main/java/com/riskdesk/infrastructure/marketdata/ibkr/IbGatewayNativeClient.java (2397 lines)"}, "properties": {"repobilityId": "d4153dd4f6e5070b", "scanner": "scanner-primary", "fingerprint": "2ddc48d74a104666", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-1c70ab2666856584", "level": "note", "message": {"text": "Very large file: src/main/java/com/riskdesk/application/execution/DefaultOrderRouter.java (992 lines)"}, "properties": {"repobilityId": "bb9b3da7682d3e97", "scanner": "scanner-primary", "fingerprint": "1c70ab2666856584", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-d03a5c6a0ebc3e9c", "level": "note", "message": {"text": "Very large file: src/main/java/com/riskdesk/application/service/OrderFlowOrchestrator.java (1717 lines)"}, "properties": {"repobilityId": "9dc06f970d8482b2", "scanner": "scanner-primary", "fingerprint": "d03a5c6a0ebc3e9c", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-42ff47ded277f009", "level": "note", "message": {"text": "Very large file: src/main/java/com/riskdesk/application/service/MentorSignalReviewService.java (1962 lines)"}, "properties": {"repobilityId": "cf9b7c64d1575245", "scanner": "scanner-primary", "fingerprint": "42ff47ded277f009", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-e52811d884317905", "level": "note", "message": {"text": "Very large file: src/main/java/com/riskdesk/application/service/strategy/WtxStrategyService.java (1047 lines)"}, "properties": {"repobilityId": "cb9154845e06038b", "scanner": "scanner-primary", "fingerprint": "e52811d884317905", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-008f19b9f8c1bff0", "level": "note", "message": {"text": "Very large file: src/main/java/com/riskdesk/application/service/strategy/WtxExecutionBridge.java (1347 lines)"}, "properties": {"repobilityId": "e2830f925c68df1d", "scanner": "scanner-primary", "fingerprint": "008f19b9f8c1bff0", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-ea3b5e389d8c9c0f", "level": "note", "message": {"text": "Low test-to-source ratio"}, "properties": {"repobilityId": "ef7b2552cc00a375", "scanner": "scanner-primary", "fingerprint": "ea3b5e389d8c9c0f", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["tests"]}}, {"ruleId": "scanner-141b30a41e03817b", "level": "note", "message": {"text": "No license file detected"}, "properties": {"repobilityId": "d350003f9402bc72", "scanner": "scanner-primary", "fingerprint": "141b30a41e03817b", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["license", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-72b2a6250083a784", "level": "warning", "message": {"text": "Placeholder or mock-heavy implementation detected"}, "properties": {"repobilityId": "927bd154d7c15e1d", "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": "37388c562597f4bc", "scanner": "scanner-primary", "fingerprint": "2d0c7b7ab8f8aacf", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "critical-flow", "generated-repo-pattern"]}}, {"ruleId": "scanner-749d4bc1bd66df5f", "level": "warning", "message": {"text": "Agent instructions exist but release-hardening basics are missing"}, "properties": {"repobilityId": "1016827a3efc0d5a", "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": "005939c7ed95db6f", "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": "c2ec7453f9ee5187", "scanner": "scanner-primary", "fingerprint": "8424db9c75e04ba4", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["provenance", "git-history", "generated-repo-pattern"]}}, {"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-68668c0ecdd87d9d", "level": "none", "message": {"text": "Commented-code block (5 lines) in frontend/app/components/WtxStrategyPanel.tsx:156"}, "properties": {"repobilityId": "316d306a782dd73d", "scanner": "scanner-primary", "fingerprint": "68668c0ecdd87d9d", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-26e67e0388713a67", "level": "none", "message": {"text": "Commented-code block (6 lines) in frontend/app/components/Dashboard.tsx:133"}, "properties": {"repobilityId": "ab18e2c6abe90c75", "scanner": "scanner-primary", "fingerprint": "26e67e0388713a67", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-b0ceb9e5fef1b12f", "level": "none", "message": {"text": "Commented-code block (5 lines) in frontend/app/components/TickChart.tsx:206"}, "properties": {"repobilityId": "5a23ecdf7d01b687", "scanner": "scanner-primary", "fingerprint": "b0ceb9e5fef1b12f", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-6369885c762d2156", "level": "none", "message": {"text": "Commented-code block (5 lines) in frontend/app/components/OrderFlowPanel.tsx:820"}, "properties": {"repobilityId": "c091156cd29110a5", "scanner": "scanner-primary", "fingerprint": "6369885c762d2156", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-68f6ffa42c0f0fec", "level": "none", "message": {"text": "Commented-code block (6 lines) in frontend/app/components/quant/Quant7GatesSimulationPanel.tsx:30"}, "properties": {"repobilityId": "9260b00a0ffff618", "scanner": "scanner-primary", "fingerprint": "68f6ffa42c0f0fec", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-c729cecaa5558831", "level": "none", "message": {"text": "Commented-code block (8 lines) in frontend/app/lib/api.ts:1324"}, "properties": {"repobilityId": "c26931f11bc0e9c6", "scanner": "scanner-primary", "fingerprint": "c729cecaa5558831", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-e0cbdfdc0c9fc4fd", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/app/lib/api.ts:271"}, "properties": {"repobilityId": "79ab04ab6b67263a", "scanner": "scanner-primary", "fingerprint": "e0cbdfdc0c9fc4fd", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-e594977230ee0816", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/app/hooks/useRollover.ts:91"}, "properties": {"repobilityId": "f2f88c4979664838", "scanner": "scanner-primary", "fingerprint": "e594977230ee0816", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-7b8b81c1de4c62f6", "level": "none", "message": {"text": "Commented-code block (5 lines) in frontend/app/hooks/useOrderFlow.ts:398"}, "properties": {"repobilityId": "a04c1231a9e79a59", "scanner": "scanner-primary", "fingerprint": "7b8b81c1de4c62f6", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-1b5a76780c3df9aa", "level": "none", "message": {"text": "1 env vars used in code but missing from .env.example"}, "properties": {"repobilityId": "d04379b337b44a15", "scanner": "scanner-primary", "fingerprint": "1b5a76780c3df9aa", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "config-drift"]}}, {"ruleId": "scanner-2c04133e54348533", "level": "note", "message": {"text": "Near-duplicate function bodies in 2 places"}, "properties": {"repobilityId": "29b1976563173d70", "scanner": "scanner-primary", "fingerprint": "2c04133e54348533", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "duplicate", "dry"]}}]}]}