An Open Source implementation of Notebook LM with more flexibility and features
This report summarizes scanner evidence for lfnovo/open-notebook, a TypeScript project with 40,035 GitHub stars. SynthScan examined 111,393 lines of code across 560 source files, recording 1430 pattern matches distributed across 21 syntactic categories. The legacy adjusted pattern signal is 18.3 (Elevated pattern signal); it is not an authorship estimate.
Use the findings to ask whether maintainers can explain intent, verify dependencies, simplify unnecessary scaffolding, and focus review effort. Risk Payload v1 adds ownership, supply-chain, over-engineering, and review-effort vectors when available. These are prompts for human verification, not probabilities, security findings, or measured maintenance costs.
Use each vector to guide manual verification of the underlying findings.
Can maintainers explain intent, assumptions, and trade-offs? 963 finding(s).
Are imports declared and package/API names verified? 47 finding(s).
Are wrappers, guards, and repeated structures necessary? 1179 finding(s).
Which changes need focused human review? 1430 finding(s).
This chart tracks the legacy adjusted pattern score across scan runs. Changes can reflect source changes, scan coverage, or detector/scoring versions; they do not measure AI adoption or prove that a team refactored code. Compare runs only when their scoring versions are compatible. The dashed line tracks the raw pattern-hit count.
Groups findings by configured severity weight. Severity is not a confidence estimate, security rating, or proof that a package is missing. Verify imports against the project's manifests and inspect each finding in its local design context.
This horizontal bar chart shows where configured pattern scores accumulate across directories. Treat the bars as locations to inspect, not as evidence of authorship or code quality. Use the file-level findings to decide whether a directory needs a focused ownership, dependency, complexity, or review check.
The scanner identified 1430 distinct pattern matches across 21 syntactic categories. Each entry below represents a discrete location in the source code where the engine recorded a detector match to inspect in context. Expand any category row to inspect the individual file paths, line numbers, code snippets, and the lexical context (CODE, COMMENT, or STRING) in which each match was detected.
Reading the findings table: The Severity column indicates the configured finding weight (CRITICAL / HIGH / MEDIUM / LOW). The Context column identifies whether the match occurred inside executable code, an inline comment, or a string literal — legacy comment-context matches receive a ×1.5 score weight. The ⚡ bolt icon marks clustered matches: three or more patterns within a 10-line window, each receiving an additional ×1.5 density multiplier under the legacy scoring model.
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | …nsformations/components/TransformationEditorDialog.tsx | 51 | export function TransformationEditorDialog({ open, onOpenChange, transformation }: TransformationEditorDialogProps) { | CODE |
| LOW | …src/components/settings/EmbeddingModelChangeDialog.tsx | 27 | export function EmbeddingModelChangeDialog({ | CODE |
| LOW | …/src/components/podcasts/generate-podcast-selection.ts | 53 | export function selectionsToContextConfigs( | CODE |
| LOW | frontend/src/lib/credential-update-payload.ts | 23 | export function buildCredentialUpdatePayload( | CODE |
| LOW⚡ | frontend/src/lib/utils/source-references.tsx | 179 | export function convertReferencesToMarkdownLinks(text: string): string { | CODE |
| LOW⚡ | frontend/src/lib/utils/source-references.tsx | 348 | export function convertReferencesToCompactMarkdown(text: string, referencesLabel: string = 'References'): string { | CODE |
| LOW | frontend/src/lib/utils/source-references.tsx | 275 | export function createReferenceLinkComponent( | CODE |
| LOW | frontend/src/lib/utils/source-references.tsx | 440 | export function createCompactReferenceLinkComponent( | CODE |
| LOW | frontend/src/lib/utils/source-references.tsx | 491 | export function convertSourceReferencesLegacy(text: string): React.ReactNode { | CODE |
| LOW | frontend/src/lib/hooks/use-podcasts.ts | 234 | export function useDuplicateEpisodeProfile() { | CODE |
| LOW | frontend/src/lib/hooks/use-podcasts.ts | 366 | export function useDuplicateSpeakerProfile() { | CODE |
| LOW | frontend/src/lib/hooks/use-sources.ts | 352 | export function useRemoveSourceFromNotebook() { | CODE |
| LOW | frontend/src/lib/hooks/use-credentials.ts | 338 | export function useMigrateFromProviderConfig() { | CODE |
| LOW | open_notebook/config.py | 41 | def ensure_llm_timeout_default(environ: MutableMapping[str, str] = os.environ) -> None: | CODE |
| LOW⚡ | open_notebook/utils/runtime_capabilities.py | 57 | def _default_playwright_cache() -> str | None: | CODE |
| LOW⚡ | open_notebook/utils/runtime_capabilities.py | 67 | def _chromium_browser_present() -> bool: | CODE |
| LOW | open_notebook/utils/version_utils.py | 14 | async def get_version_from_github_async(repo_url: str, branch: str = "main") -> str: | CODE |
| LOW | open_notebook/utils/chunking.py | 173 | def detect_content_type_from_extension( | CODE |
| LOW | open_notebook/utils/chunking.py | 195 | def detect_content_type_from_heuristics(text: str) -> Tuple[ContentType, float]: | CODE |
| LOW | open_notebook/utils/chunking.py | 266 | def _calculate_markdown_score(text: str) -> float: | CODE |
| LOW | open_notebook/utils/chunking.py | 398 | def _apply_secondary_chunking(chunks: List[str]) -> List[str]: | CODE |
| LOW | open_notebook/utils/encryption.py | 64 | def _get_or_create_encryption_key() -> str: | CODE |
| LOW | open_notebook/utils/encryption.py | 140 | def _derive_legacy_fernet_key(passphrase: str) -> str: | CODE |
| LOW | open_notebook/utils/embedding.py | 24 | def _get_embedding_batch_size() -> int: | CODE |
| LOW | open_notebook/utils/context_builder.py | 77 | def _rendered_source_context_tokens( | CODE |
| LOW | open_notebook/utils/context_builder.py | 102 | def _truncate_source_to_token_budget( | CODE |
| LOW | open_notebook/utils/url_validation.py | 115 | async def prepare_pinned_http_target(url: str, provider: str) -> PinnedHttpTarget: | CODE |
| LOW⚡ | open_notebook/utils/graph_utils.py | 9 | async def get_session_message_count(graph, session_id: str) -> int: | CODE |
| LOW⚡ | open_notebook/utils/graph_utils.py | 24 | def discard_unanswered_message(graph, thread_id: str, message: BaseMessage) -> None: | CODE |
| LOW | open_notebook/podcasts/audio_paths.py | 63 | def resolve_contained_audio_path(audio_file: Optional[str]) -> Optional[Path]: | CODE |
| LOW | open_notebook/podcasts/models.py | 110 | async def resolve_transcript_config(self) -> Tuple[str, str, dict]: | CODE |
| LOW | open_notebook/podcasts/models.py | 284 | async def get_job_details_for_commands( | CODE |
| LOW | open_notebook/ai/models.py | 55 | async def resolve_anthropic_compatible_config( | CODE |
| LOW | open_notebook/ai/connection_tester.py | 31 | def _is_vertex_credentials_file_error(exc: Exception) -> bool: | CODE |
| LOW | open_notebook/ai/connection_tester.py | 77 | def normalize_anthropic_compatible_base_url(base_url: str) -> str: | CODE |
| LOW | open_notebook/ai/connection_tester.py | 208 | async def _test_openai_compatible_connection( | CODE |
| LOW | open_notebook/ai/connection_tester.py | 264 | async def _test_anthropic_compatible_connection( | CODE |
| LOW | open_notebook/ai/connection_tester.py | 399 | def _connection_failure_reason(error_msg: str) -> Optional[str]: | CODE |
| LOW | open_notebook/ai/connection_tester.py | 482 | def classify_provider_test_error(error_msg: str) -> Tuple[bool, str]: | CODE |
| LOW | open_notebook/ai/key_provider.py | 135 | async def _provision_simple_provider(provider: str) -> bool: | CODE |
| LOW | open_notebook/ai/key_provider.py | 249 | async def _provision_url_key_compatible(provider: str, env_prefix: str) -> bool: | CODE |
| LOW | open_notebook/ai/key_provider.py | 274 | async def _provision_openai_compatible() -> bool: | CODE |
| LOW | open_notebook/ai/key_provider.py | 279 | async def _provision_anthropic_compatible() -> bool: | CODE |
| LOW | open_notebook/ai/provision.py | 10 | async def provision_langchain_model( | CODE |
| LOW⚡ | open_notebook/ai/model_discovery.py | 392 | async def fetch_anthropic_model_ids(api_key: str) -> List[str]: | CODE |
| LOW | open_notebook/ai/model_discovery.py | 305 | async def discover_openai_compatible_provider(provider: str) -> List[DiscoveredModel]: | CODE |
| LOW | open_notebook/ai/model_discovery.py | 363 | def _make_openai_compat_discoverer( | CODE |
| LOW | open_notebook/ai/model_discovery.py | 426 | async def discover_anthropic_models() -> List[DiscoveredModel]: | CODE |
| LOW | open_notebook/ai/model_discovery.py | 567 | async def discover_openrouter_models() -> List[DiscoveredModel]: | CODE |
| LOW | open_notebook/ai/model_discovery.py | 608 | async def discover_elevenlabs_models() -> List[DiscoveredModel]: | CODE |
| LOW | open_notebook/ai/model_discovery.py | 723 | async def discover_openai_compatible_models() -> List[DiscoveredModel]: | CODE |
| LOW | open_notebook/ai/model_discovery.py | 793 | async def discover_anthropic_compatible_models() -> List[DiscoveredModel]: | CODE |
| LOW | open_notebook/graphs/source_chat.py | 36 | def _source_content_is_available( | CODE |
| LOW | open_notebook/graphs/source_chat.py | 48 | def call_model_with_source_context( | CODE |
| LOW | open_notebook/graphs/source_chat.py | 69 | def _call_model_with_source_context_inner( | CODE |
| LOW | open_notebook/domain/notebook.py | 699 | def content_must_not_be_empty(cls, v): | CODE |
| LOW⚡ | tests/test_model_discovery.py | 277 | def test_speech_models_classify_as_tts(self): | CODE |
| LOW⚡ | tests/test_model_discovery.py | 286 | async def test_missing_key_returns_empty(self, monkeypatch): | CODE |
| LOW⚡ | tests/test_model_discovery.py | 291 | async def test_discovery_paginates_and_sends_anthropic_headers(self, monkeypatch): | CODE |
| LOW | tests/test_model_discovery.py | 53 | def test_table_covers_all_openai_compatible_providers(self): | CODE |
| 696 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | .pre-commit-config.yaml | 9 | # ── Basic hygiene ────────────────────────────────────────────────── | COMMENT |
| MEDIUM | .pre-commit-config.yaml | 21 | # ── Ruff: Python lint & format (mirrors CI backend-lint job) ────── | COMMENT |
| MEDIUM | open_notebook/ai/key_provider.py | 23 | # ============================================================================= | COMMENT |
| MEDIUM | open_notebook/ai/key_provider.py | 25 | # ============================================================================= | COMMENT |
| MEDIUM⚡ | open_notebook/ai/model_discovery.py | 387 | # ============================================================================= | COMMENT |
| MEDIUM⚡ | open_notebook/ai/model_discovery.py | 389 | # ============================================================================= | COMMENT |
| MEDIUM⚡ | open_notebook/ai/model_discovery.py | 921 | # ============================================================================= | COMMENT |
| MEDIUM⚡ | open_notebook/ai/model_discovery.py | 923 | # ============================================================================= | COMMENT |
| MEDIUM | open_notebook/ai/model_discovery.py | 41 | # ============================================================================= | COMMENT |
| MEDIUM | open_notebook/ai/model_discovery.py | 43 | # ============================================================================= | COMMENT |
| MEDIUM | open_notebook/ai/model_discovery.py | 248 | # ============================================================================= | COMMENT |
| MEDIUM | open_notebook/ai/model_discovery.py | 250 | # ============================================================================= | COMMENT |
| MEDIUM⚡ | tests/test_utils.py | 151 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | tests/test_utils.py | 153 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | tests/test_utils.py | 198 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | tests/test_utils.py | 200 | # ============================================================================ | COMMENT |
| MEDIUM | tests/test_utils.py | 33 | # ============================================================================ | COMMENT |
| MEDIUM | tests/test_utils.py | 35 | # ============================================================================ | COMMENT |
| MEDIUM | tests/test_utils.py | 268 | # ============================================================================ | COMMENT |
| MEDIUM | tests/test_utils.py | 270 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | tests/test_graphs.py | 26 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | tests/test_graphs.py | 28 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | tests/test_graphs.py | 73 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | tests/test_graphs.py | 75 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | tests/test_graphs.py | 101 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | tests/test_graphs.py | 103 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | tests/test_graphs.py | 187 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | tests/test_graphs.py | 189 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | tests/test_graphs.py | 306 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | tests/test_graphs.py | 308 | # ============================================================================ | COMMENT |
| MEDIUM | tests/test_graphs.py | 606 | # ============================================================================ | COMMENT |
| MEDIUM | tests/test_graphs.py | 608 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | tests/test_chunking.py | 46 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | tests/test_chunking.py | 48 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | tests/test_chunking.py | 107 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | tests/test_chunking.py | 109 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | tests/test_chunking.py | 197 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | tests/test_chunking.py | 199 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | tests/test_chunking.py | 239 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | tests/test_chunking.py | 241 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | tests/test_embedding.py | 26 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | tests/test_embedding.py | 28 | # ============================================================================ | COMMENT |
| MEDIUM | tests/test_embedding.py | 114 | # ============================================================================ | COMMENT |
| MEDIUM | tests/test_embedding.py | 116 | # ============================================================================ | COMMENT |
| MEDIUM | tests/test_embedding.py | 161 | # ============================================================================ | COMMENT |
| MEDIUM | tests/test_embedding.py | 163 | # ============================================================================ | COMMENT |
| MEDIUM | tests/test_embedding.py | 334 | # ============================================================================ | COMMENT |
| MEDIUM | tests/test_embedding.py | 336 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | tests/test_domain.py | 32 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | tests/test_domain.py | 34 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | tests/test_domain.py | 63 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | tests/test_domain.py | 65 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | tests/test_domain.py | 81 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | tests/test_domain.py | 83 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | tests/test_domain.py | 264 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | tests/test_domain.py | 266 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | tests/test_domain.py | 402 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | tests/test_domain.py | 404 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | tests/test_domain.py | 442 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | tests/test_domain.py | 444 | # ============================================================================ | COMMENT |
| 52 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | open_notebook/AGENTS.md | 34 | except Exception as e: | CODE |
| LOW | open_notebook/database/async_migrate.py | 47 | except Exception as e: | CODE |
| LOW | open_notebook/database/async_migrate.py | 235 | except Exception as e: | CODE |
| LOW | open_notebook/database/async_migrate.py | 250 | except Exception: | CODE |
| LOW | open_notebook/database/async_migrate.py | 260 | except Exception: | CODE |
| LOW | open_notebook/database/repository.py | 118 | except Exception as e: | CODE |
| LOW | open_notebook/database/repository.py | 139 | except Exception as e: | CODE |
| LOW | open_notebook/database/repository.py | 206 | except Exception as e: | CODE |
| LOW | open_notebook/database/repository.py | 216 | except Exception as e: | CODE |
| LOW | open_notebook/database/repository.py | 258 | except Exception as e: | CODE |
| LOW | open_notebook/utils/runtime_capabilities.py | 34 | except Exception: | CODE |
| LOW⚡ | open_notebook/utils/runtime_capabilities.py | 50 | except Exception: | CODE |
| LOW | open_notebook/utils/chunking.py | 191 | except Exception: | CODE |
| LOW | open_notebook/utils/encryption.py | 57 | except Exception as e: | CODE |
| LOW | open_notebook/utils/encryption.py | 247 | except Exception: | CODE |
| LOW | open_notebook/utils/encryption.py | 278 | except Exception as e: | CODE |
| LOW | open_notebook/utils/encryption.py | 293 | except Exception as e: | CODE |
| LOW | open_notebook/utils/embedding.py | 179 | except Exception as e: | CODE |
| LOW | open_notebook/utils/context_builder.py | 293 | except Exception: | CODE |
| LOW | open_notebook/utils/context_builder.py | 304 | except Exception as e: | CODE |
| LOW | open_notebook/utils/context_builder.py | 322 | except Exception as e: | CODE |
| LOW | open_notebook/utils/context_builder.py | 332 | except Exception as e: | CODE |
| LOW | open_notebook/utils/context_builder.py | 345 | except Exception as e: | CODE |
| LOW | open_notebook/utils/context_builder.py | 355 | except Exception as e: | CODE |
| LOW | open_notebook/utils/context_builder.py | 510 | except Exception as e: | CODE |
| LOW | open_notebook/utils/url_validation.py | 111 | except Exception: | CODE |
| LOW⚡ | open_notebook/utils/graph_utils.py | 19 | except Exception as e: | CODE |
| LOW | open_notebook/utils/graph_utils.py | 40 | except Exception: | CODE |
| LOW | open_notebook/utils/graph_utils.py | 57 | except Exception: | CODE |
| LOW | open_notebook/podcasts/models.py | 262 | except Exception: | CODE |
| LOW | open_notebook/podcasts/models.py | 280 | except Exception: | CODE |
| LOW | open_notebook/podcasts/models.py | 313 | except Exception as e: | CODE |
| LOW | open_notebook/ai/models.py | 125 | except Exception as e: | CODE |
| LOW | open_notebook/ai/models.py | 158 | except Exception: | CODE |
| LOW | open_notebook/ai/models.py | 212 | except Exception: | CODE |
| LOW | open_notebook/ai/connection_tester.py | 154 | except Exception as e: | CODE |
| LOW | open_notebook/ai/connection_tester.py | 204 | except Exception as e: | CODE |
| LOW | open_notebook/ai/connection_tester.py | 260 | except Exception as e: | CODE |
| LOW | open_notebook/ai/connection_tester.py | 318 | except Exception as e: | CODE |
| LOW | open_notebook/ai/connection_tester.py | 567 | except Exception: | CODE |
| LOW | open_notebook/ai/connection_tester.py | 605 | except Exception as e: | CODE |
| LOW | open_notebook/ai/key_provider.py | 104 | except Exception as e: | CODE |
| LOW⚡ | open_notebook/ai/model_discovery.py | 915 | except Exception as e: | CODE |
| LOW⚡ | open_notebook/ai/model_discovery.py | 1013 | except Exception as e: | CODE |
| LOW | open_notebook/ai/model_discovery.py | 357 | except Exception as e: | CODE |
| LOW | open_notebook/ai/model_discovery.py | 434 | except Exception as e: | CODE |
| LOW | open_notebook/ai/model_discovery.py | 486 | except Exception as e: | CODE |
| LOW | open_notebook/ai/model_discovery.py | 526 | except Exception as e: | CODE |
| LOW | open_notebook/ai/model_discovery.py | 703 | except Exception as e: | CODE |
| LOW | open_notebook/ai/model_discovery.py | 739 | except Exception as e: | CODE |
| LOW | open_notebook/ai/model_discovery.py | 787 | except Exception as e: | CODE |
| LOW | open_notebook/ai/model_discovery.py | 804 | except Exception as e: | CODE |
| LOW | open_notebook/ai/model_discovery.py | 850 | except Exception as e: | CODE |
| LOW | open_notebook/ai/model_discovery.py | 877 | except Exception as e: | CODE |
| LOW | open_notebook/ai/model_discovery.py | 1037 | except Exception as e: | CODE |
| LOW | open_notebook/graphs/transformation.py | 102 | except Exception as e: | CODE |
| LOW | open_notebook/graphs/ask.py | 107 | except Exception as e: | CODE |
| LOW | open_notebook/graphs/ask.py | 164 | except Exception as e: | CODE |
| LOW | open_notebook/graphs/ask.py | 189 | except Exception as e: | CODE |
| LOW | open_notebook/graphs/source_chat.py | 64 | except Exception as e: | CODE |
| 227 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW⚡ | README.md | 105 | ### Step 1: Download docker-compose.yml | COMMENT |
| LOW⚡ | README.md | 113 | ### Step 2: Set your encryption key | COMMENT |
| LOW⚡ | README.md | 122 | ### Step 3: Start services | COMMENT |
| LOW⚡ | README.md | 129 | ### Step 4: Connect an AI provider | COMMENT |
| LOW⚡ | frontend/src/lib/utils/source-references.tsx | 180 | // Step 1: Find ALL references using simple greedy pattern. | COMMENT |
| LOW⚡ | frontend/src/lib/utils/source-references.tsx | 210 | // Step 2: Process references from end to start (to preserve indices) | COMMENT |
| LOW⚡ | frontend/src/lib/utils/source-references.tsx | 218 | // Step 3: Analyze context around the reference | COMMENT |
| LOW⚡ | frontend/src/lib/utils/source-references.tsx | 258 | // Step 4: Build the markdown link | COMMENT |
| LOW⚡ | frontend/src/lib/utils/source-references.tsx | 262 | // Step 5: Replace in the result string | COMMENT |
| LOW⚡ | frontend/src/lib/utils/source-references.tsx | 349 | // Step 1: Parse all references using existing function | COMMENT |
| LOW⚡ | frontend/src/lib/utils/source-references.tsx | 352 | // Step 2: If no references found, return original text | COMMENT |
| LOW⚡ | frontend/src/lib/utils/source-references.tsx | 357 | // Step 3: Build reference map (deduplicate and assign numbers) | COMMENT |
| LOW⚡ | frontend/src/lib/utils/source-references.tsx | 408 | // Step 5: Build reference list | COMMENT |
| LOW⚡ | frontend/src/lib/utils/source-references.tsx | 417 | // Step 6: Append reference list to result | COMMENT |
| LOW | frontend/src/lib/utils/source-references.tsx | 372 | // Step 4: Replace references with numbered citations (process from end to start) | COMMENT |
| LOW | .claude/agents/harness-qa.md | 31 | ## Step 0: Static Checks Gate (MANDATORY) | COMMENT |
| LOW | .claude/agents/harness-qa.md | 43 | ## Step 1: Understand What to Test | COMMENT |
| LOW | .claude/agents/harness-qa.md | 53 | ## Step 2: Choose the Right Testing Approach | COMMENT |
| LOW | .claude/agents/harness-qa.md | 119 | ## Step 3: Write Your Verdict | COMMENT |
| LOW | .claude/agents/harness-qa.md | 136 | ## Step 4: Update .harness/feature_list.json | COMMENT |
| LOW | .claude/agents/harness-qa.md | 142 | ## Step 5: Summary | COMMENT |
| LOW⚡ | .claude/agents/smoke-e2e.md | 212 | # Step 1: Create session | COMMENT |
| LOW⚡ | .claude/agents/smoke-e2e.md | 221 | # Step 2: Build context for the notebook | COMMENT |
| LOW⚡ | .claude/agents/smoke-e2e.md | 230 | # Step 3: Send message with context | COMMENT |
| LOW | docs/0-START-HERE/quick-start-local.md | 13 | ## Step 1: Download and configure (1 min) | COMMENT |
| LOW | docs/0-START-HERE/quick-start-local.md | 27 | ## Step 2: Add the Ollama service (1 min) | COMMENT |
| LOW | docs/0-START-HERE/quick-start-local.md | 42 | ## Step 3: Start (1 min) | COMMENT |
| LOW | docs/0-START-HERE/quick-start-local.md | 48 | ## Step 4: Download models (2-5 min) | COMMENT |
| LOW | docs/0-START-HERE/quick-start-local.md | 61 | ## Step 5: Connect Ollama and chat (3 min) | COMMENT |
| LOW | docs/0-START-HERE/quick-start-cloud.md | 20 | ## Step 1: Download and configure (1 min) | COMMENT |
| LOW | docs/0-START-HERE/quick-start-cloud.md | 34 | ## Step 2: Start (1 min) | COMMENT |
| LOW | docs/0-START-HERE/quick-start-cloud.md | 42 | ## Step 3: Connect your provider and chat (3 min) | COMMENT |
| LOW | docs/0-START-HERE/quick-start-external-ollama.md | 12 | ## Step 1: Download models (2-5 min) | COMMENT |
| LOW | docs/0-START-HERE/quick-start-external-ollama.md | 23 | ## Step 2: Let containers reach Ollama | COMMENT |
| LOW | docs/0-START-HERE/quick-start-external-ollama.md | 50 | ## Step 3: Download and configure Open Notebook (1 min) | COMMENT |
| LOW | docs/0-START-HERE/quick-start-external-ollama.md | 73 | ## Step 4: Start (1 min) | COMMENT |
| LOW | docs/0-START-HERE/quick-start-external-ollama.md | 79 | ## Step 5: Connect Ollama and chat (3 min) | COMMENT |
| LOW | docs/1-INSTALLATION/docker-compose.md | 22 | ## Step 1: Download the compose file | COMMENT |
| LOW | docs/1-INSTALLATION/docker-compose.md | 34 | ## Step 2: Set your encryption key | COMMENT |
| LOW | docs/1-INSTALLATION/docker-compose.md | 56 | ## Step 3: Decide who can reach it | COMMENT |
| LOW | docs/1-INSTALLATION/docker-compose.md | 65 | ## Step 4: Start Open Notebook | COMMENT |
| LOW | docs/1-INSTALLATION/docker-compose.md | 84 | ## Step 5: Open the UI and connect a provider | COMMENT |
| LOW⚡ | docs/3-USER-GUIDE/adding-sources.md | 11 | ### Step 1: Add Source | COMMENT |
| LOW⚡ | docs/3-USER-GUIDE/adding-sources.md | 21 | ### Step 2: Notebooks | COMMENT |
| LOW⚡ | docs/3-USER-GUIDE/adding-sources.md | 25 | ### Step 3: Process | COMMENT |
| LOW | .codex/agents/harness-qa.toml | 24 | ## Step 0: Static Checks Gate (MANDATORY) | COMMENT |
| LOW⚡ | .codex/agents/harness-qa.toml | 36 | ## Step 1: Understand What to Test | COMMENT |
| LOW⚡ | .codex/agents/harness-qa.toml | 46 | ## Step 2: Choose the Right Testing Approach | COMMENT |
| LOW⚡ | .codex/agents/harness-qa.toml | 112 | ## Step 3: Write Your Verdict | COMMENT |
| LOW⚡ | .codex/agents/harness-qa.toml | 129 | ## Step 4: Update .harness/feature_list.json | COMMENT |
| LOW⚡ | .codex/agents/harness-qa.toml | 135 | ## Step 5: Summary | COMMENT |
| LOW⚡ | .codex/agents/smoke-e2e.toml | 205 | # Step 1: Create session | COMMENT |
| LOW⚡ | .codex/agents/smoke-e2e.toml | 214 | # Step 2: Build context for the notebook | COMMENT |
| LOW⚡ | .codex/agents/smoke-e2e.toml | 223 | # Step 3: Send message with context | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | open_notebook/utils/encryption.py | 220 | except ValueError: | CODE |
| HIGH | open_notebook/utils/url_validation.py | 103 | except socket.gaierror: | CODE |
| HIGH | open_notebook/ai/connection_tester.py | 567 | except Exception: | CODE |
| HIGH | api/middleware.py | 74 | except ValueError: | CODE |
| HIGH | api/routers/models.py | 124 | except Exception: | CODE |
| HIGH | api/routers/sources.py | 423 | except Exception: | CODE |
| HIGH | api/routers/sources.py | 552 | except Exception: | CODE |
| HIGH | api/routers/sources.py | 560 | except Exception: | CODE |
| HIGH | api/routers/sources.py | 615 | except Exception: | CODE |
| HIGH | api/routers/languages.py | 79 | except Exception: | CODE |
| HIGH | api/routers/languages.py | 62 | except Exception: | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM⚡ | open_notebook/domain/notebook.py | 872 | # Both search paths failed (e.g. no embedding model configured). | COMMENT |
| MEDIUM | open_notebook/domain/credential.py | 79 | # Ollama-only: overrides the context window (num_ctx). Esperanto defaults to | COMMENT |
| MEDIUM | open_notebook/domain/credential.py | 80 | # 8192; raise this if your hardware can handle a larger context window. | COMMENT |
| MEDIUM | tests/test_crud_404.py | 138 | mock_embed_model.return_value = MagicMock() # an embedding model is configured | CODE |
| MEDIUM | docs/2-CORE-CONCEPTS/index.md | 14 | ### 2. [AI Context & RAG](ai-context-rag.md) | COMMENT |
| MEDIUM | docs/2-CORE-CONCEPTS/ai-context-rag.md | 1 | # AI Context & RAG - How Open Notebook Uses Your Research | COMMENT |
| MEDIUM | docs/5-CONFIGURATION/ollama.md | 19 | # An embedding model (needed for search, Ask and embeddings) | COMMENT |
| MEDIUM | docs/5-CONFIGURATION/ollama.md | 44 | Follow [Connect a provider](../4-AI-PROVIDERS/index.md#connect-a-provider) and pick **Ollama**. No API key is needed; se | CODE |
| MEDIUM | docs/6-TROUBLESHOOTING/faq.md | 49 | ### What happens if I change the embedding model? | COMMENT |
| MEDIUM | docs/6-TROUBLESHOOTING/processing-issues.md | 91 | ### "This feature requires an embedding model. Please configure one in the Models section." | COMMENT |
| MEDIUM | api/routers/embedding.py | 20 | # Check if embedding model is available | COMMENT |
| MEDIUM | api/routers/search.py | 32 | # Check if embedding model is available for vector search | COMMENT |
| MEDIUM | api/routers/search.py | 169 | # Check if embedding model is available | COMMENT |
| MEDIUM | api/routers/search.py | 231 | # Check if embedding model is available | COMMENT |
| MEDIUM | commands/embedding_commands.py | 664 | # Check embedding model availability (fail fast) | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW⚡ | frontend/src/lib/utils/source-references.tsx | 180 | // Step 1: Find ALL references using simple greedy pattern. | COMMENT |
| LOW⚡ | frontend/src/lib/utils/source-references.tsx | 210 | // Step 2: Process references from end to start (to preserve indices) | COMMENT |
| LOW⚡ | frontend/src/lib/utils/source-references.tsx | 218 | // Step 3: Analyze context around the reference | COMMENT |
| LOW⚡ | frontend/src/lib/utils/source-references.tsx | 258 | // Step 4: Build the markdown link | COMMENT |
| LOW⚡ | frontend/src/lib/utils/source-references.tsx | 262 | // Step 5: Replace in the result string | COMMENT |
| LOW⚡ | frontend/src/lib/utils/source-references.tsx | 349 | // Step 1: Parse all references using existing function | COMMENT |
| LOW⚡ | frontend/src/lib/utils/source-references.tsx | 352 | // Step 2: If no references found, return original text | COMMENT |
| LOW⚡ | frontend/src/lib/utils/source-references.tsx | 357 | // Step 3: Build reference map (deduplicate and assign numbers) | COMMENT |
| LOW⚡ | frontend/src/lib/utils/source-references.tsx | 408 | // Step 5: Build reference list | COMMENT |
| LOW⚡ | frontend/src/lib/utils/source-references.tsx | 417 | // Step 6: Append reference list to result | COMMENT |
| LOW | frontend/src/lib/utils/source-references.tsx | 372 | // Step 4: Replace references with numbered citations (process from end to start) | COMMENT |
| LOW | .codex/agents/harness-qa.toml | 24 | ## Step 0: Static Checks Gate (MANDATORY) | COMMENT |
| LOW⚡ | .codex/agents/harness-qa.toml | 36 | ## Step 1: Understand What to Test | COMMENT |
| LOW⚡ | .codex/agents/harness-qa.toml | 46 | ## Step 2: Choose the Right Testing Approach | COMMENT |
| LOW⚡ | .codex/agents/harness-qa.toml | 112 | ## Step 3: Write Your Verdict | COMMENT |
| LOW⚡ | .codex/agents/harness-qa.toml | 129 | ## Step 4: Update .harness/feature_list.json | COMMENT |
| LOW⚡ | .codex/agents/harness-qa.toml | 135 | ## Step 5: Summary | COMMENT |
| LOW⚡ | .codex/agents/smoke-e2e.toml | 205 | # Step 1: Create session | COMMENT |
| LOW⚡ | .codex/agents/smoke-e2e.toml | 214 | # Step 2: Build context for the notebook | COMMENT |
| LOW⚡ | .codex/agents/smoke-e2e.toml | 223 | # Step 3: Send message with context | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | open_notebook/utils/ssl_config.py | 9 | CODE | |
| LOW | open_notebook/utils/context_builder.py | 17 | CODE | |
| LOW | open_notebook/utils/__init__.py | 12 | CODE | |
| LOW | open_notebook/utils/__init__.py | 12 | CODE | |
| LOW | open_notebook/utils/__init__.py | 12 | CODE | |
| LOW | open_notebook/utils/__init__.py | 12 | CODE | |
| LOW | open_notebook/utils/__init__.py | 12 | CODE | |
| LOW | open_notebook/utils/__init__.py | 12 | CODE | |
| LOW | open_notebook/utils/__init__.py | 20 | CODE | |
| LOW | open_notebook/utils/__init__.py | 20 | CODE | |
| LOW | open_notebook/utils/__init__.py | 20 | CODE | |
| LOW | open_notebook/utils/__init__.py | 25 | CODE | |
| LOW | open_notebook/utils/__init__.py | 25 | CODE | |
| LOW | open_notebook/utils/__init__.py | 29 | CODE | |
| LOW | open_notebook/utils/__init__.py | 30 | CODE | |
| LOW | open_notebook/utils/__init__.py | 30 | CODE | |
| LOW | open_notebook/utils/__init__.py | 30 | CODE | |
| LOW | open_notebook/utils/__init__.py | 30 | CODE | |
| LOW | open_notebook/utils/__init__.py | 36 | CODE | |
| LOW | open_notebook/utils/__init__.py | 36 | CODE | |
| LOW | open_notebook/utils/__init__.py | 37 | CODE | |
| LOW | open_notebook/utils/__init__.py | 37 | CODE | |
| LOW | open_notebook/utils/__init__.py | 37 | CODE | |
| LOW | tests/test_source_deleted_before_processing.py | 15 | CODE | |
| LOW | tests/test_content_core_errors.py | 146 | CODE | |
| LOW | tests/test_content_core_integration.py | 18 | CODE | |
| LOW | tests/test_transformation_output.py | 11 | CODE | |
| LOW | tests/test_podcast_legacy_field_removal.py | 111 | CODE | |
| LOW | tests/test_context_length_no_retry.py | 22 | CODE | |
| LOW | tests/test_background_retry_visibility.py | 8 | CODE | |
| LOW | api/command_service.py | 22 | CODE | |
| LOW | api/podcast_service.py | 91 | CODE | |
| LOW | api/routers/embedding.py | 43 | CODE | |
| LOW | api/routers/sources.py | 511 | CODE | |
| LOW | api/routers/sources.py | 576 | CODE | |
| LOW | api/routers/sources.py | 1000 | CODE | |
| LOW | api/routers/embedding_rebuild.py | 35 | CODE | |
| LOW | commands/__init__.py | 11 | CODE | |
| LOW | commands/__init__.py | 11 | CODE | |
| LOW | commands/__init__.py | 11 | CODE | |
| LOW | commands/__init__.py | 11 | CODE | |
| LOW | commands/__init__.py | 17 | CODE | |
| LOW | commands/__init__.py | 18 | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | open_notebook/utils/version_utils.py | 63 | Fetch and parse the version from pyproject.toml in a public GitHub repository. Args: repo_url (str): U | STRING |
| HIGH | open_notebook/utils/version_utils.py | 117 | Get the version of an installed package. Args: package_name (str): Name of the installed package | STRING |
| HIGH | open_notebook/utils/encryption.py | 199 | Encrypt a string value using Fernet symmetric encryption (PBKDF2 scheme). The stored form carries the version | STRING |
| HIGH | open_notebook/utils/encryption.py | 252 | Decrypt a Fernet-encrypted string value. Version-marked values decrypt under PBKDF2 only; any failure raises a | STRING |
| HIGH | open_notebook/utils/embedding.py | 51 | Combine multiple embeddings into a single embedding using mean pooling. Algorithm: 1. Normalize each embed | STRING |
| HIGH | open_notebook/utils/embedding.py | 109 | Generate embeddings for multiple texts with automatic batching and retry. Texts are split into batches of EMBE | STRING |
| HIGH | open_notebook/utils/embedding.py | 212 | Generate a single embedding for text, handling large content via chunking and mean pooling. For short text (<= | STRING |
| HIGH | open_notebook/domain/notebook.py | 585 | Submit insight creation as an async command (fire-and-forget). Submits a create_insight command that h | STRING |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | open_notebook/database/repository.py | 221 | CODE | |
| LOW | open_notebook/utils/encryption.py | 31 | CODE | |
| LOW | open_notebook/utils/text_utils.py | 128 | CODE | |
| LOW | open_notebook/utils/embedding.py | 106 | CODE | |
| LOW | open_notebook/utils/context_builder.py | 42 | CODE | |
| LOW | open_notebook/utils/context_builder.py | 262 | CODE | |
| LOW | open_notebook/utils/context_builder.py | 362 | CODE | |
| LOW | open_notebook/ai/models.py | 205 | CODE | |
| LOW | open_notebook/ai/models.py | 329 | CODE | |
| LOW | open_notebook/ai/connection_tester.py | 89 | CODE | |
| LOW | open_notebook/ai/connection_tester.py | 158 | CODE | |
| LOW | open_notebook/ai/connection_tester.py | 208 | CODE | |
| LOW | open_notebook/ai/connection_tester.py | 264 | CODE | |
| LOW | open_notebook/ai/connection_tester.py | 508 | CODE | |
| LOW | open_notebook/ai/key_provider.py | 286 | CODE | |
| LOW | open_notebook/ai/model_discovery.py | 450 | CODE | |
| LOW | open_notebook/domain/provider_config.py | 198 | CODE | |
| LOW | open_notebook/domain/notebook.py | 74 | CODE | |
| LOW | open_notebook/domain/notebook.py | 215 | CODE | |
| LOW | open_notebook/domain/credential.py | 176 | CODE | |
| LOW | open_notebook/domain/base.py | 40 | CODE | |
| LOW | open_notebook/domain/base.py | 154 | CODE | |
| LOW | open_notebook/domain/base.py | 290 | CODE | |
| LOW | tests/test_max_body_size_middleware.py | 84 | CODE | |
| LOW | api/credentials_service.py | 127 | CODE | |
| LOW | api/credentials_service.py | 256 | CODE | |
| LOW | api/credentials_service.py | 406 | CODE | |
| LOW | api/credentials_service.py | 797 | CODE | |
| LOW | api/credentials_service.py | 905 | CODE | |
| LOW | api/credentials_service.py | 1119 | CODE | |
| LOW | api/routers/models.py | 388 | CODE | |
| LOW | api/routers/models.py | 708 | CODE | |
| LOW | api/routers/transformations.py | 210 | CODE | |
| LOW | api/routers/embedding.py | 17 | CODE | |
| LOW | api/routers/credentials.py | 321 | CODE | |
| LOW | api/routers/podcasts.py | 174 | CODE | |
| LOW | api/routers/source_chat.py | 140 | CODE | |
| LOW | api/routers/sources.py | 258 | CODE | |
| LOW | api/routers/sources.py | 427 | CODE | |
| LOW | api/routers/sources.py | 844 | CODE | |
| LOW | api/routers/sources.py | 935 | CODE | |
| LOW | api/routers/embedding_rebuild.py | 20 | CODE | |
| LOW | api/routers/search.py | 77 | CODE | |
| LOW | api/routers/languages.py | 38 | CODE | |
| LOW | api/routers/commands.py | 134 | CODE | |
| LOW | commands/podcast_commands.py | 121 | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | tests/test_search_api.py | 0 | create test client after environment variables have been cleared by conftest. | STRING |
| HIGH | tests/test_recently_viewed_api.py | 0 | create test client after environment variables have been cleared by conftest. | STRING |
| HIGH | tests/test_sources_api.py | 0 | create test client after environment variables have been cleared by conftest. | STRING |
| HIGH | tests/test_models_api.py | 0 | create test client after environment variables have been cleared by conftest. | STRING |
| HIGH | tests/test_credentials_api.py | 0 | create test client after environment variables have been cleared by conftest. | STRING |
| HIGH | tests/test_notes_api.py | 0 | create test client after environment variables have been cleared by conftest. | STRING |
| HIGH | tests/test_insight_timestamps.py | 0 | create test client after environment variables have been cleared by conftest. | STRING |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | frontend/src/components/ui/markdown-editor.tsx | 24 | // (e.g. pasted content, or an AI-generated note echoing an indirect prompt | COMMENT |
| HIGH | frontend/src/components/ui/markdown-editor.test.tsx | 19 | // default). Notes can hold AI-generated content that echoes an indirect | COMMENT |
| HIGH | frontend/src/components/ui/markdown-editor.test.tsx | 173 | // its symbol table. AI-generated content routinely has one inside a | COMMENT |
| HIGH | frontend/src/lib/utils/katex-options.ts | 3 | // AI-generated content often contains Unicode punctuation (en/em dashes, | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | cubic.yaml | 1 | # yaml-language-server: $schema=https://cubic.dev/schema/cubic-repository-config.schema.json | COMMENT |
| LOW | .pre-commit-config.yaml | 21 | # ── Ruff: Python lint & format (mirrors CI backend-lint job) ────── | COMMENT |
| LOW | docker-compose.yml | 1 | services: | COMMENT |
| LOW | docker-compose.yml | 41 | - SURREAL_PASSWORD=${SURREAL_PASSWORD:-root} | COMMENT |
| LOW | frontend/src/components/ui/markdown-editor.tsx | 21 | // app/layout.tsx. | COMMENT |
| LOW | frontend/src/components/sources/SourceCard.tsx | 121 | onContextModeChange | COMMENT |
| LOW | frontend/src/lib/utils/katex-options.ts | 1 | import type { KatexOptions } from 'katex' | COMMENT |
| LOW | open_notebook/config.py | 21 | COMMENT | |
| LOW | open_notebook/podcasts/__init__.py | 1 | # Podcasts module | COMMENT |
| LOW | open_notebook/ai/__init__.py | 1 | # AI infrastructure module | COMMENT |
| LOW | open_notebook/ai/connection_tester.py | 61 | # Test models for each provider - uses minimal/cheapest models for testing. | COMMENT |
| LOW | examples/docker-compose-speaches.yml | 1 | # Docker Compose with Speaches (Local TTS/STT) | COMMENT |
| LOW | examples/docker-compose-speaches.yml | 81 | # For TTS (Text-to-Speech): | COMMENT |
| LOW | examples/docker-compose-speaches.yml | 101 | # 6. Add TTS Model: | COMMENT |
| LOW | examples/docker-compose-speaches.yml | 121 | # Test STT: | COMMENT |
| LOW | examples/docker-compose-ollama.yml | 1 | # Docker Compose with Ollama (Free Local AI) | COMMENT |
| LOW | examples/docker-compose-full-local.yml | 1 | # Docker Compose - 100% Local AI Setup | COMMENT |
| LOW | examples/docker-compose-full-local.yml | 101 | hf-hub-cache: | COMMENT |
| LOW | examples/docker-compose-full-local.yml | 121 | # | COMMENT |
| LOW | examples/docker-compose-full-local.yml | 141 | # 3. Discover Speech Models: | COMMENT |
| LOW | examples/docker-compose-full-local.yml | 161 | # For TTS: | COMMENT |
| LOW | examples/docker-compose-full-local.yml | 181 | # - 50 GB disk space | COMMENT |
| LOW | examples/docker-compose-single.yml | 21 | # Access: | COMMENT |
| LOW | scripts/docker-entrypoint.sh | 1 | #!/bin/sh | COMMENT |
| LOW | scripts/release-test/rc-stack.sh | 1 | #!/bin/bash | COMMENT |
| LOW | scripts/release-test/release-image-test.sh | 1 | #!/bin/bash | COMMENT |
| LOW | api/main.py | 261 | # | COMMENT |
| LOW | commands/podcast_commands.py | 341 | transcript=None, | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | open_notebook/utils/embedding.py | 242 | # Check if chunking is needed | COMMENT |
| LOW⚡ | open_notebook/ai/model_discovery.py | 1020 | # Check if model already exists using pre-fetched data | COMMENT |
| LOW | .github/workflows/build-dev.yml | 66 | # Check if this is a push to main (not a PR) | COMMENT |
| LOW | api/credentials_service.py | 823 | # Check if a credential already exists for this provider with same name | COMMENT |
| LOW⚡ | api/podcast_service.py | 167 | # Check if profiles already exist | COMMENT |
| LOW⚡ | api/podcast_service.py | 188 | # Check if profiles already exist | COMMENT |
| LOW | api/routers/config.py | 53 | # Check if cache is still valid (within TTL) | COMMENT |
| LOW | api/routers/embedding.py | 20 | # Check if embedding model is available | COMMENT |
| LOW | api/routers/sources.py | 852 | # Check if this is a legacy source (no command) | COMMENT |
| LOW | api/routers/sources.py | 943 | # Check if source already has a running command | COMMENT |
| LOW | api/routers/sources.py | 990 | # Check if it's a text source by trying to get full_text | COMMENT |
| LOW | api/routers/search.py | 32 | # Check if embedding model is available for vector search | COMMENT |
| LOW | api/routers/search.py | 169 | # Check if embedding model is available | COMMENT |
| LOW | api/routers/search.py | 231 | # Check if embedding model is available | COMMENT |
| LOW | api/routers/notebooks.py | 352 | # Check if reference already exists (idempotency) | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM⚡ | open_notebook/ai/model_discovery.py | 1009 | # Create a set of (name, type) tuples for O(1) lookup | COMMENT |
| MEDIUM | open_notebook/graphs/source_chat.py | 228 | # Create the StateGraph | COMMENT |
| MEDIUM | open_notebook/graphs/source.py | 360 | # Define the graph edges | COMMENT |
| MEDIUM | open_notebook/domain/credential.py | 193 | # Create a minimal credential with error info from raw DB fields | COMMENT |
| MEDIUM | tests/test_domain.py | 290 | # Create a temporary file | COMMENT |
| MEDIUM | commands/podcast_commands.py | 330 | # Create the record for the episode and associate with the ongoing command | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH⚡ | tests/test_podcast_prompt_templates.py | 252 | under Jinja's default undefined, putting an invalid example in the | STRING |
| HIGH | api/routers/transformations.py | 224 | # An explicit "" (or null) clears the description; only an absent | COMMENT |
| HIGH | api/routers/notebooks.py | 287 | # An explicit "" (or null) clears the description; only an absent | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | frontend/src/lib/api/source-chat.ts | 54 | // Use relative URL to leverage Next.js rewrites | COMMENT |
| MEDIUM | frontend/src/lib/api/search.ts | 17 | // Use relative URL to leverage Next.js rewrites | COMMENT |
| MEDIUM⚡ | .codex/agents/harness-qa.toml | 119 | ## Feature: "[description from .harness/feature_list.json]" | COMMENT |
| MEDIUM⚡ | .codex/agents/harness-qa.toml | 129 | ## Step 4: Update .harness/feature_list.json | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | examples/docker-compose-speaches.yml | 13 | # Usage: | COMMENT |
| LOW | examples/docker-compose-ollama.yml | 6 | # Usage: | COMMENT |
| LOW | examples/docker-compose-full-local.yml | 16 | # Usage: | COMMENT |
| LOW | scripts/release-test/rc-stack.sh | 6 | # Usage: | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | docs/6-TROUBLESHOOTING/index.md | 24 | | "Authentication failed. Please check your API key…" | [AI & Chat Issues](ai-chat-issues.md#authentication-failed-pleas | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | open_notebook/utils/__init__.py | 43 | __all__ = [ | CODE |
| LOW | scripts/export_docs.py | 18 | logger = logging.getLogger(__name__) | CODE |
| LOW | commands/__init__.py | 20 | __all__ = [ | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | open_notebook/domain/provider_config.py | 51 | CODE | |
| LOW | api/auth.py | 82 | CODE | |
| LOW | api/routers/sources.py | 186 | CODE |