The free AI already on your Mac. CLI tool, OpenAI-compatible server, and interactive chat — all on-device via Apple Intelligence. No API keys, no cloud, no downloads.
This report summarizes scanner evidence for Arthur-Ficial/apfel, a Swift project with 6,465 GitHub stars. SynthScan examined 56,548 lines of code across 277 source files, recording 831 pattern matches distributed across 15 syntactic categories. The legacy adjusted pattern signal is 24.2 (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? 594 finding(s).
Are imports declared and package/API names verified? 6 finding(s).
Are wrappers, guards, and repeated structures necessary? 671 finding(s).
Which changes need focused human review? 831 finding(s).
Run additional scans to build a history of the legacy pattern signal. Score changes are not a measure of AI adoption or code quality.
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 831 distinct pattern matches across 15 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 |
|---|---|---|---|---|
| MEDIUM | Tests/integration/test_tdd_red.py | 54 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM | Tests/integration/test_tdd_red.py | 56 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM | Tests/integration/test_tdd_red.py | 69 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM | Tests/integration/test_tdd_red.py | 71 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM | Tests/integration/test_tdd_red.py | 102 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM | Tests/integration/test_tdd_red.py | 104 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM | Tests/integration/test_tdd_red.py | 155 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM | Tests/integration/test_tdd_red.py | 157 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM | Tests/integration/test_tdd_red.py | 189 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM | Tests/integration/test_tdd_red.py | 192 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM | Tests/integration/test_tdd_red.py | 236 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM | Tests/integration/test_tdd_red.py | 238 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM | Tests/integration/test_tdd_red.py | 270 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM | Tests/integration/test_tdd_red.py | 276 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM | Tests/integration/test_tdd_red.py | 327 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM | Tests/integration/test_tdd_red.py | 329 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM | Tests/integration/test_tdd_red.py | 382 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM | Tests/integration/test_tdd_red.py | 384 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM | Tests/integration/test_tdd_red.py | 423 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM | Tests/integration/test_tdd_red.py | 426 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | Tests/integration/server_validation_test.py | 76 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | Tests/integration/server_validation_test.py | 78 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | Tests/integration/server_validation_test.py | 118 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | Tests/integration/server_validation_test.py | 120 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | Tests/integration/server_validation_test.py | 446 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | Tests/integration/server_validation_test.py | 448 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | Tests/integration/server_validation_test.py | 498 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | Tests/integration/server_validation_test.py | 500 | # ============================================================================ | COMMENT |
| MEDIUM | Tests/integration/server_validation_test.py | 47 | # ============================================================================ | COMMENT |
| MEDIUM | Tests/integration/server_validation_test.py | 49 | # ============================================================================ | COMMENT |
| MEDIUM | Tests/integration/server_validation_test.py | 95 | # ============================================================================ | COMMENT |
| MEDIUM | Tests/integration/server_validation_test.py | 97 | # ============================================================================ | COMMENT |
| MEDIUM | Tests/integration/server_validation_test.py | 134 | # ============================================================================ | COMMENT |
| MEDIUM | Tests/integration/server_validation_test.py | 136 | # ============================================================================ | COMMENT |
| MEDIUM | Tests/integration/server_validation_test.py | 161 | # ============================================================================ | COMMENT |
| MEDIUM | Tests/integration/server_validation_test.py | 163 | # ============================================================================ | COMMENT |
| MEDIUM | Tests/integration/server_validation_test.py | 278 | # ============================================================================ | COMMENT |
| MEDIUM | Tests/integration/server_validation_test.py | 281 | # ============================================================================ | COMMENT |
| MEDIUM | Tests/integration/server_validation_test.py | 338 | # ============================================================================ | COMMENT |
| MEDIUM | Tests/integration/server_validation_test.py | 340 | # ============================================================================ | COMMENT |
| MEDIUM | Tests/integration/server_validation_test.py | 557 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM | Tests/integration/server_validation_test.py | 560 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM | Tests/integration/server_validation_test.py | 676 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM | Tests/integration/server_validation_test.py | 680 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | Tests/integration/conftest.py | 100 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | Tests/integration/conftest.py | 111 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | Tests/integration/security_test.py | 582 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | Tests/integration/security_test.py | 584 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | Tests/integration/security_test.py | 665 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | Tests/integration/security_test.py | 667 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM | Tests/integration/test_nixpkgs_bump_alerting.py | 48 | # -------------------------------------------------------------------------- | COMMENT |
| MEDIUM | Tests/integration/test_nixpkgs_bump_alerting.py | 50 | # -------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | Tests/integration/test_nixpkgs_bump_alerting.py | 167 | # -------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | Tests/integration/test_nixpkgs_bump_alerting.py | 169 | # -------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | Tests/integration/openai_client_test.py | 985 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | Tests/integration/openai_client_test.py | 987 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | Tests/integration/openapi_spec_test.py | 257 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | Tests/integration/openapi_spec_test.py | 259 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | Tests/integration/openapi_spec_test.py | 267 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | Tests/integration/openapi_spec_test.py | 269 | # ============================================================================ | COMMENT |
| 156 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW⚡ | Tests/integration/server_validation_test.py | 66 | def test_oversized_body_includes_cors_header_for_allowed_origin(): | CODE |
| LOW⚡ | Tests/integration/server_validation_test.py | 108 | def test_error_object_always_has_null_param_and_code_when_absent(): | CODE |
| LOW⚡ | Tests/integration/server_validation_test.py | 431 | def test_responses_truncation_auto_accepted(): | CODE |
| LOW⚡ | Tests/integration/server_validation_test.py | 439 | def test_responses_truncation_disabled_accepted(): | CODE |
| LOW⚡ | Tests/integration/server_validation_test.py | 489 | def test_models_advertise_parallel_tool_calls(): | CODE |
| LOW | Tests/integration/server_validation_test.py | 177 | def test_json_schema_with_mcp_is_rejected(): | CODE |
| LOW | Tests/integration/server_validation_test.py | 203 | def test_json_schema_with_mcp_rejected_streaming(): | CODE |
| LOW | Tests/integration/server_validation_test.py | 230 | def test_json_object_with_mcp_still_accepted(): | CODE |
| LOW | Tests/integration/server_validation_test.py | 243 | def test_no_response_format_with_mcp_still_accepted(): | CODE |
| LOW | Tests/integration/server_validation_test.py | 254 | def test_json_schema_without_mcp_still_accepted(): | CODE |
| LOW | Tests/integration/server_validation_test.py | 296 | def test_include_usage_emits_usage_null_on_non_final_chunks(): | CODE |
| LOW | Tests/integration/server_validation_test.py | 321 | def test_without_include_usage_no_usage_key_on_chunks(): | CODE |
| LOW | Tests/integration/server_validation_test.py | 415 | def test_responses_error_object_has_null_param_and_code(): | CODE |
| LOW | Tests/integration/server_validation_test.py | 537 | def test_trailing_tool_exchange_larger_than_the_window_is_context_overflow(): | CODE |
| LOW | Tests/integration/conftest.py | 141 | def is_tool_choice_not_satisfied(resp): | CODE |
| LOW | Tests/integration/test_changelog_gate.py | 79 | def test_gate_blocks_source_change_without_changelog(tmp_path): | STRING |
| LOW | Tests/integration/test_changelog_gate.py | 92 | def test_gate_passes_source_change_with_changelog(tmp_path): | STRING |
| LOW | Tests/integration/test_changelog_gate.py | 105 | def test_gate_passes_docs_only_change(tmp_path): | STRING |
| LOW | Tests/integration/test_changelog_gate.py | 117 | def test_gate_ignores_generated_buildinfo(tmp_path): | STRING |
| LOW⚡ | Tests/integration/security_test.py | 157 | def test_default_host_header_allowed(): | CODE |
| LOW⚡ | Tests/integration/security_test.py | 165 | def test_no_origin_header_allowed(): | CODE |
| LOW⚡ | Tests/integration/security_test.py | 171 | def test_localhost_origin_allowed(): | CODE |
| LOW⚡ | Tests/integration/security_test.py | 214 | def test_subdomain_attack_rejected(): | CODE |
| LOW⚡ | Tests/integration/security_test.py | 224 | def test_foreign_origin_rejected_on_models(): | CODE |
| LOW⚡ | Tests/integration/security_test.py | 234 | def test_foreign_origin_rejected_on_chat(): | CODE |
| LOW⚡ | Tests/integration/security_test.py | 269 | def test_no_cors_headers_by_default(): | CODE |
| LOW⚡ | Tests/integration/security_test.py | 275 | def test_options_no_cors_headers_by_default(): | CODE |
| LOW⚡ | Tests/integration/security_test.py | 284 | def test_origin_error_is_openai_format(): | CODE |
| LOW⚡ | Tests/integration/security_test.py | 354 | def test_explicit_token_not_echoed_in_startup_banner(): | CODE |
| LOW⚡ | Tests/integration/security_test.py | 363 | def test_env_token_not_echoed_in_startup_banner(): | CODE |
| LOW⚡ | Tests/integration/security_test.py | 372 | def test_token_auto_prints_generated_secret(): | CODE |
| LOW⚡ | Tests/integration/security_test.py | 380 | def test_no_origin_check_shows_loud_warning_without_cors(): | CODE |
| LOW⚡ | Tests/integration/security_test.py | 388 | def test_footgun_still_shows_loud_warning(): | CODE |
| LOW⚡ | Tests/integration/security_test.py | 397 | def test_default_server_has_no_origin_warning(): | CODE |
| LOW⚡ | Tests/integration/security_test.py | 404 | def test_wildcard_allowed_origins_warns_like_no_origin_check(): | CODE |
| LOW⚡ | Tests/integration/security_test.py | 413 | def test_normal_allowed_origins_shows_no_warning(): | CODE |
| LOW⚡ | Tests/integration/security_test.py | 421 | def test_non_loopback_bind_without_token_warns_loudly(): | CODE |
| LOW⚡ | Tests/integration/security_test.py | 431 | def test_non_loopback_bind_with_token_has_no_exposure_warning(): | CODE |
| LOW⚡ | Tests/integration/security_test.py | 440 | def test_loopback_bind_without_token_has_no_exposure_warning(): | CODE |
| LOW⚡ | Tests/integration/security_test.py | 447 | def test_unauthorized_error_keeps_cors_for_allowed_origin(): | CODE |
| LOW⚡ | Tests/integration/security_test.py | 594 | def test_deeply_nested_schema_is_rejected_not_fatal(depth): | CODE |
| LOW⚡ | Tests/integration/security_test.py | 672 | def test_stalled_request_bodies_do_not_wedge_the_server(): | CODE |
| LOW | Tests/integration/security_test.py | 116 | def test_foreign_host_header_rejected(): | CODE |
| LOW | Tests/integration/security_test.py | 127 | def test_foreign_host_header_rejected_on_health(): | CODE |
| LOW | Tests/integration/security_test.py | 137 | def test_localhost_host_header_allowed(): | CODE |
| LOW | Tests/integration/security_test.py | 201 | def test_foreign_origin_rejected(): | CODE |
| LOW | Tests/integration/security_test.py | 245 | def test_foreign_origin_rejected_on_logs(): | CODE |
| LOW | Tests/integration/security_test.py | 256 | def test_foreign_origin_rejected_on_stats(): | CODE |
| LOW | Tests/integration/security_test.py | 298 | def test_logs_endpoints_hidden_without_debug(): | CODE |
| LOW | Tests/integration/security_test.py | 307 | def test_logs_include_bodies_in_debug_mode(): | CODE |
| LOW | Tests/integration/security_test.py | 325 | def test_logs_limit_is_clamped_to_safe_positive_range(): | CODE |
| LOW | Tests/integration/security_test.py | 337 | def test_allowed_origins_adds_to_default_localhost_allowlist(): | CODE |
| LOW | Tests/integration/security_test.py | 468 | def test_health_requires_auth_on_non_loopback_token_protected_bind(): | CODE |
| LOW | Tests/integration/security_test.py | 487 | def test_public_health_keeps_non_loopback_health_open(): | CODE |
| LOW | Tests/integration/security_test.py | 502 | def test_footgun_preflight_allows_openai_sdk_headers(): | CODE |
| LOW | Tests/integration/security_test.py | 526 | def test_footgun_preflight_allows_arbitrary_headers(): | CODE |
| LOW | Tests/integration/security_test.py | 547 | def test_cors_preflight_echoes_requested_headers(): | CODE |
| LOW | Tests/integration/security_test.py | 567 | def test_default_preflight_still_works_without_cors(): | CODE |
| LOW | Tests/integration/security_test.py | 645 | def test_realistic_nested_schema_still_accepted(): | CODE |
| LOW | Tests/integration/test_apfelcore_package.py | 28 | def test_apfelcore_can_be_imported_by_a_downstream_package(): | CODE |
| 380 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | Tests/integration/conftest.py | 101 | # Guardrail-refusal handling (#320, #323, #324) | COMMENT |
| LOW | Tests/integration/test_stream_permit_release.py | 21 | # LanguageModelSession is constructed, so these run fine on a GitHub runner | COMMENT |
| LOW | Tests/apfelTests/ApfelErrorMessageTests.swift | 1 | // ============================================================================ | COMMENT |
| LOW | Tests/apfelTests/CLIValidateTests.swift | 1 | // ============================================================================ | COMMENT |
| LOW | Tests/apfelTests/StreamErrorResolverTests.swift | 1 | // ============================================================================ | COMMENT |
| LOW | Tests/apfelTests/OpenAIWireFormatTests.swift | 1 | // ============================================================================ | COMMENT |
| LOW | Tests/apfelTests/RedTDDTests.swift | 1 | // ============================================================================ | COMMENT |
| LOW | Tests/apfelTests/ToolCallingDirectiveTests.swift | 1 | // ============================================================================ | COMMENT |
| LOW | Tests/apfelTests/ApfelCorePublicAPIUsageTests.swift | 1 | // ============================================================================ | COMMENT |
| LOW | Tests/apfelTests/NestingDepthTests.swift | 1 | import Foundation | COMMENT |
| LOW | …ts/apfelTests/BufferedLineReaderConcurrencyTests.swift | 1 | // ============================================================================ | COMMENT |
| LOW | Tests/apfelTests/BrokenPipeTests.swift | 1 | import Foundation | COMMENT |
| LOW | scripts/nixpkgs-bump-cron.sh | 1 | #!/usr/bin/env bash | COMMENT |
| LOW | scripts/publish-nixpkgs-bump.sh | 1 | #!/usr/bin/env bash | COMMENT |
| LOW | scripts/publish-nixpkgs-bump.sh | 21 | # | COMMENT |
| LOW | scripts/publish-release.sh | 1 | #!/usr/bin/env bash | COMMENT |
| LOW | scripts/stamp-changelog.sh | 1 | #!/usr/bin/env bash | COMMENT |
| LOW | scripts/release-preflight.sh | 1 | #!/usr/bin/env bash | COMMENT |
| LOW | scripts/bump-nixpkgs.sh | 1 | #!/usr/bin/env bash | COMMENT |
| LOW | scripts/dist-watch.sh | 1 | #!/usr/bin/env bash | COMMENT |
| LOW | scripts/check-changelog.sh | 1 | #!/usr/bin/env bash | COMMENT |
| LOW | .github/workflows/ci.yml | 41 | # it to satisfy a transitive dep that wants a newer one -- that killed | COMMENT |
| LOW | .github/workflows/ci.yml | 81 | python3 -m pytest Tests/integration/test_changelog_gate.py -v --tb=short | COMMENT |
| LOW | Sources/ToolCallingSupport.swift | 1 | // ============================================================================ | COMMENT |
| LOW | Sources/ContextManager.swift | 1 | // ============================================================================ | COMMENT |
| LOW | Sources/ContextManager.swift | 61 | // intact) so callers can count prompt tokens accurately. Reading them | COMMENT |
| LOW | Sources/Session.swift | 41 | case .defaultMode: | COMMENT |
| LOW | Sources/Session.swift | 721 | /// FoundationModels returns cumulative snapshots; we compute deltas by tracking prev length. | COMMENT |
| LOW | Sources/TokenCounter.swift | 61 | /// when the SDK has not yet reported a positive value. The floor prevents | COMMENT |
| LOW | Sources/ResponsesHandlers.swift | 1 | // ============================================================================ | COMMENT |
| LOW | Sources/Output.swift | 1 | // ============================================================================ | COMMENT |
| LOW | Sources/Output.swift | 61 | } | COMMENT |
| LOW | Sources/UsageAccounting.swift | 1 | // ============================================================================ | COMMENT |
| LOW | Sources/Server.swift | 61 | // Pre-fetch supportedLanguages BEFORE binding so any SDK-level crash | COMMENT |
| LOW | Sources/Summarizer.swift | 1 | // ============================================================================ | COMMENT |
| LOW | Sources/SchemaConverter.swift | 1 | // ============================================================================ | COMMENT |
| LOW | Sources/main.swift | 41 | // Adopt the user's LC_CTYPE from the environment (LANG/LC_*). apfel otherwise | COMMENT |
| LOW | Sources/TypedErrorSupport.swift | 1 | // ============================================================================ | COMMENT |
| LOW | Sources/MCPClient.swift | 1 | // ============================================================================ | COMMENT |
| LOW | Sources/MCPClient.swift | 221 | ioLock.lock() | COMMENT |
| LOW | Sources/LesbarFileReader.swift | 1 | // ============================================================================ | COMMENT |
| LOW | Sources/VisionSupport.swift | 1 | // ============================================================================ | COMMENT |
| LOW | Sources/VisionSupport.swift | 41 | : BodyLimits.maxRequestBodyBytes | COMMENT |
| LOW | Sources/Core/CodeCropper.swift | 1 | // ============================================================================ | COMMENT |
| LOW | Sources/Core/CodeCropper.swift | 41 | contains only the code or command. No text before or after the block. | COMMENT |
| LOW | Sources/Core/CodeCropper.swift | 81 | COMMENT | |
| LOW | Sources/Core/ChatRequestValidator.swift | 81 | /// The final non-tool message had empty or null content. | COMMENT |
| LOW | Sources/Core/ChatRequestValidator.swift | 201 | COMMENT | |
| LOW | Sources/Core/SchemaIR.swift | 1 | // ============================================================================ | COMMENT |
| LOW | Sources/Core/SchemaIR.swift | 21 | case integer(name: String, description: String?) | COMMENT |
| LOW | Sources/Core/OpenAIModels.swift | 1 | // ============================================================================ | COMMENT |
| LOW | Sources/Core/OpenAIModels.swift | 581 | /// ~512-level limit Foundation's own JSON scanner enforces. Depths in | COMMENT |
| LOW | Sources/Core/TokenUsage.swift | 1 | // ============================================================================ | COMMENT |
| LOW | Sources/Core/ToolCallingDirective.swift | 1 | // ============================================================================ | COMMENT |
| LOW | Sources/Core/ToolCallingDirective.swift | 21 | // on every OS. There is also no per-tool mode in the SDK, so a named | COMMENT |
| LOW | Sources/Core/ImageInput.swift | 1 | // ============================================================================ | COMMENT |
| LOW | Sources/Core/LRUCache.swift | 1 | // ============================================================================ | COMMENT |
| LOW | Sources/Core/ToolCallHandler.swift | 161 | COMMENT | |
| LOW | Sources/Core/SamplingDecision.swift | 1 | // ============================================================================ | COMMENT |
| LOW | Sources/Core/StreamingToolCallGate.swift | 1 | // ============================================================================ | COMMENT |
| 45 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | Tests/integration/security_test.py | 107 | except httpx.HTTPError: | CODE |
| HIGH | Tests/integration/security_test.py | 54 | except httpx.HTTPError: | CODE |
| HIGH | Tests/integration/test_chat.py | 383 | except OSError: | CODE |
| HIGH | Tests/integration/test_chat.py | 447 | except OSError: | CODE |
| HIGH | Tests/integration/test_chat.py | 1009 | except OSError: | CODE |
| HIGH | Tests/integration/test_chat.py | 443 | except OSError: | CODE |
| HIGH | Tests/integration/mcp_server_test.py | 95 | except httpx.HTTPError: | CODE |
| HIGH | Tests/integration/mcp_remote_test.py | 59 | except httpx.HTTPError: | CODE |
| HIGH | Tests/integration/mcp_remote_test.py | 358 | except (json.JSONDecodeError, KeyError, IndexError): | CODE |
| HIGH | mcp/calculator/server.py | 111 | except ValueError: | CODE |
| HIGH | mcp/http-test-server/server.py | 250 | except KeyboardInterrupt: | CODE |
| HIGH | mcp/http-test-server/server.py | 98 | except ValueError: | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | CHANGELOG.md | 15 | - Typed `LanguageModelError` classification on macOS 27 (#510 item 4, #197). Every main-target catch site now classifies | CODE |
| MEDIUM | README.md | 292 | ### Permissive guardrails for the server | COMMENT |
| MEDIUM | README.md | 297 | apfel --serve --permissive # every request uses permissive guardrails | CODE |
| MEDIUM⚡ | Tests/integration/conftest.py | 103 | # The on-device model's guardrails fire on arbitrary benign prompts along | COMMENT |
| MEDIUM | Tests/integration/openai_client_test.py | 764 | # generate until the 4096-token context window overflowed and returned a | COMMENT |
| MEDIUM | Tests/integration/openai_client_test.py | 966 | # REQUIRE them: the on-device model occasionally hallucinates keys | COMMENT |
| MEDIUM | .claude/routines/_golden-goal.md | 29 | ## Hard guardrails - non-negotiable | COMMENT |
| MEDIUM | docs/coreai-impact.md | 185 | parked ticket #119); a `DynamicProfile` agentic API; and image analysis (`OCRTool`, | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | mcp/calculator/test_round_trip.py | 64 | # Step 1: Ask apfel with calculator tool | COMMENT |
| LOW⚡ | mcp/calculator/test_round_trip.py | 83 | # Step 2: Execute via MCP calculator | COMMENT |
| LOW⚡ | mcp/calculator/test_round_trip.py | 87 | # Step 3: Feed result back to apfel | COMMENT |
| LOW⚡ | mcp/calculator/README.md | 9 | # Step 1: Model called multiply({"a": 247, "b": 83}) | COMMENT |
| LOW⚡ | mcp/calculator/README.md | 10 | # Step 2: Calculator result: 20501 | COMMENT |
| LOW⚡ | mcp/calculator/README.md | 11 | # Step 3: Final answer: The product of 247 and 83 is 20,501. | COMMENT |
| LOW | docs/tool-calling-guide.md | 186 | ### Step 1 - Model calls tool: | COMMENT |
| LOW | docs/tool-calling-guide.md | 193 | ### Step 2 - We send the tool result back + a follow-up question: | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | Tests/integration/test_tdd_red.py | 159 | CODE | |
| LOW | Tests/integration/test_build_info.py | 66 | CODE | |
| LOW | Tests/integration/openai_client_test.py | 370 | CODE | |
| LOW | Tests/integration/openai_client_test.py | 521 | CODE | |
| LOW | Tests/integration/openai_client_test.py | 558 | CODE | |
| LOW | Tests/integration/openai_client_test.py | 589 | CODE | |
| LOW | Tests/integration/openapi_spec_test.py | 236 | CODE | |
| LOW | Tests/integration/test_marker_discipline.py | 60 | CODE | |
| LOW | Tests/integration/test_chat.py | 64 | CODE | |
| LOW | Tests/integration/test_chat.py | 134 | CODE | |
| LOW | Tests/integration/test_chat.py | 968 | CODE | |
| LOW | Tests/integration/openapi_conformance_test.py | 271 | CODE | |
| LOW | Tests/integration/openapi_conformance_test.py | 129 | CODE | |
| LOW | Tests/integration/mcp_remote_test.py | 322 | CODE | |
| LOW | Tests/integration/cli_e2e_test.py | 78 | CODE | |
| LOW | Tests/integration/cli_e2e_test.py | 130 | CODE | |
| LOW | Tests/integration/cli_e2e_test.py | 224 | CODE | |
| LOW | mcp/calculator/server.py | 102 | CODE | |
| LOW | mcp/calculator/server.py | 136 | CODE | |
| LOW | mcp/calculator/server.py | 196 | CODE | |
| LOW | mcp/http-test-server/server.py | 107 | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | Tests/integration/performance_test.py | 23 | # MEDIAN speedup across repeated runs instead, which is robust to occasional | COMMENT |
| MEDIUM | scripts/publish-nixpkgs-bump.sh | 72 | # Default target = latest published GitHub release (robust for the launchd | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | mcp/calculator/test_round_trip.py | 64 | # Step 1: Ask apfel with calculator tool | COMMENT |
| LOW⚡ | mcp/calculator/test_round_trip.py | 83 | # Step 2: Execute via MCP calculator | COMMENT |
| LOW⚡ | mcp/calculator/test_round_trip.py | 87 | # Step 3: Feed result back to apfel | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | scripts/publish-nixpkgs-bump.sh | 30 | # Usage: | COMMENT |
| LOW | scripts/publish-release.sh | 8 | # Usage: | COMMENT |
| LOW | scripts/stamp-changelog.sh | 12 | # Usage: | COMMENT |
| LOW | scripts/bump-nixpkgs.sh | 9 | # Usage: | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | Tests/integration/test_demo_packaging.py | 145 | "Release build artefacts missing (run `make build && make generate-man-page`)" | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | Tests/apfelTests/ApfelErrorTests.swift | 105 | localizedMsg: "I cannot provide that information." | CODE |
| MEDIUM | Tests/apfelTests/ApfelErrorTests.swift | 109 | try assertEqual(text, "I cannot provide that information.") | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | Tests/integration/openapi_spec_test.py | 20 | CODE | |
| LOW | Tests/integration/test_chat.py | 231 | CODE | |
| LOW | Tests/integration/mcp_server_test.py | 27 | CODE | |
| LOW | Tests/integration/test_brew_service.py | 13 | CODE | |
| LOW | Tests/integration/cli_e2e_test.py | 311 | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | Tests/integration/openai_client_test.py | 1054 | except Exception as exc: # noqa: BLE001 - SDK validation error is the signal | CODE |
| LOW | mcp/calculator/server.py | 172 | except Exception as e: | CODE |
| LOW | mcp/http-test-server/server.py | 134 | except Exception as e: | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | mcp/http-test-server/server.py | 138 | def handle_request(body): | CODE |