# BAT-006 Design ## Architecture Summary BAT-006 introduces a CI safety layer around existing test and smoke assets. GitHub Actions becomes the external gate for PR/push validation, while CI wrapper scripts provide deterministic entrypoints for environment setup, synthetic fixture DB creation, Streamlit readiness checks, DB safety smoke invocation, timeout handling, cleanup, and sensitive-output control. The required CI gates are pytest, Streamlit AppTest, dashboard HTTP smoke, and DB safety smoke. Browser screenshot E2E remains a local evidence workflow from dcy-004 and is intentionally excluded from the required CI blocker set. ## Changed Areas - `.github/workflows/` - New workflow for `pull_request`, `push` to `main`, and `workflow_dispatch`. - Required jobs should have stable names so branch protection can reference them later. - `scripts/` - New or adapted CI wrapper entrypoint for dashboard HTTP smoke. - New or adapted CI wrapper entrypoint for DB safety smoke using existing `ledger_restore_smoke.py` logic where appropriate. - Wrapper logs must avoid dumping raw transactions, account numbers, `raw_payload`, source file names, passwords, or live DB paths. - `tests/` - Existing pytest and Streamlit AppTest assets are reused. Add fixture helpers only if needed to make CI deterministic. - `pyproject.toml` / dependency setup - Confirm CI installs the extras required for pytest and dashboard/AppTest execution. - Docs - `docs/project-structure.md`: CI workflow and wrapper responsibilities. - `docs/runtime-flows.md`: PR/push -> CI jobs -> gate result flow and synthetic fixture DB boundary. - `docs/runbooks/`: CI failure reproduction runbook if the workflow/wrapper commands need operator guidance. ## Key Decisions 1. CI platform is GitHub Actions, with `pull_request`, `push` to `main`, and optional `workflow_dispatch`. 2. Required blocker gates are pytest, Streamlit AppTest, dashboard HTTP smoke, and DB safety smoke. 3. HTTP smoke and DB safety smoke use CI-specific thin wrappers rather than ad-hoc shell snippets, so exit codes, logs, readiness, timeout, and cleanup are deterministic. 4. Every CI run creates or uses synthetic fixture/temporary validation DBs. The operating DB default path is not used. 5. Browser screenshot E2E is not a required CI gate. It remains a local/manual evidence path for UI-heavy changes. 6. Branch protection enforcement is external GitHub repository configuration; the batch stabilizes workflow/check names and documents the required-check expectation. ## CI Job Boundary - `pytest` gate: - Install project with test dependencies. - Run the repository pytest suite using the standard project command. - Fail the workflow on any test failure. - `dashboard-app-test` gate: - Prepare synthetic fixture DB. - Run Streamlit AppTest coverage, especially `tests/test_dashboard_app.py`. - Fail with test-level logs only. - `dashboard-http-smoke` gate: - Prepare synthetic fixture DB in runner temp space. - Start Streamlit dashboard with that DB and deterministic port policy. - Poll HTTP readiness until 200 or timeout. - Terminate the server and fail if cleanup fails materially. - `db-safety-smoke` gate: - Prepare source/backup/target paths under runner temp space. - Invoke DB restore/safety smoke without live DB paths. - Fail if overwrite approval policy, integrity check, or fixture health check fails. ## Sensitive Evidence Boundary CI output may include command names, job names, synthetic DB temp paths, test identifiers, exit status, row counts for synthetic fixtures, and high-level error messages. CI output must not include live account numbers, real balances, `raw_payload`, original financial file names, passwords, or full transaction row dumps. ## Reference Doc Update Plan - Update `docs/project-structure.md` to replace the current "CI workflow ... not yet defined" baseline with the BAT-006 workflow and wrapper structure. - Update `docs/runtime-flows.md` with the CI validation flow and the local browser evidence boundary. - Add a `docs/runbooks/ci-smoke.md` or equivalent only if local reproduction commands are not already obvious from the workflow/wrappers.