{"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": "foundry_unresolved_feedback", "name": "Foundry mined unresolved feedback: silviosotelo/esign-v3", "shortDescription": {"text": "Foundry mined unresolved feedback: silviosotelo/esign-v3"}, "fullDescription": {"text": "Graph query export: Human feedback without linked fix evidence\nQuery id: unresolved_feedback\nQuery type: motif_query\nIntent: Negative/unresolved examples that should not be hallucinated into fixes.\nMotif: unlinked_feedback_needs_evidence\nTraining usage: negative_or_unresolved\nGraph gold label: needs_more_evidence\nRepo: silviosotelo/esign-v3\nThread: silviosotelo/esign-v3#1\nEvidence:\nGraph motif: Human feedback exists without a linked fix\nMotif id: unlinked_feedback_needs_evidence\nPolarity: bad\nTraining usage: negative_or_unresolved\nSeverity: medium\nRepo: silviosotelo/esign-v3\nThread: silviosotelo/esign-v3#1\nGraph gold label: needs_more_evidence\nThread graph evidence:\nGitHub issue/PR evidence subgraph\nThread: silviosotelo/esign-v3#1\nRepo: silviosotelo/esign-v3\nIssue/PR number: 1\nGraph consistency label: needs_more_evidence\nNodes: 82\nEdges: 108\nNode types: {'pr_file': 73, 'link_quality': 3, 'thread': 1, 'repo': 1, 'comment': 1, 'comment_chain': 1, 'issue_chain': 1, 'fix_outcome': 1}\nEdge "}, "properties": {"scanner": "foundry_dataset", "category": "practices", "severity": "medium", "confidence": 0.7, "cwe": "", "owasp": ""}}, {"id": "foundry_schema_ui_api_gap", "name": "Foundry mined schema ui api mismatch: silviosotelo/esign-v3", "shortDescription": {"text": "Foundry mined schema ui api mismatch: silviosotelo/esign-v3"}, "fullDescription": {"text": "Graph query export: Schema, UI, and API mismatch\nQuery id: schema_ui_api_mismatch\nQuery type: motif_query\nIntent: Assumption-check examples for data-path consistency across layers.\nMotif: schema_ui_api_mismatch\nTraining usage: assumption_check\nGraph gold label: needs_more_evidence\nRepo: silviosotelo/esign-v3\nThread: silviosotelo/esign-v3#1\nEvidence:\nGraph motif: Schema, UI, and API evidence do not line up\nMotif id: schema_ui_api_mismatch\nPolarity: bad\nTraining usage: assumption_check\nSeverity: high\nRepo: silviosotelo/esign-v3\nThread: silviosotelo/esign-v3#1\nGraph gold label: needs_more_evidence\nThread graph evidence:\nGitHub issue/PR evidence subgraph\nThread: silviosotelo/esign-v3#1\nRepo: silviosotelo/esign-v3\nIssue/PR number: 1\nGraph consistency label: needs_more_evidence\nNodes: 82\nEdges: 108\nNode types: {'pr_file': 73, 'link_quality': 3, 'thread': 1, 'repo': 1, 'comment': 1, 'comment_chain': 1, 'issue_chain': 1, 'fix_outcome': 1}\nEdge types: {'thread_touches_file': 73, 'comment_chain_"}, "properties": {"scanner": "foundry_dataset", "category": "quality", "severity": "high", "confidence": 0.76, "cwe": "", "owasp": ""}}, {"id": "foundry_bad_chain", "name": "Foundry mined bad chains: silviosotelo/esign-v3", "shortDescription": {"text": "Foundry mined bad chains: silviosotelo/esign-v3"}, "fullDescription": {"text": "Comment chain pattern product: bad_chains\nRepo: silviosotelo/esign-v3\nThread: silviosotelo/esign-v3#1\nOutcome: not_resolved_or_not_observed\nThread label: thread_has_human_issue_without_fix_context\nSource graph label: source_backed_multi_signal_graph\nReasons: source_graph_has_real_artifacts, source_graph_has_verification_artifacts, repo_has_isolated_helicopter_views, link_quality_unresolved, high_risk_human_feedback_label\nChain evidence:\nIssue/PR evidence chain: silviosotelo/esign-v3#1\nRepo: silviosotelo/esign-v3\nThread label: thread_has_human_issue_without_fix_context\nOutcome: not_resolved_or_not_observed\nComment count: 1\nLinked commit count: 0\nLinked CI commit count: 0\nLinked CI labels: {}\nChanged file count: 73\nLabels: {'data_schema_persistence': 1}\nPolarities: {'bad': 1}\nChanged file labels: {'api_or_backend': 33, 'schema_or_data': 10, 'dependency_or_build': 1, 'ui_or_frontend': 28, 'source_or_other': 1}\nExamples:\n[\n  {\n    \"id\": \"github-feedback-comment-9bc4bf5981cfae6f\",\n    \"kind"}, "properties": {"scanner": "foundry_dataset", "category": "practices", "severity": "high", "confidence": 0.84, "cwe": "", "owasp": ""}}, {"id": "scanner-863085ab92899940", "name": "Stray `console.log` in TS/JS \u2014 frontend/src/components/PDFViewer.js:16", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 frontend/src/components/PDFViewer.js:16"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-25fe368bb58272c2", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/layout/Sidebar.jsx:91", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/layout/Sidebar.jsx:91"}, "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-4ce7f86a6864550f", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/layout/Header.jsx:78", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/layout/Header.jsx:78"}, "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-b32c451ff94d4312", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/fields/FieldPalette.jsx:40", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/fields/FieldPalette.jsx: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-d0070878b0bc51e6", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/fields/FieldBox.jsx:48", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/fields/FieldBox.jsx:48"}, "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-f30a3a8ba4edef76", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/app/(dashboard)/settings/page.js:489", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/app/(dashboard)/settings/page.js:489"}, "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-ea420bf555fd8504", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/app/(dashboard)/flows/page.js:125", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/app/(dashboard)/flows/page.js:125"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-29035f38b0e1f534", "name": "React Flow <MiniMap> without dark background \u2014 frontend/src/app/(dashboard)/flows/[id]/page.js:293", "shortDescription": {"text": "React Flow <MiniMap> without dark background \u2014 frontend/src/app/(dashboard)/flows/[id]/page.js:293"}, "fullDescription": {"text": "A bare <MiniMap> renders with the vendor's white default in dark themes. Wrap the canvas in a class that overrides `.react-flow__minimap` background, or pass an explicit `style`/`maskColor`/`bgColor`.\n\nWhy: P1 in CHECKLIST.md \u2014 vendor defaults bleed light through.\nRule id: fq.minimap.no-bg"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-5a84076697c53807", "name": "React Flow <Controls> without dark theming \u2014 frontend/src/app/(dashboard)/flows/[id]/page.js:292", "shortDescription": {"text": "React Flow <Controls> without dark theming \u2014 frontend/src/app/(dashboard)/flows/[id]/page.js:292"}, "fullDescription": {"text": "`<Controls>` ships with white buttons. Override `.react-flow__controls` and `.react-flow__controls-button` in your stylesheet or pass a styled wrapper.\n\nWhy: P1 in CHECKLIST.md \u2014 vendor defaults bleed light through.\nRule id: fq.controls.no-bg"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-06be8a943d600935", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/app/(dashboard)/flows/[id]/page.js:46", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/app/(dashboard)/flows/[id]/page.js:46"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-243722bbae13e51a", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/app/(dashboard)/notifications/page.js:321", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/app/(dashboard)/notifications/page.js:321"}, "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-37d6034264c64f0e", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/app/(dashboard)/dashboard/page.js:296", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/app/(dashboard)/dashboard/page.js:296"}, "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-f5a6c07d7592283b", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/app/(dashboard)/templates/page.js:275", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/app/(dashboard)/templates/page.js:275"}, "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-178065e765501036", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/app/(dashboard)/templates/[id]/edit/page.js:122", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/app/(dashboard)/templates/[id]/edit/page.js:122"}, "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-1a8f9ca9d8989990", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/app/(dashboard)/contracts/page.js:383", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/app/(dashboard)/contracts/page.js:383"}, "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-866d81b87da56849", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/app/(dashboard)/contracts/[id]/page.js:121", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/app/(dashboard)/contracts/[id]/page.js:121"}, "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-2592d82f2e66b031", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/app/(dashboard)/contracts/[id]/fields/page.js:186", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/app/(dashboard)/contracts/[id]/fields/page.js:186"}, "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-fbcb9b349c111f2e", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/app/sign/[token]/page.js:589", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/app/sign/[token]/page.js:589"}, "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-58038a7319d95fd5", "name": "TODO/FIXME marker in shipping code \u2014 backend/tests/integration/legacy.load.test.js:212", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 backend/tests/integration/legacy.load.test.js:212"}, "fullDescription": {"text": "Track in /reviews or /issues, not as a code comment that rots.\n\nWhy: Drift control \u2014 shouldn't be the same as Quality TODO scanner.\nRule id: fq.todo-marker"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-b47be7e50428ce16", "name": "TODO/FIXME marker in shipping code \u2014 backend/src/api/v1/tenants/index.js:112", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 backend/src/api/v1/tenants/index.js:112"}, "fullDescription": {"text": "Track in /reviews or /issues, not as a code comment that rots.\n\nWhy: Drift control \u2014 shouldn't be the same as Quality TODO scanner.\nRule id: fq.todo-marker"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-5a7ec00d3fc00502", "name": "Stray `console.log` in TS/JS \u2014 backend/src/scripts/loadLegacy.js:115", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/src/scripts/loadLegacy.js:115"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-3a4f67ada83a36c3", "name": "Stray `console.log` in TS/JS \u2014 backend/src/scripts/repairLegacyHashes.js:32", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/src/scripts/repairLegacyHashes.js:32"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-b2340f2365c62564", "name": "Stray `console.log` in TS/JS \u2014 backend/src/database/init.js:18", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/src/database/init.js:18"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-f22f3abf289d43d0", "name": "Stray `console.log` in TS/JS \u2014 backend/src/database/seeds/001_super_admin.js:13", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/src/database/seeds/001_super_admin.js:13"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-14b06fc455e87b1a", "name": "Stray `console.log` in TS/JS \u2014 backend/src/database/seeds/003_flow_templates.js:117", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/src/database/seeds/003_flow_templates.js:117"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-25242c282ad50610", "name": "Stray `console.log` in TS/JS \u2014 backend/src/database/seeds/002_default_templates.js:109", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/src/database/seeds/002_default_templates.js:109"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-c64026c3a348412b", "name": "TODO/FIXME marker in shipping code \u2014 backend/src/services/identity/providers/tekoProvider.js:26", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 backend/src/services/identity/providers/tekoProvider.js:26"}, "fullDescription": {"text": "Track in /reviews or /issues, not as a code comment that rots.\n\nWhy: Drift control \u2014 shouldn't be the same as Quality TODO scanner.\nRule id: fq.todo-marker"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-32c22842885b4dd3", "name": "Privileged port 34 in use", "shortDescription": {"text": "Privileged port 34 in use"}, "fullDescription": {"text": "Port 34 is privileged (<1024). Make sure the service runs with the right caps or front it with a non-privileged port via a load balancer."}, "properties": {"scanner": "scanner-primary", "layer": "network", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-60427b03771411b6", "name": "Dockerfile runs as root: frontend/Dockerfile", "shortDescription": {"text": "Dockerfile runs as root: frontend/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-a7f39cdd5fa21931", "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-1f66ad88286ca30a", "name": "Dockerfile runs as root: backend/Dockerfile", "shortDescription": {"text": "Dockerfile runs as root: backend/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-5ed7f5425f82efb4", "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-b37957a6b4d17c33", "name": "Insecure pattern 'local_storage_auth_token' in frontend/src/components/LoginForm.js:15", "shortDescription": {"text": "Insecure pattern 'local_storage_auth_token' in frontend/src/components/LoginForm.js:15"}, "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-dc53d4fe64ad5b15", "name": "Insecure pattern 'local_storage_auth_token' in frontend/src/lib/api.js:64", "shortDescription": {"text": "Insecure pattern 'local_storage_auth_token' in frontend/src/lib/api.js:64"}, "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-2ce2aa39f3c70d51", "name": "Insecure pattern 'local_storage_auth_token' in frontend/src/store/authStore.js:30", "shortDescription": {"text": "Insecure pattern 'local_storage_auth_token' in frontend/src/store/authStore.js:30"}, "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-836c365089f38992", "name": "Very large file: backend/src/api/v1/contracts/index.js (1363 lines)", "shortDescription": {"text": "Very large file: backend/src/api/v1/contracts/index.js (1363 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": "30 tests / 146 src (ratio 0.21)."}, "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-f45271c30a093938", "name": "Node manifest has dependencies but no lockfile: backend/src/package.json", "shortDescription": {"text": "Node manifest has dependencies but no lockfile: backend/src/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 31 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 88 placeholder/mock markers across 21 source files. This often means the repo looks complete while core flows still use generated scaffolding or fake data."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-2d0c7b7ab8f8aacf", "name": "Critical user flow still appears backed by mock or placeholder data", "shortDescription": {"text": "Critical user flow still appears backed by mock or placeholder data"}, "fullDescription": {"text": "A payment/auth/admin/order/billing-style flow contains mock, fake, TODO, dummy, or placeholder markers in runtime source. In the Fable corpus this is a high-leverage completeness smell: the app can look finished while the money, identity, or tenant flow is still scaffolded."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-b9088664ace7f748", "name": "Composite production-readiness gap", "shortDescription": {"text": "Composite production-readiness gap"}, "fullDescription": {"text": "Multiple low-cost hardening controls are missing together: license, 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": "low", "confidence": 1.0}}, {"id": "scanner-ea8f3013f588db25", "name": "Shallow git history limits provenance confidence", "shortDescription": {"text": "Shallow git history limits provenance confidence"}, "fullDescription": {"text": "The repository is a shallow clone. Origin/evolution analysis cannot distinguish fresh generation, imported legacy code, or long-lived human code with high confidence."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-8424db9c75e04ba4", "name": "Very short observed git history", "shortDescription": {"text": "Very short observed git history"}, "fullDescription": {"text": "The repo has multiple source files but two or fewer visible commits. This is not a failure by itself, but it lowers confidence in evolution-based diagnosis."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-b16c4d735fb2dc20", "name": "Commented-code block (5 lines) in frontend/src/components/fields/PdfFieldCanvas.jsx:5", "shortDescription": {"text": "Commented-code block (5 lines) in frontend/src/components/fields/PdfFieldCanvas.jsx: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-97d2eb4a8f870413", "name": "Commented-code block (6 lines) in frontend/src/app/(dashboard)/contracts/[id]/fields/page.js:3", "shortDescription": {"text": "Commented-code block (6 lines) in frontend/src/app/(dashboard)/contracts/[id]/fields/page.js: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-4e0aeb8d21603d6f", "name": "Legacy-named symbol `loadLegacy` in backend/tests/integration/legacy.load.test.js:2", "shortDescription": {"text": "Legacy-named symbol `loadLegacy` in backend/tests/integration/legacy.load.test.js:2"}, "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-b31170d959c5dc3d", "name": "Commented-code block (5 lines) in backend/src/api/v1/templates/index.js:44", "shortDescription": {"text": "Commented-code block (5 lines) in backend/src/api/v1/templates/index.js:44"}, "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-d2ba391317167fab", "name": "Commented-code block (5 lines) in backend/src/api/v1/branding/index.js:20", "shortDescription": {"text": "Commented-code block (5 lines) in backend/src/api/v1/branding/index.js:20"}, "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-cf93bd633d9a870a", "name": "Legacy-named symbol `loadLegacy` in backend/src/scripts/loadLegacy.js:6", "shortDescription": {"text": "Legacy-named symbol `loadLegacy` in backend/src/scripts/loadLegacy.js:6"}, "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-34e2e41fa2539b52", "name": "Commented-code block (7 lines) in backend/src/scripts/loadLegacy.js:214", "shortDescription": {"text": "Commented-code block (7 lines) in backend/src/scripts/loadLegacy.js:214"}, "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-ccb6d1e87778fe93", "name": "Commented-code block (9 lines) in backend/src/database/migrations/005_signature_flows.js:21", "shortDescription": {"text": "Commented-code block (9 lines) in backend/src/database/migrations/005_signature_flows.js:21"}, "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-799a4f2556fda79e", "name": "Commented-code block (7 lines) in backend/src/services/signature/signatureService.js:175", "shortDescription": {"text": "Commented-code block (7 lines) in backend/src/services/signature/signatureService.js:175"}, "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-cad046c72bad29d3", "name": "Commented-code block (5 lines) in backend/src/services/identity/providers/tekoProvider.js:26", "shortDescription": {"text": "Commented-code block (5 lines) in backend/src/services/identity/providers/tekoProvider.js:26"}, "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-ac6ce0e6d1dca97a", "name": "61 env vars used in code but missing from .env.example", "shortDescription": {"text": "61 env vars used in code but missing from .env.example"}, "fullDescription": {"text": "Drift between code and config docs. The first few: `APP_BASE_URL`, `CORS_ORIGINS`, `DB_DEBUG`, `DOCUMENT_DIRECTORY`, `EMAIL_FROM`, `EMAIL_HOST`, `EMAIL_PASSWORD`, `EMAIL_PORT` + 53 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-8292c0931391749a", "name": "Unused endpoint: POST /auth/register", "shortDescription": {"text": "Unused endpoint: POST /auth/register"}, "fullDescription": {"text": "`frontend/src/lib/api.js` declares `POST /auth/register` 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-b36892106ecdc9aa", "name": "Unused endpoint: POST /auth/refresh", "shortDescription": {"text": "Unused endpoint: POST /auth/refresh"}, "fullDescription": {"text": "`frontend/src/lib/api.js` declares `POST /auth/refresh` 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-c059f57186114027", "name": "Unused endpoint: POST /auth/logout", "shortDescription": {"text": "Unused endpoint: POST /auth/logout"}, "fullDescription": {"text": "`frontend/src/lib/api.js` declares `POST /auth/logout` 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-ac42422b23e45104", "name": "Unused endpoint: GET /auth/me", "shortDescription": {"text": "Unused endpoint: GET /auth/me"}, "fullDescription": {"text": "`frontend/src/lib/api.js` declares `GET /auth/me` 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-1e56771f48149c0b", "name": "Unused endpoint: PATCH /auth/me", "shortDescription": {"text": "Unused endpoint: PATCH /auth/me"}, "fullDescription": {"text": "`frontend/src/lib/api.js` declares `PATCH /auth/me` 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-7c28c4a0d2765ca6", "name": "Unused endpoint: POST /auth/2fa/setup", "shortDescription": {"text": "Unused endpoint: POST /auth/2fa/setup"}, "fullDescription": {"text": "`frontend/src/lib/api.js` declares `POST /auth/2fa/setup` 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-59cb6e2c914d4369", "name": "Unused endpoint: POST /auth/2fa/enable", "shortDescription": {"text": "Unused endpoint: POST /auth/2fa/enable"}, "fullDescription": {"text": "`frontend/src/lib/api.js` declares `POST /auth/2fa/enable` 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-4585c350da9e880d", "name": "Unused endpoint: POST /auth/change-password", "shortDescription": {"text": "Unused endpoint: POST /auth/change-password"}, "fullDescription": {"text": "`frontend/src/lib/api.js` declares `POST /auth/change-password` 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-13df96bc0886466a", "name": "Unused endpoint: GET /tenants/me", "shortDescription": {"text": "Unused endpoint: GET /tenants/me"}, "fullDescription": {"text": "`frontend/src/lib/api.js` declares `GET /tenants/me` 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-07ca93b9120f9713", "name": "Unused endpoint: PATCH /tenants/me", "shortDescription": {"text": "Unused endpoint: PATCH /tenants/me"}, "fullDescription": {"text": "`frontend/src/lib/api.js` declares `PATCH /tenants/me` 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-07bb77eeabde9f9c", "name": "Unused endpoint: GET /tenants/me/users", "shortDescription": {"text": "Unused endpoint: GET /tenants/me/users"}, "fullDescription": {"text": "`frontend/src/lib/api.js` declares `GET /tenants/me/users` 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-535d3a6cc160b8f4", "name": "Unused endpoint: POST /tenants/me/users/invite", "shortDescription": {"text": "Unused endpoint: POST /tenants/me/users/invite"}, "fullDescription": {"text": "`frontend/src/lib/api.js` declares `POST /tenants/me/users/invite` 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-bcc78b3655976a80", "name": "Unused endpoint: GET /oauth/clients", "shortDescription": {"text": "Unused endpoint: GET /oauth/clients"}, "fullDescription": {"text": "`frontend/src/lib/api.js` declares `GET /oauth/clients` 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-e0bd5555c5617d29", "name": "Unused endpoint: POST /oauth/clients", "shortDescription": {"text": "Unused endpoint: POST /oauth/clients"}, "fullDescription": {"text": "`frontend/src/lib/api.js` declares `POST /oauth/clients` 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-1acc5b65952c49f9", "name": "Unused endpoint: GET /contracts/stats", "shortDescription": {"text": "Unused endpoint: GET /contracts/stats"}, "fullDescription": {"text": "`frontend/src/lib/api.js` declares `GET /contracts/stats` 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-de13d3a35d08cc8e", "name": "Unused endpoint: GET /contracts", "shortDescription": {"text": "Unused endpoint: GET /contracts"}, "fullDescription": {"text": "`frontend/src/lib/api.js` declares `GET /contracts` 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-d9b2535a290d486e", "name": "Unused endpoint: POST /contracts", "shortDescription": {"text": "Unused endpoint: POST /contracts"}, "fullDescription": {"text": "`frontend/src/lib/api.js` declares `POST /contracts` 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-a3a7cfb0e400fc68", "name": "Unused endpoint: POST /contracts/template/variables", "shortDescription": {"text": "Unused endpoint: POST /contracts/template/variables"}, "fullDescription": {"text": "`frontend/src/lib/api.js` declares `POST /contracts/template/variables` 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-017394171548a2b2", "name": "Unused endpoint: GET /templates", "shortDescription": {"text": "Unused endpoint: GET /templates"}, "fullDescription": {"text": "`frontend/src/lib/api.js` declares `GET /templates` 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-2b73958ead43e47d", "name": "Unused endpoint: POST /templates", "shortDescription": {"text": "Unused endpoint: POST /templates"}, "fullDescription": {"text": "`frontend/src/lib/api.js` declares `POST /templates` 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-143475d4c22c9819", "name": "Unused endpoint: POST /templates/blank", "shortDescription": {"text": "Unused endpoint: POST /templates/blank"}, "fullDescription": {"text": "`frontend/src/lib/api.js` declares `POST /templates/blank` 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-8dfdaa61a04e0f15", "name": "Unused endpoint: GET /flows", "shortDescription": {"text": "Unused endpoint: GET /flows"}, "fullDescription": {"text": "`frontend/src/lib/api.js` declares `GET /flows` 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-c610883e7c445749", "name": "Unused endpoint: POST /flows", "shortDescription": {"text": "Unused endpoint: POST /flows"}, "fullDescription": {"text": "`frontend/src/lib/api.js` declares `POST /flows` 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-9d5282b056e1fef4", "name": "Unused endpoint: GET /notifications/templates", "shortDescription": {"text": "Unused endpoint: GET /notifications/templates"}, "fullDescription": {"text": "`frontend/src/lib/api.js` declares `GET /notifications/templates` 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-a3c51b4548adcf10", "name": "Unused endpoint: POST /notifications/templates", "shortDescription": {"text": "Unused endpoint: POST /notifications/templates"}, "fullDescription": {"text": "`frontend/src/lib/api.js` declares `POST /notifications/templates` 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-c69979eb34db974c", "name": "Unused endpoint: GET /notifications/logs", "shortDescription": {"text": "Unused endpoint: GET /notifications/logs"}, "fullDescription": {"text": "`frontend/src/lib/api.js` declares `GET /notifications/logs` 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-abd445b038693a3f", "name": "Unused endpoint: POST /notifications/send/email", "shortDescription": {"text": "Unused endpoint: POST /notifications/send/email"}, "fullDescription": {"text": "`frontend/src/lib/api.js` declares `POST /notifications/send/email` 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-a8ce623cef7d6ed3", "name": "Unused endpoint: POST /notifications/send/whatsapp", "shortDescription": {"text": "Unused endpoint: POST /notifications/send/whatsapp"}, "fullDescription": {"text": "`frontend/src/lib/api.js` declares `POST /notifications/send/whatsapp` 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-ec5073cba5362010", "name": "Unused endpoint: GET /webhooks", "shortDescription": {"text": "Unused endpoint: GET /webhooks"}, "fullDescription": {"text": "`frontend/src/lib/api.js` declares `GET /webhooks` 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-fcf74c0015b4c952", "name": "Unused endpoint: POST /webhooks", "shortDescription": {"text": "Unused endpoint: POST /webhooks"}, "fullDescription": {"text": "`frontend/src/lib/api.js` declares `POST /webhooks` 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-c32b4607df0975e2", "name": "Unused endpoint: GET /api-keys", "shortDescription": {"text": "Unused endpoint: GET /api-keys"}, "fullDescription": {"text": "`frontend/src/lib/api.js` declares `GET /api-keys` 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-224cbb7548a6b13c", "name": "Unused endpoint: POST /api-keys", "shortDescription": {"text": "Unused endpoint: POST /api-keys"}, "fullDescription": {"text": "`frontend/src/lib/api.js` declares `POST /api-keys` 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-e34f02337c261a05", "name": "Unused endpoint: GET /branding", "shortDescription": {"text": "Unused endpoint: GET /branding"}, "fullDescription": {"text": "`frontend/src/lib/api.js` declares `GET /branding` 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-8ffa5c735d594215", "name": "Unused endpoint: PUT /branding", "shortDescription": {"text": "Unused endpoint: PUT /branding"}, "fullDescription": {"text": "`frontend/src/lib/api.js` declares `PUT /branding` 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-3072d05b1a69ed8b", "name": "Unused endpoint: POST /bulk/from-template", "shortDescription": {"text": "Unused endpoint: POST /bulk/from-template"}, "fullDescription": {"text": "`frontend/src/lib/api.js` declares `POST /bulk/from-template` 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-785a6131d850d7c6", "name": "Unused endpoint: GET /bulk/jobs", "shortDescription": {"text": "Unused endpoint: GET /bulk/jobs"}, "fullDescription": {"text": "`frontend/src/lib/api.js` declares `GET /bulk/jobs` 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-dd159bd05997c05c", "name": "Unused endpoint: GET /admin/stats", "shortDescription": {"text": "Unused endpoint: GET /admin/stats"}, "fullDescription": {"text": "`frontend/src/lib/api.js` declares `GET /admin/stats` 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-2273ac666d251484", "name": "Unused endpoint: GET /admin/plans", "shortDescription": {"text": "Unused endpoint: GET /admin/plans"}, "fullDescription": {"text": "`frontend/src/lib/api.js` declares `GET /admin/plans` 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-6c9282666b199ce9", "name": "Unused endpoint: GET /admin/audit", "shortDescription": {"text": "Unused endpoint: GET /admin/audit"}, "fullDescription": {"text": "`frontend/src/lib/api.js` declares `GET /admin/audit` 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-0aba7f1883cb96f2", "name": "Unused endpoint: GET /admin/users", "shortDescription": {"text": "Unused endpoint: GET /admin/users"}, "fullDescription": {"text": "`frontend/src/lib/api.js` declares `GET /admin/users` 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-61858cb8c2841124", "name": "Unused endpoint: GET /admin/tenants", "shortDescription": {"text": "Unused endpoint: GET /admin/tenants"}, "fullDescription": {"text": "`frontend/src/lib/api.js` declares `GET /admin/tenants` 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-cc6dc53aa8b9accd", "name": "Unused endpoint: POST /admin/tenants", "shortDescription": {"text": "Unused endpoint: POST /admin/tenants"}, "fullDescription": {"text": "`frontend/src/lib/api.js` declares `POST /admin/tenants` 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-76889df7c8e240c5", "name": "Unused endpoint: USE /api/", "shortDescription": {"text": "Unused endpoint: USE /api/"}, "fullDescription": {"text": "`backend/src/app.js` 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-6f9d80087bdb9ee9", "name": "Unused endpoint: USE /api/v1/auth/", "shortDescription": {"text": "Unused endpoint: USE /api/v1/auth/"}, "fullDescription": {"text": "`backend/src/app.js` declares `USE /api/v1/auth/` 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-9696bcc3e59d0856", "name": "Unused endpoint: USE /api/v1/webhooks/whatsapp", "shortDescription": {"text": "Unused endpoint: USE /api/v1/webhooks/whatsapp"}, "fullDescription": {"text": "`backend/src/app.js` declares `USE /api/v1/webhooks/whatsapp` 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-3bec7ccd0b909bea", "name": "Unused endpoint: USE /api/v1/auth", "shortDescription": {"text": "Unused endpoint: USE /api/v1/auth"}, "fullDescription": {"text": "`backend/src/app.js` declares `USE /api/v1/auth` 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-a6bdfc267cbeb804", "name": "Unused endpoint: USE /api/v1/tenants", "shortDescription": {"text": "Unused endpoint: USE /api/v1/tenants"}, "fullDescription": {"text": "`backend/src/app.js` declares `USE /api/v1/tenants` 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-4b1afd0ba2b8f574", "name": "Unused endpoint: USE /api/v1/users", "shortDescription": {"text": "Unused endpoint: USE /api/v1/users"}, "fullDescription": {"text": "`backend/src/app.js` declares `USE /api/v1/users` 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-7ab1341d8c478a3b", "name": "Unused endpoint: USE /api/v1/contracts", "shortDescription": {"text": "Unused endpoint: USE /api/v1/contracts"}, "fullDescription": {"text": "`backend/src/app.js` declares `USE /api/v1/contracts` 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-74dc8be8b2b4c7e6", "name": "Unused endpoint: USE /api/v1/flows", "shortDescription": {"text": "Unused endpoint: USE /api/v1/flows"}, "fullDescription": {"text": "`backend/src/app.js` declares `USE /api/v1/flows` 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/19653"}, "properties": {"repository": "silviosotelo/esign-v3", "repoUrl": "https://github.com/silviosotelo/esign-v3", "branch": "main"}, "results": [{"ruleId": "foundry_unresolved_feedback", "level": "warning", "message": {"text": "Foundry mined unresolved feedback: silviosotelo/esign-v3"}, "properties": {"repobilityId": 467225, "scanner": "foundry_dataset", "fingerprint": "f2413e0ecb3175fde9f7dad8123bcef8cf02c8a421bb78bb25ef538291e222ad", "category": "practices", "severity": "medium", "confidence": 0.7, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Imported from mined Foundry/Fable5 evidence with real GitHub/source provenance. Review source_id before acting.", "evidence": {"meta": {"kind": "graph_query_record", "title": "Human feedback without linked fix evidence", "intent": "Negative/unresolved examples that should not be hallucinated into fixes.", "labels": {"api_or_backend": 33, "schema_or_data": 10, "ui_or_frontend": 28, "source_or_other": 1, "dependency_or_build": 1, "data_schema_persistence": 1, "issue_or_pull_request_thread": 1, "not_resolved_or_not_observed": 3, "human_reported_issue_no_linked_fix": 1, "thread_has_human_issue_without_fix_context": 2}, "source": "graph_query_export", "motif_id": "unlinked_feedback_needs_evidence", "outcomes": {"not_resolved_or_not_observed": 6}, "polarity": "bad", "query_id": "unresolved_feedback", "severity": "medium", "ci_labels": {}, "synthetic": false, "edge_count": 108, "edge_types": {"repo_has_thread": 1, "comment_has_chain": 1, "thread_has_comment": 1, "thread_touches_file": 73, "chain_has_link_quality": 3, "thread_has_fix_outcome": 1, "thread_has_issue_chain": 1, "issue_chain_touches_file": 12, "thread_has_comment_chain": 1, "comment_chain_touches_file": 12, "issue_chain_has_fix_outcome": 1, "issue_chain_has_comment_chain": 1}, "node_count": 82, "node_types": {"repo": 1, "thread": 1, "comment": 1, "pr_file": 73, "fix_outcome": 1, "issue_chain": 1, "link_quality": 3, "comment_chain": 1}, "query_type": "motif_query", "thread_key": "silviosotelo/esign-v3#1", "issue_number": "1", "quality_tiers": {"unresolved": 3}, "repo_full_name": "silviosotelo/esign-v3", "training_usage": "negative_or_unresolved", "source_motif_id": "graph-pattern-motif-thread-5b98378c1d0041f6", "graph_gold_label": "needs_more_evidence", "changed_file_labels": {"api_or_backend": 132, "schema_or_data": 40, "ui_or_frontend": 112, "source_or_other": 4, "dependency_or_build": 4}}, "text": "Graph query export: Human feedback without linked fix evidence\nQuery id: unresolved_feedback\nQuery type: motif_query\nIntent: Negative/unresolved examples that should not be hallucinated into fixes.\nMotif: unlinked_feedback_needs_evidence\nTraining usage: negative_or_unresolved\nGraph gold label: needs_more_evidence\nRepo: silviosotelo/esign-v3\nThread: silviosotelo/esign-v3#1\nEvidence:\nGraph motif: Human feedback exists without a linked fix\nMotif id: unlinked_feedback_needs_evidence\nPolarity: bad\nTraining usage: negative_or_unresolved\nSeverity: medium\nRepo: silviosotelo/esign-v3\nThread: silviosotelo/esign-v3#1\nGraph gold label: needs_more_evidence\nThread graph evidence:\nGitHub issue/PR evidence subgraph\nThread: silviosotelo/esign-v3#1\nRepo: silviosotelo/esign-v3\nIssue/PR number: 1\nGraph consistency label: needs_more_evidence\nNodes: 82\nEdges: 108\nNode types: {'pr_file': 73, 'link_quality': 3, 'thread': 1, 'repo': 1, 'comment': 1, 'comment_chain': 1, 'issue_chain': 1, 'fix_outcome': 1}\nEdge types: {'thread_touches_file': 73, 'comment_chain_touches_file': 12, 'issue_chain_touches_file': 12, 'chain_has_link_quality': 3, 'repo_has_thread': 1, 'thread_has_comment': 1, 'thread_has_comment_chain': 1, 'comment_has_chain': 1, 'thread_has_issue_chain': 1, 'issue_chain_has_comment_chain': 1, 'thread_has_fix_outcome': 1, 'issue_chain_has_fix_outcome': 1}\nLabels: {'api_or_backend': 33, 'ui_or_frontend': 28, 'schema_or_data': 10, 'not_resolved_or_not_observed': 3, 'thread_has_human_issue_without_fix_context': 2, 'issue_or_pull_request_thread': 1, 'data_schema_persistence': 1, 'dependency_or_build': 1, 'source_or_other': 1, 'human_reported_issue_no_linked_fix': 1}\nOutcomes: {'not_resolved_or_not_observed': 6}\nQuality tiers: {'unresolved': 3}\nCI labels: {}\nCurriculum targets:\n- Teach models to preserve unresolved human feedback instead of hallucinating fixes.\n- Build issue-to-regression examples where no accepted fix exists yet.\nAssumption checks:\n- Can a commit be linked by issue number, SHA, changed path, or time window?\n- If no link exists, is this explicitly labelled unresolved?", "source": "foundry_mined_dataset", "repo_url": "https://github.com/silviosotelo/esign-v3", "source_id": "graph-query-motif_query-5caaf1eedd18a58f", "synthetic": false, "gold_label": "", "graph_label": "", "source_path": "/data/distillate/foundry_data/graph_queries/unresolved_feedback/shard-0.jsonl", "bundle_label": "", "priority_band": "", "priority_score": 0, "repo_full_name": "silviosotelo/esign-v3", "source_dataset": "graph_queries/unresolved_feedback", "training_usage": "negative_or_unresolved"}}}, {"ruleId": "foundry_schema_ui_api_gap", "level": "error", "message": {"text": "Foundry mined schema ui api mismatch: silviosotelo/esign-v3"}, "properties": {"repobilityId": 453845, "scanner": "foundry_dataset", "fingerprint": "f156dcf05d4d2de7c7c9a36b5f3b4f96665ac17e11aaf230bb1521820c7d23eb", "category": "quality", "severity": "high", "confidence": 0.76, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Imported from mined Foundry/Fable5 evidence with real GitHub/source provenance. Review source_id before acting.", "evidence": {"meta": {"kind": "graph_query_record", "title": "Schema, UI, and API mismatch", "intent": "Assumption-check examples for data-path consistency across layers.", "labels": {"api_or_backend": 33, "schema_or_data": 10, "ui_or_frontend": 28, "source_or_other": 1, "dependency_or_build": 1, "data_schema_persistence": 1, "issue_or_pull_request_thread": 1, "not_resolved_or_not_observed": 3, "human_reported_issue_no_linked_fix": 1, "thread_has_human_issue_without_fix_context": 2}, "source": "graph_query_export", "motif_id": "schema_ui_api_mismatch", "outcomes": {"not_resolved_or_not_observed": 6}, "polarity": "bad", "query_id": "schema_ui_api_mismatch", "severity": "high", "ci_labels": {}, "synthetic": false, "edge_count": 108, "edge_types": {"repo_has_thread": 1, "comment_has_chain": 1, "thread_has_comment": 1, "thread_touches_file": 73, "chain_has_link_quality": 3, "thread_has_fix_outcome": 1, "thread_has_issue_chain": 1, "issue_chain_touches_file": 12, "thread_has_comment_chain": 1, "comment_chain_touches_file": 12, "issue_chain_has_fix_outcome": 1, "issue_chain_has_comment_chain": 1}, "node_count": 82, "node_types": {"repo": 1, "thread": 1, "comment": 1, "pr_file": 73, "fix_outcome": 1, "issue_chain": 1, "link_quality": 3, "comment_chain": 1}, "query_type": "motif_query", "thread_key": "silviosotelo/esign-v3#1", "issue_number": "1", "quality_tiers": {"unresolved": 3}, "repo_full_name": "silviosotelo/esign-v3", "training_usage": "assumption_check", "source_motif_id": "graph-pattern-motif-thread-6eb66689c7135fe0", "graph_gold_label": "needs_more_evidence", "changed_file_labels": {"api_or_backend": 132, "schema_or_data": 40, "ui_or_frontend": 112, "source_or_other": 4, "dependency_or_build": 4}}, "text": "Graph query export: Schema, UI, and API mismatch\nQuery id: schema_ui_api_mismatch\nQuery type: motif_query\nIntent: Assumption-check examples for data-path consistency across layers.\nMotif: schema_ui_api_mismatch\nTraining usage: assumption_check\nGraph gold label: needs_more_evidence\nRepo: silviosotelo/esign-v3\nThread: silviosotelo/esign-v3#1\nEvidence:\nGraph motif: Schema, UI, and API evidence do not line up\nMotif id: schema_ui_api_mismatch\nPolarity: bad\nTraining usage: assumption_check\nSeverity: high\nRepo: silviosotelo/esign-v3\nThread: silviosotelo/esign-v3#1\nGraph gold label: needs_more_evidence\nThread graph evidence:\nGitHub issue/PR evidence subgraph\nThread: silviosotelo/esign-v3#1\nRepo: silviosotelo/esign-v3\nIssue/PR number: 1\nGraph consistency label: needs_more_evidence\nNodes: 82\nEdges: 108\nNode types: {'pr_file': 73, 'link_quality': 3, 'thread': 1, 'repo': 1, 'comment': 1, 'comment_chain': 1, 'issue_chain': 1, 'fix_outcome': 1}\nEdge types: {'thread_touches_file': 73, 'comment_chain_touches_file': 12, 'issue_chain_touches_file': 12, 'chain_has_link_quality': 3, 'repo_has_thread': 1, 'thread_has_comment': 1, 'thread_has_comment_chain': 1, 'comment_has_chain': 1, 'thread_has_issue_chain': 1, 'issue_chain_has_comment_chain': 1, 'thread_has_fix_outcome': 1, 'issue_chain_has_fix_outcome': 1}\nLabels: {'api_or_backend': 33, 'ui_or_frontend': 28, 'schema_or_data': 10, 'not_resolved_or_not_observed': 3, 'thread_has_human_issue_without_fix_context': 2, 'issue_or_pull_request_thread': 1, 'data_schema_persistence': 1, 'dependency_or_build': 1, 'source_or_other': 1, 'human_reported_issue_no_linked_fix': 1}\nOutcomes: {'not_resolved_or_not_observed': 6}\nQuality tiers: {'unresolved': 3}\nCI labels: {}\nCurriculum targets:\n- Create schema-to-API-to-UI consistency tasks with migrations and tests.\n- Teach models to verify persistence, route contracts, and UI state together.\nAssumption checks:\n- Do schema changes have matching API and UI handling?\n- Are migrations and tests present for the data path?", "source": "foundry_mined_dataset", "repo_url": "https://github.com/silviosotelo/esign-v3", "source_id": "graph-query-motif_query-54ab2711b7670132", "synthetic": false, "gold_label": "", "graph_label": "", "source_path": "/data/distillate/foundry_data/graph_queries/schema_ui_api_mismatch/shard-0.jsonl", "bundle_label": "", "priority_band": "", "priority_score": 0, "repo_full_name": "silviosotelo/esign-v3", "source_dataset": "graph_queries/schema_ui_api_mismatch", "training_usage": "assumption_check"}}}, {"ruleId": "foundry_bad_chain", "level": "error", "message": {"text": "Foundry mined bad chains: silviosotelo/esign-v3"}, "properties": {"repobilityId": 444928, "scanner": "foundry_dataset", "fingerprint": "5766f913b173e04497d2de44a1afeb719ce53b68ec7e9c230ebb81bdd03c618c", "category": "practices", "severity": "high", "confidence": 0.84, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Imported from mined Foundry/Fable5 evidence with real GitHub/source provenance. Review source_id before acting.", "evidence": {"meta": {"kind": "comment_chain_pattern_product", "source": "comment_chain_pattern_miner", "product": "bad_chains", "synthetic": false, "thread_key": "silviosotelo/esign-v3#1", "human_labels": ["api_or_backend", "data_schema_persistence", "dependency_or_build", "schema_or_data", "source_or_other", "ui_or_frontend"], "issue_number": "1", "thread_label": "thread_has_human_issue_without_fix_context", "outcome_label": "not_resolved_or_not_observed", "source_backed": true, "max_confidence": 0.0, "repo_full_name": "silviosotelo/esign-v3", "training_usage": "negative_or_unresolved", "confidence_tier": "unresolved", "source_chain_id": "evidence-chain-issue_chain-7c1f426867dc4543", "helicopter_views": {"graphs": 2, "schemas": 2}, "artifact_families": {"ci": 4, "docs": 3, "architecture": 1}, "source_chain_kind": "issue_chain", "changed_file_count": 73, "source_graph_label": "source_backed_multi_signal_graph", "changed_file_labels": {"api_or_backend": 33, "schema_or_data": 10, "ui_or_frontend": 28, "source_or_other": 1, "dependency_or_build": 1}, "linked_commit_count": 0, "helicopter_view_count": 4, "source_artifact_count": 8, "classification_reasons": ["source_graph_has_real_artifacts", "source_graph_has_verification_artifacts", "repo_has_isolated_helicopter_views", "link_quality_unresolved", "high_risk_human_feedback_label"], "linked_ci_commit_count": 0, "verification_artifact_count": 4, "design_schema_api_artifact_count": 1}, "text": "Comment chain pattern product: bad_chains\nRepo: silviosotelo/esign-v3\nThread: silviosotelo/esign-v3#1\nOutcome: not_resolved_or_not_observed\nThread label: thread_has_human_issue_without_fix_context\nSource graph label: source_backed_multi_signal_graph\nReasons: source_graph_has_real_artifacts, source_graph_has_verification_artifacts, repo_has_isolated_helicopter_views, link_quality_unresolved, high_risk_human_feedback_label\nChain evidence:\nIssue/PR evidence chain: silviosotelo/esign-v3#1\nRepo: silviosotelo/esign-v3\nThread label: thread_has_human_issue_without_fix_context\nOutcome: not_resolved_or_not_observed\nComment count: 1\nLinked commit count: 0\nLinked CI commit count: 0\nLinked CI labels: {}\nChanged file count: 73\nLabels: {'data_schema_persistence': 1}\nPolarities: {'bad': 1}\nChanged file labels: {'api_or_backend': 33, 'schema_or_data': 10, 'dependency_or_build': 1, 'ui_or_frontend': 28, 'source_or_other': 1}\nExamples:\n[\n  {\n    \"id\": \"github-feedback-comment-9bc4bf5981cfae6f\",\n    \"kind\": \"pull_request_body\",\n    \"label\": \"data_schema_persistence\",\n    \"polarity\": \"bad\",\n    \"url\": \"https://github.com/silviosotelo/esign-v3/pull/1\",\n    \"text\": \"GitHub feedback: data_schema_persistence\\nPolarity: bad\\nKind: pull_request_body\\nRepo: silviosotelo/esign-v3\\nAuthor: silviosotelo (User)\\nURL: https://github.com/silviosotelo/esign-v3/pull/1\\nTitle: Refactor signature handling with unified array and AES-256-GCM encryption\\nBody:\\n## Summary\\nThis PR refactors the contract signature system to use a unified `additionalSignatures` array that accumulates all signatures (client + additional signers) with proper ordering and metadata. It also upgrades cryptographic operations from AES-256-CBC to AES-256-GCM with HMAC verification, implements async key derivation, and adds supporting services for caching, metrics, and job queuing.\\n\\n## Key Changes\\n\\n### Signature Management\\n- **Unified signature array**: `additionalSignatures` now contains all signatures (client at position 0, then additional signers in order), eliminating separate handling logic\\n- **Signature ordering**: Added `order` field to track signature sequence; client signature always appears first regardless of insertion order\\n- **Deduplication**: Prevents duplicate signatures from the same user/type before insertion; replaces same-type signatures while preserving client signature\\n- **Me\"\n  }\n]\nChanged files:\n[\n  {\n    \"id\": \"github-pr-file-file-5d5e230fb2a0bc92\",\n    \"filename\": \"backend/services/cacheService.js\",\n    \"label\": \"api_or_backend\",\n    \"status\": \"added\",\n    \"additions\": 76,\n    \"deletions\": 0,\n    \"changes\": 76,\n    \"blob_url\": \"https://github.com/silviosotelo/esign-v3/blob/a0693ff7d53089881bee026fc91293aeeac362a9/backend%2Fservices%2FcacheService.js\"\n  },\n  {\n    \"id\": \"github-pr-file-file-52ab812b2645ce04\",\n    \"filename\": \"backend/services/contractService.js\",\n    \"label\": \"api_or_backend\",\n    \"status\": \"modified\",\n    \"additions\": 246,\n    \"dele\n[truncated by importer]", "source": "foundry_mined_dataset", "repo_url": "https://github.com/silviosotelo/esign-v3", "source_id": "comment-chain-pattern-bad_chains-1e2f25c3964b11c8", "synthetic": false, "gold_label": "", "graph_label": "source_backed_multi_signal_graph", "source_path": "/data/distillate/foundry_data/comment_chain_patterns/bad_chains/shard-0.jsonl", "bundle_label": "", "priority_band": "", "priority_score": 0, "repo_full_name": "silviosotelo/esign-v3", "source_dataset": "comment_chain_patterns/bad_chains", "training_usage": "negative_or_unresolved"}}}, {"ruleId": "scanner-863085ab92899940", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 frontend/src/components/PDFViewer.js:16"}, "properties": {"repobilityId": "651a2f15cf44d85d", "scanner": "scanner-primary", "fingerprint": "863085ab92899940", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-25fe368bb58272c2", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/layout/Sidebar.jsx:91"}, "properties": {"repobilityId": "b08aca2f4d1ee6ca", "scanner": "scanner-primary", "fingerprint": "25fe368bb58272c2", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-4ce7f86a6864550f", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/layout/Header.jsx:78"}, "properties": {"repobilityId": "96f3be75b10964ce", "scanner": "scanner-primary", "fingerprint": "4ce7f86a6864550f", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-b32c451ff94d4312", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/fields/FieldPalette.jsx:40"}, "properties": {"repobilityId": "384ee4abc7c4fb53", "scanner": "scanner-primary", "fingerprint": "b32c451ff94d4312", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-d0070878b0bc51e6", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/fields/FieldBox.jsx:48"}, "properties": {"repobilityId": "9113bb5c6e951354", "scanner": "scanner-primary", "fingerprint": "d0070878b0bc51e6", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-f30a3a8ba4edef76", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/app/(dashboard)/settings/page.js:489"}, "properties": {"repobilityId": "b5419fd7f47566eb", "scanner": "scanner-primary", "fingerprint": "f30a3a8ba4edef76", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-ea420bf555fd8504", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/app/(dashboard)/flows/page.js:125"}, "properties": {"repobilityId": "6b219cb281c54339", "scanner": "scanner-primary", "fingerprint": "ea420bf555fd8504", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-29035f38b0e1f534", "level": "note", "message": {"text": "React Flow <MiniMap> without dark background \u2014 frontend/src/app/(dashboard)/flows/[id]/page.js:293"}, "properties": {"repobilityId": "357b049d8b5bb81c", "scanner": "scanner-primary", "fingerprint": "29035f38b0e1f534", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.minimap.no-bg"]}}, {"ruleId": "scanner-5a84076697c53807", "level": "note", "message": {"text": "React Flow <Controls> without dark theming \u2014 frontend/src/app/(dashboard)/flows/[id]/page.js:292"}, "properties": {"repobilityId": "f552e8416851ff94", "scanner": "scanner-primary", "fingerprint": "5a84076697c53807", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.controls.no-bg"]}}, {"ruleId": "scanner-06be8a943d600935", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/app/(dashboard)/flows/[id]/page.js:46"}, "properties": {"repobilityId": "354e83817a470e51", "scanner": "scanner-primary", "fingerprint": "06be8a943d600935", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-243722bbae13e51a", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/app/(dashboard)/notifications/page.js:321"}, "properties": {"repobilityId": "d7d965d5ddb883cd", "scanner": "scanner-primary", "fingerprint": "243722bbae13e51a", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-37d6034264c64f0e", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/app/(dashboard)/dashboard/page.js:296"}, "properties": {"repobilityId": "d970465e3ec3ac5c", "scanner": "scanner-primary", "fingerprint": "37d6034264c64f0e", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-f5a6c07d7592283b", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/app/(dashboard)/templates/page.js:275"}, "properties": {"repobilityId": "9deb66870d2ecc14", "scanner": "scanner-primary", "fingerprint": "f5a6c07d7592283b", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-178065e765501036", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/app/(dashboard)/templates/[id]/edit/page.js:122"}, "properties": {"repobilityId": "c60eb1ce494caad0", "scanner": "scanner-primary", "fingerprint": "178065e765501036", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-1a8f9ca9d8989990", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/app/(dashboard)/contracts/page.js:383"}, "properties": {"repobilityId": "5de30c3a38a24bbb", "scanner": "scanner-primary", "fingerprint": "1a8f9ca9d8989990", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-866d81b87da56849", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/app/(dashboard)/contracts/[id]/page.js:121"}, "properties": {"repobilityId": "f9a03d7581954753", "scanner": "scanner-primary", "fingerprint": "866d81b87da56849", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-2592d82f2e66b031", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/app/(dashboard)/contracts/[id]/fields/page.js:186"}, "properties": {"repobilityId": "c13d00e1df37778d", "scanner": "scanner-primary", "fingerprint": "2592d82f2e66b031", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-fbcb9b349c111f2e", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/app/sign/[token]/page.js:589"}, "properties": {"repobilityId": "29a963da99714fdf", "scanner": "scanner-primary", "fingerprint": "fbcb9b349c111f2e", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-58038a7319d95fd5", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 backend/tests/integration/legacy.load.test.js:212"}, "properties": {"repobilityId": "262592fddfc79301", "scanner": "scanner-primary", "fingerprint": "58038a7319d95fd5", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-b47be7e50428ce16", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 backend/src/api/v1/tenants/index.js:112"}, "properties": {"repobilityId": "d9b700603cc458fb", "scanner": "scanner-primary", "fingerprint": "b47be7e50428ce16", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-5a7ec00d3fc00502", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/src/scripts/loadLegacy.js:115"}, "properties": {"repobilityId": "56e73b7a200f8883", "scanner": "scanner-primary", "fingerprint": "5a7ec00d3fc00502", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-3a4f67ada83a36c3", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/src/scripts/repairLegacyHashes.js:32"}, "properties": {"repobilityId": "83e2e44e624134f2", "scanner": "scanner-primary", "fingerprint": "3a4f67ada83a36c3", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-b2340f2365c62564", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/src/database/init.js:18"}, "properties": {"repobilityId": "64f5751d238ac9c2", "scanner": "scanner-primary", "fingerprint": "b2340f2365c62564", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-f22f3abf289d43d0", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/src/database/seeds/001_super_admin.js:13"}, "properties": {"repobilityId": "1a6f70511459b93a", "scanner": "scanner-primary", "fingerprint": "f22f3abf289d43d0", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-14b06fc455e87b1a", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/src/database/seeds/003_flow_templates.js:117"}, "properties": {"repobilityId": "641d9ebac4807af9", "scanner": "scanner-primary", "fingerprint": "14b06fc455e87b1a", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-25242c282ad50610", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/src/database/seeds/002_default_templates.js:109"}, "properties": {"repobilityId": "233d61e8a8403e99", "scanner": "scanner-primary", "fingerprint": "25242c282ad50610", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-c64026c3a348412b", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 backend/src/services/identity/providers/tekoProvider.js:26"}, "properties": {"repobilityId": "3f8691cb9c8976b5", "scanner": "scanner-primary", "fingerprint": "c64026c3a348412b", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-32c22842885b4dd3", "level": "warning", "message": {"text": "Privileged port 34 in use"}, "properties": {"repobilityId": "2febb579b1c7080d", "scanner": "scanner-primary", "fingerprint": "32c22842885b4dd3", "layer": "network", "severity": "medium", "confidence": 1.0, "tags": ["security", "ports"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker-compose.yml"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-60427b03771411b6", "level": "warning", "message": {"text": "Dockerfile runs as root: frontend/Dockerfile"}, "properties": {"repobilityId": "735c01d8531dfd2c", "scanner": "scanner-primary", "fingerprint": "60427b03771411b6", "layer": "hardware", "severity": "medium", "confidence": 1.0, "tags": ["security", "container"]}}, {"ruleId": "scanner-a7f39cdd5fa21931", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: node:22-alpine"}, "properties": {"repobilityId": "6086a1867bf8e871", "scanner": "scanner-primary", "fingerprint": "a7f39cdd5fa21931", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/Dockerfile"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-a7f39cdd5fa21931", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: node:22-alpine"}, "properties": {"repobilityId": "028552d4bcdb10a8", "scanner": "scanner-primary", "fingerprint": "a7f39cdd5fa21931", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/Dockerfile"}, "region": {"startLine": 9}}}]}, {"ruleId": "scanner-1f66ad88286ca30a", "level": "warning", "message": {"text": "Dockerfile runs as root: backend/Dockerfile"}, "properties": {"repobilityId": "7afd2b0e8a8c9eeb", "scanner": "scanner-primary", "fingerprint": "1f66ad88286ca30a", "layer": "hardware", "severity": "medium", "confidence": 1.0, "tags": ["security", "container"]}}, {"ruleId": "scanner-5ed7f5425f82efb4", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: node:22-alpine"}, "properties": {"repobilityId": "de0efa60c3e9b0da", "scanner": "scanner-primary", "fingerprint": "5ed7f5425f82efb4", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/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-b37957a6b4d17c33", "level": "warning", "message": {"text": "Insecure pattern 'local_storage_auth_token' in frontend/src/components/LoginForm.js:15"}, "properties": {"repobilityId": "92e6da25d629d2a0", "scanner": "scanner-primary", "fingerprint": "b37957a6b4d17c33", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "local_storage_auth_token"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/src/components/LoginForm.js"}, "region": {"startLine": 15}}}]}, {"ruleId": "scanner-dc53d4fe64ad5b15", "level": "warning", "message": {"text": "Insecure pattern 'local_storage_auth_token' in frontend/src/lib/api.js:64"}, "properties": {"repobilityId": "c8b2a4977794b8bd", "scanner": "scanner-primary", "fingerprint": "dc53d4fe64ad5b15", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "local_storage_auth_token"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/src/lib/api.js"}, "region": {"startLine": 64}}}]}, {"ruleId": "scanner-2ce2aa39f3c70d51", "level": "warning", "message": {"text": "Insecure pattern 'local_storage_auth_token' in frontend/src/store/authStore.js:30"}, "properties": {"repobilityId": "0c219bad952e6629", "scanner": "scanner-primary", "fingerprint": "2ce2aa39f3c70d51", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "local_storage_auth_token"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/src/store/authStore.js"}, "region": {"startLine": 30}}}]}, {"ruleId": "scanner-836c365089f38992", "level": "note", "message": {"text": "Very large file: backend/src/api/v1/contracts/index.js (1363 lines)"}, "properties": {"repobilityId": "ad6232b69d889067", "scanner": "scanner-primary", "fingerprint": "836c365089f38992", "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": "a50c3c5ef3b72b72", "scanner": "scanner-primary", "fingerprint": "141b30a41e03817b", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["license", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-f45271c30a093938", "level": "note", "message": {"text": "Node manifest has dependencies but no lockfile: backend/src/package.json"}, "properties": {"repobilityId": "c1c0f462df1415ea", "scanner": "scanner-primary", "fingerprint": "f45271c30a093938", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["dependency", "lockfile", "reproducibility", "generated-repo-pattern"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/src/package.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-3ab5d313dda8e5f9", "level": "note", "message": {"text": "Debug logging residue appears in source files"}, "properties": {"repobilityId": "00eeb6ad3af01c44", "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": "b326edeaaf3481ad", "scanner": "scanner-primary", "fingerprint": "72b2a6250083a784", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "incomplete", "generated-repo-pattern"]}}, {"ruleId": "scanner-2d0c7b7ab8f8aacf", "level": "warning", "message": {"text": "Critical user flow still appears backed by mock or placeholder data"}, "properties": {"repobilityId": "d9747f7878141e93", "scanner": "scanner-primary", "fingerprint": "2d0c7b7ab8f8aacf", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "critical-flow", "generated-repo-pattern"]}}, {"ruleId": "scanner-b9088664ace7f748", "level": "note", "message": {"text": "Composite production-readiness gap"}, "properties": {"repobilityId": "4e4f14ae4c99717a", "scanner": "scanner-primary", "fingerprint": "b9088664ace7f748", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["production-readiness", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-ea8f3013f588db25", "level": "note", "message": {"text": "Shallow git history limits provenance confidence"}, "properties": {"repobilityId": "69febff1f541854a", "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": "b1269dc448aa63d4", "scanner": "scanner-primary", "fingerprint": "8424db9c75e04ba4", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["provenance", "git-history", "generated-repo-pattern"]}}, {"ruleId": "scanner-b16c4d735fb2dc20", "level": "none", "message": {"text": "Commented-code block (5 lines) in frontend/src/components/fields/PdfFieldCanvas.jsx:5"}, "properties": {"repobilityId": "08ed6deb19cf4a41", "scanner": "scanner-primary", "fingerprint": "b16c4d735fb2dc20", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-97d2eb4a8f870413", "level": "none", "message": {"text": "Commented-code block (6 lines) in frontend/src/app/(dashboard)/contracts/[id]/fields/page.js:3"}, "properties": {"repobilityId": "f7ae4d4f8b79cb67", "scanner": "scanner-primary", "fingerprint": "97d2eb4a8f870413", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-4e0aeb8d21603d6f", "level": "note", "message": {"text": "Legacy-named symbol `loadLegacy` in backend/tests/integration/legacy.load.test.js:2"}, "properties": {"repobilityId": "947a69fb4b591896", "scanner": "scanner-primary", "fingerprint": "4e0aeb8d21603d6f", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-b31170d959c5dc3d", "level": "none", "message": {"text": "Commented-code block (5 lines) in backend/src/api/v1/templates/index.js:44"}, "properties": {"repobilityId": "e21f872e2a4655bb", "scanner": "scanner-primary", "fingerprint": "b31170d959c5dc3d", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-d2ba391317167fab", "level": "none", "message": {"text": "Commented-code block (5 lines) in backend/src/api/v1/branding/index.js:20"}, "properties": {"repobilityId": "04a70c0aefdbc676", "scanner": "scanner-primary", "fingerprint": "d2ba391317167fab", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-cf93bd633d9a870a", "level": "note", "message": {"text": "Legacy-named symbol `loadLegacy` in backend/src/scripts/loadLegacy.js:6"}, "properties": {"repobilityId": "d624e2eea5b43b11", "scanner": "scanner-primary", "fingerprint": "cf93bd633d9a870a", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-34e2e41fa2539b52", "level": "none", "message": {"text": "Commented-code block (7 lines) in backend/src/scripts/loadLegacy.js:214"}, "properties": {"repobilityId": "c450341133ec5011", "scanner": "scanner-primary", "fingerprint": "34e2e41fa2539b52", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-ccb6d1e87778fe93", "level": "none", "message": {"text": "Commented-code block (9 lines) in backend/src/database/migrations/005_signature_flows.js:21"}, "properties": {"repobilityId": "2fc0ba21671c9581", "scanner": "scanner-primary", "fingerprint": "ccb6d1e87778fe93", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-799a4f2556fda79e", "level": "none", "message": {"text": "Commented-code block (7 lines) in backend/src/services/signature/signatureService.js:175"}, "properties": {"repobilityId": "510a228fc1031094", "scanner": "scanner-primary", "fingerprint": "799a4f2556fda79e", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-cad046c72bad29d3", "level": "none", "message": {"text": "Commented-code block (5 lines) in backend/src/services/identity/providers/tekoProvider.js:26"}, "properties": {"repobilityId": "8ef31efc40f1802d", "scanner": "scanner-primary", "fingerprint": "cad046c72bad29d3", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-ac6ce0e6d1dca97a", "level": "note", "message": {"text": "61 env vars used in code but missing from .env.example"}, "properties": {"repobilityId": "d9bf04d375a56cee", "scanner": "scanner-primary", "fingerprint": "ac6ce0e6d1dca97a", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "config-drift"]}}, {"ruleId": "scanner-8292c0931391749a", "level": "note", "message": {"text": "Unused endpoint: POST /auth/register"}, "properties": {"repobilityId": "80b5cc904faa4762", "scanner": "scanner-primary", "fingerprint": "8292c0931391749a", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-b36892106ecdc9aa", "level": "note", "message": {"text": "Unused endpoint: POST /auth/refresh"}, "properties": {"repobilityId": "36e4a623051de289", "scanner": "scanner-primary", "fingerprint": "b36892106ecdc9aa", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-c059f57186114027", "level": "note", "message": {"text": "Unused endpoint: POST /auth/logout"}, "properties": {"repobilityId": "233ed2bb0fcfdb5a", "scanner": "scanner-primary", "fingerprint": "c059f57186114027", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-ac42422b23e45104", "level": "note", "message": {"text": "Unused endpoint: GET /auth/me"}, "properties": {"repobilityId": "015cf774077293de", "scanner": "scanner-primary", "fingerprint": "ac42422b23e45104", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-1e56771f48149c0b", "level": "note", "message": {"text": "Unused endpoint: PATCH /auth/me"}, "properties": {"repobilityId": "cd7abf765c12105c", "scanner": "scanner-primary", "fingerprint": "1e56771f48149c0b", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-7c28c4a0d2765ca6", "level": "note", "message": {"text": "Unused endpoint: POST /auth/2fa/setup"}, "properties": {"repobilityId": "fbb71c37ceb60bac", "scanner": "scanner-primary", "fingerprint": "7c28c4a0d2765ca6", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-59cb6e2c914d4369", "level": "note", "message": {"text": "Unused endpoint: POST /auth/2fa/enable"}, "properties": {"repobilityId": "1598072e33db6196", "scanner": "scanner-primary", "fingerprint": "59cb6e2c914d4369", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-4585c350da9e880d", "level": "note", "message": {"text": "Unused endpoint: POST /auth/change-password"}, "properties": {"repobilityId": "ce4149af5835b192", "scanner": "scanner-primary", "fingerprint": "4585c350da9e880d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-13df96bc0886466a", "level": "note", "message": {"text": "Unused endpoint: GET /tenants/me"}, "properties": {"repobilityId": "b6dbe90822e2f727", "scanner": "scanner-primary", "fingerprint": "13df96bc0886466a", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-07ca93b9120f9713", "level": "note", "message": {"text": "Unused endpoint: PATCH /tenants/me"}, "properties": {"repobilityId": "b948e72f1fd03ecf", "scanner": "scanner-primary", "fingerprint": "07ca93b9120f9713", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-07bb77eeabde9f9c", "level": "note", "message": {"text": "Unused endpoint: GET /tenants/me/users"}, "properties": {"repobilityId": "a6c695776b1e43c3", "scanner": "scanner-primary", "fingerprint": "07bb77eeabde9f9c", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-535d3a6cc160b8f4", "level": "note", "message": {"text": "Unused endpoint: POST /tenants/me/users/invite"}, "properties": {"repobilityId": "484e5eed4006c8c2", "scanner": "scanner-primary", "fingerprint": "535d3a6cc160b8f4", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-bcc78b3655976a80", "level": "note", "message": {"text": "Unused endpoint: GET /oauth/clients"}, "properties": {"repobilityId": "de595b71f4c4465a", "scanner": "scanner-primary", "fingerprint": "bcc78b3655976a80", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-e0bd5555c5617d29", "level": "note", "message": {"text": "Unused endpoint: POST /oauth/clients"}, "properties": {"repobilityId": "96ac690b3c7158a6", "scanner": "scanner-primary", "fingerprint": "e0bd5555c5617d29", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-1acc5b65952c49f9", "level": "note", "message": {"text": "Unused endpoint: GET /contracts/stats"}, "properties": {"repobilityId": "c3f1a0a903f07161", "scanner": "scanner-primary", "fingerprint": "1acc5b65952c49f9", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-de13d3a35d08cc8e", "level": "note", "message": {"text": "Unused endpoint: GET /contracts"}, "properties": {"repobilityId": "e25c3cdcf69c4a7a", "scanner": "scanner-primary", "fingerprint": "de13d3a35d08cc8e", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-d9b2535a290d486e", "level": "note", "message": {"text": "Unused endpoint: POST /contracts"}, "properties": {"repobilityId": "79af34ed21bd5203", "scanner": "scanner-primary", "fingerprint": "d9b2535a290d486e", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-a3a7cfb0e400fc68", "level": "note", "message": {"text": "Unused endpoint: POST /contracts/template/variables"}, "properties": {"repobilityId": "74519b00a94ceb97", "scanner": "scanner-primary", "fingerprint": "a3a7cfb0e400fc68", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-017394171548a2b2", "level": "note", "message": {"text": "Unused endpoint: GET /templates"}, "properties": {"repobilityId": "6ffd6be03383f9db", "scanner": "scanner-primary", "fingerprint": "017394171548a2b2", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-2b73958ead43e47d", "level": "note", "message": {"text": "Unused endpoint: POST /templates"}, "properties": {"repobilityId": "e1fcc52981e25bba", "scanner": "scanner-primary", "fingerprint": "2b73958ead43e47d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-143475d4c22c9819", "level": "note", "message": {"text": "Unused endpoint: POST /templates/blank"}, "properties": {"repobilityId": "a5ba5479d41a8f4d", "scanner": "scanner-primary", "fingerprint": "143475d4c22c9819", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-8dfdaa61a04e0f15", "level": "note", "message": {"text": "Unused endpoint: GET /flows"}, "properties": {"repobilityId": "fdeda69493a66a9d", "scanner": "scanner-primary", "fingerprint": "8dfdaa61a04e0f15", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-c610883e7c445749", "level": "note", "message": {"text": "Unused endpoint: POST /flows"}, "properties": {"repobilityId": "aa2edde6c460a9e9", "scanner": "scanner-primary", "fingerprint": "c610883e7c445749", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-9d5282b056e1fef4", "level": "note", "message": {"text": "Unused endpoint: GET /notifications/templates"}, "properties": {"repobilityId": "3aaf84d9443a9df3", "scanner": "scanner-primary", "fingerprint": "9d5282b056e1fef4", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-a3c51b4548adcf10", "level": "note", "message": {"text": "Unused endpoint: POST /notifications/templates"}, "properties": {"repobilityId": "33856115928799f2", "scanner": "scanner-primary", "fingerprint": "a3c51b4548adcf10", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-c69979eb34db974c", "level": "note", "message": {"text": "Unused endpoint: GET /notifications/logs"}, "properties": {"repobilityId": "a6caac63feead8f9", "scanner": "scanner-primary", "fingerprint": "c69979eb34db974c", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-abd445b038693a3f", "level": "note", "message": {"text": "Unused endpoint: POST /notifications/send/email"}, "properties": {"repobilityId": "48be16cca5f394b0", "scanner": "scanner-primary", "fingerprint": "abd445b038693a3f", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-a8ce623cef7d6ed3", "level": "note", "message": {"text": "Unused endpoint: POST /notifications/send/whatsapp"}, "properties": {"repobilityId": "7666ffc184b9f859", "scanner": "scanner-primary", "fingerprint": "a8ce623cef7d6ed3", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-ec5073cba5362010", "level": "note", "message": {"text": "Unused endpoint: GET /webhooks"}, "properties": {"repobilityId": "dee0d2fa31578cfa", "scanner": "scanner-primary", "fingerprint": "ec5073cba5362010", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-fcf74c0015b4c952", "level": "note", "message": {"text": "Unused endpoint: POST /webhooks"}, "properties": {"repobilityId": "ae7bb9b7a04a36bc", "scanner": "scanner-primary", "fingerprint": "fcf74c0015b4c952", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-c32b4607df0975e2", "level": "note", "message": {"text": "Unused endpoint: GET /api-keys"}, "properties": {"repobilityId": "437086a2a5e5aae3", "scanner": "scanner-primary", "fingerprint": "c32b4607df0975e2", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-224cbb7548a6b13c", "level": "note", "message": {"text": "Unused endpoint: POST /api-keys"}, "properties": {"repobilityId": "577e6f0382dadcaa", "scanner": "scanner-primary", "fingerprint": "224cbb7548a6b13c", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-e34f02337c261a05", "level": "note", "message": {"text": "Unused endpoint: GET /branding"}, "properties": {"repobilityId": "280bc51a63eb35bf", "scanner": "scanner-primary", "fingerprint": "e34f02337c261a05", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-8ffa5c735d594215", "level": "note", "message": {"text": "Unused endpoint: PUT /branding"}, "properties": {"repobilityId": "b758cd378d5ed7af", "scanner": "scanner-primary", "fingerprint": "8ffa5c735d594215", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-3072d05b1a69ed8b", "level": "note", "message": {"text": "Unused endpoint: POST /bulk/from-template"}, "properties": {"repobilityId": "ea7c1b860ba30029", "scanner": "scanner-primary", "fingerprint": "3072d05b1a69ed8b", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-785a6131d850d7c6", "level": "note", "message": {"text": "Unused endpoint: GET /bulk/jobs"}, "properties": {"repobilityId": "6808dce5bc228eca", "scanner": "scanner-primary", "fingerprint": "785a6131d850d7c6", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-dd159bd05997c05c", "level": "note", "message": {"text": "Unused endpoint: GET /admin/stats"}, "properties": {"repobilityId": "a67b95024beefc41", "scanner": "scanner-primary", "fingerprint": "dd159bd05997c05c", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-2273ac666d251484", "level": "note", "message": {"text": "Unused endpoint: GET /admin/plans"}, "properties": {"repobilityId": "64fc72870e7f7f5e", "scanner": "scanner-primary", "fingerprint": "2273ac666d251484", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-6c9282666b199ce9", "level": "note", "message": {"text": "Unused endpoint: GET /admin/audit"}, "properties": {"repobilityId": "7ca5e8717e9d2c59", "scanner": "scanner-primary", "fingerprint": "6c9282666b199ce9", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-0aba7f1883cb96f2", "level": "note", "message": {"text": "Unused endpoint: GET /admin/users"}, "properties": {"repobilityId": "887911b5e752a2b7", "scanner": "scanner-primary", "fingerprint": "0aba7f1883cb96f2", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-61858cb8c2841124", "level": "note", "message": {"text": "Unused endpoint: GET /admin/tenants"}, "properties": {"repobilityId": "5984d517999e1cd6", "scanner": "scanner-primary", "fingerprint": "61858cb8c2841124", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-cc6dc53aa8b9accd", "level": "note", "message": {"text": "Unused endpoint: POST /admin/tenants"}, "properties": {"repobilityId": "0e266f137d3a681f", "scanner": "scanner-primary", "fingerprint": "cc6dc53aa8b9accd", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-76889df7c8e240c5", "level": "note", "message": {"text": "Unused endpoint: USE /api/"}, "properties": {"repobilityId": "96424d327ae7e810", "scanner": "scanner-primary", "fingerprint": "76889df7c8e240c5", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-6f9d80087bdb9ee9", "level": "note", "message": {"text": "Unused endpoint: USE /api/v1/auth/"}, "properties": {"repobilityId": "4788bb5a6f425f4b", "scanner": "scanner-primary", "fingerprint": "6f9d80087bdb9ee9", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-9696bcc3e59d0856", "level": "note", "message": {"text": "Unused endpoint: USE /api/v1/webhooks/whatsapp"}, "properties": {"repobilityId": "f2569354b7d68108", "scanner": "scanner-primary", "fingerprint": "9696bcc3e59d0856", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-3bec7ccd0b909bea", "level": "note", "message": {"text": "Unused endpoint: USE /api/v1/auth"}, "properties": {"repobilityId": "06e8de098a70ddaa", "scanner": "scanner-primary", "fingerprint": "3bec7ccd0b909bea", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-a6bdfc267cbeb804", "level": "note", "message": {"text": "Unused endpoint: USE /api/v1/tenants"}, "properties": {"repobilityId": "e46a79eec1f465cc", "scanner": "scanner-primary", "fingerprint": "a6bdfc267cbeb804", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-4b1afd0ba2b8f574", "level": "note", "message": {"text": "Unused endpoint: USE /api/v1/users"}, "properties": {"repobilityId": "53328be5eaf1a5d8", "scanner": "scanner-primary", "fingerprint": "4b1afd0ba2b8f574", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-7ab1341d8c478a3b", "level": "note", "message": {"text": "Unused endpoint: USE /api/v1/contracts"}, "properties": {"repobilityId": "ad56d1846881b056", "scanner": "scanner-primary", "fingerprint": "7ab1341d8c478a3b", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-74dc8be8b2b4c7e6", "level": "note", "message": {"text": "Unused endpoint: USE /api/v1/flows"}, "properties": {"repobilityId": "2ad81296cf99ab95", "scanner": "scanner-primary", "fingerprint": "74dc8be8b2b4c7e6", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}]}]}