{"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-d76ed27304f9aafd", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/chat/ChatHeader.tsx:40", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/chat/ChatHeader.tsx:40"}, "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-2c93774262559558", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 frontend/src/components/chat/StatusHUD.tsx:22", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 frontend/src/components/chat/StatusHUD.tsx:22"}, "fullDescription": {"text": "Open XSS surface unless the input is provably trusted. Replace with explicit JSX or sanitize via a vetted library.\n\nWhy: OWASP basics. Already partially flagged by the security analyzer.\nRule id: fq.dangerous-html"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-31d1fd4df7c5508d", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 frontend/src/components/chat/ChatMessage.tsx:140", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 frontend/src/components/chat/ChatMessage.tsx:140"}, "fullDescription": {"text": "Open XSS surface unless the input is provably trusted. Replace with explicit JSX or sanitize via a vetted library.\n\nWhy: OWASP basics. Already partially flagged by the security analyzer.\nRule id: fq.dangerous-html"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-213c76f8b8e8c70d", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/pages/History.tsx:66", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/pages/History.tsx:66"}, "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-048018e20c7aea3b", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 frontend/src/pages/History.tsx:109", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 frontend/src/pages/History.tsx:109"}, "fullDescription": {"text": "Open XSS surface unless the input is provably trusted. Replace with explicit JSX or sanitize via a vetted library.\n\nWhy: OWASP basics. Already partially flagged by the security analyzer.\nRule id: fq.dangerous-html"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-14ac808a810b347f", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend-next/src/components/chat/ChatHeader.tsx:40", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend-next/src/components/chat/ChatHeader.tsx:40"}, "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-5e028bf45f2a54e0", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend-next/src/pages/History.tsx:66", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend-next/src/pages/History.tsx:66"}, "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-9905184ded1695cf", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 frontend-next/src/pages/History.tsx:109", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 frontend-next/src/pages/History.tsx:109"}, "fullDescription": {"text": "Open XSS surface unless the input is provably trusted. Replace with explicit JSX or sanitize via a vetted library.\n\nWhy: OWASP basics. Already partially flagged by the security analyzer.\nRule id: fq.dangerous-html"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-284d059641477266", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend-next/src/pages/Home.tsx:126", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend-next/src/pages/Home.tsx:126"}, "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-d63da3583b14afc0", "name": "Dockerfile runs as root: Dockerfile", "shortDescription": {"text": "Dockerfile runs as root: Dockerfile"}, "fullDescription": {"text": "No non-root USER set. Containers running as root expand the blast radius of any vulnerability inside the image."}, "properties": {"scanner": "scanner-primary", "layer": "hardware", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-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-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-7e83d05051d8c984", "name": "Insecure pattern 'direct_innerhtml_assignment' in frontend/src/components/chat/StreamingText.tsx:59", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in frontend/src/components/chat/StreamingText.tsx:59"}, "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-46f4f13223f5b439", "name": "Insecure pattern 'dangerous_innerhtml' in frontend/src/components/chat/StatusHUD.tsx:22", "shortDescription": {"text": "Insecure pattern 'dangerous_innerhtml' in frontend/src/components/chat/StatusHUD.tsx:22"}, "fullDescription": {"text": "Found a known-risky pattern (dangerous_innerhtml). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-2762da9e7afd6146", "name": "Insecure pattern 'dangerous_innerhtml' in frontend/src/components/chat/ChatMessage.tsx:140", "shortDescription": {"text": "Insecure pattern 'dangerous_innerhtml' in frontend/src/components/chat/ChatMessage.tsx:140"}, "fullDescription": {"text": "Found a known-risky pattern (dangerous_innerhtml). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-0f2b947e6fa3440e", "name": "Insecure pattern 'local_storage_auth_token' in frontend/src/lib/api.ts:12", "shortDescription": {"text": "Insecure pattern 'local_storage_auth_token' in frontend/src/lib/api.ts:12"}, "fullDescription": {"text": "Found a known-risky pattern (local_storage_auth_token). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-43cf00a8dff25914", "name": "Insecure pattern 'dangerous_innerhtml' in frontend/src/pages/History.tsx:109", "shortDescription": {"text": "Insecure pattern 'dangerous_innerhtml' in frontend/src/pages/History.tsx:109"}, "fullDescription": {"text": "Found a known-risky pattern (dangerous_innerhtml). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-f106a66fd19c8cb8", "name": "Insecure pattern 'direct_innerhtml_assignment' in frontend-next/src/components/chat/StreamingText.tsx:59", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in frontend-next/src/components/chat/StreamingText.tsx:59"}, "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-fbb6a742d5a1826c", "name": "Insecure pattern 'local_storage_auth_token' in frontend-next/src/lib/api.ts:12", "shortDescription": {"text": "Insecure pattern 'local_storage_auth_token' in frontend-next/src/lib/api.ts:12"}, "fullDescription": {"text": "Found a known-risky pattern (local_storage_auth_token). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-39e5ca9b67936662", "name": "Insecure pattern 'dangerous_innerhtml' in frontend-next/src/pages/History.tsx:109", "shortDescription": {"text": "Insecure pattern 'dangerous_innerhtml' in frontend-next/src/pages/History.tsx:109"}, "fullDescription": {"text": "Found a known-risky pattern (dangerous_innerhtml). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-469d375d171c4b4c", "name": "Insecure pattern 'local_storage_auth_token' in frontend-next/src/hooks/useSettings.ts:39", "shortDescription": {"text": "Insecure pattern 'local_storage_auth_token' in frontend-next/src/hooks/useSettings.ts:39"}, "fullDescription": {"text": "Found a known-risky pattern (local_storage_auth_token). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-09e976753568c88c", "name": "Insecure pattern 'node_child_process' in scripts/generate-slug-candidates.mjs:16", "shortDescription": {"text": "Insecure pattern 'node_child_process' in scripts/generate-slug-candidates.mjs:16"}, "fullDescription": {"text": "Found a known-risky pattern (node_child_process). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-ca112150c56a985b", "name": "Insecure pattern 'node_child_process' in scripts/upload-images.mjs:12", "shortDescription": {"text": "Insecure pattern 'node_child_process' in scripts/upload-images.mjs:12"}, "fullDescription": {"text": "Found a known-risky pattern (node_child_process). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-ad97e5864267f428", "name": "Insecure pattern 'node_child_process' in scripts/fix-description-urls.mjs:22", "shortDescription": {"text": "Insecure pattern 'node_child_process' in scripts/fix-description-urls.mjs:22"}, "fullDescription": {"text": "Found a known-risky pattern (node_child_process). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-95d6abed2f1857ff", "name": "Insecure pattern 'node_child_process' in scripts/audit-output-length.mjs:17", "shortDescription": {"text": "Insecure pattern 'node_child_process' in scripts/audit-output-length.mjs:17"}, "fullDescription": {"text": "Found a known-risky pattern (node_child_process). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-3d0969f5073e441d", "name": "Insecure pattern 'node_child_process' in scripts/fix-output-length.mjs:18", "shortDescription": {"text": "Insecure pattern 'node_child_process' in scripts/fix-output-length.mjs:18"}, "fullDescription": {"text": "Found a known-risky pattern (node_child_process). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-d4c5cb87ca8bb9b8", "name": "Insecure pattern 'node_child_process' in lib/nai-client.mjs:6", "shortDescription": {"text": "Insecure pattern 'node_child_process' in lib/nai-client.mjs:6"}, "fullDescription": {"text": "Found a known-risky pattern (node_child_process). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-6372cebde0220094", "name": "No auth library detected", "shortDescription": {"text": "No auth library detected"}, "fullDescription": {"text": "The scanner did not find any standard auth library (JWT, OAuth, NextAuth, Auth0, etc.). The repo has auth/admin/session surface indicators, so auth may live in custom code, in a separate service, or be missing."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-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-2d63e69b595e3a0c", "name": "Very large file: frontend/src/pages/Admin.tsx (963 lines)", "shortDescription": {"text": "Very large file: frontend/src/pages/Admin.tsx (963 lines)"}, "fullDescription": {"text": "Files with >800 lines often hide complexity hotspots and discourage tests."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-8a50731cc1e2becc", "name": "Very large file: frontend-next/src/pages/Admin.tsx (1000 lines)", "shortDescription": {"text": "Very large file: frontend-next/src/pages/Admin.tsx (1000 lines)"}, "fullDescription": {"text": "Files with >800 lines often hide complexity hotspots and discourage tests."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-a180a2f56c181527", "name": "Very large file: lib/db.mjs (1378 lines)", "shortDescription": {"text": "Very large file: lib/db.mjs (1378 lines)"}, "fullDescription": {"text": "Files with >800 lines often hide complexity hotspots and discourage tests."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-ea3b5e389d8c9c0f", "name": "Low test-to-source ratio", "shortDescription": {"text": "Low test-to-source ratio"}, "fullDescription": {"text": "29 tests / 245 src (ratio 0.12)."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-141b30a41e03817b", "name": "No license file detected", "shortDescription": {"text": "No license file detected"}, "fullDescription": {"text": "No LICENSE/COPYING/NOTICE file was found. Generated repositories often omit licensing, which blocks reuse and automated intake."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-0e8a76eb13fd3249", "name": "Node manifest has dependencies but no lockfile: frontend/package.json", "shortDescription": {"text": "Node manifest has dependencies but no lockfile: frontend/package.json"}, "fullDescription": {"text": "`package.json` declares dependencies, but no same-directory npm/pnpm/yarn/bun lockfile was found. Generated projects without lockfiles are less reproducible and harder to secure-scan precisely."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-ea6c290779fc2f51", "name": "Node manifest has dependencies but no lockfile: frontend-next/package.json", "shortDescription": {"text": "Node manifest has dependencies but no lockfile: frontend-next/package.json"}, "fullDescription": {"text": "`package.json` declares dependencies, but no same-directory npm/pnpm/yarn/bun lockfile was found. Generated projects without lockfiles are less reproducible and harder to secure-scan precisely."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-f85d8f0719e22fa8", "name": "Node manifest has dependencies but no lockfile: packages/contracts/package.json", "shortDescription": {"text": "Node manifest has dependencies but no lockfile: packages/contracts/package.json"}, "fullDescription": {"text": "`package.json` declares dependencies, but no same-directory npm/pnpm/yarn/bun lockfile was found. Generated projects without lockfiles are less reproducible and harder to secure-scan precisely."}, "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 776 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 97 placeholder/mock markers across 36 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-9d79c4077342a7d0", "name": "Runtime service client appears to use placeholder configuration", "shortDescription": {"text": "Runtime service client appears to use placeholder configuration"}, "fullDescription": {"text": "A runtime source file appears to wire Supabase/Firebase/AI/payment-style clients to placeholder URLs, keys, or fallback values. In the Fable corpus this often means the UI/API shape is present while the backend service is not actually configured."}, "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, lockfile. 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, lockfile. 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-6b90d4c000e4b864", "name": "Agent authority lacks a verifier contract: .claude/skills/persona-codex/references/qa-checklist.md", "shortDescription": {"text": "Agent authority lacks a verifier contract: .claude/skills/persona-codex/references/qa-checklist.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-0f61b164d669b540", "name": "Agent authority lacks a verifier contract: .claude/skills/persona-codex/references/achat-engine.md", "shortDescription": {"text": "Agent authority lacks a verifier contract: .claude/skills/persona-codex/references/achat-engine.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-b2804cfe60c6ba48", "name": "Agent authority lacks a verifier contract: .claude/skills/remote-story/skill.md", "shortDescription": {"text": "Agent authority lacks a verifier contract: .claude/skills/remote-story/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-6e1bf2c9d51fb9c0", "name": "Agent authority lacks a verifier contract: .claude/skills/story-qa/skill.md", "shortDescription": {"text": "Agent authority lacks a verifier contract: .claude/skills/story-qa/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-555aa55d5b77619c", "name": "Agent authority lacks a verifier contract: .claude/skills/apply-custom-scenes/SKILL.md", "shortDescription": {"text": "Agent authority lacks a verifier contract: .claude/skills/apply-custom-scenes/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-6cc30eea22f26bd6", "name": "Agent authority lacks a verifier contract: .claude/skills/create-story/references/prompt-guidelines.md", "shortDescription": {"text": "Agent authority lacks a verifier contract: .claude/skills/create-story/references/prompt-guidelines.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-29746be761736d74", "name": "Legacy-named symbol `chara_card_v2` in export-stories.mjs:3", "shortDescription": {"text": "Legacy-named symbol `chara_card_v2` in export-stories.mjs:3"}, "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-51fc6c6f10fb6dad", "name": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/src/lib/api.ts:54", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/src/lib/api.ts:54"}, "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-174d759237618ab3", "name": "`fetch()` without try/.catch or AbortSignal \u2014 frontend-next/src/lib/api.ts:55", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend-next/src/lib/api.ts:55"}, "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-61d88dd0e60ee671", "name": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/dayoung-piled-up/smoke-test-v2.mjs:11", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/dayoung-piled-up/smoke-test-v2.mjs:11"}, "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-5913bc9640ce667c", "name": "Commented-code block (7 lines) in docs/stories/dayoung-piled-up/build-payloads-v2.mjs:5", "shortDescription": {"text": "Commented-code block (7 lines) in docs/stories/dayoung-piled-up/build-payloads-v2.mjs: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-3dc2843baed6d84a", "name": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/dayoung-piled-up/smoke-test.mjs:10", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/dayoung-piled-up/smoke-test.mjs: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-b147c87acef15904", "name": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/momo-surrogate/smoke-test-v2.mjs:12", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/momo-surrogate/smoke-test-v2.mjs:12"}, "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-fd21c8c92efccbf6", "name": "Commented-code block (5 lines) in docs/stories/momo-surrogate/build-payloads.mjs:9", "shortDescription": {"text": "Commented-code block (5 lines) in docs/stories/momo-surrogate/build-payloads.mjs:9"}, "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-2bae98c0fd02babf", "name": "Commented-code block (7 lines) in docs/stories/momo-surrogate/build-payloads-v2.mjs:7", "shortDescription": {"text": "Commented-code block (7 lines) in docs/stories/momo-surrogate/build-payloads-v2.mjs:7"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-ab57856c0567050b", "name": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/momo-surrogate/smoke-test.mjs:11", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/momo-surrogate/smoke-test.mjs:11"}, "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-f0f25dadc0bff120", "name": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/sect-sisters/smoke-test-v2.mjs:11", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/sect-sisters/smoke-test-v2.mjs:11"}, "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-0e2e66d5a002128c", "name": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/sect-sisters/smoke-test.mjs:11", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/sect-sisters/smoke-test.mjs:11"}, "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-b49a6d6b1785d93a", "name": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/scary-noonas/smoke-test.mjs:9", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/scary-noonas/smoke-test.mjs: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-010904572399e89e", "name": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/_archive/sieun-smartphone-v1/smoke-test-v2.mjs:13", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/_archive/sieun-smartphone-v1/smoke-test-v2.mjs:13"}, "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-09b33868ccad9279", "name": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/_archive/sieun-smartphone-v1/smoke-test.mjs:11", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/_archive/sieun-smartphone-v1/smoke-test.mjs:11"}, "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-58d147e0d2fd3c0e", "name": "Commented-code block (5 lines) in docs/stories/bangkok-poolvilla/build-payloads.mjs:5", "shortDescription": {"text": "Commented-code block (5 lines) in docs/stories/bangkok-poolvilla/build-payloads.mjs: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-3357c26dc143faca", "name": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/bangkok-poolvilla/smoke-test.mjs:10", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/bangkok-poolvilla/smoke-test.mjs: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-162a827d577d64e7", "name": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/male-conservation-clinic/smoke-test-v2.mjs:12", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/male-conservation-clinic/smoke-test-v2.mjs:12"}, "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-4838d32c27d286f1", "name": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/male-conservation-clinic/smoke-test.mjs:11", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/male-conservation-clinic/smoke-test.mjs:11"}, "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-fd8e36a7b0215279", "name": "Commented-code block (5 lines) in docs/stories/male-conservation-clinic/apply-remote-v2.mjs:1", "shortDescription": {"text": "Commented-code block (5 lines) in docs/stories/male-conservation-clinic/apply-remote-v2.mjs:1"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-30a555232ac85cb6", "name": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/baseball-cheer/smoke-test-v2.mjs:11", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/baseball-cheer/smoke-test-v2.mjs:11"}, "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-e1b27ed7ea6bf968", "name": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/baseball-cheer/smoke-test.mjs:11", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/baseball-cheer/smoke-test.mjs:11"}, "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-006c188a81595a4f", "name": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/not-yours/smoke-test.mjs:9", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/not-yours/smoke-test.mjs: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-5303d29e99b62144", "name": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/next-door-slut/smoke-test.mjs:7", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/next-door-slut/smoke-test.mjs:7"}, "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-a0a349772cf5d61e", "name": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/byeondahae-remake/smoke-test-v2.mjs:13", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/byeondahae-remake/smoke-test-v2.mjs:13"}, "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-84819d3e87cb1ff2", "name": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/byeondahae-remake/fetch-snapshot-v2.mjs:11", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/byeondahae-remake/fetch-snapshot-v2.mjs:11"}, "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-a63a1164dc1e228b", "name": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/byeondahae-remake/verify-v2.mjs:9", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/byeondahae-remake/verify-v2.mjs: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-b1f67ec56b06129b", "name": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/byeondahae-remake/smoke-test.mjs:11", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/byeondahae-remake/smoke-test.mjs:11"}, "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-4e7f2f81679ece2f", "name": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/summer-village-harem/smoke-test-v2.mjs:13", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/summer-village-harem/smoke-test-v2.mjs:13"}, "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-d10d037c0e452653", "name": "Commented-code block (6 lines) in docs/stories/summer-village-harem/build-payloads.mjs:155", "shortDescription": {"text": "Commented-code block (6 lines) in docs/stories/summer-village-harem/build-payloads.mjs:155"}, "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-307d4ff6b7605018", "name": "Commented-code block (7 lines) in docs/stories/summer-village-harem/build-payloads-v2.mjs:5", "shortDescription": {"text": "Commented-code block (7 lines) in docs/stories/summer-village-harem/build-payloads-v2.mjs: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-f0613cf0c3865043", "name": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/summer-village-harem/smoke-test.mjs:11", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/summer-village-harem/smoke-test.mjs:11"}, "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-28d8cdc6d2750c0f", "name": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/yera-onlyfans/smoke-test.mjs:10", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/yera-onlyfans/smoke-test.mjs: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-46a6bccf04ff0195", "name": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/kim-areum/smoke-test.mjs:9", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/kim-areum/smoke-test.mjs: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-c65e6233c2143c86", "name": "Commented-code block (5 lines) in docs/stories/\ucea0\ud37c\uc2a4\ud038/smoke-test-v2.mjs:1", "shortDescription": {"text": "Commented-code block (5 lines) in docs/stories/\ucea0\ud37c\uc2a4\ud038/smoke-test-v2.mjs:1"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-95f464a747270c4b", "name": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/\ucea0\ud37c\uc2a4\ud038/smoke-test-v2.mjs:13", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/\ucea0\ud37c\uc2a4\ud038/smoke-test-v2.mjs:13"}, "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-ca94d6575fbb90d3", "name": "Commented-code block (5 lines) in docs/stories/\ucea0\ud37c\uc2a4\ud038/apply-remote.mjs:1", "shortDescription": {"text": "Commented-code block (5 lines) in docs/stories/\ucea0\ud37c\uc2a4\ud038/apply-remote.mjs:1"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-0d11aca50f506017", "name": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/\ucea0\ud37c\uc2a4\ud038/smoke-test.mjs:10", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/\ucea0\ud37c\uc2a4\ud038/smoke-test.mjs: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-49564bc573736656", "name": "Commented-code block (5 lines) in docs/stories/\ucea0\ud37c\uc2a4\ud038/apply-remote-v2.mjs:1", "shortDescription": {"text": "Commented-code block (5 lines) in docs/stories/\ucea0\ud37c\uc2a4\ud038/apply-remote-v2.mjs:1"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-b5c7522bb715b178", "name": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/island-harem-war/smoke-test-v2.mjs:11", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/island-harem-war/smoke-test-v2.mjs:11"}, "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-e39da7e3aff522bc", "name": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/island-harem-war/smoke-test.mjs:11", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/island-harem-war/smoke-test.mjs:11"}, "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-8828ce7c5f7268b0", "name": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/mom-milk/smoke-test.mjs:9", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/mom-milk/smoke-test.mjs: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-db55b2744fc30a79", "name": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/maple-villa/smoke-test.mjs:9", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/maple-villa/smoke-test.mjs: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-772c3dfcc378c883", "name": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/import-zips.mjs:48", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/import-zips.mjs:48"}, "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-2a8badd2c38d2fa4", "name": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/upload-images.mjs:69", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/upload-images.mjs: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-539ee29fdeeb7b62", "name": "Commented-code block (6 lines) in scripts/migrate-to-slug.mjs:10", "shortDescription": {"text": "Commented-code block (6 lines) in scripts/migrate-to-slug.mjs:10"}, "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-ad29ba643aeff935", "name": "Commented-code block (10 lines) in scripts/generate-duo-scenes.mjs:9", "shortDescription": {"text": "Commented-code block (10 lines) in scripts/generate-duo-scenes.mjs:9"}, "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-557bb312d1e37cc9", "name": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/generate-duo-scenes.mjs:139", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/generate-duo-scenes.mjs:139"}, "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-93741df87a09d6fb", "name": "Legacy-named symbol `existsOld` in scripts/rename-story-dirs.mjs:60", "shortDescription": {"text": "Legacy-named symbol `existsOld` in scripts/rename-story-dirs.mjs:60"}, "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-031feb7c6f35387d", "name": "Legacy-named symbol `chara_card_v2` in scripts/import-stories.mjs:3", "shortDescription": {"text": "Legacy-named symbol `chara_card_v2` in scripts/import-stories.mjs:3"}, "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-824650f57845da5c", "name": "Commented-code block (9 lines) in scripts/import-stories.mjs:2", "shortDescription": {"text": "Commented-code block (9 lines) in scripts/import-stories.mjs:2"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-40d2761f382e14d3", "name": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/audit-commands.mjs:24", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/audit-commands.mjs:24"}, "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-2d63fa12cdb1140d", "name": "Commented-code block (8 lines) in lib/composition-builder.mjs:495", "shortDescription": {"text": "Commented-code block (8 lines) in lib/composition-builder.mjs:495"}, "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-b678f6c4e5ac1b77", "name": "Commented-code block (5 lines) in lib/context-builder.mjs:102", "shortDescription": {"text": "Commented-code block (5 lines) in lib/context-builder.mjs:102"}, "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-01783c446a2081dc", "name": "Legacy-named symbol `is_v2` in lib/db.mjs:600", "shortDescription": {"text": "Legacy-named symbol `is_v2` in lib/db.mjs:600"}, "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-1dbb735391e8793b", "name": "Commented-code block (6 lines) in lib/db.mjs:451", "shortDescription": {"text": "Commented-code block (6 lines) in lib/db.mjs:451"}, "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-ce597201778a9b84", "name": "Commented-code block (6 lines) in lib/prompt/builtins.mjs:292", "shortDescription": {"text": "Commented-code block (6 lines) in lib/prompt/builtins.mjs:292"}, "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-a82061f068e71eb0", "name": "Commented-code block (7 lines) in lib/actors/publish.mjs:5", "shortDescription": {"text": "Commented-code block (7 lines) in lib/actors/publish.mjs: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-bea70be350bf3d7a", "name": "Commented-code block (5 lines) in lib/etl/extract.mjs:6", "shortDescription": {"text": "Commented-code block (5 lines) in lib/etl/extract.mjs:6"}, "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-c7ece9be3860f0e4", "name": "Legacy-named symbol `chara_card_v2` in lib/migrations/002_ws_j_schema.mjs:147", "shortDescription": {"text": "Legacy-named symbol `chara_card_v2` in lib/migrations/002_ws_j_schema.mjs:147"}, "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-2f1a28b3907ea42f", "name": "Commented-code block (6 lines) in lib/migrations/002_ws_j_schema.mjs:5", "shortDescription": {"text": "Commented-code block (6 lines) in lib/migrations/002_ws_j_schema.mjs: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-f9dc5dde9dc75fe7", "name": "Commented-code block (9 lines) in lib/migrations/004_ws_k_etl.mjs:5", "shortDescription": {"text": "Commented-code block (9 lines) in lib/migrations/004_ws_k_etl.mjs: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-47675af63d089059", "name": "Commented-code block (5 lines) in lib/migrations/003_ws_l_session_release.mjs:8", "shortDescription": {"text": "Commented-code block (5 lines) in lib/migrations/003_ws_l_session_release.mjs:8"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-5936a325c1d42de6", "name": "Commented-code block (6 lines) in lib/migrations/005_ws_i_actors.mjs:12", "shortDescription": {"text": "Commented-code block (6 lines) in lib/migrations/005_ws_i_actors.mjs:12"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-86323c4953253446", "name": "Commented-code block (5 lines) in lib/migrations/index.mjs:3", "shortDescription": {"text": "Commented-code block (5 lines) in lib/migrations/index.mjs:3"}, "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-509d58515f961cf7", "name": "Legacy-named symbol `chara_card_v2` in routes/admin.mjs:164", "shortDescription": {"text": "Legacy-named symbol `chara_card_v2` in routes/admin.mjs:164"}, "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-74eb91b197621f1e", "name": "Commented-code block (5 lines) in routes/releases.mjs:3", "shortDescription": {"text": "Commented-code block (5 lines) in routes/releases.mjs:3"}, "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-ad1f2c0971b89ce0", "name": "10 env vars used in code but missing from .env.example", "shortDescription": {"text": "10 env vars used in code but missing from .env.example"}, "fullDescription": {"text": "Drift between code and config docs. The first few: `ALLOWED_IMAGE_HOSTS`, `AUDIT_BASE`, `BASE_URL`, `CLAUDE_MODEL`, `GEMINI_API_KEY`, `HOME`, `LOG_FORMAT`, `NAI_API_TOKEN` + 2 more. Add them (with a placeholder/comment) to .env.example so onboarding doesn't break."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-26b4bfa0a08b1360", "name": "Frontend route `/story/:slug` has no Link/navigate to it \u2014 frontend-next/src/App.tsx", "shortDescription": {"text": "Frontend route `/story/:slug` has no Link/navigate to it \u2014 frontend-next/src/App.tsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-1f5009a917e7511b", "name": "Frontend route `/gallery/:slug` has no Link/navigate to it \u2014 frontend-next/src/App.tsx", "shortDescription": {"text": "Frontend route `/gallery/:slug` has no Link/navigate to it \u2014 frontend-next/src/App.tsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-68ebd6f9b0b03b7e", "name": "Frontend route `/chat/:slug` has no Link/navigate to it \u2014 frontend-next/src/App.tsx", "shortDescription": {"text": "Frontend route `/chat/:slug` has no Link/navigate to it \u2014 frontend-next/src/App.tsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-5d25ba627d54771e", "name": "Frontend route `/login` has no Link/navigate to it \u2014 frontend-next/src/App.tsx", "shortDescription": {"text": "Frontend route `/login` has no Link/navigate to it \u2014 frontend-next/src/App.tsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-b34adf979eb20a3d", "name": "Dangling fetch: POST https://api.anthropic.com/v1/messages (scripts/migrate-narration-style.mjs:50)", "shortDescription": {"text": "Dangling fetch: POST https://api.anthropic.com/v1/messages (scripts/migrate-narration-style.mjs:50)"}, "fullDescription": {"text": "`scripts/migrate-narration-style.mjs:50` calls `POST https://api.anthropic.com/v1/messages` 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.anthropic.com/v1/messages`\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-1da25fd97b19f490", "name": "Dangling fetch: POST https://api.anthropic.com/v1/messages (lib/claude-stream.mjs:48)", "shortDescription": {"text": "Dangling fetch: POST https://api.anthropic.com/v1/messages (lib/claude-stream.mjs:48)"}, "fullDescription": {"text": "`lib/claude-stream.mjs:48` calls `POST https://api.anthropic.com/v1/messages` 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.anthropic.com/v1/messages`\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-1b677626276f0062", "name": "Dangling fetch: POST https://api.anthropic.com/v1/messages (lib/claude-stream.mjs:200)", "shortDescription": {"text": "Dangling fetch: POST https://api.anthropic.com/v1/messages (lib/claude-stream.mjs:200)"}, "fullDescription": {"text": "`lib/claude-stream.mjs:200` calls `POST https://api.anthropic.com/v1/messages` 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.anthropic.com/v1/messages`\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-2377aa85fe935090", "name": "Dangling fetch: POST https://api.anthropic.com/v1/messages (lib/claude-stream.mjs:234)", "shortDescription": {"text": "Dangling fetch: POST https://api.anthropic.com/v1/messages (lib/claude-stream.mjs:234)"}, "fullDescription": {"text": "`lib/claude-stream.mjs:234` calls `POST https://api.anthropic.com/v1/messages` 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.anthropic.com/v1/messages`\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-0a2d0a672f5e5795", "name": "Unused endpoint: USE /next", "shortDescription": {"text": "Unused endpoint: USE /next"}, "fullDescription": {"text": "`index.mjs` declares `USE /next` 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}}, {"id": "scanner-2df5549c6b2b1f36", "name": "Unused endpoint: GET /next/{*path}", "shortDescription": {"text": "Unused endpoint: GET /next/{*path}"}, "fullDescription": {"text": "`index.mjs` declares `GET /next/{*path}` 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}}, {"id": "scanner-99631cf9d6f6a972", "name": "Unused endpoint: USE /eh", "shortDescription": {"text": "Unused endpoint: USE /eh"}, "fullDescription": {"text": "`index.mjs` declares `USE /eh` 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}}, {"id": "scanner-dde3adb27bf7eebe", "name": "Unused endpoint: USE /api", "shortDescription": {"text": "Unused endpoint: USE /api"}, "fullDescription": {"text": "`index.mjs` declares `USE /api` 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}}, {"id": "scanner-d93a530ce10d47d9", "name": "Unused endpoint: USE /api/admin", "shortDescription": {"text": "Unused endpoint: USE /api/admin"}, "fullDescription": {"text": "`index.mjs` declares `USE /api/admin` 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}}, {"id": "scanner-d23a060528c7d8b7", "name": "Unused endpoint: USE /api/stories", "shortDescription": {"text": "Unused endpoint: USE /api/stories"}, "fullDescription": {"text": "`index.mjs` declares `USE /api/stories` 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}}, {"id": "scanner-4006f18ec4db10cf", "name": "Unused endpoint: USE /images", "shortDescription": {"text": "Unused endpoint: USE /images"}, "fullDescription": {"text": "`index.mjs` declares `USE /images` 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}}, {"id": "scanner-b4bbd026c3a7db25", "name": "Unused endpoint: USE /releases", "shortDescription": {"text": "Unused endpoint: USE /releases"}, "fullDescription": {"text": "`index.mjs` declares `USE /releases` 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}}, {"id": "scanner-8636dd48e48d1da9", "name": "Unused endpoint: USE /api/sessions", "shortDescription": {"text": "Unused endpoint: USE /api/sessions"}, "fullDescription": {"text": "`index.mjs` declares `USE /api/sessions` 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}}, {"id": "scanner-9a300508c4edb651", "name": "Unused endpoint: USE /api/messages", "shortDescription": {"text": "Unused endpoint: USE /api/messages"}, "fullDescription": {"text": "`index.mjs` declares `USE /api/messages` 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}}, {"id": "scanner-77a21e69b379a5bf", "name": "Unused endpoint: GET /{*path}", "shortDescription": {"text": "Unused endpoint: GET /{*path}"}, "fullDescription": {"text": "`index.mjs` declares `GET /{*path}` 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}}, {"id": "scanner-304619b20b4dd358", "name": "Unused endpoint: POST /stories", "shortDescription": {"text": "Unused endpoint: POST /stories"}, "fullDescription": {"text": "`routes/admin.mjs` declares `POST /stories` 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}}, {"id": "scanner-31ee350ba491d18c", "name": "Unused endpoint: GET /stories/:slug/export", "shortDescription": {"text": "Unused endpoint: GET /stories/:slug/export"}, "fullDescription": {"text": "`routes/admin.mjs` declares `GET /stories/:slug/export` 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}}, {"id": "scanner-160d4849adff59e3", "name": "Unused endpoint: POST /stories/:slug/composition", "shortDescription": {"text": "Unused endpoint: POST /stories/:slug/composition"}, "fullDescription": {"text": "`routes/admin.mjs` declares `POST /stories/:slug/composition` 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}}, {"id": "scanner-86c531bfa019ef11", "name": "Unused endpoint: GET /stories/:slug/composition", "shortDescription": {"text": "Unused endpoint: GET /stories/:slug/composition"}, "fullDescription": {"text": "`routes/admin.mjs` declares `GET /stories/:slug/composition` 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}}, {"id": "scanner-c15ff30e9148b55f", "name": "Unused endpoint: PUT /stories/:slug/composition", "shortDescription": {"text": "Unused endpoint: PUT /stories/:slug/composition"}, "fullDescription": {"text": "`routes/admin.mjs` declares `PUT /stories/:slug/composition` 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}}, {"id": "scanner-3c1ddf16ccc32925", "name": "Unused endpoint: POST /stories/:slug/generate", "shortDescription": {"text": "Unused endpoint: POST /stories/:slug/generate"}, "fullDescription": {"text": "`routes/admin.mjs` declares `POST /stories/:slug/generate` 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}}, {"id": "scanner-b490105ce90479de", "name": "Unused endpoint: POST /stories/:slug/cleanup", "shortDescription": {"text": "Unused endpoint: POST /stories/:slug/cleanup"}, "fullDescription": {"text": "`routes/admin.mjs` declares `POST /stories/:slug/cleanup` 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}}, {"id": "scanner-5b72df0362fb8125", "name": "Unused endpoint: GET /stories/:slug/generate/progress", "shortDescription": {"text": "Unused endpoint: GET /stories/:slug/generate/progress"}, "fullDescription": {"text": "`routes/admin.mjs` declares `GET /stories/:slug/generate/progress` 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}}, {"id": "scanner-2b44eaef8c693232", "name": "Unused endpoint: GET /stories/:slug/generate/status", "shortDescription": {"text": "Unused endpoint: GET /stories/:slug/generate/status"}, "fullDescription": {"text": "`routes/admin.mjs` declares `GET /stories/:slug/generate/status` 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}}, {"id": "scanner-34eca90566bbf356", "name": "Unused endpoint: POST /generate/stop", "shortDescription": {"text": "Unused endpoint: POST /generate/stop"}, "fullDescription": {"text": "`routes/admin.mjs` declares `POST /generate/stop` 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}}, {"id": "scanner-6d0cc9cd2b52303d", "name": "Unused endpoint: GET /stories/:slug", "shortDescription": {"text": "Unused endpoint: GET /stories/:slug"}, "fullDescription": {"text": "`routes/admin.mjs` declares `GET /stories/:slug` 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}}, {"id": "scanner-66cf9f22ec6aac7f", "name": "Unused endpoint: PUT /stories/:slug", "shortDescription": {"text": "Unused endpoint: PUT /stories/:slug"}, "fullDescription": {"text": "`routes/admin.mjs` declares `PUT /stories/:slug` 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}}, {"id": "scanner-72d3dd8e9244506d", "name": "Unused endpoint: GET /stories/:slug/lore", "shortDescription": {"text": "Unused endpoint: GET /stories/:slug/lore"}, "fullDescription": {"text": "`routes/admin.mjs` declares `GET /stories/:slug/lore` 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}}, {"id": "scanner-42931c8a905333c7", "name": "Unused endpoint: POST /stories/:slug/embed-lore", "shortDescription": {"text": "Unused endpoint: POST /stories/:slug/embed-lore"}, "fullDescription": {"text": "`routes/admin.mjs` declares `POST /stories/:slug/embed-lore` 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}}, {"id": "scanner-e0e1c2c991c16929", "name": "Unused endpoint: POST /stories/:slug/lore", "shortDescription": {"text": "Unused endpoint: POST /stories/:slug/lore"}, "fullDescription": {"text": "`routes/admin.mjs` declares `POST /stories/:slug/lore` 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}}, {"id": "scanner-5a08dfb334762b0e", "name": "Unused endpoint: PUT /stories/:slug/lore/:id", "shortDescription": {"text": "Unused endpoint: PUT /stories/:slug/lore/:id"}, "fullDescription": {"text": "`routes/admin.mjs` declares `PUT /stories/:slug/lore/:id` 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}}, {"id": "scanner-45b767afc7001d96", "name": "Unused endpoint: DELETE /stories/:slug/lore/:id", "shortDescription": {"text": "Unused endpoint: DELETE /stories/:slug/lore/:id"}, "fullDescription": {"text": "`routes/admin.mjs` declares `DELETE /stories/:slug/lore/:id` 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}}, {"id": "scanner-0a03c799a5557797", "name": "Unused endpoint: POST /import/card", "shortDescription": {"text": "Unused endpoint: POST /import/card"}, "fullDescription": {"text": "`routes/admin.mjs` declares `POST /import/card` 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}}, {"id": "scanner-43e3fc3604b5e233", "name": "Unused endpoint: POST /import/images", "shortDescription": {"text": "Unused endpoint: POST /import/images"}, "fullDescription": {"text": "`routes/admin.mjs` declares `POST /import/images` 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}}, {"id": "scanner-60bac743842aa0d9", "name": "Unused endpoint: POST /import/zip", "shortDescription": {"text": "Unused endpoint: POST /import/zip"}, "fullDescription": {"text": "`routes/admin.mjs` declares `POST /import/zip` 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}}, {"id": "scanner-27414aa879f6640c", "name": "Unused endpoint: GET /stories/:slug/url-mappings", "shortDescription": {"text": "Unused endpoint: GET /stories/:slug/url-mappings"}, "fullDescription": {"text": "`routes/admin.mjs` declares `GET /stories/:slug/url-mappings` 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}}, {"id": "scanner-6f09d37cf5d63717", "name": "Unused endpoint: POST /stories/:slug/url-mappings", "shortDescription": {"text": "Unused endpoint: POST /stories/:slug/url-mappings"}, "fullDescription": {"text": "`routes/admin.mjs` declares `POST /stories/:slug/url-mappings` 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}}, {"id": "scanner-152dcbe4f1e9fe19", "name": "Unused endpoint: GET /stories/:slug/images", "shortDescription": {"text": "Unused endpoint: GET /stories/:slug/images"}, "fullDescription": {"text": "`routes/admin.mjs` declares `GET /stories/:slug/images` 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}}, {"id": "scanner-d1961c05a61d96a2", "name": "Unused endpoint: DELETE /stories/:slug/images/:sceneKey", "shortDescription": {"text": "Unused endpoint: DELETE /stories/:slug/images/:sceneKey"}, "fullDescription": {"text": "`routes/admin.mjs` declares `DELETE /stories/:slug/images/:sceneKey` 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}}, {"id": "scanner-40d28e41c60e2745", "name": "Unused endpoint: POST /stories/:slug/images/:sceneKey/regenerate", "shortDescription": {"text": "Unused endpoint: POST /stories/:slug/images/:sceneKey/regenerate"}, "fullDescription": {"text": "`routes/admin.mjs` declares `POST /stories/:slug/images/:sceneKey/regenerate` 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}}, {"id": "scanner-c142f12797464528", "name": "Unused endpoint: GET /stories/:slug/note", "shortDescription": {"text": "Unused endpoint: GET /stories/:slug/note"}, "fullDescription": {"text": "`routes/admin.mjs` declares `GET /stories/:slug/note` 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}}, {"id": "scanner-2cca0df69666f496", "name": "Unused endpoint: POST /stories/:slug/note", "shortDescription": {"text": "Unused endpoint: POST /stories/:slug/note"}, "fullDescription": {"text": "`routes/admin.mjs` declares `POST /stories/:slug/note` 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}}, {"id": "scanner-c53703d9548a9538", "name": "Unused endpoint: GET /personas", "shortDescription": {"text": "Unused endpoint: GET /personas"}, "fullDescription": {"text": "`routes/admin.mjs` declares `GET /personas` 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}}, {"id": "scanner-ab56ca7af5e807b6", "name": "Unused endpoint: POST /personas", "shortDescription": {"text": "Unused endpoint: POST /personas"}, "fullDescription": {"text": "`routes/admin.mjs` declares `POST /personas` 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}}, {"id": "scanner-f56688825d38399f", "name": "Unused endpoint: PUT /personas/:id", "shortDescription": {"text": "Unused endpoint: PUT /personas/:id"}, "fullDescription": {"text": "`routes/admin.mjs` declares `PUT /personas/:id` 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}}, {"id": "scanner-5d09cddb0afa3733", "name": "Unused endpoint: DELETE /personas/:id", "shortDescription": {"text": "Unused endpoint: DELETE /personas/:id"}, "fullDescription": {"text": "`routes/admin.mjs` declares `DELETE /personas/:id` 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}}, {"id": "scanner-06867d9c56f7463c", "name": "Unused endpoint: POST /personas/:id/default", "shortDescription": {"text": "Unused endpoint: POST /personas/:id/default"}, "fullDescription": {"text": "`routes/admin.mjs` declares `POST /personas/:id/default` 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}}, {"id": "scanner-fbcf5fe2535c4ebd", "name": "Unused endpoint: GET /personas/check", "shortDescription": {"text": "Unused endpoint: GET /personas/check"}, "fullDescription": {"text": "`routes/admin.mjs` declares `GET /personas/check` 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}}, {"id": "scanner-ee0f531b6b002527", "name": "Unused endpoint: POST /stories/:slug/persona", "shortDescription": {"text": "Unused endpoint: POST /stories/:slug/persona"}, "fullDescription": {"text": "`routes/admin.mjs` declares `POST /stories/:slug/persona` 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}}, {"id": "scanner-fbed72e4f8b23943", "name": "Unused endpoint: POST /stories/:slug/persona-age", "shortDescription": {"text": "Unused endpoint: POST /stories/:slug/persona-age"}, "fullDescription": {"text": "`routes/admin.mjs` declares `POST /stories/:slug/persona-age` 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}}, {"id": "scanner-5fe5100968b84060", "name": "Unused endpoint: GET /stories/:slug/persona", "shortDescription": {"text": "Unused endpoint: GET /stories/:slug/persona"}, "fullDescription": {"text": "`routes/admin.mjs` declares `GET /stories/:slug/persona` 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}}, {"id": "scanner-412be719aa2c3037", "name": "Unused endpoint: POST /stories/:slug/rename", "shortDescription": {"text": "Unused endpoint: POST /stories/:slug/rename"}, "fullDescription": {"text": "`routes/admin.mjs` declares `POST /stories/:slug/rename` 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}}, {"id": "scanner-ca91ca9600e81e08", "name": "Unused endpoint: POST /stories/:slug/change-slug", "shortDescription": {"text": "Unused endpoint: POST /stories/:slug/change-slug"}, "fullDescription": {"text": "`routes/admin.mjs` declares `POST /stories/:slug/change-slug` 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}}, {"id": "scanner-54131a7b3bf0fe55", "name": "Unused endpoint: DELETE /stories/:slug", "shortDescription": {"text": "Unused endpoint: DELETE /stories/:slug"}, "fullDescription": {"text": "`routes/admin.mjs` declares `DELETE /stories/:slug` 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/18458"}, "properties": {"repository": "roopbreak/achat", "repoUrl": "https://github.com/roopbreak/achat", "branch": "main"}, "results": [{"ruleId": "scanner-d76ed27304f9aafd", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/chat/ChatHeader.tsx:40"}, "properties": {"repobilityId": "1419140d793e52de", "scanner": "scanner-primary", "fingerprint": "d76ed27304f9aafd", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-2c93774262559558", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 frontend/src/components/chat/StatusHUD.tsx:22"}, "properties": {"repobilityId": "d55afc1a81499f06", "scanner": "scanner-primary", "fingerprint": "2c93774262559558", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-31d1fd4df7c5508d", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 frontend/src/components/chat/ChatMessage.tsx:140"}, "properties": {"repobilityId": "9d2912bd5e9b9709", "scanner": "scanner-primary", "fingerprint": "31d1fd4df7c5508d", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-213c76f8b8e8c70d", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/pages/History.tsx:66"}, "properties": {"repobilityId": "640f2d1f76a639dc", "scanner": "scanner-primary", "fingerprint": "213c76f8b8e8c70d", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-048018e20c7aea3b", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 frontend/src/pages/History.tsx:109"}, "properties": {"repobilityId": "b1167336e078d3e9", "scanner": "scanner-primary", "fingerprint": "048018e20c7aea3b", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-14ac808a810b347f", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend-next/src/components/chat/ChatHeader.tsx:40"}, "properties": {"repobilityId": "5a3b442ac56e29d9", "scanner": "scanner-primary", "fingerprint": "14ac808a810b347f", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-5e028bf45f2a54e0", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend-next/src/pages/History.tsx:66"}, "properties": {"repobilityId": "73d46d98d6ed5327", "scanner": "scanner-primary", "fingerprint": "5e028bf45f2a54e0", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-9905184ded1695cf", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 frontend-next/src/pages/History.tsx:109"}, "properties": {"repobilityId": "c63a5a756850963d", "scanner": "scanner-primary", "fingerprint": "9905184ded1695cf", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-284d059641477266", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend-next/src/pages/Home.tsx:126"}, "properties": {"repobilityId": "726016e40bf8fdba", "scanner": "scanner-primary", "fingerprint": "284d059641477266", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-d63da3583b14afc0", "level": "warning", "message": {"text": "Dockerfile runs as root: Dockerfile"}, "properties": {"repobilityId": "a2ed1bd120e507db", "scanner": "scanner-primary", "fingerprint": "d63da3583b14afc0", "layer": "hardware", "severity": "medium", "confidence": 1.0, "tags": ["security", "container"]}}, {"ruleId": "scanner-835eae4c7f17a2f8", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: node:22-alpine"}, "properties": {"repobilityId": "e469cde27591e1b7", "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": 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-7e83d05051d8c984", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in frontend/src/components/chat/StreamingText.tsx:59"}, "properties": {"repobilityId": "0d14f4badad987fa", "scanner": "scanner-primary", "fingerprint": "7e83d05051d8c984", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/src/components/chat/StreamingText.tsx"}, "region": {"startLine": 59}}}]}, {"ruleId": "scanner-46f4f13223f5b439", "level": "warning", "message": {"text": "Insecure pattern 'dangerous_innerhtml' in frontend/src/components/chat/StatusHUD.tsx:22"}, "properties": {"repobilityId": "227df2726bd6f7ef", "scanner": "scanner-primary", "fingerprint": "46f4f13223f5b439", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "dangerous_innerhtml"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/src/components/chat/StatusHUD.tsx"}, "region": {"startLine": 22}}}]}, {"ruleId": "scanner-2762da9e7afd6146", "level": "warning", "message": {"text": "Insecure pattern 'dangerous_innerhtml' in frontend/src/components/chat/ChatMessage.tsx:140"}, "properties": {"repobilityId": "45e30b985a52dcaa", "scanner": "scanner-primary", "fingerprint": "2762da9e7afd6146", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "dangerous_innerhtml"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/src/components/chat/ChatMessage.tsx"}, "region": {"startLine": 140}}}]}, {"ruleId": "scanner-0f2b947e6fa3440e", "level": "warning", "message": {"text": "Insecure pattern 'local_storage_auth_token' in frontend/src/lib/api.ts:12"}, "properties": {"repobilityId": "90843d9d5330409d", "scanner": "scanner-primary", "fingerprint": "0f2b947e6fa3440e", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "local_storage_auth_token"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/src/lib/api.ts"}, "region": {"startLine": 12}}}]}, {"ruleId": "scanner-43cf00a8dff25914", "level": "warning", "message": {"text": "Insecure pattern 'dangerous_innerhtml' in frontend/src/pages/History.tsx:109"}, "properties": {"repobilityId": "e107f45a2342db94", "scanner": "scanner-primary", "fingerprint": "43cf00a8dff25914", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "dangerous_innerhtml"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/src/pages/History.tsx"}, "region": {"startLine": 109}}}]}, {"ruleId": "scanner-f106a66fd19c8cb8", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in frontend-next/src/components/chat/StreamingText.tsx:59"}, "properties": {"repobilityId": "95f45ae4fdb5b55b", "scanner": "scanner-primary", "fingerprint": "f106a66fd19c8cb8", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend-next/src/components/chat/StreamingText.tsx"}, "region": {"startLine": 59}}}]}, {"ruleId": "scanner-fbb6a742d5a1826c", "level": "warning", "message": {"text": "Insecure pattern 'local_storage_auth_token' in frontend-next/src/lib/api.ts:12"}, "properties": {"repobilityId": "0e6cdb16927c2d72", "scanner": "scanner-primary", "fingerprint": "fbb6a742d5a1826c", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "local_storage_auth_token"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend-next/src/lib/api.ts"}, "region": {"startLine": 12}}}]}, {"ruleId": "scanner-39e5ca9b67936662", "level": "warning", "message": {"text": "Insecure pattern 'dangerous_innerhtml' in frontend-next/src/pages/History.tsx:109"}, "properties": {"repobilityId": "c16bfb5107838074", "scanner": "scanner-primary", "fingerprint": "39e5ca9b67936662", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "dangerous_innerhtml"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend-next/src/pages/History.tsx"}, "region": {"startLine": 109}}}]}, {"ruleId": "scanner-469d375d171c4b4c", "level": "warning", "message": {"text": "Insecure pattern 'local_storage_auth_token' in frontend-next/src/hooks/useSettings.ts:39"}, "properties": {"repobilityId": "2e6259d5b0fbfc30", "scanner": "scanner-primary", "fingerprint": "469d375d171c4b4c", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "local_storage_auth_token"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend-next/src/hooks/useSettings.ts"}, "region": {"startLine": 39}}}]}, {"ruleId": "scanner-09e976753568c88c", "level": "warning", "message": {"text": "Insecure pattern 'node_child_process' in scripts/generate-slug-candidates.mjs:16"}, "properties": {"repobilityId": "7fa91c4c245ca11e", "scanner": "scanner-primary", "fingerprint": "09e976753568c88c", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "node_child_process"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/generate-slug-candidates.mjs"}, "region": {"startLine": 16}}}]}, {"ruleId": "scanner-ca112150c56a985b", "level": "warning", "message": {"text": "Insecure pattern 'node_child_process' in scripts/upload-images.mjs:12"}, "properties": {"repobilityId": "c67809230802712b", "scanner": "scanner-primary", "fingerprint": "ca112150c56a985b", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "node_child_process"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/upload-images.mjs"}, "region": {"startLine": 12}}}]}, {"ruleId": "scanner-ad97e5864267f428", "level": "warning", "message": {"text": "Insecure pattern 'node_child_process' in scripts/fix-description-urls.mjs:22"}, "properties": {"repobilityId": "623bb491233a99af", "scanner": "scanner-primary", "fingerprint": "ad97e5864267f428", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "node_child_process"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/fix-description-urls.mjs"}, "region": {"startLine": 22}}}]}, {"ruleId": "scanner-95d6abed2f1857ff", "level": "warning", "message": {"text": "Insecure pattern 'node_child_process' in scripts/audit-output-length.mjs:17"}, "properties": {"repobilityId": "a3275f14165712e4", "scanner": "scanner-primary", "fingerprint": "95d6abed2f1857ff", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "node_child_process"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/audit-output-length.mjs"}, "region": {"startLine": 17}}}]}, {"ruleId": "scanner-3d0969f5073e441d", "level": "warning", "message": {"text": "Insecure pattern 'node_child_process' in scripts/fix-output-length.mjs:18"}, "properties": {"repobilityId": "ef59e62ba1700ad7", "scanner": "scanner-primary", "fingerprint": "3d0969f5073e441d", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "node_child_process"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/fix-output-length.mjs"}, "region": {"startLine": 18}}}]}, {"ruleId": "scanner-d4c5cb87ca8bb9b8", "level": "warning", "message": {"text": "Insecure pattern 'node_child_process' in lib/nai-client.mjs:6"}, "properties": {"repobilityId": "b0e6b062d7f0a5d6", "scanner": "scanner-primary", "fingerprint": "d4c5cb87ca8bb9b8", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "node_child_process"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "lib/nai-client.mjs"}, "region": {"startLine": 6}}}]}, {"ruleId": "scanner-6372cebde0220094", "level": "warning", "message": {"text": "No auth library detected"}, "properties": {"repobilityId": "a5b6035a5bbf8054", "scanner": "scanner-primary", "fingerprint": "6372cebde0220094", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["coverage", "auth"]}}, {"ruleId": "scanner-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-2d63e69b595e3a0c", "level": "note", "message": {"text": "Very large file: frontend/src/pages/Admin.tsx (963 lines)"}, "properties": {"repobilityId": "b96a2a8dc0a3d683", "scanner": "scanner-primary", "fingerprint": "2d63e69b595e3a0c", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-8a50731cc1e2becc", "level": "note", "message": {"text": "Very large file: frontend-next/src/pages/Admin.tsx (1000 lines)"}, "properties": {"repobilityId": "ad30f5291cf43588", "scanner": "scanner-primary", "fingerprint": "8a50731cc1e2becc", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-a180a2f56c181527", "level": "note", "message": {"text": "Very large file: lib/db.mjs (1378 lines)"}, "properties": {"repobilityId": "5618b682cae47ff8", "scanner": "scanner-primary", "fingerprint": "a180a2f56c181527", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-ea3b5e389d8c9c0f", "level": "note", "message": {"text": "Low test-to-source ratio"}, "properties": {"repobilityId": "ef7b2552cc00a375", "scanner": "scanner-primary", "fingerprint": "ea3b5e389d8c9c0f", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["tests"]}}, {"ruleId": "scanner-141b30a41e03817b", "level": "note", "message": {"text": "No license file detected"}, "properties": {"repobilityId": "53e6ff74caee896d", "scanner": "scanner-primary", "fingerprint": "141b30a41e03817b", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["license", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-0e8a76eb13fd3249", "level": "note", "message": {"text": "Node manifest has dependencies but no lockfile: frontend/package.json"}, "properties": {"repobilityId": "d8c65da5b68ee95b", "scanner": "scanner-primary", "fingerprint": "0e8a76eb13fd3249", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["dependency", "lockfile", "reproducibility", "generated-repo-pattern"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/package.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-ea6c290779fc2f51", "level": "note", "message": {"text": "Node manifest has dependencies but no lockfile: frontend-next/package.json"}, "properties": {"repobilityId": "4b02bb70a1ae59a4", "scanner": "scanner-primary", "fingerprint": "ea6c290779fc2f51", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["dependency", "lockfile", "reproducibility", "generated-repo-pattern"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend-next/package.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-f85d8f0719e22fa8", "level": "note", "message": {"text": "Node manifest has dependencies but no lockfile: packages/contracts/package.json"}, "properties": {"repobilityId": "9533b27beaa7d171", "scanner": "scanner-primary", "fingerprint": "f85d8f0719e22fa8", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["dependency", "lockfile", "reproducibility", "generated-repo-pattern"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "packages/contracts/package.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-3ab5d313dda8e5f9", "level": "note", "message": {"text": "Debug logging residue appears in source files"}, "properties": {"repobilityId": "f3dfaef0da40ef1f", "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": "ad1305d2a86ba2fb", "scanner": "scanner-primary", "fingerprint": "72b2a6250083a784", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "incomplete", "generated-repo-pattern"]}}, {"ruleId": "scanner-9d79c4077342a7d0", "level": "warning", "message": {"text": "Runtime service client appears to use placeholder configuration"}, "properties": {"repobilityId": "68de165f7675f143", "scanner": "scanner-primary", "fingerprint": "9d79c4077342a7d0", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "runtime-config", "service-client", "generated-repo-pattern"]}}, {"ruleId": "scanner-2d0c7b7ab8f8aacf", "level": "warning", "message": {"text": "Critical user flow still appears backed by mock or placeholder data"}, "properties": {"repobilityId": "6d38c291890d3c8c", "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": "69c9ea3665829d74", "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": "8659c967afc58abd", "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": "4fb128692a6ffd69", "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": "ad326f830b4e43fe", "scanner": "scanner-primary", "fingerprint": "8424db9c75e04ba4", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["provenance", "git-history", "generated-repo-pattern"]}}, {"ruleId": "scanner-6b90d4c000e4b864", "level": "warning", "message": {"text": "Agent authority lacks a verifier contract: .claude/skills/persona-codex/references/qa-checklist.md"}, "properties": {"repobilityId": "da15dc548bcb1cd3", "scanner": "scanner-primary", "fingerprint": "6b90d4c000e4b864", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "verification", "claude_instruction"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".claude/skills/persona-codex/references/qa-checklist.md"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-0f61b164d669b540", "level": "warning", "message": {"text": "Agent authority lacks a verifier contract: .claude/skills/persona-codex/references/achat-engine.md"}, "properties": {"repobilityId": "4281cadb759b8979", "scanner": "scanner-primary", "fingerprint": "0f61b164d669b540", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "verification", "claude_instruction"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".claude/skills/persona-codex/references/achat-engine.md"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-b2804cfe60c6ba48", "level": "warning", "message": {"text": "Agent authority lacks a verifier contract: .claude/skills/remote-story/skill.md"}, "properties": {"repobilityId": "0ae4ac7d33ed832b", "scanner": "scanner-primary", "fingerprint": "b2804cfe60c6ba48", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "verification", "claude_instruction"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".claude/skills/remote-story/skill.md"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-6e1bf2c9d51fb9c0", "level": "warning", "message": {"text": "Agent authority lacks a verifier contract: .claude/skills/story-qa/skill.md"}, "properties": {"repobilityId": "0f58d08f4f6f26f6", "scanner": "scanner-primary", "fingerprint": "6e1bf2c9d51fb9c0", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "verification", "claude_instruction"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".claude/skills/story-qa/skill.md"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-555aa55d5b77619c", "level": "warning", "message": {"text": "Agent authority lacks a verifier contract: .claude/skills/apply-custom-scenes/SKILL.md"}, "properties": {"repobilityId": "addaad91b431525d", "scanner": "scanner-primary", "fingerprint": "555aa55d5b77619c", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "verification", "claude_instruction"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".claude/skills/apply-custom-scenes/SKILL.md"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-6cc30eea22f26bd6", "level": "warning", "message": {"text": "Agent authority lacks a verifier contract: .claude/skills/create-story/references/prompt-guidelines.md"}, "properties": {"repobilityId": "2b616a439a2e4aa5", "scanner": "scanner-primary", "fingerprint": "6cc30eea22f26bd6", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "verification", "claude_instruction"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".claude/skills/create-story/references/prompt-guidelines.md"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-29746be761736d74", "level": "note", "message": {"text": "Legacy-named symbol `chara_card_v2` in export-stories.mjs:3"}, "properties": {"repobilityId": "ea8921cee7a3a65d", "scanner": "scanner-primary", "fingerprint": "29746be761736d74", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-51fc6c6f10fb6dad", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/src/lib/api.ts:54"}, "properties": {"repobilityId": "b45a2303f729e71c", "scanner": "scanner-primary", "fingerprint": "51fc6c6f10fb6dad", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-174d759237618ab3", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend-next/src/lib/api.ts:55"}, "properties": {"repobilityId": "f7ef0caba2037395", "scanner": "scanner-primary", "fingerprint": "174d759237618ab3", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-61d88dd0e60ee671", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/dayoung-piled-up/smoke-test-v2.mjs:11"}, "properties": {"repobilityId": "d845d844b748a70e", "scanner": "scanner-primary", "fingerprint": "61d88dd0e60ee671", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-5913bc9640ce667c", "level": "none", "message": {"text": "Commented-code block (7 lines) in docs/stories/dayoung-piled-up/build-payloads-v2.mjs:5"}, "properties": {"repobilityId": "262975c3a81e30d1", "scanner": "scanner-primary", "fingerprint": "5913bc9640ce667c", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-3dc2843baed6d84a", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/dayoung-piled-up/smoke-test.mjs:10"}, "properties": {"repobilityId": "d8b636edec97faeb", "scanner": "scanner-primary", "fingerprint": "3dc2843baed6d84a", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-b147c87acef15904", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/momo-surrogate/smoke-test-v2.mjs:12"}, "properties": {"repobilityId": "a8d443135f3d27a4", "scanner": "scanner-primary", "fingerprint": "b147c87acef15904", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-fd21c8c92efccbf6", "level": "none", "message": {"text": "Commented-code block (5 lines) in docs/stories/momo-surrogate/build-payloads.mjs:9"}, "properties": {"repobilityId": "d61d1908571124dc", "scanner": "scanner-primary", "fingerprint": "fd21c8c92efccbf6", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-2bae98c0fd02babf", "level": "none", "message": {"text": "Commented-code block (7 lines) in docs/stories/momo-surrogate/build-payloads-v2.mjs:7"}, "properties": {"repobilityId": "ad2d7f45b34774fb", "scanner": "scanner-primary", "fingerprint": "2bae98c0fd02babf", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-ab57856c0567050b", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/momo-surrogate/smoke-test.mjs:11"}, "properties": {"repobilityId": "682f1687a115ccdd", "scanner": "scanner-primary", "fingerprint": "ab57856c0567050b", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-f0f25dadc0bff120", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/sect-sisters/smoke-test-v2.mjs:11"}, "properties": {"repobilityId": "2ed741ebcfaed294", "scanner": "scanner-primary", "fingerprint": "f0f25dadc0bff120", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-0e2e66d5a002128c", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/sect-sisters/smoke-test.mjs:11"}, "properties": {"repobilityId": "b0c5d8c7bf2bbb69", "scanner": "scanner-primary", "fingerprint": "0e2e66d5a002128c", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-b49a6d6b1785d93a", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/scary-noonas/smoke-test.mjs:9"}, "properties": {"repobilityId": "8c40f33e0c60f076", "scanner": "scanner-primary", "fingerprint": "b49a6d6b1785d93a", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-010904572399e89e", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/_archive/sieun-smartphone-v1/smoke-test-v2.mjs:13"}, "properties": {"repobilityId": "664d9708435b700e", "scanner": "scanner-primary", "fingerprint": "010904572399e89e", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-09b33868ccad9279", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/_archive/sieun-smartphone-v1/smoke-test.mjs:11"}, "properties": {"repobilityId": "aae65e2a2009e793", "scanner": "scanner-primary", "fingerprint": "09b33868ccad9279", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-58d147e0d2fd3c0e", "level": "none", "message": {"text": "Commented-code block (5 lines) in docs/stories/bangkok-poolvilla/build-payloads.mjs:5"}, "properties": {"repobilityId": "f0d48c9f9b9048b8", "scanner": "scanner-primary", "fingerprint": "58d147e0d2fd3c0e", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-3357c26dc143faca", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/bangkok-poolvilla/smoke-test.mjs:10"}, "properties": {"repobilityId": "15150c145b730cfa", "scanner": "scanner-primary", "fingerprint": "3357c26dc143faca", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-162a827d577d64e7", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/male-conservation-clinic/smoke-test-v2.mjs:12"}, "properties": {"repobilityId": "14dfca1796fb63ea", "scanner": "scanner-primary", "fingerprint": "162a827d577d64e7", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-4838d32c27d286f1", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/male-conservation-clinic/smoke-test.mjs:11"}, "properties": {"repobilityId": "770310cbd1eace1b", "scanner": "scanner-primary", "fingerprint": "4838d32c27d286f1", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-fd8e36a7b0215279", "level": "none", "message": {"text": "Commented-code block (5 lines) in docs/stories/male-conservation-clinic/apply-remote-v2.mjs:1"}, "properties": {"repobilityId": "d35a5461c2287a80", "scanner": "scanner-primary", "fingerprint": "fd8e36a7b0215279", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-30a555232ac85cb6", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/baseball-cheer/smoke-test-v2.mjs:11"}, "properties": {"repobilityId": "34a8bdd39c92ba5d", "scanner": "scanner-primary", "fingerprint": "30a555232ac85cb6", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-e1b27ed7ea6bf968", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/baseball-cheer/smoke-test.mjs:11"}, "properties": {"repobilityId": "61264b04c0b6f2fe", "scanner": "scanner-primary", "fingerprint": "e1b27ed7ea6bf968", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-006c188a81595a4f", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/not-yours/smoke-test.mjs:9"}, "properties": {"repobilityId": "cd217f4618dfd283", "scanner": "scanner-primary", "fingerprint": "006c188a81595a4f", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-5303d29e99b62144", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/next-door-slut/smoke-test.mjs:7"}, "properties": {"repobilityId": "32c9e23e687f6968", "scanner": "scanner-primary", "fingerprint": "5303d29e99b62144", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-a0a349772cf5d61e", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/byeondahae-remake/smoke-test-v2.mjs:13"}, "properties": {"repobilityId": "1af5d66bc5a91347", "scanner": "scanner-primary", "fingerprint": "a0a349772cf5d61e", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-84819d3e87cb1ff2", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/byeondahae-remake/fetch-snapshot-v2.mjs:11"}, "properties": {"repobilityId": "1769f918228432ca", "scanner": "scanner-primary", "fingerprint": "84819d3e87cb1ff2", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-a63a1164dc1e228b", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/byeondahae-remake/verify-v2.mjs:9"}, "properties": {"repobilityId": "8e25d1370abba4ef", "scanner": "scanner-primary", "fingerprint": "a63a1164dc1e228b", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-b1f67ec56b06129b", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/byeondahae-remake/smoke-test.mjs:11"}, "properties": {"repobilityId": "c105e1400c7b9fd2", "scanner": "scanner-primary", "fingerprint": "b1f67ec56b06129b", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-4e7f2f81679ece2f", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/summer-village-harem/smoke-test-v2.mjs:13"}, "properties": {"repobilityId": "c012e37c78a69de7", "scanner": "scanner-primary", "fingerprint": "4e7f2f81679ece2f", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-d10d037c0e452653", "level": "none", "message": {"text": "Commented-code block (6 lines) in docs/stories/summer-village-harem/build-payloads.mjs:155"}, "properties": {"repobilityId": "8d8142ef261b7bbf", "scanner": "scanner-primary", "fingerprint": "d10d037c0e452653", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-307d4ff6b7605018", "level": "none", "message": {"text": "Commented-code block (7 lines) in docs/stories/summer-village-harem/build-payloads-v2.mjs:5"}, "properties": {"repobilityId": "10e5d14c2d7cccd1", "scanner": "scanner-primary", "fingerprint": "307d4ff6b7605018", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-f0613cf0c3865043", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/summer-village-harem/smoke-test.mjs:11"}, "properties": {"repobilityId": "3ead9c87d872b452", "scanner": "scanner-primary", "fingerprint": "f0613cf0c3865043", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-28d8cdc6d2750c0f", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/yera-onlyfans/smoke-test.mjs:10"}, "properties": {"repobilityId": "4c8c6c6c09560763", "scanner": "scanner-primary", "fingerprint": "28d8cdc6d2750c0f", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-46a6bccf04ff0195", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/kim-areum/smoke-test.mjs:9"}, "properties": {"repobilityId": "2f42f807b1a06352", "scanner": "scanner-primary", "fingerprint": "46a6bccf04ff0195", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-c65e6233c2143c86", "level": "none", "message": {"text": "Commented-code block (5 lines) in docs/stories/\ucea0\ud37c\uc2a4\ud038/smoke-test-v2.mjs:1"}, "properties": {"repobilityId": "2938f9aff96c1207", "scanner": "scanner-primary", "fingerprint": "c65e6233c2143c86", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-95f464a747270c4b", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/\ucea0\ud37c\uc2a4\ud038/smoke-test-v2.mjs:13"}, "properties": {"repobilityId": "aec88c6df1ffb8fd", "scanner": "scanner-primary", "fingerprint": "95f464a747270c4b", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-ca94d6575fbb90d3", "level": "none", "message": {"text": "Commented-code block (5 lines) in docs/stories/\ucea0\ud37c\uc2a4\ud038/apply-remote.mjs:1"}, "properties": {"repobilityId": "8591618f257717ab", "scanner": "scanner-primary", "fingerprint": "ca94d6575fbb90d3", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-0d11aca50f506017", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/\ucea0\ud37c\uc2a4\ud038/smoke-test.mjs:10"}, "properties": {"repobilityId": "d4c386d7c0bd4552", "scanner": "scanner-primary", "fingerprint": "0d11aca50f506017", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-49564bc573736656", "level": "none", "message": {"text": "Commented-code block (5 lines) in docs/stories/\ucea0\ud37c\uc2a4\ud038/apply-remote-v2.mjs:1"}, "properties": {"repobilityId": "52fe0b42f94c71e0", "scanner": "scanner-primary", "fingerprint": "49564bc573736656", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-b5c7522bb715b178", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/island-harem-war/smoke-test-v2.mjs:11"}, "properties": {"repobilityId": "f10c315d575b7d3e", "scanner": "scanner-primary", "fingerprint": "b5c7522bb715b178", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-e39da7e3aff522bc", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/island-harem-war/smoke-test.mjs:11"}, "properties": {"repobilityId": "da4cee9fcbaa77b0", "scanner": "scanner-primary", "fingerprint": "e39da7e3aff522bc", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-8828ce7c5f7268b0", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/mom-milk/smoke-test.mjs:9"}, "properties": {"repobilityId": "07d4644f8c0180d8", "scanner": "scanner-primary", "fingerprint": "8828ce7c5f7268b0", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-db55b2744fc30a79", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 docs/stories/maple-villa/smoke-test.mjs:9"}, "properties": {"repobilityId": "8a3e90baef964341", "scanner": "scanner-primary", "fingerprint": "db55b2744fc30a79", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-772c3dfcc378c883", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/import-zips.mjs:48"}, "properties": {"repobilityId": "6a3c98f6c6d28247", "scanner": "scanner-primary", "fingerprint": "772c3dfcc378c883", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-2a8badd2c38d2fa4", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/upload-images.mjs:69"}, "properties": {"repobilityId": "dbb3df2c686ee756", "scanner": "scanner-primary", "fingerprint": "2a8badd2c38d2fa4", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-539ee29fdeeb7b62", "level": "none", "message": {"text": "Commented-code block (6 lines) in scripts/migrate-to-slug.mjs:10"}, "properties": {"repobilityId": "bdfa398408f874cd", "scanner": "scanner-primary", "fingerprint": "539ee29fdeeb7b62", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-ad29ba643aeff935", "level": "none", "message": {"text": "Commented-code block (10 lines) in scripts/generate-duo-scenes.mjs:9"}, "properties": {"repobilityId": "4876ce8d971d952f", "scanner": "scanner-primary", "fingerprint": "ad29ba643aeff935", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-557bb312d1e37cc9", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/generate-duo-scenes.mjs:139"}, "properties": {"repobilityId": "cf0c4de7b21cd52c", "scanner": "scanner-primary", "fingerprint": "557bb312d1e37cc9", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-93741df87a09d6fb", "level": "note", "message": {"text": "Legacy-named symbol `existsOld` in scripts/rename-story-dirs.mjs:60"}, "properties": {"repobilityId": "106da55306bd6410", "scanner": "scanner-primary", "fingerprint": "93741df87a09d6fb", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-031feb7c6f35387d", "level": "note", "message": {"text": "Legacy-named symbol `chara_card_v2` in scripts/import-stories.mjs:3"}, "properties": {"repobilityId": "1dfd12804cf0b3b0", "scanner": "scanner-primary", "fingerprint": "031feb7c6f35387d", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-824650f57845da5c", "level": "none", "message": {"text": "Commented-code block (9 lines) in scripts/import-stories.mjs:2"}, "properties": {"repobilityId": "04a87be7aa0aff7c", "scanner": "scanner-primary", "fingerprint": "824650f57845da5c", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-40d2761f382e14d3", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/audit-commands.mjs:24"}, "properties": {"repobilityId": "43aed3c9355f760c", "scanner": "scanner-primary", "fingerprint": "40d2761f382e14d3", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-2d63fa12cdb1140d", "level": "none", "message": {"text": "Commented-code block (8 lines) in lib/composition-builder.mjs:495"}, "properties": {"repobilityId": "bf91463d7dc97328", "scanner": "scanner-primary", "fingerprint": "2d63fa12cdb1140d", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-b678f6c4e5ac1b77", "level": "none", "message": {"text": "Commented-code block (5 lines) in lib/context-builder.mjs:102"}, "properties": {"repobilityId": "ba826db89840a423", "scanner": "scanner-primary", "fingerprint": "b678f6c4e5ac1b77", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-01783c446a2081dc", "level": "note", "message": {"text": "Legacy-named symbol `is_v2` in lib/db.mjs:600"}, "properties": {"repobilityId": "bfeaf2954b47bf3a", "scanner": "scanner-primary", "fingerprint": "01783c446a2081dc", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-1dbb735391e8793b", "level": "none", "message": {"text": "Commented-code block (6 lines) in lib/db.mjs:451"}, "properties": {"repobilityId": "82dd2193e195a8cd", "scanner": "scanner-primary", "fingerprint": "1dbb735391e8793b", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-ce597201778a9b84", "level": "none", "message": {"text": "Commented-code block (6 lines) in lib/prompt/builtins.mjs:292"}, "properties": {"repobilityId": "b715e2261a605553", "scanner": "scanner-primary", "fingerprint": "ce597201778a9b84", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-a82061f068e71eb0", "level": "none", "message": {"text": "Commented-code block (7 lines) in lib/actors/publish.mjs:5"}, "properties": {"repobilityId": "1400a42e4633ca13", "scanner": "scanner-primary", "fingerprint": "a82061f068e71eb0", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-bea70be350bf3d7a", "level": "none", "message": {"text": "Commented-code block (5 lines) in lib/etl/extract.mjs:6"}, "properties": {"repobilityId": "3e1d46c8a9986332", "scanner": "scanner-primary", "fingerprint": "bea70be350bf3d7a", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-c7ece9be3860f0e4", "level": "note", "message": {"text": "Legacy-named symbol `chara_card_v2` in lib/migrations/002_ws_j_schema.mjs:147"}, "properties": {"repobilityId": "af72c3170e1afece", "scanner": "scanner-primary", "fingerprint": "c7ece9be3860f0e4", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-2f1a28b3907ea42f", "level": "none", "message": {"text": "Commented-code block (6 lines) in lib/migrations/002_ws_j_schema.mjs:5"}, "properties": {"repobilityId": "6e35bf7c491b98c8", "scanner": "scanner-primary", "fingerprint": "2f1a28b3907ea42f", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-f9dc5dde9dc75fe7", "level": "none", "message": {"text": "Commented-code block (9 lines) in lib/migrations/004_ws_k_etl.mjs:5"}, "properties": {"repobilityId": "750ee3fadca44217", "scanner": "scanner-primary", "fingerprint": "f9dc5dde9dc75fe7", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-47675af63d089059", "level": "none", "message": {"text": "Commented-code block (5 lines) in lib/migrations/003_ws_l_session_release.mjs:8"}, "properties": {"repobilityId": "457ead6264943be3", "scanner": "scanner-primary", "fingerprint": "47675af63d089059", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-5936a325c1d42de6", "level": "none", "message": {"text": "Commented-code block (6 lines) in lib/migrations/005_ws_i_actors.mjs:12"}, "properties": {"repobilityId": "3ca77cfee3434c6f", "scanner": "scanner-primary", "fingerprint": "5936a325c1d42de6", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-86323c4953253446", "level": "none", "message": {"text": "Commented-code block (5 lines) in lib/migrations/index.mjs:3"}, "properties": {"repobilityId": "451369c512fdaab4", "scanner": "scanner-primary", "fingerprint": "86323c4953253446", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-509d58515f961cf7", "level": "note", "message": {"text": "Legacy-named symbol `chara_card_v2` in routes/admin.mjs:164"}, "properties": {"repobilityId": "ab3662c383e74d07", "scanner": "scanner-primary", "fingerprint": "509d58515f961cf7", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-74eb91b197621f1e", "level": "none", "message": {"text": "Commented-code block (5 lines) in routes/releases.mjs:3"}, "properties": {"repobilityId": "96e23b312037dcd8", "scanner": "scanner-primary", "fingerprint": "74eb91b197621f1e", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-ad1f2c0971b89ce0", "level": "note", "message": {"text": "10 env vars used in code but missing from .env.example"}, "properties": {"repobilityId": "3bfdc60c61f1870e", "scanner": "scanner-primary", "fingerprint": "ad1f2c0971b89ce0", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "config-drift"]}}, {"ruleId": "scanner-26b4bfa0a08b1360", "level": "warning", "message": {"text": "Frontend route `/story/:slug` has no Link/navigate to it \u2014 frontend-next/src/App.tsx"}, "properties": {"repobilityId": "454bdcbcdcbffbe7", "scanner": "scanner-primary", "fingerprint": "26b4bfa0a08b1360", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-1f5009a917e7511b", "level": "warning", "message": {"text": "Frontend route `/gallery/:slug` has no Link/navigate to it \u2014 frontend-next/src/App.tsx"}, "properties": {"repobilityId": "ae7ccdd2b7ae31ef", "scanner": "scanner-primary", "fingerprint": "1f5009a917e7511b", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-68ebd6f9b0b03b7e", "level": "warning", "message": {"text": "Frontend route `/chat/:slug` has no Link/navigate to it \u2014 frontend-next/src/App.tsx"}, "properties": {"repobilityId": "5f67da2e1160e7a6", "scanner": "scanner-primary", "fingerprint": "68ebd6f9b0b03b7e", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-5d25ba627d54771e", "level": "warning", "message": {"text": "Frontend route `/login` has no Link/navigate to it \u2014 frontend-next/src/App.tsx"}, "properties": {"repobilityId": "cfd8b75377c6abef", "scanner": "scanner-primary", "fingerprint": "5d25ba627d54771e", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-b34adf979eb20a3d", "level": "error", "message": {"text": "Dangling fetch: POST https://api.anthropic.com/v1/messages (scripts/migrate-narration-style.mjs:50)"}, "properties": {"repobilityId": "98fee811d717c375", "scanner": "scanner-primary", "fingerprint": "b34adf979eb20a3d", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-1da25fd97b19f490", "level": "error", "message": {"text": "Dangling fetch: POST https://api.anthropic.com/v1/messages (lib/claude-stream.mjs:48)"}, "properties": {"repobilityId": "d5d19ba03956ee7d", "scanner": "scanner-primary", "fingerprint": "1da25fd97b19f490", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-1b677626276f0062", "level": "error", "message": {"text": "Dangling fetch: POST https://api.anthropic.com/v1/messages (lib/claude-stream.mjs:200)"}, "properties": {"repobilityId": "8978f92b0a2fc238", "scanner": "scanner-primary", "fingerprint": "1b677626276f0062", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-2377aa85fe935090", "level": "error", "message": {"text": "Dangling fetch: POST https://api.anthropic.com/v1/messages (lib/claude-stream.mjs:234)"}, "properties": {"repobilityId": "8853b9753a291fe1", "scanner": "scanner-primary", "fingerprint": "2377aa85fe935090", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-0a2d0a672f5e5795", "level": "note", "message": {"text": "Unused endpoint: USE /next"}, "properties": {"repobilityId": "43911b157e712b2d", "scanner": "scanner-primary", "fingerprint": "0a2d0a672f5e5795", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-2df5549c6b2b1f36", "level": "note", "message": {"text": "Unused endpoint: GET /next/{*path}"}, "properties": {"repobilityId": "320403d0499c3ef4", "scanner": "scanner-primary", "fingerprint": "2df5549c6b2b1f36", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-99631cf9d6f6a972", "level": "note", "message": {"text": "Unused endpoint: USE /eh"}, "properties": {"repobilityId": "dcc59808d9ae69d9", "scanner": "scanner-primary", "fingerprint": "99631cf9d6f6a972", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-dde3adb27bf7eebe", "level": "note", "message": {"text": "Unused endpoint: USE /api"}, "properties": {"repobilityId": "5e20e0c4f1fd78d2", "scanner": "scanner-primary", "fingerprint": "dde3adb27bf7eebe", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-d93a530ce10d47d9", "level": "note", "message": {"text": "Unused endpoint: USE /api/admin"}, "properties": {"repobilityId": "4786441987a0d279", "scanner": "scanner-primary", "fingerprint": "d93a530ce10d47d9", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-d23a060528c7d8b7", "level": "note", "message": {"text": "Unused endpoint: USE /api/stories"}, "properties": {"repobilityId": "c4b6c599bf207928", "scanner": "scanner-primary", "fingerprint": "d23a060528c7d8b7", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-4006f18ec4db10cf", "level": "note", "message": {"text": "Unused endpoint: USE /images"}, "properties": {"repobilityId": "ab2c24b635dae444", "scanner": "scanner-primary", "fingerprint": "4006f18ec4db10cf", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-b4bbd026c3a7db25", "level": "note", "message": {"text": "Unused endpoint: USE /releases"}, "properties": {"repobilityId": "dedad955d3f33f6c", "scanner": "scanner-primary", "fingerprint": "b4bbd026c3a7db25", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-8636dd48e48d1da9", "level": "note", "message": {"text": "Unused endpoint: USE /api/sessions"}, "properties": {"repobilityId": "2e636d6759bd10f3", "scanner": "scanner-primary", "fingerprint": "8636dd48e48d1da9", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-9a300508c4edb651", "level": "note", "message": {"text": "Unused endpoint: USE /api/messages"}, "properties": {"repobilityId": "1bbede5fc13924b3", "scanner": "scanner-primary", "fingerprint": "9a300508c4edb651", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-77a21e69b379a5bf", "level": "note", "message": {"text": "Unused endpoint: GET /{*path}"}, "properties": {"repobilityId": "20de4c95a044f51a", "scanner": "scanner-primary", "fingerprint": "77a21e69b379a5bf", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-304619b20b4dd358", "level": "note", "message": {"text": "Unused endpoint: POST /stories"}, "properties": {"repobilityId": "cca42e38b6fcf24f", "scanner": "scanner-primary", "fingerprint": "304619b20b4dd358", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-31ee350ba491d18c", "level": "note", "message": {"text": "Unused endpoint: GET /stories/:slug/export"}, "properties": {"repobilityId": "b690fe06b29974aa", "scanner": "scanner-primary", "fingerprint": "31ee350ba491d18c", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-160d4849adff59e3", "level": "note", "message": {"text": "Unused endpoint: POST /stories/:slug/composition"}, "properties": {"repobilityId": "0a2fa2712ade80a8", "scanner": "scanner-primary", "fingerprint": "160d4849adff59e3", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-86c531bfa019ef11", "level": "note", "message": {"text": "Unused endpoint: GET /stories/:slug/composition"}, "properties": {"repobilityId": "732bd55d127e6705", "scanner": "scanner-primary", "fingerprint": "86c531bfa019ef11", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-c15ff30e9148b55f", "level": "note", "message": {"text": "Unused endpoint: PUT /stories/:slug/composition"}, "properties": {"repobilityId": "2d14d00ff12c3acb", "scanner": "scanner-primary", "fingerprint": "c15ff30e9148b55f", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-3c1ddf16ccc32925", "level": "note", "message": {"text": "Unused endpoint: POST /stories/:slug/generate"}, "properties": {"repobilityId": "c77b686513cd6600", "scanner": "scanner-primary", "fingerprint": "3c1ddf16ccc32925", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-b490105ce90479de", "level": "note", "message": {"text": "Unused endpoint: POST /stories/:slug/cleanup"}, "properties": {"repobilityId": "e6fbb58dd5d308f1", "scanner": "scanner-primary", "fingerprint": "b490105ce90479de", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-5b72df0362fb8125", "level": "note", "message": {"text": "Unused endpoint: GET /stories/:slug/generate/progress"}, "properties": {"repobilityId": "edf33bb57ff067a0", "scanner": "scanner-primary", "fingerprint": "5b72df0362fb8125", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-2b44eaef8c693232", "level": "note", "message": {"text": "Unused endpoint: GET /stories/:slug/generate/status"}, "properties": {"repobilityId": "bb02debe061a84df", "scanner": "scanner-primary", "fingerprint": "2b44eaef8c693232", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-34eca90566bbf356", "level": "note", "message": {"text": "Unused endpoint: POST /generate/stop"}, "properties": {"repobilityId": "b16787b4363ada59", "scanner": "scanner-primary", "fingerprint": "34eca90566bbf356", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-6d0cc9cd2b52303d", "level": "note", "message": {"text": "Unused endpoint: GET /stories/:slug"}, "properties": {"repobilityId": "4849fdec6bf31c31", "scanner": "scanner-primary", "fingerprint": "6d0cc9cd2b52303d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-66cf9f22ec6aac7f", "level": "note", "message": {"text": "Unused endpoint: PUT /stories/:slug"}, "properties": {"repobilityId": "d4a17017b02bb2e4", "scanner": "scanner-primary", "fingerprint": "66cf9f22ec6aac7f", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-72d3dd8e9244506d", "level": "note", "message": {"text": "Unused endpoint: GET /stories/:slug/lore"}, "properties": {"repobilityId": "b726b2e5136f972b", "scanner": "scanner-primary", "fingerprint": "72d3dd8e9244506d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-42931c8a905333c7", "level": "note", "message": {"text": "Unused endpoint: POST /stories/:slug/embed-lore"}, "properties": {"repobilityId": "3263326fbf2e6c3e", "scanner": "scanner-primary", "fingerprint": "42931c8a905333c7", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-e0e1c2c991c16929", "level": "note", "message": {"text": "Unused endpoint: POST /stories/:slug/lore"}, "properties": {"repobilityId": "18eabbdd85ad5a7b", "scanner": "scanner-primary", "fingerprint": "e0e1c2c991c16929", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-5a08dfb334762b0e", "level": "note", "message": {"text": "Unused endpoint: PUT /stories/:slug/lore/:id"}, "properties": {"repobilityId": "51c7d897e61bbfdb", "scanner": "scanner-primary", "fingerprint": "5a08dfb334762b0e", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-45b767afc7001d96", "level": "note", "message": {"text": "Unused endpoint: DELETE /stories/:slug/lore/:id"}, "properties": {"repobilityId": "6fd8337f5eb58c05", "scanner": "scanner-primary", "fingerprint": "45b767afc7001d96", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-0a03c799a5557797", "level": "note", "message": {"text": "Unused endpoint: POST /import/card"}, "properties": {"repobilityId": "6c001a20b06bfe92", "scanner": "scanner-primary", "fingerprint": "0a03c799a5557797", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-43e3fc3604b5e233", "level": "note", "message": {"text": "Unused endpoint: POST /import/images"}, "properties": {"repobilityId": "9820efbdb00a6ab4", "scanner": "scanner-primary", "fingerprint": "43e3fc3604b5e233", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-60bac743842aa0d9", "level": "note", "message": {"text": "Unused endpoint: POST /import/zip"}, "properties": {"repobilityId": "52e675211bb89db8", "scanner": "scanner-primary", "fingerprint": "60bac743842aa0d9", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-27414aa879f6640c", "level": "note", "message": {"text": "Unused endpoint: GET /stories/:slug/url-mappings"}, "properties": {"repobilityId": "55f4a1415f133827", "scanner": "scanner-primary", "fingerprint": "27414aa879f6640c", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-6f09d37cf5d63717", "level": "note", "message": {"text": "Unused endpoint: POST /stories/:slug/url-mappings"}, "properties": {"repobilityId": "31a72ac5e97a50fb", "scanner": "scanner-primary", "fingerprint": "6f09d37cf5d63717", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-152dcbe4f1e9fe19", "level": "note", "message": {"text": "Unused endpoint: GET /stories/:slug/images"}, "properties": {"repobilityId": "a32c405164731642", "scanner": "scanner-primary", "fingerprint": "152dcbe4f1e9fe19", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-d1961c05a61d96a2", "level": "note", "message": {"text": "Unused endpoint: DELETE /stories/:slug/images/:sceneKey"}, "properties": {"repobilityId": "1c1c62be51582204", "scanner": "scanner-primary", "fingerprint": "d1961c05a61d96a2", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-40d28e41c60e2745", "level": "note", "message": {"text": "Unused endpoint: POST /stories/:slug/images/:sceneKey/regenerate"}, "properties": {"repobilityId": "d5039ecb91777c75", "scanner": "scanner-primary", "fingerprint": "40d28e41c60e2745", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-c142f12797464528", "level": "note", "message": {"text": "Unused endpoint: GET /stories/:slug/note"}, "properties": {"repobilityId": "c86fbf41891dae4c", "scanner": "scanner-primary", "fingerprint": "c142f12797464528", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-2cca0df69666f496", "level": "note", "message": {"text": "Unused endpoint: POST /stories/:slug/note"}, "properties": {"repobilityId": "5f41f75158e40894", "scanner": "scanner-primary", "fingerprint": "2cca0df69666f496", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-c53703d9548a9538", "level": "note", "message": {"text": "Unused endpoint: GET /personas"}, "properties": {"repobilityId": "b5a8de5fbcd64577", "scanner": "scanner-primary", "fingerprint": "c53703d9548a9538", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-ab56ca7af5e807b6", "level": "note", "message": {"text": "Unused endpoint: POST /personas"}, "properties": {"repobilityId": "a1bde79f257202cb", "scanner": "scanner-primary", "fingerprint": "ab56ca7af5e807b6", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-f56688825d38399f", "level": "note", "message": {"text": "Unused endpoint: PUT /personas/:id"}, "properties": {"repobilityId": "94755e0e1cc28396", "scanner": "scanner-primary", "fingerprint": "f56688825d38399f", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-5d09cddb0afa3733", "level": "note", "message": {"text": "Unused endpoint: DELETE /personas/:id"}, "properties": {"repobilityId": "01634f6d0e46b56e", "scanner": "scanner-primary", "fingerprint": "5d09cddb0afa3733", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-06867d9c56f7463c", "level": "note", "message": {"text": "Unused endpoint: POST /personas/:id/default"}, "properties": {"repobilityId": "38bdbed157008077", "scanner": "scanner-primary", "fingerprint": "06867d9c56f7463c", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-fbcf5fe2535c4ebd", "level": "note", "message": {"text": "Unused endpoint: GET /personas/check"}, "properties": {"repobilityId": "54ea64838cdfec62", "scanner": "scanner-primary", "fingerprint": "fbcf5fe2535c4ebd", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-ee0f531b6b002527", "level": "note", "message": {"text": "Unused endpoint: POST /stories/:slug/persona"}, "properties": {"repobilityId": "d294ba1922abedcf", "scanner": "scanner-primary", "fingerprint": "ee0f531b6b002527", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-fbed72e4f8b23943", "level": "note", "message": {"text": "Unused endpoint: POST /stories/:slug/persona-age"}, "properties": {"repobilityId": "501d4f4874ed5dbc", "scanner": "scanner-primary", "fingerprint": "fbed72e4f8b23943", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-5fe5100968b84060", "level": "note", "message": {"text": "Unused endpoint: GET /stories/:slug/persona"}, "properties": {"repobilityId": "e3551bf42c620328", "scanner": "scanner-primary", "fingerprint": "5fe5100968b84060", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-412be719aa2c3037", "level": "note", "message": {"text": "Unused endpoint: POST /stories/:slug/rename"}, "properties": {"repobilityId": "d5ec62e7e712f4b8", "scanner": "scanner-primary", "fingerprint": "412be719aa2c3037", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-ca91ca9600e81e08", "level": "note", "message": {"text": "Unused endpoint: POST /stories/:slug/change-slug"}, "properties": {"repobilityId": "79fd8f592164a064", "scanner": "scanner-primary", "fingerprint": "ca91ca9600e81e08", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-54131a7b3bf0fe55", "level": "note", "message": {"text": "Unused endpoint: DELETE /stories/:slug"}, "properties": {"repobilityId": "bf40f3cc9f303ecc", "scanner": "scanner-primary", "fingerprint": "54131a7b3bf0fe55", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}]}]}