Files
Charon/docs/plans/current_spec.md
GitHub Actions 716ec91f8f chore: Enhance test coverage across various handlers and services
- Added tests for transient SQLite errors in emergency_handler_test.go.
- Introduced validation tests for provider errors in notification_provider_handler_validation_test.go.
- Implemented helper tests for settings handling in settings_handler_helpers_test.go.
- Expanded backup_handler_test.go to include SQLite database setup and validation.
- Improved system_permissions_handler_test.go with additional path repair tests.
- Updated backup_service_test.go to ensure proper database handling and error checks during backup operations.
- Refined import_handler_test.go with additional session validation tests.
2026-02-16 20:32:16 +00:00

8.7 KiB

PR #666 Patch Coverage Recovery Spec (Approval-Ready)

Date: 2026-02-16 Owner: Planning Agent Status: Draft for Supervisor approval (single coherent plan)

1) Scope Decision (Unified)

In Scope

  • Backend unit-test additions only, targeting changed patch lines in backend handlers/services/utils.
  • Minimum-risk posture: prioritize test-only additions in files already touched by PR #666 before opening any new test surface.
  • Coverage validation using current backend coverage task/script.

Out of Scope

  • E2E/Playwright, integration, frontend, Docker, and security scan remediation.

E2E Decision for this task

  • E2E is explicitly out-of-scope for this patch-coverage remediation.
  • Rationale: target metric is Codecov patch lines on backend changes; E2E adds runtime risk/cycle time without direct line-level patch closure.

Scope Reconciliation with Current Implementation (PR #666)

Confirmed already touched backend test files:

  • backend/internal/api/handlers/import_handler_test.go
  • backend/internal/api/handlers/settings_handler_helpers_test.go
  • backend/internal/api/handlers/emergency_handler_test.go
  • backend/internal/services/backup_service_test.go
  • backend/internal/api/handlers/backup_handler_test.go
  • backend/internal/api/handlers/system_permissions_handler_test.go
  • backend/internal/api/handlers/notification_provider_handler_validation_test.go

Optional/deferred (not yet touched in current remediation pass):

  • backend/internal/util/permissions_test.go
  • backend/internal/services/notification_service_json_test.go
  • backend/internal/services/backup_service_rehydrate_test.go
  • backend/internal/api/handlers/security_handler_coverage_test.go

2) Single Source of Truth for Success

Authoritative success metric:

  • Codecov PR patch status (lines) is the source of truth for this task.

Relationship to codecov.yml:

  • coverage.status.patch.default.target: 100% and required: false means patch status is advisory in CI.
  • For this plan, we set an internal quality gate: patch lines >= 85% (minimum), preferred >= 87% buffer.
  • Local script output (go tool cover) remains diagnostic; pass/fail is decided by Codecov patch lines after upload.

3) Feasibility Math and Coverage-Line Budget

Given baseline:

  • Patch coverage = 60.84011%
  • Missing patch lines = 578

Derived totals:

  • Let total patch lines = T
  • 578 = T * (1 - 0.6084011) => T ≈ 1476
  • Currently covered lines C0 = 1476 - 578 = 898

Required for >=85%:

  • C85 = ceil(0.85 * 1476) = 1255
  • Additional covered lines required: 1255 - 898 = 357

Budget by phase (line-coverage gain target):

Phase Target line gain Cumulative gain target Stop/Go threshold
Phase 1 +220 +220 Stop if <+170; re-scope before Phase 2
Phase 2 +100 +320 Stop if <+70; activate residual plan
Phase 3 (residual closure) +45 +365 Must reach >=+357 total

Notes:

  • Planned total gain +365 gives +8 lines safety over minimum +357.
  • If patch denominator changes due to rebase/new touched lines, recompute budget before continuing.

4) Target Files/Functions (Concise, Specific)

Primary hotspots (Phase 1 focus, aligned to touched tests first):

  • backend/internal/api/handlers/system_permissions_handler.go
    • RepairPermissions, repairPath, normalizePath, pathHasSymlink, isWithinAllowlist, mapRepairErrorCode
  • backend/internal/services/backup_service.go
    • RestoreBackup, extractDatabaseFromBackup, unzipWithSkip, RehydrateLiveDatabase, GetAvailableSpace
  • backend/internal/api/handlers/settings_handler.go
    • UpdateSetting, PatchConfig, validateAdminWhitelist, syncAdminWhitelistWithDB
  • backend/internal/api/handlers/import_handler.go
    • GetStatus, Upload, Commit, Cancel, safeJoin
  • backend/internal/api/handlers/backup_handler.go
    • Restore, isSQLiteTransientRehydrateError
  • backend/internal/api/handlers/emergency_handler.go
    • SecurityReset, disableAllSecurityModules, upsertSettingWithRetry
  • backend/internal/api/handlers/notification_provider_handler.go
    • isProviderValidationError, provider validation branches

Secondary hotspots (Phase 2 focus, optional/deferred expansion):

  • backend/internal/api/handlers/security_handler.go (GetStatus, latestConfigApplyState)
  • backend/internal/util/permissions.go (CheckPathPermissions, MapSaveErrorCode, MapDiagnosticErrorCode)
  • backend/internal/services/notification_service.go (sendJSONPayload, TestProvider, RenderTemplate)

5) Execution Phases with Strict Stop/Go and De-Scoping Rules

Phase 0 - Baseline Lock

Actions:

  • Run Test: Backend with Coverage task (.github/skills/scripts/skill-runner.sh test-backend-coverage).
  • Record baseline patch lines from Codecov PR view and local artifact backend/coverage.txt.

Go gate:

  • Baseline captured and denominator confirmed.

Stop gate:

  • If patch denominator changed by >5% from 1476, pause and recompute budgets before coding.

Phase 1 - High-yield branch closure

Actions:

  • Extend existing tests only in:
    • backend/internal/api/handlers/system_permissions_handler_test.go
    • backend/internal/services/backup_service_test.go
    • backend/internal/api/handlers/backup_handler_test.go
    • backend/internal/api/handlers/emergency_handler_test.go
    • backend/internal/api/handlers/settings_handler_helpers_test.go
    • backend/internal/api/handlers/import_handler_test.go
    • backend/internal/api/handlers/notification_provider_handler_validation_test.go

Go gate:

  • Achieve >= +170 covered patch lines and no failing backend tests.

Stop gate:

  • If < +170, do not proceed; re-scope to only highest delta-per-test functions.

Phase 2 - Secondary branch fill

Actions:

  • Extend tests in:
    • backend/internal/api/handlers/security_handler_coverage_test.go
    • backend/internal/util/permissions_test.go
    • backend/internal/services/backup_service_rehydrate_test.go
    • backend/internal/services/notification_service_json_test.go

Go gate:

  • Additional >= +70 covered patch lines in this phase.

Stop gate:

  • If < +70, skip low-yield areas and move directly to residual-line closure.

Phase 3 - Residual-line closure (minimum-risk)

Actions:

  • Work only uncovered/partial lines still shown in Codecov patch details.
  • Add narrow table-driven tests to existing files; no new harness/framework.

Go gate:

  • Reach total >= +357 covered lines and patch >=85%.

Stop gate:

  • If a residual branch requires production refactor, de-scope it and log as follow-up.

Global de-scope rules (all phases)

  • No production code changes unless a test proves a correctness bug.
  • No new test framework, no integration/E2E expansion, no unrelated cleanup.
  • No edits outside targeted backend test and directly related helper files.

6) Current Tasks/Scripts (Deprecated references removed)

Use these current commands/tasks only:

  • Backend coverage (preferred): Test: Backend with Coverage
    • command: .github/skills/scripts/skill-runner.sh test-backend-coverage
  • Equivalent direct script: bash scripts/go-test-coverage.sh
  • Optional backend unit quick check: Test: Backend Unit Tests
    • command: .github/skills/scripts/skill-runner.sh test-backend-unit

Deprecated tasks are explicitly out-of-plan (for this work):

  • Security: CodeQL Go Scan (DEPRECATED)
  • Security: CodeQL JS Scan (DEPRECATED)

7) Residual Uncovered Lines Handling (Beyond hotspot table)

After each phase, run a residual triage loop:

  1. Export remaining uncovered/partial patch lines from Codecov patch detail.
  2. Classify each residual line into one of:
    • validation/error mapping
    • permission/role guard
    • fallback/retry
    • low-value defensive log/telemetry
  3. Apply closure rule:
    • First three classes: add targeted tests in existing suite.
    • Last class: close only if deterministic and cheap; otherwise de-scope with rationale.
  4. Maintain a residual ledger in the PR description:
    • line(s), owning function, planned test, status (closed/de-scoped), reason.

Exit condition:

  • No unclassified residual lines remain.
  • Any de-scoped residual lines have explicit follow-up items.

8) Acceptance Criteria (Unified)

  1. One coherent plan only (this document), no conflicting statuses.
  2. E2E explicitly out-of-scope for this patch-coverage task.
  3. Success is measured by Codecov patch lines; local statement output is diagnostic only.
  4. Feasibility math and phase budgets remain explicit and tracked against actual deltas.
  5. All phase stop/go gates enforced; de-scope rules followed.
  6. Only current tasks/scripts are referenced.
  7. Residual uncovered lines are either closed with tests or formally de-scoped with follow-up.
  8. Scope remains reconciled with touched files first; deferred files are only pulled in if phase gates require expansion.