diff --git a/.github/agents/DevOps.agent.md b/.github/agents/DevOps.agent.md index 7f30af42..23988e8d 100644 --- a/.github/agents/DevOps.agent.md +++ b/.github/agents/DevOps.agent.md @@ -135,6 +135,7 @@ main: - Look for error messages - Check timing (timeout vs crash) - Environment variables set correctly? + - If MCP web fetch lacks auth, pull workflow logs with `gh` CLI 3. **Verify environment configuration** ```bash diff --git a/.github/instructions/github-actions-ci-cd-best-practices.instructions.md b/.github/instructions/github-actions-ci-cd-best-practices.instructions.md index a3ffe691..b01d00a9 100644 --- a/.github/instructions/github-actions-ci-cd-best-practices.instructions.md +++ b/.github/instructions/github-actions-ci-cd-best-practices.instructions.md @@ -502,6 +502,8 @@ This checklist provides a granular set of criteria for reviewing GitHub Actions This section provides an expanded guide to diagnosing and resolving frequent problems encountered when working with GitHub Actions workflows. +Note: If workflow logs are not accessible via MCP web fetch due to missing auth, retrieve logs with the authenticated `gh` CLI. + ### **1. Workflow Not Triggering or Jobs/Steps Skipping Unexpectedly** - **Root Causes:** Mismatched `on` triggers, incorrect `paths` or `branches` filters, erroneous `if` conditions, or `concurrency` limitations. - **Actionable Steps:** diff --git a/docs/plans/current_spec.md b/docs/plans/current_spec.md index a1b0372e..e699eaf4 100644 --- a/docs/plans/current_spec.md +++ b/docs/plans/current_spec.md @@ -1,141 +1,326 @@ - -# Plan: Conditional E2E Rebuild Rules + Navigation Test Continuation +--- +title: "CI Docker Build and Scanning Blocker (PR #666)" +status: "draft" +scope: "ci/docker-build-scan" +--- ## 1. Introduction -This plan updates E2E testing instructions so the Docker rebuild runs only when application code changes, explicitly skips rebuilds for test-only changes, and then continues navigation E2E testing using the existing task. The intent is to reduce unnecessary rebuild time while keeping the environment reliable and consistent. +This plan addresses the CI failure that blocks Docker build and scanning +for PR #666. The goal is to restore a clean, deterministic pipeline +where the image builds once, scans consistently, and security artifacts +align across workflows. The approach is minimal and evidence-driven: +collect logs, map the path, isolate the blocker, and apply the smallest +effective fix. Objectives: -- Define clear, repeatable criteria for when an E2E container rebuild is required vs optional. -- Update instruction and agent documents to use the same conditional rebuild guidance. -- Preserve current E2E execution behavior and task surface, then proceed with navigation testing. +- Identify the exact failing step in the build/scan chain. +- Trace the failure to a reproducible root cause. +- Propose minimal workflow/Dockerfile changes to restore green CI. +- Ensure all scan workflows resolve the same PR image. +- Review .gitignore, codecov.yml, .dockerignore, and Dockerfile if + needed for artifact hygiene. ## 2. Research Findings -- The current testing protocol mandates rebuilding the E2E container before Playwright runs in [testing.instructions.md](.github/instructions/testing.instructions.md). -- The Management and Playwright agent definitions require rebuilding the E2E container before each test run in [Management.agent.md](.github/agents/Management.agent.md) and [Playwright_Dev.agent.md](.github/agents/Playwright_Dev.agent.md). -- QA Security also mandates rebuilds on every code change in [QA_Security.agent.md](.github/agents/QA_Security.agent.md). -- The main E2E skill doc encourages rebuilds before testing in [test-e2e-playwright.SKILL.md](.github/skills/test-e2e-playwright.SKILL.md). -- The rebuild skill itself is stable and already describes when it should be used in [docker-rebuild-e2e.SKILL.md](.github/skills/docker-rebuild-e2e.SKILL.md). -- Navigation test tasks already exist in [tasks.json](.vscode/tasks.json), including “Test: E2E Playwright (FireFox) - Core: Navigation”. -- CI E2E jobs rebuild via Docker image creation in [e2e-tests-split.yml](.github/workflows/e2e-tests-split.yml); no CI changes are required for this instruction-only update. +CI workflow and build context (already reviewed): + +- Docker build orchestration: .github/workflows/docker-build.yml +- Security scan for PR artifacts: .github/workflows/security-pr.yml +- Supply-chain verification for PRs: .github/workflows/supply-chain-pr.yml +- SBOM verification for non-PR builds: .github/workflows/supply-chain-verify.yml +- Dockerfile linting: .github/workflows/docker-lint.yml and + .hadolint.yaml +- Weekly rebuild and scan: .github/workflows/security-weekly-rebuild.yml +- Quality checks (non-Docker): .github/workflows/quality-checks.yml +- Build context filters: .dockerignore +- Runtime Docker build instructions: Dockerfile +- Ignored artifacts: .gitignore +- Coverage configuration: codecov.yml + +Observed from the public workflow summary (PR #666): + +- Job build-and-push failed in the Docker Build, Publish & Test workflow. +- Logs require GitHub authentication; obtained via gh CLI after auth. +- Evidence status: confirmed via gh CLI logs (see Results). + +Root cause captured from CI logs (authenticated gh CLI): + +- npm ci failed with ERESOLVE due to eslint@10 conflicting with the + @typescript-eslint peer dependency range. + +Secondary/unconfirmed mismatch to verify only if remediation fails: + +- PR tags are generated as pr-{number}-{short-sha} in docker-build.yml. +- Several steps reference pr-{number} (no short SHA) and use + --pull=never. +- This can cause image-not-found errors after Buildx pushes without + --load. ## 3. Technical Specifications -### 3.1 Rebuild Decision Rules +### 3.1 CI Flow Map (Build -> Scan -> Verify) -Define explicit change categories to decide when to rebuild: +```mermaid +flowchart LR + A[PR Push] --> B[docker-build.yml: build-and-push] + B --> C[docker-build.yml: scan-pr-image] + B --> D[security-pr.yml: Trivy binary scan] + B --> E[supply-chain-pr.yml: SBOM + Grype] + B --> F[supply-chain-verify.yml: SBOM verify (non-PR)] +``` -- **Rebuild Required (application/runtime changes)** - - Application code or dependencies: backend/**, frontend/**, backend/go.mod, backend/go.sum, package.json, package-lock.json. - - Container build/runtime configuration: Dockerfile, .docker/**, .docker/compose/docker-compose.playwright-*.yml, .docker/docker-entrypoint.sh. - - Runtime behavior changes that affect container startup (e.g., config files baked into the image). +### 3.2 Primary Failure Hypotheses (Ordered) -- **Rebuild Optional (test-only changes)** - - Playwright tests and fixtures: tests/**. - - Playwright config and test runners: playwright.config.js, playwright.caddy-debug.config.js. - - Documentation or planning files: docs/**, requirements.md, design.md, tasks.md. - - CI/workflow changes that do not affect runtime images: .github/workflows/**. +1) Eslint peer dependency conflict (confirmed root cause) -Decision guidance: +- npm ci failed with ERESOLVE due to eslint@10 conflicting with the + @typescript-eslint peer dependency range. -- If only test files or documentation change, reuse the existing E2E container if it is already healthy. -- If the container is not running, start it with docker-rebuild-e2e even for test-only changes. -- If there is uncertainty about whether a change affects the runtime image, default to rebuilding. +2) Tag mismatch between build output and verification steps -### 3.2 Instruction Targets and Proposed Wording +- Build tags for PRs are pr-{number}-{short-sha} (metadata action). +- Verification steps reference pr-{number} (no SHA) and do not pull. +- This is consistent with image-not-found errors. + Status: unconfirmed secondary hypothesis. -Update the following instruction and agent files to align with the conditional rebuild policy: +3) Buildx push without local image for verification steps -- [testing.instructions.md](.github/instructions/testing.instructions.md) - - Replace the current “Always rebuild the E2E container before running Playwright tests” statement with: - - “Rebuild the E2E container when application or Docker build inputs change (backend, frontend, dependencies, Dockerfile, .docker/compose). If changes are test-only, reuse the existing container when it is already healthy; rebuild only if the container is not running or state is suspect.” - - Add a short file-scope checklist defining “rebuild required” vs “test-only.” +- Build uses docker buildx build --push without --load. +- Verification steps use docker run --pull=never with local tags. +- Buildx does not allow --load with multi-arch builds; --load only + produces a single-platform image. For multi-arch, prioritize pull by + digest or publish a single-platform build output for local checks. +- If the tag is not local and not pulled, verification fails. -- [Management.agent.md](.github/agents/Management.agent.md) - - Update the “PREREQUISITE: Rebuild E2E container before each test run” bullet to: - - “PREREQUISITE: Rebuild the E2E container only when application or Docker build inputs change; skip rebuild for test-only changes if the container is already healthy.” +4) Dockerfile stage failure during network-heavy steps -- [Playwright_Dev.agent.md](.github/agents/Playwright_Dev.agent.md) - - Update “ALWAYS rebuild the E2E container before running tests” to: - - “Rebuild the E2E container when application or Docker build inputs change. For test-only changes, reuse the running container if healthy; rebuild only when the container is not running or state is suspect.” +- gosu-builder: git clone and Go build +- frontend-builder: npm ci / npm run build +- backend-builder: go mod download / xx-go build +- caddy-builder: xcaddy build and Go dependency patching +- crowdsec-builder: git clone + go get + sed patch +- GeoLite2 download and checksum verification -- [QA_Security.agent.md](.github/agents/QA_Security.agent.md) - - Update workflow step 1 to: - - “Rebuild the E2E image and container when application or Docker build inputs change. Skip rebuild for test-only changes if the container is already healthy.” +Any of these can fail with network timeouts or dependency resolution +errors in CI. The eslint peer dependency conflict is confirmed; other +hypotheses remain unconfirmed. -- [test-e2e-playwright.SKILL.md](.github/skills/test-e2e-playwright.SKILL.md) - - Adjust “Quick Start” language to: - - “Run docker-rebuild-e2e when application or Docker build inputs change. If only tests changed and the container is already healthy, skip rebuild and run the tests.” +### 3.3 Evidence Required (Single-Request Capture) -- Optional alignment (if desired for consistency): - - [test-e2e-playwright-debug.SKILL.md](.github/skills/test-e2e-playwright-debug.SKILL.md) - - [test-e2e-playwright-coverage.SKILL.md](.github/skills/test-e2e-playwright-coverage.SKILL.md) - - Update prerequisite language in the same conditional format when referencing docker-rebuild-e2e. +Evidence capture completed in a single session. The following items +were captured: -### 3.3 Data Flow and Component Impact +- Full logs for the failing docker-build.yml build-and-push job +- Failing step name and exit code +- Buildx command line as executed +- Metadata tags produced by docker/metadata-action +- Dockerfile stage that failed (if build failure) -- No API, database, or runtime component changes are introduced. -- The change is documentation-only: it modifies decision guidance for when to rebuild the E2E container. -- The E2E execution flow remains: optionally rebuild → run navigation test task → review Playwright report. +If accessible, also capture downstream scan job logs to confirm the image +reference used. -### 3.4 Error Handling and Edge Cases +### 3.4 Specific Files and Components to Investigate -- If the container is running but tests fail due to stale state, rebuild with docker-rebuild-e2e and re-run the navigation test. -- If only tests changed but the container is stopped, rebuild to create a known-good environment. -- If Dockerfile or .docker/compose changes occurred, rebuild is required even if tests are the only edited files in the last commit. +Docker build and tagging: -## 4. Implementation Plan +- .github/workflows/docker-build.yml + - Generate Docker metadata (tag formatting) + - Build and push Docker image (with retry) + - Verify Caddy Security Patches + - Verify CrowdSec Security Patches + - Job: scan-pr-image -### Phase 1: Instruction Updates (Documentation-only) +Security scanning: -- Update conditional rebuild guidance in the instruction files listed in section 3.2. -- Ensure the rebuild decision criteria are consistent and use the same file-scope examples across documents. +- .github/workflows/security-pr.yml + - Extract PR number from workflow_run + - Extract charon binary from container (image reference) + - Trivy scans (fs, SARIF, blocking table) -### Phase 2: Supporting Artifacts +Supply-chain verification: -- Update requirements.md with EARS requirements for conditional rebuild behavior. -- Update design.md to document the decision rules and file-scope criteria. -- Update tasks.md with a checklist that explicitly separates rebuild-required vs test-only scenarios. +- .github/workflows/supply-chain-pr.yml + - Check for PR image artifact + - Load Docker image (artifact) + - Build Docker image (Local) -### Phase 3: Navigation Test Continuation +Dockerfile stages and critical components: -- Determine change scope: - - If application/runtime files changed, run the Docker rebuild step first. - - If only tests or docs changed and the E2E container is already healthy, skip rebuild. -- Run the existing navigation task: “Test: E2E Playwright (FireFox) - Core: Navigation” from [tasks.json](.vscode/tasks.json). -- If the navigation test fails due to environment issues, rebuild and re-run. +- gosu-builder: /tmp/gosu build +- frontend-builder: /app/frontend build +- backend-builder: /app/backend build +- caddy-builder: xcaddy build and Go dependency patching +- crowdsec-builder: Go build and sed patch in + pkg/exprhelpers/debugger.go +- Final runtime stage: GeoLite2 download and checksum -## 5. Acceptance Criteria +### 3.5 Tag and Digest Source-of-Truth Propagation -- Instruction and agent files reflect the same conditional rebuild policy. -- Rebuild-required vs test-only criteria are explicitly defined with file path examples. -- Navigation tests can be run without a rebuild when only tests change and the container is healthy. -- The navigation test task remains unchanged and is used for validation. -- requirements.md, design.md, and tasks.md are updated to reflect the new rebuild rules. +Source of truth for the PR image reference is the output of the metadata +and build steps in docker-build.yml. Downstream workflows must consume a +single canonical reference, defined as: -## 6. Testing Steps +- primary: digest from buildx outputs (immutable) +- secondary: pr-{number}-{short-sha} tag (human-friendly) -- If application/runtime files changed, run the E2E rebuild using docker-rebuild-e2e before testing. -- If only tests changed and the container is healthy, skip rebuild. -- Run the navigation test task: “Test: E2E Playwright (FireFox) - Core: Navigation”. -- Review Playwright report and logs if failures occur; rebuild and re-run if the failure is environment-related. +Propagation rules: -## 7. Config Hygiene Review (Requested Files) +- docker-build.yml SHALL publish the digest and tag as job outputs. +- docker-build.yml SHALL write digest and tag to a small artifact + (e.g., pr-image-ref.txt) for downstream workflow_run consumers. +- security-pr.yml and supply-chain-pr.yml SHALL prefer the digest from + outputs or artifact, and only fall back to tag if digest is absent. +- Any step that runs a local container SHALL ensure the referenced image + is available by either --load (local) or explicit pull by digest. -- .gitignore: No change required for this instruction update. -- codecov.yml: No change required; E2E outputs are already ignored. -- .dockerignore: No change required; tests/ and Playwright artifacts remain excluded from image build context. -- Dockerfile: No change required. +### 3.6 Required Outcome (EARS Requirements) -## 8. Risks and Mitigations +- WHEN a pull request triggers docker-build.yml, THE SYSTEM SHALL build a + PR image tagged as pr-{number}-{short-sha} and emit its digest. +- WHEN verification steps run in docker-build.yml, THE SYSTEM SHALL + reference the same digest or tag emitted by the build step. +- WHEN security-pr.yml runs for a workflow_run, THE SYSTEM SHALL resolve + the PR image using the digest or the emitted tag. +- WHEN supply-chain-pr.yml runs, THE SYSTEM SHALL load the exact PR image + by digest or by the emitted tag without ambiguity. +- IF the image reference cannot be resolved, THEN THE SYSTEM SHALL fail + fast with a clear message that includes the expected digest and tag. -- Risk: Tests may run against stale containers when changes are misclassified as test-only. Mitigation: Provide explicit file-scope criteria and default to rebuild when unsure. -- Risk: Contributors interpret “test-only” too narrowly. Mitigation: include dependency files and Docker build inputs in rebuild-required list. +### 3.7 Config Hygiene Review (Requested Files) -## 9. Confidence Score +.gitignore: + +- Ensure CI scan artifacts are ignored locally, including any new names + introduced by fixes (e.g., trivy-pr-results.sarif, + trivy-binary-results.sarif, grype-results.json, + sbom.cyclonedx.json). + +codecov.yml: + +- Confirm CI-generated security artifacts are excluded from coverage. +- Add any new artifact names if introduced by fixes. + +.dockerignore: + +- Verify required frontend/backend sources and manifests are included. + +Dockerfile: + +- Review GeoLite2 download behavior for CI reliability. +- Confirm CADDY_IMAGE build-arg naming consistency across workflows. + +## 4. Implementation Plan (Minimal-Request Phases) + +### Phase 0: Evidence Capture (Single Request) + +Status: completed. Evidence captured and root cause confirmed. + +- Retrieve full logs for the failing docker-build.yml build-and-push job. +- Capture the exact failing step, error output, and emitted tags/digest. +- Record the buildx command output as executed. +- Capture downstream scan logs if accessible to confirm image reference. + +### Phase 1: Reproducibility Pass (Single Local Build) + +- Run a local docker buildx build using the same arguments as + docker-build.yml. +- Capture any stage failures and map them to Dockerfile stages. +- Confirm whether Buildx produces local images or only remote tags. + +### Phase 2: Root Cause Isolation + +Status: completed. Root cause identified as the eslint peer dependency +conflict in the frontend build stage. + +- If failure is tag mismatch, trace tag references across docker-build.yml, + security-pr.yml, and supply-chain-pr.yml. +- If failure is a Dockerfile stage, isolate to specific step (gosu, + frontend, backend, caddy, crowdsec, GeoLite2). +- If failure is network-related, document retries/timeout behavior and + any missing mirrors. + +### Phase 3: Targeted Remediation Plan + +Focus on validating the eslint remediation. Revisit secondary +hypotheses only if the remediation does not resolve CI. + +Conditional options (fallbacks, unconfirmed): + +Option A (Tag alignment): + +- Update verification steps to use pr-{number}-{short-sha} tag. +- Or add a secondary tag pr-{number} for compatibility. + +Option B (Local image availability): + +- Add --load for PR builds so verification can run locally. +- Or explicitly pull by digest/tag before verification and remove + --pull=never. + +Option C (Workflow scan alignment): + +- Update security-pr.yml and supply-chain-pr.yml to consume the digest + or emitted tag from docker-build.yml outputs/artifact. +- Add fallback order: digest artifact -> emitted tag -> local build. + +## 5. Results (Evidence) + +Evidence status: confirmed via gh CLI logs after authentication. + +Root cause (confirmed): + +- Align eslint with the @typescript-eslint peer range to resolve npm ci + ERESOLVE in the frontend build stage. + +### Phase 4: Validation (Minimal Jobs) + +- Rerun docker-build.yml for the PR (or workflow_dispatch). +- Confirm build-and-push succeeds and verification steps resolve the + exact digest or tag. +- Confirm security-pr.yml and supply-chain-pr.yml resolve the same + digest or tag and complete scans. +- Deterministic check: use docker buildx imagetools inspect on the + emitted tag and compare the reported digest to the recorded build + digest, or pull by digest and verify the digest of the local image + matches the build output. + +### Phase 5: Documentation and Hygiene + +- Document the final tag/digest propagation in this plan. +- Update .gitignore / .dockerignore / codecov.yml if new artifacts are + produced. + +## 6. Acceptance Criteria + +- docker-build.yml build-and-push succeeds for PR #666. +- Verification steps resolve the same digest or tag emitted by build. +- security-pr.yml and supply-chain-pr.yml consume the same digest or tag + published by docker-build.yml. +- A validation check confirms tag-to-digest alignment across workflows + (digest matches tag for the PR image), using buildx imagetools inspect + or an equivalent digest comparison. +- No new CI artifacts are committed to the repository. +- Root cause is documented with logs and mapped to specific steps. + +## 7. Risks and Mitigations + +- Risk: CI logs are inaccessible without login, delaying diagnosis. + - Mitigation: request logs or export them once, then reproduce locally. + +- Risk: Multiple workflows use divergent tag formats. + - Mitigation: define a single source of truth for PR tags and digest + propagation. + +- Risk: Buildx produces only remote tags, breaking local verification. + - Mitigation: add --load for PR builds or pull by digest before + verification. + +## 8. Confidence Score Confidence: 88 percent -Rationale: This is a documentation-only change with no runtime or CI impact, but it relies on consistent interpretation of file-scope criteria. +Rationale: The eslint peer dependency conflict is confirmed as the +frontend build failure. Secondary tag mismatch hypotheses remain +unconfirmed and are now conditional fallbacks only. diff --git a/docs/reports/qa_report.md b/docs/reports/qa_report.md index 11b72243..01d14a73 100644 --- a/docs/reports/qa_report.md +++ b/docs/reports/qa_report.md @@ -1,20 +1,30 @@ # QA & Security Report -**Date:** 2026-02-07 +**Date:** 2026-02-08 **Status:** 🔴 FAILED **Evaluator:** GitHub Copilot (QA Security Mode) ## Executive Summary -QA validation was **stopped** after frontend coverage tests failed. Remaining checks were not executed per stop-on-failure policy. +QA validation ran per Definition of Done. Failures are listed below with verbatim output. | Check | Status | Details | | :--- | :--- | :--- | -| **Frontend Coverage** | 🔴 FAIL | Test failures; see verbatim output below | -| **TypeScript Check** | ⚪ NOT RUN | Stopped after frontend coverage failure | -| **Pre-commit Hooks** | ⚪ NOT RUN | Stopped after frontend coverage failure | -| **Linting (Go/Frontend/Markdown/Hadolint)** | ⚪ NOT RUN | Stopped after frontend coverage failure | -| **Security Scans** | ⚪ SKIPPED | Skipped by request | +| **Docker: Rebuild E2E Environment** | 🟢 PASS | Completed | +| **Playwright E2E (All Browsers)** | 🔴 FAIL | Container not ready after 30000ms | +| **Backend Coverage** | 🟢 PASS | Skill reported success | +| **Frontend Coverage** | 🔴 FAIL | Test failures; see output | +| **TypeScript Check** | 🟢 PASS | `tsc --noEmit` completed | +| **Pre-commit Hooks** | 🟢 PASS | Hooks passed | +| **Lint: Frontend** | 🟢 PASS | `eslint . --report-unused-disable-directives` completed | +| **Lint: Go Vet** | 🟢 PASS | No errors reported | +| **Lint: Staticcheck (Fast)** | 🟢 PASS | `0 issues.` | +| **Lint: Markdownlint** | 🟢 PASS | No errors reported | +| **Lint: Hadolint Dockerfile** | 🔴 FAIL | DL3008, DL4006, SC2015 warnings | +| **Security: Trivy Scan (filesystem)** | 🟢 PASS | No issues found | +| **Security: Docker Image Scan (Local)** | 🔴 FAIL | 0 critical, 8 high vulnerabilities | +| **Security: CodeQL Go Scan (CI-Aligned)** | 🟢 PASS | Completed (output truncated) | +| **Security: CodeQL JS Scan (CI-Aligned)** | 🟢 PASS | Completed (output truncated) | --- @@ -139,187 +149,202 @@ Connecting to Cerberus logs WebSocket: wss://secure.example.com/api/v1/cerberus/ stdout | src/api/logs.test.ts > connectSecurityLogs > combines multiple filters in websocket url Connecting to Cerberus logs WebSocket: ws://localhost/api/v1/cerberus/logs/ws?source=waf&level=warn&ip=10.0.0&host=examp le.com&blocked_only=true +## 1. Validation Results - ✓ src/api/logs.test.ts (19 tests) 18ms - ✓ src/pages/__tests__/Security.spec.tsx (6 tests) 613ms - ❯ src/pages/__tests__/AccessLists.test.tsx (5 tests | 3 failed) 4121ms - ✓ renders empty state and opens create form 168ms - ✓ shows CGNAT warning and allows dismiss 74ms - × deletes access list with backup 1188ms - × bulk deletes selected access lists 1282ms - × tests IP against access list 1407ms - ✓ src/components/__tests__/ProxyHostForm-dns.test.tsx (15 tests) 14889ms - ✓ detects *.example.com as wildcard 1330ms - ✓ does not detect sub.example.com as wildcard 632ms - ✓ detects multiple wildcards in comma-separated list 1525ms - ✓ detects wildcard at start of comma-separated list 1276ms - ✓ shows DNS provider selector when wildcard domain entered 638ms - ✓ shows info alert explaining DNS-01 requirement 645ms - ✓ shows validation error on submit if wildcard without provider 1976ms - ✓ does not show DNS provider selector without wildcard 711ms - ✓ DNS provider selector is present for wildcard domains 542ms - ✓ clears DNS provider when switching to non-wildcard 1362ms - ✓ preserves form state during wildcard domain edits 1027ms - ✓ includes dns_provider_id null for non-wildcard domains 1506ms - ✓ prevents submission when wildcard present without DNS provider 1446ms - ✓ src/hooks/__tests__/usePlugins.test.tsx (15 tests) 842ms - ❯ src/components/__tests__/Layout.test.tsx (16 tests | 1 failed) 1129ms - ✓ renders the application logo 125ms - × renders all navigation items 302ms - ✓ renders children content 26ms - ✓ displays version information 50ms - ✓ calls logout when logout button is clicked 140ms - ✓ toggles sidebar on mobile 73ms - ✓ persists collapse state to localStorage 63ms - ✓ restores collapsed state from localStorage on load 25ms - ✓ displays Security nav item when Cerberus is enabled 25ms - ✓ hides Security nav item when Cerberus is disabled 49ms - ✓ displays Uptime nav item when Uptime is enabled 38ms - ✓ hides Uptime nav item when Uptime is disabled 46ms - ✓ shows Security and Uptime when both features are enabled 55ms - ✓ hides both Security and Uptime when both features are disabled 66ms - ✓ defaults to showing Security and Uptime when feature flags are loading 24ms - ✓ shows other nav items regardless of feature flags 19ms - ✓ src/components/ui/__tests__/DataTable.test.tsx (19 tests) 450ms - ✓ src/pages/__tests__/SMTPSettings.test.tsx (10 tests) 2655ms - ✓ saves SMTP settings successfully 724ms - ✓ sends test email 312ms - ✓ surfaces backend validation errors on save 375ms - ✓ disables test connection until required fields are set and shows error toast on failure 487ms - ✓ handles test email failures and keeps input value intact 375ms - ✓ src/components/__tests__/SecurityNotificationSettingsModal.test.tsx (13 tests) 1103ms - ✓ submits updated settings 372ms - ✓ src/hooks/__tests__/useCredentials.test.tsx (16 tests) 242ms - ✓ src/pages/__tests__/Uptime.test.tsx (9 tests) 587ms - ✓ src/hooks/__tests__/useRemoteServers.test.tsx (10 tests) 774ms - ✓ src/api/auditLogs.test.ts (14 tests) 13ms - ✓ src/api/__tests__/security.test.ts (16 tests) 13ms - ✓ src/pages/__tests__/Login.overlay.audit.test.tsx (7 tests) 3011ms - ✓ shows coin-themed overlay during login 650ms - ✓ ATTACK: rapid fire login attempts are blocked by overlay 499ms - ✓ ATTACK: XSS in login credentials does not break overlay 788ms - ✓ ATTACK: network timeout does not leave overlay stuck 323ms - ✓ src/hooks/__tests__/useNotifications.test.tsx (9 tests) 541ms - ✓ src/pages/__tests__/CrowdSecConfig.test.tsx (7 tests) 1928ms - ✓ allows reading and saving config files 582ms - ✓ allows banning an IP 581ms - ✓ src/pages/__tests__/EncryptionManagement.test.tsx (14 tests) 1237ms - ✓ src/components/__tests__/WebSocketStatusCard.test.tsx (8 tests) 432ms - ✓ src/components/__tests__/CSPBuilder.test.tsx (13 tests) 788ms - ✓ src/components/__tests__/DNSProviderForm.test.tsx (7 tests) 2406ms - ✓ handles form submission for creation 743ms - ✓ tests connection 553ms - ✓ handles test connection failure 402ms - ✓ src/hooks/__tests__/useManualChallenge.test.tsx (11 tests) 236ms - ✓ src/components/__tests__/ImportReviewTable.test.tsx (9 tests) 463ms - ✓ src/pages/__tests__/RateLimiting.spec.tsx (9 tests) 389ms - ✓ src/components/ui/Tabs.test.tsx (10 tests) 406ms - ✓ src/components/import/__tests__/FileUploadSection.test.tsx (9 tests) 651ms - ✓ rejects files over 5MB limit 415ms - ✓ src/components/__tests__/CertificateList.test.tsx (6 tests) 365ms - ✓ src/hooks/__tests__/useProxyHosts.test.tsx (8 tests) 492ms - ✓ src/components/__tests__/DNSDetectionResult.test.tsx (10 tests) 210ms - ✓ src/api/__tests__/users.test.ts (10 tests) 14ms - ✓ src/api/__tests__/manualChallenge.test.ts (14 tests) 13ms -stdout | src/api/__tests__/logs-websocket.test.ts > logs API - connectLiveLogs > creates WebSocket connection with corre -ct URL -Connecting to WebSocket: ws://localhost:8080/api/v1/logs/live? +### Playwright E2E - FAILED -stdout | src/api/__tests__/logs-websocket.test.ts > logs API - connectLiveLogs > uses wss protocol when page is https -Connecting to WebSocket: wss://example.com/api/v1/logs/live? - -stdout | src/api/__tests__/logs-websocket.test.ts > logs API - connectLiveLogs > includes filters in query parameters -Connecting to WebSocket: ws://localhost:8080/api/v1/logs/live?level=error&source=waf - -stdout | src/api/__tests__/logs-websocket.test.ts > logs API - connectLiveLogs > calls onMessage callback when message i -s received -Connecting to WebSocket: ws://localhost:8080/api/v1/logs/live? - -stdout | src/api/__tests__/logs-websocket.test.ts > logs API - connectLiveLogs > handles JSON parse errors gracefully -Connecting to WebSocket: ws://localhost:8080/api/v1/logs/live? - -stdout | src/api/__tests__/logs-websocket.test.ts > logs API - connectLiveLogs > returns a close function that closes th -e WebSocket -Connecting to WebSocket: ws://localhost:8080/api/v1/logs/live? - -stdout | src/api/__tests__/logs-websocket.test.ts > logs API - connectLiveLogs > does not throw when closing already clo -sed connection -Connecting to WebSocket: ws://localhost:8080/api/v1/logs/live? - -stdout | src/api/__tests__/logs-websocket.test.ts > logs API - connectLiveLogs > handles missing optional callbacks -Connecting to WebSocket: ws://localhost:8080/api/v1/logs/live? -Connecting to WebSocket: ws://localhost:8080/api/v1/logs/live? - -stderr | src/api/__tests__/logs-websocket.test.ts > logs API - connectLiveLogs > handles missing optional callbacks -WebSocket error: Event { isTrusted: [Getter] } - -stdout | src/api/__tests__/logs-websocket.test.ts > logs API - connectLiveLogs > processes multiple messages in sequence -Connecting to WebSocket: ws://localhost:8080/api/v1/logs/live? - -stdout | src/api/__tests__/logs-websocket.test.ts -WebSocket connection closed { code: 1000, reason: '', wasClean: true } - - ✓ src/api/__tests__/logs-websocket.test.ts (11 tests | 2 skipped) 30ms - ✓ src/hooks/__tests__/useDNSDetection.test.tsx (10 tests) 680ms - ✓ src/components/__tests__/CrowdSecBouncerKeyDisplay.test.tsx (13 tests | 4 skipped) 198ms - ✓ src/pages/__tests__/ProxyHosts-coverage-isolated.test.tsx (3 tests) 1504ms - ✓ renders SSL staging badge, websocket badge 634ms - ✓ bulk apply merges host data and calls updateHost 628ms - ✓ src/components/__tests__/ImportReviewTable-warnings.test.tsx (7 tests) 337ms - ✓ src/api/__tests__/settings.test.ts (16 tests) 11ms - ✓ src/pages/__tests__/AcceptInvite.test.tsx (8 tests) 1368ms - ✓ shows password mismatch error 315ms - ✓ submits form and shows success 522ms - ✓ shows error on submit failure 336ms - ✓ src/components/__tests__/RemoteServerForm.test.tsx (9 tests) 726ms - ✓ src/components/ui/__tests__/Skeleton.test.tsx (18 tests) 233ms - ✓ src/components/__tests__/CrowdSecKeyWarning.test.tsx (8 tests) 380ms - ✓ src/pages/__tests__/ProxyHosts-progress.test.tsx (2 tests) 902ms - ✓ shows progress when applying multiple ACLs 819ms - ✓ src/api/notifications.test.ts (5 tests) 10ms - ✓ src/pages/__tests__/ImportCaddy-multifile-modal.test.tsx (9 tests) 359ms - ✓ src/pages/__tests__/ProxyHosts-bulk-apply.test.tsx (3 tests) 1241ms - ✓ shows Bulk Apply button when hosts selected and opens modal 497ms - ✓ applies selected settings to all selected hosts by calling updateProxyHost merged payload 429ms - ✓ cancels bulk apply modal when Cancel clicked 313ms - ✓ src/components/ui/__tests__/Alert.test.tsx (18 tests) 210ms - ✓ src/data/__tests__/securityPresets.test.ts (24 tests) 11ms - ✓ src/pages/__tests__/ImportCaddy-warnings.test.tsx (6 tests) 82ms - ✓ src/hooks/__tests__/useAccessLists.test.tsx (6 tests) 361ms - ✓ src/components/__tests__/PermissionsPolicyBuilder.test.tsx (8 tests) 723ms - ✓ src/components/ui/__tests__/StatsCard.test.tsx (14 tests) 245ms - - - ❯ src/components/__tests__/NotificationCenter.test.tsx 2/6 - ❯ src/components/ui/__tests__/Input.test.tsx 10/16 - - Test Files 4 failed | 83 passed | 5 skipped (153) - Tests 39 failed | 1397 passed | 90 skipped (1536) - Start at 04:46:11 - Duration 109.78s +**Failure Output (verbatim):** ``` - ❯ src/pages/__tests__/ImportCrowdSec.spec.tsx 1/1 +> e2e:all +> PLAYWRIGHT_HTML_OPEN=never npx playwright test - Test Files 8 failed | 129 passed | 5 skipped (153) - Tests 44 failed | 1669 passed | 90 skipped (1803) - Start at 04:32:30 - Duration 119.07s +[dotenv@17.2.4] injecting env (2) from .env -- tip: ⚙️ override existing env vars with { override: true } + +🧹 Running global test setup... + +🔐 Validating emergency token configuration... + 🔑 Token present: f51dedd6...346b + ✓ Token length: 64 chars (valid) + ✓ Token format: Valid hexadecimal + ✓ Token appears to be unique (not a placeholder) +✅ Emergency token validation passed + +📍 Base URL: http://127.0.0.1:8080 +⏳ Waiting for container to be ready at http://127.0.0.1:8080... + ⏳ Waiting for container... (1/15) + ⏳ Waiting for container... (2/15) + ⏳ Waiting for container... (3/15) + ⏳ Waiting for container... (4/15) + ⏳ Waiting for container... (5/15) + ⏳ Waiting for container... (6/15) + ⏳ Waiting for container... (7/15) + ⏳ Waiting for container... (8/15) + ⏳ Waiting for container... (9/15) + ⏳ Waiting for container... (10/15) + ⏳ Waiting for container... (11/15) + ⏳ Waiting for container... (12/15) + ⏳ Waiting for container... (13/15) + ⏳ Waiting for container... (14/15) + ⏳ Waiting for container... (15/15) +Error: Container failed to start after 30000ms + + at global-setup.ts:158 + + 156 | } + 157 | } +> 158 | throw new Error(`Container failed to start after ${maxRetries * delayMs}ms`); + | ^ + 159 | } + 160 | + 161 | /** + at waitForContainer (/projects/Charon/tests/global-setup.ts:158:9) + at globalSetup (/projects/Charon/tests/global-setup.ts:203:3) + + +To open last HTML report run: + + npx playwright show-report ``` ---- +### Frontend Coverage - FAILED -## 3. Completed Checks +**Failure Output (verbatim):** +``` +Terminal: Test: Frontend with Coverage (Charon) +Output: -No other checks were executed. ---- +[... PREVIOUS OUTPUT TRUNCATED ...] -## 4. Deferred Checks (Not Run) +An update to SelectItemText inside a test was not wrapped in act(...). -The following checks were **not executed** due to the frontend coverage failure: -- TypeScript type check -- Pre-commit hooks -- Linting (Go vet, staticcheck, frontend lint, markdownlint, hadolint) +When testing, code that causes React state updates should be wrapped into act(...): + +act(() => { + /* fire events that update state */ +}); +/* assert on the output */ + +This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/w +rap-tests-with-act +An update to SelectItem inside a test was not wrapped in act(...). + +When testing, code that causes React state updates should be wrapped into act(...): + +act(() => { + /* fire events that update state */ +}); +/* assert on the output */ + +This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/w +rap-tests-with-act + + ✓ src/pages/__tests__/AuditLogs.test.tsx (14 tests) 2443ms + ✓ toggles filter panel 307ms + ✓ closes detail modal 346ms + + ❯ src/components/__tests__/ProxyHostForm-dns.test.tsx 9/15 + ❯ src/pages/__tests__/AccessLists.test.tsx 1/5 + ❯ src/pages/__tests__/AuditLogs.test.tsx 14/14 + + Test Files 1 failed | 33 passed | 5 skipped (153) + Tests 1 failed | 862 passed | 84 skipped (957) + Start at 01:04:39 + Duration 105.97s +``` + +### Lint: Hadolint Dockerfile - FAILED + +**Failure Output (verbatim):** +``` +this check +-:335 DL3008 warning: Pin versions in apt get install. Instead of `apt-get install ` use `apt-get install =` +-:354 DL4006 warning: Set the SHELL option -o pipefail before RUN with a pipe in it. If you are using /bin/sh in an alpine image or if your shell is symlinked to busybox then consider explicitly setting your SHELL to /bin/ash, or disable this check +-:354 SC2015 info: Note that A && B || C is not if-then-else. C may run when A is true. + * The terminal process "/bin/bash '-c', 'docker run --rm -i hadolint/hadolint < Dockerfile'" terminated with exit code: 1. +``` + +### Security: Docker Image Scan (Local) - FAILED + +**Failure Output (verbatim):** +``` +[SUCCESS] Vulnerability scan complete +[ANALYSIS] Analyzing vulnerability scan results + +[INFO] Vulnerability Summary: + 🔴 Critical: 0 + 🟠 High: 8 + 🟡 Medium: 20 + 🟢 Low: 2 + ⚪ Negligible: 380 + 📊 Total: 410 + +[WARNING] High Severity Vulnerabilities Found: + + - CVE-2025-13151 in libtasn1-6 + Package: libtasn1-6@4.20.0-2 + Fixed: No fix available + CVSS: 7.5 + Description: Stack-based buffer overflow in libtasn1 version: v4.20.0. The function fails to validate the size of.. +. + + - CVE-2025-15281 in libc-bin + Package: libc-bin@2.41-12+deb13u1 + Fixed: No fix available + CVSS: 7.5 + Description: Calling wordexp with WRDE_REUSE in conjunction with WRDE_APPEND in the GNU C Library version 2.0 to .. +. + + - CVE-2025-15281 in libc6 + Package: libc6@2.41-12+deb13u1 + Fixed: No fix available + CVSS: 7.5 + Description: Calling wordexp with WRDE_REUSE in conjunction with WRDE_APPEND in the GNU C Library version 2.0 to .. +. + + - CVE-2026-0915 in libc-bin + Package: libc-bin@2.41-12+deb13u1 + Fixed: No fix available + CVSS: 7.5 + Description: Calling getnetbyaddr or getnetbyaddr_r with a configured nsswitch.conf that specifies the library's .. +. + + - CVE-2026-0915 in libc6 + Package: libc6@2.41-12+deb13u1 + Fixed: No fix available + CVSS: 7.5 + Description: Calling getnetbyaddr or getnetbyaddr_r with a configured nsswitch.conf that specifies the library's .. +. + + - CVE-2026-0861 in libc-bin + Package: libc-bin@2.41-12+deb13u1 + Fixed: No fix available + CVSS: 8.4 + Description: Passing too large an alignment to the memalign suite of functions (memalign, posix_memalign, aligned.. +. + + - CVE-2026-0861 in libc6 + Package: libc6@2.41-12+deb13u1 + Fixed: No fix available + CVSS: 8.4 + Description: Passing too large an alignment to the memalign suite of functions (memalign, posix_memalign, aligned.. +. + + - GHSA-69x3-g4r3-p962 in github.com/slackhq/nebula + Package: github.com/slackhq/nebula@v1.9.7 + Fixed: 1.10.3 + CVSS: 7.6 + Description: Blocklist Bypass possible via ECDSA Signature Malleability... + +[ERROR] Found 0 Critical and 8 High severity vulnerabilities +[ERROR] These issues must be resolved before deployment +[ERROR] Review grype-results.json for detailed remediation guidance +[ERROR] Skill execution failed: security-scan-docker-image +``` + +## 2. Notes + +- Some tool outputs were truncated by the runner; the report includes the exact emitted text where available. --- diff --git a/frontend/package.json b/frontend/package.json index c7c7827d..0392ef34 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -66,7 +66,7 @@ "@vitest/coverage-v8": "^4.0.18", "@vitest/ui": "^4.0.18", "autoprefixer": "^10.4.24", - "eslint": "^10.0.0", + "eslint": "^9.39.2", "eslint-plugin-react-hooks": "^7.0.1", "eslint-plugin-react-refresh": "^0.5.0", "jsdom": "28.0.0",