{"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-46f618d3fdf4cf79", "name": "Possibly dead Python function: natural_key", "shortDescription": {"text": "Possibly dead Python function: natural_key"}, "fullDescription": {"text": "No callers detected by AST scan in this repo. Could be exported for external callers or a framework handler."}, "properties": {"scanner": "scanner-primary", "layer": "software", "severity": "low", "confidence": 1.0}}, {"id": "scanner-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-3ad89d2a4bf54e8a", "name": "Stray `console.log` in TS/JS \u2014 scripts/kimi-diag.ts:33", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/kimi-diag.ts:33"}, "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-573ae34785b828ab", "name": "Stray `console.log` in TS/JS \u2014 scripts/kimi-ab.ts:109", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/kimi-ab.ts:109"}, "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-c274e3a27de38989", "name": "Stray `console.log` in TS/JS \u2014 scripts/fix-dialogue-durations.ts:36", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/fix-dialogue-durations.ts:36"}, "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-ae00112cf6e134ef", "name": "Stray `console.log` in TS/JS \u2014 scripts/sysblock-test.ts:28", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/sysblock-test.ts: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-a26728d20f3995b2", "name": "Stray `console.log` in TS/JS \u2014 scripts/probe-seedance.ts:8", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/probe-seedance.ts:8"}, "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-2b0c35c1633b94a4", "name": "Stray `console.log` in TS/JS \u2014 scripts/dev-db.ts:22", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/dev-db.ts:22"}, "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-8f91bde3db1d757e", "name": "Stray `console.log` in TS/JS \u2014 scripts/cache-test.ts:15", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/cache-test.ts:15"}, "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-5aff2e286719b489", "name": "Stray `console.log` in TS/JS \u2014 scripts/probe-image.ts:22", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/probe-image.ts:22"}, "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-d2a1acfb91f2b826", "name": "Stray `console.log` in TS/JS \u2014 scripts/q.ts:9", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/q.ts:9"}, "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-b1d1e704d0e06cb6", "name": "Stray `console.log` in TS/JS \u2014 scripts/probe-variants.ts:49", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/probe-variants.ts:49"}, "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-da05f891253a3a44", "name": "Stray `console.log` in TS/JS \u2014 scripts/concurrency-test.ts:32", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/concurrency-test.ts:32"}, "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-191a8f8ef0932cf9", "name": "`truncate` class without `title=` for hover reveal \u2014 src/apps/prompt-studio/item-card.tsx:72", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/apps/prompt-studio/item-card.tsx:72"}, "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-61c42e126827b712", "name": "`truncate` class without `title=` for hover reveal \u2014 src/apps/prompt-studio/index.tsx:338", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/apps/prompt-studio/index.tsx:338"}, "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-a890b823fa3f0848", "name": "`truncate` class without `title=` for hover reveal \u2014 src/apps/prompt-studio/assets-stage.tsx:365", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/apps/prompt-studio/assets-stage.tsx:365"}, "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-6696601ce8b980d9", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/artifact-list.tsx:85", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/artifact-list.tsx:85"}, "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-6b10ae748090af1f", "name": "`truncate` class without `title=` for hover reveal \u2014 src/app/(platform)/projects/page.tsx:97", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/(platform)/projects/page.tsx:97"}, "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-f5a94ba7ee1e6247", "name": "`truncate` class without `title=` for hover reveal \u2014 src/app/(platform)/projects/[id]/project-scripts.tsx:149", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/(platform)/projects/[id]/project-scripts.tsx:149"}, "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-d6ad0f4b26b5f7c9", "name": "`truncate` class without `title=` for hover reveal \u2014 src/app/(platform)/wallet/page.tsx:117", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/(platform)/wallet/page.tsx:117"}, "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-0a80c654cb339dff", "name": "Stray `console.log` in TS/JS \u2014 src/lib/ai/llm.ts:29", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/lib/ai/llm.ts:29"}, "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-2315478b5785e1b0", "name": "Stray `console.log` in TS/JS \u2014 src/lib/db/seed.ts:20", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/lib/db/seed.ts:20"}, "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-835eae4c7f17a2f8", "name": "Docker base image is tag-pinned but not digest-pinned: node:22-alpine", "shortDescription": {"text": "Docker base image is tag-pinned but not digest-pinned: node:22-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-071c8881d571b5a5", "name": "Docker base image is tag-pinned but not digest-pinned: node:24-alpine", "shortDescription": {"text": "Docker base image is tag-pinned but not digest-pinned: node:24-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-b203f0d696734325", "name": "Possible secret in scripts/dev-db.ts", "shortDescription": {"text": "Possible secret in scripts/dev-db.ts"}, "fullDescription": {"text": "Detected pattern matching password_literal. Rotate the credential and move to a secret manager."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "critical", "confidence": 1.0}}, {"id": "scanner-abe97cf1b9ae24fd", "name": "Insecure pattern 'weak_hash' in src/lib/sms.ts:33", "shortDescription": {"text": "Insecure pattern 'weak_hash' in src/lib/sms.ts:33"}, "fullDescription": {"text": "Found a known-risky pattern (weak_hash). 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-6893a6c8b0861585", "name": "Very low test-to-source ratio", "shortDescription": {"text": "Very low test-to-source ratio"}, "fullDescription": {"text": "3 test file(s) for 143 source file(s) (ratio 0.02). Consider adding integration or unit tests for critical paths."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-141b30a41e03817b", "name": "No license file detected", "shortDescription": {"text": "No license file detected"}, "fullDescription": {"text": "No LICENSE/COPYING/NOTICE file was found. Generated repositories often omit licensing, which blocks reuse and automated intake."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-3ab5d313dda8e5f9", "name": "Debug logging residue appears in source files", "shortDescription": {"text": "Debug logging residue appears in source files"}, "fullDescription": {"text": "Found 55 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 19 placeholder/mock markers across 13 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, tests. Opus verification showed these co-occurring gaps are a better readiness signal than reading each flag in isolation."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "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, ci, tests. Treat this as a contract gap: the agent is guided, but the generated output is not yet guarded by the controls that make it repeatable."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-ea8f3013f588db25", "name": "Shallow git history limits provenance confidence", "shortDescription": {"text": "Shallow git history limits provenance confidence"}, "fullDescription": {"text": "The repository is a shallow clone. Origin/evolution analysis cannot distinguish fresh generation, imported legacy code, or long-lived human code with high confidence."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-8424db9c75e04ba4", "name": "Very short observed git history", "shortDescription": {"text": "Very short observed git history"}, "fullDescription": {"text": "The repo has multiple source files but two or fewer visible commits. This is not a failure by itself, but it lowers confidence in evolution-based diagnosis."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-ec46930098082cda", "name": "Agent authority lacks a verifier contract: docs/\u938f\u5149\u667a\u7ed8\u63d0\u793a\u8bcdSKILL/script-revision/SKILL.md", "shortDescription": {"text": "Agent authority lacks a verifier contract: docs/\u938f\u5149\u667a\u7ed8\u63d0\u793a\u8bcdSKILL/script-revision/SKILL.md"}, "fullDescription": {"text": "This agent instruction grants code or shell authority but does not state the verification gate that decides promotion. The recurring safe pattern is: LLM proposes; deterministic tests/build/security checks verify; only verified code promotes."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-2c5f98b152cddb6d", "name": "Agent authority lacks a verifier contract: .claude/launch.json", "shortDescription": {"text": "Agent authority lacks a verifier contract: .claude/launch.json"}, "fullDescription": {"text": "This agent instruction grants code or shell authority but does not state the verification gate that decides promotion. The recurring safe pattern is: LLM proposes; deterministic tests/build/security checks verify; only verified code promotes."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-ffa1dbf842ca714a", "name": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/kimi-diag.ts:17", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/kimi-diag.ts:17"}, "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-b92b2d105505a44e", "name": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/kimi-ab.ts:25", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/kimi-ab.ts:25"}, "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-7645f5d50ad722df", "name": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/sysblock-test.ts:14", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/sysblock-test.ts:14"}, "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-0f86b6ae22e63f6b", "name": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/probe-seedance.ts:9", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/probe-seedance.ts:9"}, "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-d1d3075aca45a0f0", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/apps/prompt-studio/video-segments-stage.tsx:96", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/apps/prompt-studio/video-segments-stage.tsx:96"}, "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-353b8498e7ed70a7", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/apps/prompt-studio/shot-prompts-stage.tsx:56", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/apps/prompt-studio/shot-prompts-stage.tsx:56"}, "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-54084ebf0a43fad4", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/apps/prompt-studio/index.tsx:70", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/apps/prompt-studio/index.tsx:70"}, "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-c1a10b5289201766", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/apps/prompt-studio/shotlist-stage.tsx:83", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/apps/prompt-studio/shotlist-stage.tsx:83"}, "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-683f168dac1d9f01", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/apps/prompt-studio/assets-stage.tsx:40", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/apps/prompt-studio/assets-stage.tsx:40"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-31948d909a7a9325", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/apps/video-studio/index.tsx:70", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/apps/video-studio/index.tsx:70"}, "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-ae145342b5e4b423", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/apps/script-doctor/index.tsx:61", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/apps/script-doctor/index.tsx:61"}, "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-395f2761a39d8951", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/apps/image-studio/index.tsx:69", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/apps/image-studio/index.tsx:69"}, "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-3c82027d6e07f7ce", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/member-rail.tsx:27", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/member-rail.tsx:27"}, "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-337ada09e8017f3d", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/(platform)/projects/create-project-dialog.tsx:28", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/(platform)/projects/create-project-dialog.tsx:28"}, "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-0101a7c6f1cdc0bd", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/(platform)/projects/[id]/members-panel.tsx:50", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/(platform)/projects/[id]/members-panel.tsx:50"}, "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-dfbd45e58634d307", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/(platform)/projects/[id]/project-spec-card.tsx:36", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/(platform)/projects/[id]/project-spec-card.tsx:36"}, "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-3d12d72f86106fbf", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/(platform)/projects/[id]/project-scripts.tsx:99", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/(platform)/projects/[id]/project-scripts.tsx:99"}, "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-da361be9c59e8330", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/(platform)/admin/users-table.tsx:46", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/(platform)/admin/users-table.tsx:46"}, "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-32afa97946440334", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/(platform)/admin/pricing/pricing-table.tsx:47", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/(platform)/admin/pricing/pricing-table.tsx:47"}, "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-6fe59613fc77475a", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/(auth)/reset-password/page.tsx:21", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/(auth)/reset-password/page.tsx:21"}, "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-bbf019bf5b49c574", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/(auth)/forgot-password/page.tsx:18", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/(auth)/forgot-password/page.tsx:18"}, "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-4c6ff363ab4dfefd", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/(auth)/register/register-form.tsx:30", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/(auth)/register/register-form.tsx:30"}, "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-4d0f60ba0e2de957", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/lib/sms.ts:51", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/lib/sms.ts:51"}, "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-fd8418fa92dff841", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/lib/ai/video.ts:45", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/lib/ai/video.ts:45"}, "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-e6c7c0b645c5fb53", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/lib/ai/image.ts:66", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/lib/ai/image.ts:66"}, "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-0130722e05dead31", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/lib/ai/llm.ts:38", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/lib/ai/llm.ts:38"}, "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-d33cebe940845679", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/lib/storage/index.ts:84", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/lib/storage/index.ts:84"}, "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-b334d875f2339fa1", "name": "5 env vars used in code but missing from .env.example", "shortDescription": {"text": "5 env vars used in code but missing from .env.example"}, "fullDescription": {"text": "Drift between code and config docs. The first few: `DMXAPI_GPT_IMAGE_MODEL`, `DMXAPI_NANO_IMAGE_MODEL`, `LLM_DEBUG`, `NODE_ENV`, `PROBE_SEEDANCE_MODEL`. 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/19508"}, "properties": {"repository": "shiyuji49-source/liuguangji--AI-----", "repoUrl": "https://github.com/shiyuji49-source/liuguangji--AI-----", "branch": "main"}, "results": [{"ruleId": "scanner-46f618d3fdf4cf79", "level": "note", "message": {"text": "Possibly dead Python function: natural_key"}, "properties": {"repobilityId": "4360b4c70da0ed92", "scanner": "scanner-primary", "fingerprint": "46f618d3fdf4cf79", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docs/\u938f\u5149\u667a\u7ed8\u63d0\u793a\u8bcdSKILL/script-revision/scripts/extract_script.py:132"}, "region": {"startLine": 1}}}]}, {"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-3ad89d2a4bf54e8a", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/kimi-diag.ts:33"}, "properties": {"repobilityId": "88029ce3ee110bd6", "scanner": "scanner-primary", "fingerprint": "3ad89d2a4bf54e8a", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-573ae34785b828ab", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/kimi-ab.ts:109"}, "properties": {"repobilityId": "5452e0f6a13c02c0", "scanner": "scanner-primary", "fingerprint": "573ae34785b828ab", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-c274e3a27de38989", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/fix-dialogue-durations.ts:36"}, "properties": {"repobilityId": "c36b4a21dd661b0a", "scanner": "scanner-primary", "fingerprint": "c274e3a27de38989", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-ae00112cf6e134ef", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/sysblock-test.ts:28"}, "properties": {"repobilityId": "4d1d1604a315914d", "scanner": "scanner-primary", "fingerprint": "ae00112cf6e134ef", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-a26728d20f3995b2", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/probe-seedance.ts:8"}, "properties": {"repobilityId": "77377f9f4742e98e", "scanner": "scanner-primary", "fingerprint": "a26728d20f3995b2", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-2b0c35c1633b94a4", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/dev-db.ts:22"}, "properties": {"repobilityId": "ae11a54388751eb5", "scanner": "scanner-primary", "fingerprint": "2b0c35c1633b94a4", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-8f91bde3db1d757e", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/cache-test.ts:15"}, "properties": {"repobilityId": "a7cb3053959549e6", "scanner": "scanner-primary", "fingerprint": "8f91bde3db1d757e", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-5aff2e286719b489", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/probe-image.ts:22"}, "properties": {"repobilityId": "2198ef48b870ff2b", "scanner": "scanner-primary", "fingerprint": "5aff2e286719b489", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-d2a1acfb91f2b826", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/q.ts:9"}, "properties": {"repobilityId": "1eb52e1fe1aa09b6", "scanner": "scanner-primary", "fingerprint": "d2a1acfb91f2b826", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-b1d1e704d0e06cb6", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/probe-variants.ts:49"}, "properties": {"repobilityId": "93ca81f4bfa55981", "scanner": "scanner-primary", "fingerprint": "b1d1e704d0e06cb6", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-da05f891253a3a44", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/concurrency-test.ts:32"}, "properties": {"repobilityId": "1798a3c0c73c4602", "scanner": "scanner-primary", "fingerprint": "da05f891253a3a44", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-191a8f8ef0932cf9", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/apps/prompt-studio/item-card.tsx:72"}, "properties": {"repobilityId": "c78ea445b0f2ea87", "scanner": "scanner-primary", "fingerprint": "191a8f8ef0932cf9", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-61c42e126827b712", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/apps/prompt-studio/index.tsx:338"}, "properties": {"repobilityId": "2366740f86fa5d34", "scanner": "scanner-primary", "fingerprint": "61c42e126827b712", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-a890b823fa3f0848", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/apps/prompt-studio/assets-stage.tsx:365"}, "properties": {"repobilityId": "3fb0a4362f7ab1e6", "scanner": "scanner-primary", "fingerprint": "a890b823fa3f0848", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-6696601ce8b980d9", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/artifact-list.tsx:85"}, "properties": {"repobilityId": "70deb15696135d31", "scanner": "scanner-primary", "fingerprint": "6696601ce8b980d9", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-6b10ae748090af1f", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/(platform)/projects/page.tsx:97"}, "properties": {"repobilityId": "92f363f0bffaa015", "scanner": "scanner-primary", "fingerprint": "6b10ae748090af1f", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-f5a94ba7ee1e6247", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/(platform)/projects/[id]/project-scripts.tsx:149"}, "properties": {"repobilityId": "af8b5042cf720891", "scanner": "scanner-primary", "fingerprint": "f5a94ba7ee1e6247", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-d6ad0f4b26b5f7c9", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/(platform)/wallet/page.tsx:117"}, "properties": {"repobilityId": "984a54409289d300", "scanner": "scanner-primary", "fingerprint": "d6ad0f4b26b5f7c9", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-0a80c654cb339dff", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/lib/ai/llm.ts:29"}, "properties": {"repobilityId": "39a099b1591acd8c", "scanner": "scanner-primary", "fingerprint": "0a80c654cb339dff", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-2315478b5785e1b0", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/lib/db/seed.ts:20"}, "properties": {"repobilityId": "f4a10698a28b28a2", "scanner": "scanner-primary", "fingerprint": "2315478b5785e1b0", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-835eae4c7f17a2f8", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: node:22-alpine"}, "properties": {"repobilityId": "9408e95c98ba497f", "scanner": "scanner-primary", "fingerprint": "835eae4c7f17a2f8", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Dockerfile"}, "region": {"startLine": 4}}}]}, {"ruleId": "scanner-071c8881d571b5a5", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: node:24-alpine"}, "properties": {"repobilityId": "441dfaa4e02ba33e", "scanner": "scanner-primary", "fingerprint": "071c8881d571b5a5", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/Dockerfile"}, "region": {"startLine": 2}}}]}, {"ruleId": "scanner-071c8881d571b5a5", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: node:24-alpine"}, "properties": {"repobilityId": "caecfa837409134f", "scanner": "scanner-primary", "fingerprint": "071c8881d571b5a5", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/Dockerfile"}, "region": {"startLine": 6}}}]}, {"ruleId": "scanner-071c8881d571b5a5", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: node:24-alpine"}, "properties": {"repobilityId": "bf7e82d3fc41cd1f", "scanner": "scanner-primary", "fingerprint": "071c8881d571b5a5", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/Dockerfile"}, "region": {"startLine": 13}}}]}, {"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-b203f0d696734325", "level": "error", "message": {"text": "Possible secret in scripts/dev-db.ts"}, "properties": {"repobilityId": "babbfd7bd2b13d34", "scanner": "scanner-primary", "fingerprint": "b203f0d696734325", "layer": "security", "severity": "critical", "confidence": 1.0, "tags": ["secrets"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/dev-db.ts"}, "region": {"startLine": 8}}}]}, {"ruleId": "scanner-abe97cf1b9ae24fd", "level": "warning", "message": {"text": "Insecure pattern 'weak_hash' in src/lib/sms.ts:33"}, "properties": {"repobilityId": "1364534f8435ef96", "scanner": "scanner-primary", "fingerprint": "abe97cf1b9ae24fd", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "weak_hash"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/lib/sms.ts"}, "region": {"startLine": 33}}}]}, {"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-6893a6c8b0861585", "level": "warning", "message": {"text": "Very low test-to-source ratio"}, "properties": {"repobilityId": "54a7de3f06314bf0", "scanner": "scanner-primary", "fingerprint": "6893a6c8b0861585", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["tests", "coverage"]}}, {"ruleId": "scanner-141b30a41e03817b", "level": "note", "message": {"text": "No license file detected"}, "properties": {"repobilityId": "366abada518e6e06", "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": "1fa9416a994f0573", "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": "254f4aa52169968c", "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": "46caf2ad8377fcf4", "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": "warning", "message": {"text": "Composite production-readiness gap"}, "properties": {"repobilityId": "69e589bd241eb8b0", "scanner": "scanner-primary", "fingerprint": "b9088664ace7f748", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["production-readiness", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-749d4bc1bd66df5f", "level": "warning", "message": {"text": "Agent instructions exist but release-hardening basics are missing"}, "properties": {"repobilityId": "7c4b3c4b510c2385", "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": "ba012083451e80c1", "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": "036c867739063456", "scanner": "scanner-primary", "fingerprint": "8424db9c75e04ba4", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["provenance", "git-history", "generated-repo-pattern"]}}, {"ruleId": "scanner-ec46930098082cda", "level": "warning", "message": {"text": "Agent authority lacks a verifier contract: docs/\u938f\u5149\u667a\u7ed8\u63d0\u793a\u8bcdSKILL/script-revision/SKILL.md"}, "properties": {"repobilityId": "df8c417152c51087", "scanner": "scanner-primary", "fingerprint": "ec46930098082cda", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "verification", "skill_file"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docs/\u938f\u5149\u667a\u7ed8\u63d0\u793a\u8bcdSKILL/script-revision/SKILL.md"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-2c5f98b152cddb6d", "level": "warning", "message": {"text": "Agent authority lacks a verifier contract: .claude/launch.json"}, "properties": {"repobilityId": "0de48c0f4ab303d8", "scanner": "scanner-primary", "fingerprint": "2c5f98b152cddb6d", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "verification", "claude_instruction"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".claude/launch.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-ffa1dbf842ca714a", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/kimi-diag.ts:17"}, "properties": {"repobilityId": "072e0743a854f35a", "scanner": "scanner-primary", "fingerprint": "ffa1dbf842ca714a", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-b92b2d105505a44e", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/kimi-ab.ts:25"}, "properties": {"repobilityId": "f7f981578b8c5468", "scanner": "scanner-primary", "fingerprint": "b92b2d105505a44e", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-7645f5d50ad722df", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/sysblock-test.ts:14"}, "properties": {"repobilityId": "82029245b36746a0", "scanner": "scanner-primary", "fingerprint": "7645f5d50ad722df", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-0f86b6ae22e63f6b", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/probe-seedance.ts:9"}, "properties": {"repobilityId": "a2daf5f769ae3ec6", "scanner": "scanner-primary", "fingerprint": "0f86b6ae22e63f6b", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-d1d3075aca45a0f0", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/apps/prompt-studio/video-segments-stage.tsx:96"}, "properties": {"repobilityId": "f7e022c10c3af3ff", "scanner": "scanner-primary", "fingerprint": "d1d3075aca45a0f0", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-353b8498e7ed70a7", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/apps/prompt-studio/shot-prompts-stage.tsx:56"}, "properties": {"repobilityId": "29550449b0f9b5df", "scanner": "scanner-primary", "fingerprint": "353b8498e7ed70a7", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-54084ebf0a43fad4", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/apps/prompt-studio/index.tsx:70"}, "properties": {"repobilityId": "74483a64b509eb09", "scanner": "scanner-primary", "fingerprint": "54084ebf0a43fad4", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-c1a10b5289201766", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/apps/prompt-studio/shotlist-stage.tsx:83"}, "properties": {"repobilityId": "2818ec51c4b2f39a", "scanner": "scanner-primary", "fingerprint": "c1a10b5289201766", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-683f168dac1d9f01", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/apps/prompt-studio/assets-stage.tsx:40"}, "properties": {"repobilityId": "27fbd1cb4d498ecb", "scanner": "scanner-primary", "fingerprint": "683f168dac1d9f01", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-31948d909a7a9325", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/apps/video-studio/index.tsx:70"}, "properties": {"repobilityId": "fb44401515f11adb", "scanner": "scanner-primary", "fingerprint": "31948d909a7a9325", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-ae145342b5e4b423", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/apps/script-doctor/index.tsx:61"}, "properties": {"repobilityId": "9650678f0b3f9bd1", "scanner": "scanner-primary", "fingerprint": "ae145342b5e4b423", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-395f2761a39d8951", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/apps/image-studio/index.tsx:69"}, "properties": {"repobilityId": "a83fa56105bc2add", "scanner": "scanner-primary", "fingerprint": "395f2761a39d8951", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-3c82027d6e07f7ce", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/member-rail.tsx:27"}, "properties": {"repobilityId": "8f39c6e8af3bd496", "scanner": "scanner-primary", "fingerprint": "3c82027d6e07f7ce", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-337ada09e8017f3d", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/(platform)/projects/create-project-dialog.tsx:28"}, "properties": {"repobilityId": "4ef59e38d7476950", "scanner": "scanner-primary", "fingerprint": "337ada09e8017f3d", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-0101a7c6f1cdc0bd", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/(platform)/projects/[id]/members-panel.tsx:50"}, "properties": {"repobilityId": "1e537e72a04dbe7a", "scanner": "scanner-primary", "fingerprint": "0101a7c6f1cdc0bd", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-dfbd45e58634d307", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/(platform)/projects/[id]/project-spec-card.tsx:36"}, "properties": {"repobilityId": "e18777ebf5e416bb", "scanner": "scanner-primary", "fingerprint": "dfbd45e58634d307", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-3d12d72f86106fbf", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/(platform)/projects/[id]/project-scripts.tsx:99"}, "properties": {"repobilityId": "fe0d5bd5d8a15f76", "scanner": "scanner-primary", "fingerprint": "3d12d72f86106fbf", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-da361be9c59e8330", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/(platform)/admin/users-table.tsx:46"}, "properties": {"repobilityId": "4d149fdf8d176fc1", "scanner": "scanner-primary", "fingerprint": "da361be9c59e8330", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-32afa97946440334", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/(platform)/admin/pricing/pricing-table.tsx:47"}, "properties": {"repobilityId": "7609415afdc2642a", "scanner": "scanner-primary", "fingerprint": "32afa97946440334", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-6fe59613fc77475a", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/(auth)/reset-password/page.tsx:21"}, "properties": {"repobilityId": "04869f61838183ff", "scanner": "scanner-primary", "fingerprint": "6fe59613fc77475a", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-bbf019bf5b49c574", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/(auth)/forgot-password/page.tsx:18"}, "properties": {"repobilityId": "98200f87ca0f9e7f", "scanner": "scanner-primary", "fingerprint": "bbf019bf5b49c574", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-4c6ff363ab4dfefd", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/(auth)/register/register-form.tsx:30"}, "properties": {"repobilityId": "bc70cb92af869780", "scanner": "scanner-primary", "fingerprint": "4c6ff363ab4dfefd", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-4d0f60ba0e2de957", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/lib/sms.ts:51"}, "properties": {"repobilityId": "242c51caaa72fc56", "scanner": "scanner-primary", "fingerprint": "4d0f60ba0e2de957", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-fd8418fa92dff841", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/lib/ai/video.ts:45"}, "properties": {"repobilityId": "89a3830c697bdc0e", "scanner": "scanner-primary", "fingerprint": "fd8418fa92dff841", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-e6c7c0b645c5fb53", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/lib/ai/image.ts:66"}, "properties": {"repobilityId": "ebe49c5242262fec", "scanner": "scanner-primary", "fingerprint": "e6c7c0b645c5fb53", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-0130722e05dead31", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/lib/ai/llm.ts:38"}, "properties": {"repobilityId": "4a2f7aa711bba432", "scanner": "scanner-primary", "fingerprint": "0130722e05dead31", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-d33cebe940845679", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/lib/storage/index.ts:84"}, "properties": {"repobilityId": "83e9e70ff1a44799", "scanner": "scanner-primary", "fingerprint": "d33cebe940845679", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-b334d875f2339fa1", "level": "note", "message": {"text": "5 env vars used in code but missing from .env.example"}, "properties": {"repobilityId": "faa38682016f5d53", "scanner": "scanner-primary", "fingerprint": "b334d875f2339fa1", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "config-drift"]}}]}]}