{"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-3662b6cc4926d129", "name": "Stray `console.log` in TS/JS \u2014 smoke/phase0-live-ports/index.js:88", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 smoke/phase0-live-ports/index.js:88"}, "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-332d39e2f6713bf3", "name": "Stray `console.log` in TS/JS \u2014 server/scripts/set-user-model.ts:18", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 server/scripts/set-user-model.ts:18"}, "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-bda502fac3312792", "name": "Stray `console.log` in TS/JS \u2014 server/scripts/repro-agent.ts:42", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 server/scripts/repro-agent.ts:42"}, "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-e69a21647cf4a822", "name": "Stray `console.log` in TS/JS \u2014 server/src/publish.test.ts:50", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 server/src/publish.test.ts:50"}, "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-edf3cfbabf058373", "name": "Stray `console.log` in TS/JS \u2014 server/src/index.ts:37", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 server/src/index.ts:37"}, "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-e2a37af2b0e513f0", "name": "Stray `console.log` in TS/JS \u2014 server/src/prompt.test.ts:40", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 server/src/prompt.test.ts:40"}, "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-40857ec3f33a23e8", "name": "Stray `console.log` in TS/JS \u2014 src/zip.test.ts:16", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/zip.test.ts:16"}, "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-a63426e7e80a36d6", "name": "Stray `console.log` in TS/JS \u2014 src/templates.ts:333", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/templates.ts:333"}, "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-d15fa39f7d9f287a", "name": "Stray `console.log` in TS/JS \u2014 src/templates.test.ts:52", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/templates.test.ts:52"}, "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-17c7f6358868b9b4", "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-f2b16030c0d8121a", "name": "Docker base image is tag-pinned but not digest-pinned: node:20-alpine", "shortDescription": {"text": "Docker base image is tag-pinned but not digest-pinned: node:20-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-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-9710c8d059e53154", "name": "No frontend routes/components detected", "shortDescription": {"text": "No frontend routes/components detected"}, "fullDescription": {"text": "No React/Vue/Next routes were found. This is fine for backend-only repos."}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-6f66e16f6324db4e", "name": "Insecure pattern 'direct_outerhtml_assignment' in src/preview-inspector.ts:26", "shortDescription": {"text": "Insecure pattern 'direct_outerhtml_assignment' in src/preview-inspector.ts:26"}, "fullDescription": {"text": "Found a known-risky pattern (direct_outerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-7923791982733dd9", "name": "Insecure pattern 'direct_innerhtml_assignment' in src/preview-message-guard.test.ts:13", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in src/preview-message-guard.test.ts:13"}, "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-4601e3ad3bb28677", "name": "No CI/CD pipelines detected", "shortDescription": {"text": "No CI/CD pipelines detected"}, "fullDescription": {"text": "No GitHub Actions, GitLab CI, or CircleCI configs found. Without CI you can't gate deploys on tests/lints."}, "properties": {"scanner": "scanner-primary", "layer": "cicd", "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 25 console/debugger/print-style debug statements in non-test source. This is a common fast-generation residue before production cleanup."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-72b2a6250083a784", "name": "Placeholder or mock-heavy implementation detected", "shortDescription": {"text": "Placeholder or mock-heavy implementation detected"}, "fullDescription": {"text": "Found 15 placeholder/mock markers across 4 source files. This often means the repo looks complete while core flows still use generated scaffolding or fake data."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-2d0c7b7ab8f8aacf", "name": "Critical user flow still appears backed by mock or placeholder data", "shortDescription": {"text": "Critical user flow still appears backed by mock or placeholder data"}, "fullDescription": {"text": "A payment/auth/admin/order/billing-style flow contains mock, fake, TODO, dummy, or placeholder markers in runtime source. In the Fable corpus this is a high-leverage completeness smell: the app can look finished while the money, identity, or tenant flow is still scaffolded."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-b9088664ace7f748", "name": "Composite production-readiness gap", "shortDescription": {"text": "Composite production-readiness gap"}, "fullDescription": {"text": "Multiple low-cost hardening controls are missing together: license, ci. Opus verification showed these co-occurring gaps are a better readiness signal than reading each flag in isolation."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-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-82e54e787406d1e1", "name": "Commented-code block (5 lines) in smoke/phase0-live-ports/index.js:5", "shortDescription": {"text": "Commented-code block (5 lines) in smoke/phase0-live-ports/index.js:5"}, "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-2fbf871f69e042a6", "name": "`fetch()` without try/.catch or AbortSignal \u2014 server/scripts/repro-agent.ts:10", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 server/scripts/repro-agent.ts:10"}, "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-58626f283f5d6e25", "name": "Legacy-named symbol `bld_unused` in server/src/credentials.test.ts:34", "shortDescription": {"text": "Legacy-named symbol `bld_unused` in server/src/credentials.test.ts:34"}, "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-488e4540dbdc788f", "name": "Commented-code block (5 lines) in src/templates.ts:224", "shortDescription": {"text": "Commented-code block (5 lines) in src/templates.ts:224"}, "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-2735f59c8de6e719", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/templates.ts:344", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/templates.ts:344"}, "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-4f6ec20f99362920", "name": "Commented-code block (5 lines) in src/managed-auth.ts:92", "shortDescription": {"text": "Commented-code block (5 lines) in src/managed-auth.ts:92"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-d0b17c8c07a7421d", "name": "8 env vars used in code but missing from .env.example", "shortDescription": {"text": "8 env vars used in code but missing from .env.example"}, "fullDescription": {"text": "Drift between code and config docs. The first few: `CLERK_SESSION_ID`, `CLERK_WEBHOOK_SIGNING_SECRET`, `PGLITE_DATA_DIR`, `PORT`, `RENDER`, `SCOUTOS_PORTS_URL`, `SCOUT_PORTS_URL`, `VERIFY_BASE_URL`. 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}}, {"id": "scanner-4d97945cb7db42cb", "name": "Dangling fetch: POST https://api.clerk.com/v1/sessions/${SESSION_ID}/tokens (server/scripts/repro-agent.ts:10)", "shortDescription": {"text": "Dangling fetch: POST https://api.clerk.com/v1/sessions/${SESSION_ID}/tokens (server/scripts/repro-agent.ts:10)"}, "fullDescription": {"text": "`server/scripts/repro-agent.ts:10` calls `POST https://api.clerk.com/v1/sessions/${SESSION_ID}/tokens` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/api.clerk.com/v1/sessions/<p>/tokens`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-5d31fa0f1dd47bea", "name": "Dangling fetch: POST http://localhost:3000/api/agent (server/scripts/repro-agent.ts:25)", "shortDescription": {"text": "Dangling fetch: POST http://localhost:3000/api/agent (server/scripts/repro-agent.ts:25)"}, "fullDescription": {"text": "`server/scripts/repro-agent.ts:25` calls `POST http://localhost:3000/api/agent` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/http:/localhost:3000/api/agent`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-52b35fa4eb95b045", "name": "Dangling fetch: GET /api/publish/bld_1 (server/src/publish.test.ts:299)", "shortDescription": {"text": "Dangling fetch: GET /api/publish/bld_1 (server/src/publish.test.ts:299)"}, "fullDescription": {"text": "`server/src/publish.test.ts:299` calls `GET /api/publish/bld_1` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/publish/bld_1`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-acb53822a3252ab6", "name": "Dangling fetch: GET /api/deployments/proj_1 (server/src/publish.test.ts:319)", "shortDescription": {"text": "Dangling fetch: GET /api/deployments/proj_1 (server/src/publish.test.ts:319)"}, "fullDescription": {"text": "`server/src/publish.test.ts:319` calls `GET /api/deployments/proj_1` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/deployments/proj_1`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-fcb783071f0de58d", "name": "Dangling fetch: GET /api/deployments/proj_1 (server/src/publish.test.ts:322)", "shortDescription": {"text": "Dangling fetch: GET /api/deployments/proj_1 (server/src/publish.test.ts:322)"}, "fullDescription": {"text": "`server/src/publish.test.ts:322` calls `GET /api/deployments/proj_1` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/deployments/proj_1`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-0519c712b215d88d", "name": "Dangling fetch: GET /api/deployments/proj_1 (server/src/publish.test.ts:333)", "shortDescription": {"text": "Dangling fetch: GET /api/deployments/proj_1 (server/src/publish.test.ts:333)"}, "fullDescription": {"text": "`server/src/publish.test.ts:333` calls `GET /api/deployments/proj_1` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/deployments/proj_1`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-4c2507d93c96fe1c", "name": "Dangling fetch: GET /api/publish/bld_unknown (server/src/publish.test.ts:343)", "shortDescription": {"text": "Dangling fetch: GET /api/publish/bld_unknown (server/src/publish.test.ts:343)"}, "fullDescription": {"text": "`server/src/publish.test.ts:343` calls `GET /api/publish/bld_unknown` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/publish/bld_unknown`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-31dc12f01053960d", "name": "Dangling fetch: GET /api/publish/bld_1 (server/src/publish.test.ts:358)", "shortDescription": {"text": "Dangling fetch: GET /api/publish/bld_1 (server/src/publish.test.ts:358)"}, "fullDescription": {"text": "`server/src/publish.test.ts:358` calls `GET /api/publish/bld_1` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/publish/bld_1`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-6669fdd0b585c231", "name": "Dangling fetch: GET /api/publish/bld_1 (server/src/publish.test.ts:379)", "shortDescription": {"text": "Dangling fetch: GET /api/publish/bld_1 (server/src/publish.test.ts:379)"}, "fullDescription": {"text": "`server/src/publish.test.ts:379` calls `GET /api/publish/bld_1` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/publish/bld_1`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-d22e1e2b13abe098", "name": "Dangling fetch: GET /api/publish/bld_2 (server/src/publish.test.ts:403)", "shortDescription": {"text": "Dangling fetch: GET /api/publish/bld_2 (server/src/publish.test.ts:403)"}, "fullDescription": {"text": "`server/src/publish.test.ts:403` calls `GET /api/publish/bld_2` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/publish/bld_2`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-1380f4fa08c2e248", "name": "Dangling fetch: GET https://openrouter.ai/api/v1/chat/completions (src/agent.ts:222)", "shortDescription": {"text": "Dangling fetch: GET https://openrouter.ai/api/v1/chat/completions (src/agent.ts:222)"}, "fullDescription": {"text": "`src/agent.ts:222` calls `GET https://openrouter.ai/api/v1/chat/completions` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/openrouter.ai/api/v1/chat/completions`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-025588c49e4a5fb8", "name": "Dangling fetch: GET https://openrouter.ai/api/v1/chat/completions (src/agent.ts:233)", "shortDescription": {"text": "Dangling fetch: GET https://openrouter.ai/api/v1/chat/completions (src/agent.ts:233)"}, "fullDescription": {"text": "`src/agent.ts:233` calls `GET https://openrouter.ai/api/v1/chat/completions` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/openrouter.ai/api/v1/chat/completions`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-fdeb9aa32fd0f967", "name": "Unused endpoint: USE /api/db", "shortDescription": {"text": "Unused endpoint: USE /api/db"}, "fullDescription": {"text": "`src/templates.ts` declares `USE /api/db` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}]}}, "automationDetails": {"id": "repobility/19097"}, "properties": {"repository": "scoutos-labs/build", "repoUrl": "https://github.com/scoutos-labs/build", "branch": "main"}, "results": [{"ruleId": "scanner-3662b6cc4926d129", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 smoke/phase0-live-ports/index.js:88"}, "properties": {"repobilityId": "8effc8cc8c90a708", "scanner": "scanner-primary", "fingerprint": "3662b6cc4926d129", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-332d39e2f6713bf3", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 server/scripts/set-user-model.ts:18"}, "properties": {"repobilityId": "08adb4aa242878c6", "scanner": "scanner-primary", "fingerprint": "332d39e2f6713bf3", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-bda502fac3312792", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 server/scripts/repro-agent.ts:42"}, "properties": {"repobilityId": "71fce0619bfefd64", "scanner": "scanner-primary", "fingerprint": "bda502fac3312792", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-e69a21647cf4a822", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 server/src/publish.test.ts:50"}, "properties": {"repobilityId": "de21eb9265ce90eb", "scanner": "scanner-primary", "fingerprint": "e69a21647cf4a822", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-edf3cfbabf058373", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 server/src/index.ts:37"}, "properties": {"repobilityId": "966123b8e19cb728", "scanner": "scanner-primary", "fingerprint": "edf3cfbabf058373", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-e2a37af2b0e513f0", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 server/src/prompt.test.ts:40"}, "properties": {"repobilityId": "428b3d057cd6a8aa", "scanner": "scanner-primary", "fingerprint": "e2a37af2b0e513f0", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-40857ec3f33a23e8", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/zip.test.ts:16"}, "properties": {"repobilityId": "e05b09318f039d84", "scanner": "scanner-primary", "fingerprint": "40857ec3f33a23e8", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-a63426e7e80a36d6", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/templates.ts:333"}, "properties": {"repobilityId": "ab1a882b26f3ece4", "scanner": "scanner-primary", "fingerprint": "a63426e7e80a36d6", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-d15fa39f7d9f287a", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/templates.test.ts:52"}, "properties": {"repobilityId": "9670e3587ecb5f43", "scanner": "scanner-primary", "fingerprint": "d15fa39f7d9f287a", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-17c7f6358868b9b4", "level": "warning", "message": {"text": "Privileged port 1000 in use"}, "properties": {"repobilityId": "5ac9fc9372cfe169", "scanner": "scanner-primary", "fingerprint": "17c7f6358868b9b4", "layer": "network", "severity": "medium", "confidence": 1.0, "tags": ["security", "ports"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "smoke/phase0-live-ports/Dockerfile"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-f2b16030c0d8121a", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: node:20-alpine"}, "properties": {"repobilityId": "b08e70e335bb186d", "scanner": "scanner-primary", "fingerprint": "f2b16030c0d8121a", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "smoke/phase0-live-ports/Dockerfile"}, "region": {"startLine": 1}}}]}, {"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-9710c8d059e53154", "level": "none", "message": {"text": "No frontend routes/components detected"}, "properties": {"repobilityId": "44ca61485762e494", "scanner": "scanner-primary", "fingerprint": "9710c8d059e53154", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["coverage"]}}, {"ruleId": "scanner-6f66e16f6324db4e", "level": "warning", "message": {"text": "Insecure pattern 'direct_outerhtml_assignment' in src/preview-inspector.ts:26"}, "properties": {"repobilityId": "07ec8b992a05e339", "scanner": "scanner-primary", "fingerprint": "6f66e16f6324db4e", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_outerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/preview-inspector.ts"}, "region": {"startLine": 26}}}]}, {"ruleId": "scanner-7923791982733dd9", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in src/preview-message-guard.test.ts:13"}, "properties": {"repobilityId": "b7e92f943474e005", "scanner": "scanner-primary", "fingerprint": "7923791982733dd9", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/preview-message-guard.test.ts"}, "region": {"startLine": 13}}}]}, {"ruleId": "scanner-4601e3ad3bb28677", "level": "warning", "message": {"text": "No CI/CD pipelines detected"}, "properties": {"repobilityId": "c3ee439bce2bc51e", "scanner": "scanner-primary", "fingerprint": "4601e3ad3bb28677", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["coverage"]}}, {"ruleId": "scanner-141b30a41e03817b", "level": "note", "message": {"text": "No license file detected"}, "properties": {"repobilityId": "0d143dd6ef595ab3", "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": "6279a0f48b22a98f", "scanner": "scanner-primary", "fingerprint": "3ab5d313dda8e5f9", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["debug", "cleanup", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-72b2a6250083a784", "level": "warning", "message": {"text": "Placeholder or mock-heavy implementation detected"}, "properties": {"repobilityId": "e84c2caad56040ec", "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": "4ceb08c08762a5e4", "scanner": "scanner-primary", "fingerprint": "2d0c7b7ab8f8aacf", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "critical-flow", "generated-repo-pattern"]}}, {"ruleId": "scanner-b9088664ace7f748", "level": "note", "message": {"text": "Composite production-readiness gap"}, "properties": {"repobilityId": "a63ae1abe00a24fd", "scanner": "scanner-primary", "fingerprint": "b9088664ace7f748", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["production-readiness", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-ea8f3013f588db25", "level": "note", "message": {"text": "Shallow git history limits provenance confidence"}, "properties": {"repobilityId": "b2f8f45a116e18ff", "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": "20d43912a15bc661", "scanner": "scanner-primary", "fingerprint": "8424db9c75e04ba4", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["provenance", "git-history", "generated-repo-pattern"]}}, {"ruleId": "scanner-82e54e787406d1e1", "level": "none", "message": {"text": "Commented-code block (5 lines) in smoke/phase0-live-ports/index.js:5"}, "properties": {"repobilityId": "b6bab6729a6c9270", "scanner": "scanner-primary", "fingerprint": "82e54e787406d1e1", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-2fbf871f69e042a6", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 server/scripts/repro-agent.ts:10"}, "properties": {"repobilityId": "8cb44a4057499c03", "scanner": "scanner-primary", "fingerprint": "2fbf871f69e042a6", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-58626f283f5d6e25", "level": "note", "message": {"text": "Legacy-named symbol `bld_unused` in server/src/credentials.test.ts:34"}, "properties": {"repobilityId": "13f9cc757125f6b2", "scanner": "scanner-primary", "fingerprint": "58626f283f5d6e25", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-488e4540dbdc788f", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/templates.ts:224"}, "properties": {"repobilityId": "7b87a1ac93234c37", "scanner": "scanner-primary", "fingerprint": "488e4540dbdc788f", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-2735f59c8de6e719", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/templates.ts:344"}, "properties": {"repobilityId": "082b576430262a5d", "scanner": "scanner-primary", "fingerprint": "2735f59c8de6e719", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-4f6ec20f99362920", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/managed-auth.ts:92"}, "properties": {"repobilityId": "8d3c6222e63d6902", "scanner": "scanner-primary", "fingerprint": "4f6ec20f99362920", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-d0b17c8c07a7421d", "level": "note", "message": {"text": "8 env vars used in code but missing from .env.example"}, "properties": {"repobilityId": "17fe720e8247f9df", "scanner": "scanner-primary", "fingerprint": "d0b17c8c07a7421d", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "config-drift"]}}, {"ruleId": "scanner-4d97945cb7db42cb", "level": "error", "message": {"text": "Dangling fetch: POST https://api.clerk.com/v1/sessions/${SESSION_ID}/tokens (server/scripts/repro-agent.ts:10)"}, "properties": {"repobilityId": "b7d033c5e77f2754", "scanner": "scanner-primary", "fingerprint": "4d97945cb7db42cb", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-5d31fa0f1dd47bea", "level": "error", "message": {"text": "Dangling fetch: POST http://localhost:3000/api/agent (server/scripts/repro-agent.ts:25)"}, "properties": {"repobilityId": "008734ade89cd999", "scanner": "scanner-primary", "fingerprint": "5d31fa0f1dd47bea", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-52b35fa4eb95b045", "level": "error", "message": {"text": "Dangling fetch: GET /api/publish/bld_1 (server/src/publish.test.ts:299)"}, "properties": {"repobilityId": "884761a9b0df2fb1", "scanner": "scanner-primary", "fingerprint": "52b35fa4eb95b045", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-acb53822a3252ab6", "level": "error", "message": {"text": "Dangling fetch: GET /api/deployments/proj_1 (server/src/publish.test.ts:319)"}, "properties": {"repobilityId": "33216647ce57d67f", "scanner": "scanner-primary", "fingerprint": "acb53822a3252ab6", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-fcb783071f0de58d", "level": "error", "message": {"text": "Dangling fetch: GET /api/deployments/proj_1 (server/src/publish.test.ts:322)"}, "properties": {"repobilityId": "5e93aa095a78202c", "scanner": "scanner-primary", "fingerprint": "fcb783071f0de58d", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-0519c712b215d88d", "level": "error", "message": {"text": "Dangling fetch: GET /api/deployments/proj_1 (server/src/publish.test.ts:333)"}, "properties": {"repobilityId": "5a83f95e1f3f7505", "scanner": "scanner-primary", "fingerprint": "0519c712b215d88d", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-4c2507d93c96fe1c", "level": "error", "message": {"text": "Dangling fetch: GET /api/publish/bld_unknown (server/src/publish.test.ts:343)"}, "properties": {"repobilityId": "aef4ad4e49004ecd", "scanner": "scanner-primary", "fingerprint": "4c2507d93c96fe1c", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-31dc12f01053960d", "level": "error", "message": {"text": "Dangling fetch: GET /api/publish/bld_1 (server/src/publish.test.ts:358)"}, "properties": {"repobilityId": "05527a32b64f1a2c", "scanner": "scanner-primary", "fingerprint": "31dc12f01053960d", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-6669fdd0b585c231", "level": "error", "message": {"text": "Dangling fetch: GET /api/publish/bld_1 (server/src/publish.test.ts:379)"}, "properties": {"repobilityId": "3709805dd4d2e8a9", "scanner": "scanner-primary", "fingerprint": "6669fdd0b585c231", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-d22e1e2b13abe098", "level": "error", "message": {"text": "Dangling fetch: GET /api/publish/bld_2 (server/src/publish.test.ts:403)"}, "properties": {"repobilityId": "b377c9458927e3c6", "scanner": "scanner-primary", "fingerprint": "d22e1e2b13abe098", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-1380f4fa08c2e248", "level": "error", "message": {"text": "Dangling fetch: GET https://openrouter.ai/api/v1/chat/completions (src/agent.ts:222)"}, "properties": {"repobilityId": "0a9c28c9ab1c8e7a", "scanner": "scanner-primary", "fingerprint": "1380f4fa08c2e248", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-025588c49e4a5fb8", "level": "error", "message": {"text": "Dangling fetch: GET https://openrouter.ai/api/v1/chat/completions (src/agent.ts:233)"}, "properties": {"repobilityId": "99858c66df5e495c", "scanner": "scanner-primary", "fingerprint": "025588c49e4a5fb8", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-fdeb9aa32fd0f967", "level": "note", "message": {"text": "Unused endpoint: USE /api/db"}, "properties": {"repobilityId": "203c736545a69005", "scanner": "scanner-primary", "fingerprint": "fdeb9aa32fd0f967", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}]}]}