diff --git a/.env.example b/.env.example index 57023d6..abb9ede 100644 --- a/.env.example +++ b/.env.example @@ -30,8 +30,6 @@ POST_LOGIN_REDIRECT_PATH=/dashboard CORS_ALLOWED_ORIGINS=http://localhost:3000,http://localhost:8000 LOG_LEVEL=INFO -WORKER_ID=local-worker-1 -QUEUE_NAME=default # Connected Accounts Module # GitHub provider integration uses GitHub App installation flow. @@ -40,6 +38,7 @@ GITHUB_APP_NAME=YGIT GITHUB_APP_SLUG= GITHUB_APP_ID= GITHUB_APP_PRIVATE_KEY= +GITHUB_APP_WEBHOOK_ENABLED=false GITHUB_APP_WEBHOOK_SECRET= GITHUB_APP_INSTALL_URL=https://github.com/apps/ygit/installations/new GITHUB_API_BASE_URL=https://api.github.com @@ -56,5 +55,6 @@ CLOUDFLARE_API_BASE_URL=https://api.cloudflare.com/client/v4 # Worker Runtime WORKER_ID=local-worker-1 QUEUE_NAME=default +WORKER_PROVIDER_EXECUTION_MODE=disabled WORKER_POLL_INTERVAL_SECONDS=5 WORKER_MAX_ATTEMPTS=3 diff --git a/.github/workflows/backend-ci.yml b/.github/workflows/backend-ci.yml new file mode 100644 index 0000000..e30a9fe --- /dev/null +++ b/.github/workflows/backend-ci.yml @@ -0,0 +1,164 @@ +name: Backend CI + +on: + pull_request: + branches: + - main + push: + branches: + - main + +permissions: + contents: read + +concurrency: + group: backend-ci-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +env: + PYTHONUTF8: "1" + PYTHONDONTWRITEBYTECODE: "1" + PYTHONUNBUFFERED: "1" + APP_ENV: test + GITHUB_APP_WEBHOOK_ENABLED: "false" + WORKER_PROVIDER_EXECUTION_MODE: disabled + +jobs: + validate: + name: Validate + runs-on: ubuntu-latest + timeout-minutes: 20 + + steps: + - name: Check out repository + uses: actions/checkout@v4 + with: + persist-credentials: false + fetch-depth: 0 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.12" + cache: pip + cache-dependency-path: pyproject.toml + + - name: Upgrade pip + run: python -m pip install --upgrade pip + + - name: Install project dependencies + run: python -m pip install -e ".[dev]" + + - name: Compile Python sources + run: python -m compileall -q backend scripts + + - name: Verify MyPy deferral + run: | + python - <<'PY' + from pathlib import Path + + workflow_text = Path(".github/workflows/backend-ci.yml").read_text( + encoding="utf-8" + ) + forbidden_command = "python -m " + "mypy backend" + if forbidden_command in workflow_text: + raise SystemExit("Full-backend MyPy must remain deferred.") + + print("MYPY_REQUIRED_GATE: DEFERRED") + PY + + - name: Run baseline-aware Ruff + shell: bash + env: + EVENT_NAME: ${{ github.event_name }} + PR_BASE_SHA: ${{ github.event.pull_request.base.sha }} + PUSH_BEFORE_SHA: ${{ github.event.before }} + run: | + set -euo pipefail + + if [[ "$EVENT_NAME" == "pull_request" ]]; then + base_sha="$PR_BASE_SHA" + else + base_sha="$PUSH_BEFORE_SHA" + fi + + head_sha="$GITHUB_SHA" + + if [[ -z "$base_sha" || "$base_sha" =~ ^0+$ ]]; then + base_sha="$(git rev-parse HEAD^)" + fi + + git cat-file -e "${base_sha}^{commit}" + git cat-file -e "${head_sha}^{commit}" + + changed_file_list="$(mktemp)" + trap 'rm -f "$changed_file_list"' EXIT + + git diff \ + --name-only \ + -z \ + --find-renames \ + --diff-filter=ACMR \ + "$base_sha" \ + "$head_sha" \ + -- \ + backend \ + scripts | + sort -zu > "$changed_file_list" + + all_changed_files=() + mapfile -d '' -t all_changed_files < "$changed_file_list" + + changed_files=() + for file in "${all_changed_files[@]}"; do + case "$file" in + *.py) + changed_files+=("$file") + ;; + esac + done + + general_files=() + config_changed=false + release_gate_changed=false + + for file in "${changed_files[@]}"; do + case "$file" in + backend/core/config.py) + config_changed=true + ;; + scripts/release_gate.py) + release_gate_changed=true + ;; + *) + general_files+=("$file") + ;; + esac + done + + if (( ${#general_files[@]} > 0 )); then + python -m ruff check "${general_files[@]}" + fi + + if [[ "$config_changed" == "true" ]]; then + python -m ruff check --ignore S105 backend/core/config.py + fi + + if [[ "$release_gate_changed" == "true" ]]; then + python -m ruff check \ + --ignore E501,I001,UP035 \ + scripts/release_gate.py + fi + + if (( ${#changed_files[@]} == 0 )); then + echo "No eligible changed Python files." + fi + + - name: Run full test suite + run: python -m pytest -q + + - name: Run smoke test + run: python scripts/smoke_test.py --skip-db + + - name: Run release gate + run: python scripts/release_gate.py --skip-db diff --git a/AUDIT_REPORT.md b/AUDIT_REPORT.md index 00609ec..627a5b0 100644 --- a/AUDIT_REPORT.md +++ b/AUDIT_REPORT.md @@ -1,8 +1,8 @@ # YGIT Current Engineering Audit Report -Version: 1.6 +Version: 1.8 Status: Verified Foundation / Pre-Live Integration -Updated: 2026-07-21 +Updated: 2026-07-24 ## Audit Scope @@ -22,6 +22,9 @@ This report covers the current YGIT MVP source through: - GitHub App architecture lock and fail-closed rejection of legacy GitHub OAuth environment variables. - Default-disabled GitHub App webhook capability with conditional secret readiness validation. - AG-001 Deploy Provider Gate standalone foundation. +- AG-002 Repository Provider Gate standalone foundation with GitHub default and no runtime wiring. +- Immutable running baseline lock at `b9019b79d1af3fe73d1a74769792ebb6958c4f4c`. +- Backend CI documentation contract, implementation workflow, read-only security boundary, and successful Draft PR validation. - Connected Accounts metadata and repository-reuse UI. ## Verified Results @@ -29,6 +32,7 @@ This report covers the current YGIT MVP source through: | Check | Result | |---|---:| | Expected source base and remote alignment | PASS | +| Running baseline lock | PASS — `b9019b79d1af3fe73d1a74769792ebb6958c4f4c` | | Worker architecture regression | PASS | | Credential acquisition boundary tests | PASS | | Cloudflare provider gateway tests | PASS | @@ -40,11 +44,12 @@ This report covers the current YGIT MVP source through: | Worker Runtime architecture tests | 4 passed | | Deploy/redeploy architecture tests | 2 passed | | AG-001 regression | 15 passed | +| AG-002 regression | 9 passed | | Deployment History runtime tests | 8 passed | | Deployment History idempotency tests | 4 passed | | Live-readiness tooling tests | 18 passed | | Runtime image packaging tests | 4 passed | -| Full test suite | 514 passed | +| Full test suite | 579 passed, 1 warning | | Smoke test with database skipped | PASS | | Release gate with database skipped | PASS | | Basic secret scan | PASS | @@ -53,6 +58,7 @@ This report covers the current YGIT MVP source through: | Deploy/redeploy provider binding | WIRED, DEFAULT DISABLED | | Trusted provider execution policy | RUNTIME WIRED, DEFAULT DISABLED | | AG-001 runtime integration | NOT WIRED | +| AG-002 runtime integration | NOT WIRED; GITHUB DEFAULT UNCHANGED | | YGIT App Engine | NOT CREATED | | Deployment History runtime persistence | WIRED, NOT LIVE-VERIFIED | | Retry-safe history intent replay | IMPLEMENTED | @@ -62,6 +68,15 @@ This report covers the current YGIT MVP source through: | GitHub OAuth client credentials | FORBIDDEN | | GitHub App webhook capability | DEFAULT DISABLED | | GitHub App webhook secret | CONDITIONAL WHEN ENABLED | +| Backend CI workflow | IMPLEMENTED — `.github/workflows/backend-ci.yml` | +| Backend CI required status | `Backend CI / Validate` | +| Backend CI pull-request run | PASS — `30061513976` | +| Backend CI Validate job | PASS — `89383928195` | +| Backend CI permissions | CONTENTS READ ONLY | +| Backend CI provider execution | DISABLED | +| Backend CI production secrets | NOT USED | +| Backend CI post-merge push verification | PENDING | +| Backend CI branch protection | NOT ENABLED / NOT AUTHORIZED | | Runtime readiness artifacts in image | PACKAGED, REDEPLOY PENDING | | Coolify redeploy | NOT EXECUTED | | Live provider execution | NOT EXECUTED | @@ -79,6 +94,7 @@ One non-blocking `StarletteDeprecationWarning` remains in the existing test-clie - Deploy/redeploy handlers validate the policy and pass only the resulting boolean to the neutral binding. - The default `disabled` policy preserves the non-provider path; explicit `cloudflare` remains unverified against live credentials and APIs. - AG-001 is a pure Deploy Engine decision contract and does not import providers, pipelines, workers, settings, or database infrastructure. +- AG-002 is a pure Repository Engine decision contract; the current Repository Engine service does not import it, and existing GitHub parsing, metadata, persistence, and analysis-input behavior remain unchanged. - Provider credentials remain secret-wrapped during gateway construction. - The global/default Deploy Pipeline remains the contract-skeleton path. - Provider-enabled context is created only inside the trusted runtime binding function. @@ -86,6 +102,8 @@ One non-blocking `StarletteDeprecationWarning` remains in the existing test-clie - Deployment History Engine remains the persistence owner and now consumes pipeline history intents through its public boundary. - Deterministic intent keys prevent duplicate log writes during sequential retries. - Completed history records short-circuit duplicate deploy/redeploy execution. +- Backend CI runs with `contents: read`, checkout credentials are not persisted, provider execution remains disabled, and no production secret or deployment action is present. +- Pull-request run `30061513976` completed successfully at workflow commit `7f383ba6b0c17b92de9a27e0abe4cbeb8adbbac2`; post-merge push validation remains pending. ## Documentation Findings @@ -100,6 +118,8 @@ Before this update: This update separates the historical release baseline from the current engineering snapshot. +This closure update also records the implemented Backend CI workflow and its successful Draft PR validation. It does not claim post-merge validation, branch-protection enforcement, Phase 0 completion, or production readiness. + ## Not Executed ```text @@ -111,8 +131,11 @@ Live Cloudflare Pages project/deployment execution Production HTTPS authenticated user flow Production admin operations flow Deployment history persistence from a real provider result +Backend CI push-triggered validation on merged main +Branch-protection enforcement using Backend CI / Validate ``` + No production-readiness claim is made for these areas. ## Remaining Risk @@ -122,12 +145,15 @@ Primary remaining risks are integration risks rather than missing core provider - Controlled activation and validation of the explicit `cloudflare` policy in the live environment. - Live PostgreSQL transaction behavior and provider-result persistence evidence. - Reviewed future AG-001 runtime integration without changing the current Cloudflare default. +- Reviewed future AG-002 runtime integration without changing the current GitHub default. - Transaction boundaries between worker state and deployment history. - Provider timeout and retry behavior. - Idempotency and duplicate deployment prevention. - Partial asset-upload recovery. - External account and permission misconfiguration. - Production observability. +- Successful `push`-triggered Backend CI verification after an approved merge. +- Separately approved branch-protection enforcement using the stable CI check. ## Verification Commands diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b0e0f8..15e917e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,66 @@ All notable YGIT MVP implementation releases and active engineering foundations are tracked here. +## Unreleased — Phase 0 Backend CI Documentation and Status Closure — 2026-07-24 + +### Added + +- Backend CI workflow status and evidence across the authoritative current-state documents. +- Machine-readable Backend CI quality-gate and contract records. +- Successful Draft PR workflow evidence for `Backend CI / Validate`. + +### Changed + +- Transitioned Backend CI specification, implementation, and testing documents from draft/pre-implementation language to implemented and PR-verified states. +- Updated the Phase 0 critical path to require documentation closure, PR metadata reconciliation, explicit Ready/merge approval, and post-merge `main` validation before Phase 0 completion. + +### Verified + +- Workflow: `Backend CI`. +- Job: `Validate`. +- Stable status: `Backend CI / Validate`. +- Workflow implementation commit: `7f383ba6b0c17b92de9a27e0abe4cbeb8adbbac2`. +- Pull-request run `30061513976`: SUCCESS. +- Job `89383928195`: SUCCESS. +- Full suite: 579 passed. +- Smoke test with database skipped: PASS. +- Release gate with database skipped: PASS. + +### Boundaries + +- Provider execution remains disabled. +- No production secret, database service, Redis service, provider API, deployment action, or Coolify action is used by Backend CI. +- Post-merge push validation, branch protection, Ready transition, merge, deployment, and Phase 0 completion remain pending separate approval. + +## Unreleased — Phase 0 Baseline Reconciliation and AG-002 — 2026-07-23 + +### Added + +- Immutable running baseline lock at commit `b9019b79d1af3fe73d1a74769792ebb6958c4f4c`. +- AG-002 Repository Provider Gate as a standalone Repository Engine decision contract. +- AG-002 architecture documentation and regression coverage. +- Explicit `.env.example` entries for the default-disabled GitHub webhook and worker provider-execution mode. + +### Changed + +- Reconciled `README.md`, `PROJECT_STATUS.md`, `VERSION.json`, `CONTRACT_MANIFEST.json`, and `AUDIT_REPORT.md` with the current authoritative engineering state. +- Removed duplicate Worker Runtime identity/queue entries from `.env.example`. +- Aligned the immediate critical path around real GitHub App repository acquisition, real analysis evidence, and one controlled Cloudflare deployment. + +### Verified + +- AG-002 regression: 9 passed. +- Full suite: 579 passed, 1 warning. +- Smoke test with database skipped: PASS. +- Release gate with database skipped: PASS. + +### Runtime Boundary + +- GitHub remains the Repository Engine default. +- AG-002 is not imported by the current Repository Engine service. +- No provider adapter, API route, database model, migration, worker behavior, deployment behavior, or production configuration is changed. +- No Coolify redeploy is required for this isolated foundation and documentation reconciliation patch. + ## Unreleased — Provider Orchestration and Runtime Binding Foundations — 2026-07-21 ### Added diff --git a/CONTRACT_MANIFEST.json b/CONTRACT_MANIFEST.json index cb25e8d..c91bc2d 100644 --- a/CONTRACT_MANIFEST.json +++ b/CONTRACT_MANIFEST.json @@ -77,7 +77,10 @@ "provider_execution_policy_source": "server_settings_only", "provider_execution_policy_payload_control": "forbidden", "github_repository_integration": "github_app_only", - "github_oauth_client_credentials": "forbidden" + "github_oauth_client_credentials": "forbidden", + "repository_provider_default": "github", + "repository_provider_gate_runtime_wiring": "forbidden_until_separate_future_approval", + "repository_provider_gate_current_logic_change": "forbidden" }, "company": "Vib Tools", "connected_accounts_module_version": "0.1.0", @@ -130,11 +133,12 @@ "live_postgresql_verified": false }, "development_snapshot": { - "date": "2026-07-21", + "date": "2026-07-24", "status": "ready_for_controlled_live_redeploy", "mvp_completion_estimate": "approximately_97_percent", - "latest_full_suite": "514_passed_1_warning", - "release_gate_skip_db": "pass" + "latest_full_suite": "579_passed_1_warning", + "release_gate_skip_db": "pass", + "backend_ci_status": "implemented_pr_verified_post_merge_pending" }, "engine_contract": "1.0", "engine_contract_version": "1.0", @@ -150,7 +154,7 @@ "platform_engine", "notification_engine" ], - "implementation": "FastAPI modular monolith with MVP engines, worker runtime, dashboard/admin surfaces, provider primitives, concrete Cloudflare orchestration, trusted provider-policy runtime handoff, default-disabled execution, and AG-001 gate foundation", + "implementation": "FastAPI modular monolith with MVP engines, worker runtime, dashboard/admin surfaces, provider primitives, concrete Cloudflare orchestration, trusted provider-policy runtime handoff, default-disabled execution, AG-001 gate foundation, and AG-002 repository provider gate foundation, and Backend CI verification", "implementation_version": "0.1.0-pre-live-provider-integration", "implemented_components": [ "worker_runtime_integration", @@ -167,7 +171,9 @@ "deployment_history_runtime_persistence", "controlled_live_readiness_tooling", "runtime_image_live_readiness_packaging", - "github_app_architecture_lock" + "github_app_architecture_lock", + "ag_002_repository_provider_gate_foundation", + "backend_ci_workflow" ], "implemented_engines": [ "audit_engine", @@ -245,7 +251,11 @@ "smoke_script": "scripts/smoke_test.py", "version_registry": "VERSION.json", "live_runtime_smoke_test_plan": "LIVE_RUNTIME_SMOKE_TEST_PLAN_v0.1.0.md", - "live_runtime_smoke_script": "scripts/live_runtime_smoke_test.py" + "live_runtime_smoke_script": "scripts/live_runtime_smoke_test.py", + "backend_ci_workflow": ".github/workflows/backend-ci.yml", + "backend_ci_specification": "docs/ci/BACKEND_CI_SPECIFICATION.md", + "backend_ci_implementation_plan": "docs/ci/BACKEND_CI_IMPLEMENTATION_PLAN.md", + "backend_ci_testing_and_rollback": "docs/ci/BACKEND_CI_TESTING_AND_ROLLBACK_SPECIFICATION.md" }, "release_gate": { "new_migration": null, @@ -386,5 +396,59 @@ "github_app_active_checkbox": false, "live_verified": false } + }, + "repository_engine_extension_gates": { + "AG-002": { + "name": "Repository Provider Gate", + "audit_name": "AG-002 Repository Provider Gate", + "status": "foundation_ready_not_runtime_wired", + "default_provider": "github", + "missing_provider_resolution": "github", + "explicit_provider_resolution": "selected_provider", + "current_flow_changed": false, + "current_service_imports_gate": false, + "provider_access": false, + "database_access": false, + "api_routes_added": false, + "migration_added": false, + "future_runtime_wiring_requires_separate_approval": true + } + }, + "backend_ci": { + "contract_version": "0.1.0", + "status": "implemented_pr_verified_post_merge_pending", + "workflow_path": ".github/workflows/backend-ci.yml", + "workflow_name": "Backend CI", + "job_id": "validate", + "job_name": "Validate", + "required_status": "Backend CI / Validate", + "triggers": [ + "pull_request_to_main", + "push_to_main" + ], + "permissions": { + "contents": "read" + }, + "python": "3.12", + "dependency_source": "pyproject.toml", + "mypy_required_gate": "deferred", + "production_secrets": "forbidden", + "provider_execution": "disabled", + "deployment_action": "absent", + "pull_request_validation": { + "verified": true, + "implementation_commit": "7f383ba6b0c17b92de9a27e0abe4cbeb8adbbac2", + "run_id": 30061513976, + "job_id": 89383928195, + "conclusion": "success" + }, + "post_merge_push_validation": { + "verified": false, + "status": "pending_approved_merge" + }, + "branch_protection": { + "enabled": false, + "authorized": false + } } } diff --git a/PROJECT_STATUS.md b/PROJECT_STATUS.md index a3fa606..57e0ae9 100644 --- a/PROJECT_STATUS.md +++ b/PROJECT_STATUS.md @@ -2,7 +2,7 @@ Version: 0.1.0 Status: Active Engineering Snapshot -Updated: 2026-07-22 +Updated: 2026-07-24 Product: YGIT Company: Vib Tools @@ -51,7 +51,7 @@ Business logic remains outside the Dashboard. Providers are not imported directl | Auth Engine | Implemented | Controlled production identity/session validation | | Connected Accounts Module | Implemented | Live account/credential lifecycle validation under production configuration | | Project Engine | Implemented | No critical foundation gap identified | -| Repository Engine | Metadata persistence implemented; live tree acquisition incomplete | GitHub App installation-token metadata/tree fetch, commit pinning, and private repository validation | +| Repository Engine | Metadata persistence implemented; AG-002 standalone provider gate foundation added but not runtime-wired; live tree acquisition incomplete | GitHub App installation-token metadata/tree fetch, commit pinning, and private repository validation | | Repository Analysis Engine | Quick-analysis contract implemented; current live input is incomplete | Actual repository tree acquisition, deep-analysis execution, Project reattachment after recalculation, and broader framework validation | | Deploy Engine | Implemented; AG-001 provider gate foundation added but not runtime-wired | Provider result reconciliation and reviewed future gate integration | | Deploy Pipeline | Concrete Cloudflare orchestration and trusted policy-to-binding handoff implemented; default runtime disabled | Controlled live provider validation and operational hardening | @@ -65,6 +65,7 @@ Business logic remains outside the Dashboard. Providers are not imported directl | Admin Panel | Implemented | Production operations validation | | GitHub Provider | Foundation implemented | Controlled live API execution | | Cloudflare Provider | OAuth/account and Pages deployment primitives implemented | Controlled live API execution and operational hardening | +| Backend CI | Implemented; Draft PR pull-request validation succeeded with stable status `Backend CI / Validate` | Documentation/PR metadata closure, approved merge, post-merge push validation, and separately approved branch protection | ## Recently Completed Foundations @@ -85,6 +86,9 @@ Business logic remains outside the Dashboard. Providers are not imported directl - Deployment History runtime persistence and deterministic retry-safe history-write idempotency. - Production configuration, PostgreSQL, Redis, public-route, and provider-mode live-readiness tooling. - AG-001 Deploy Provider Gate foundation with Cloudflare default and fail-closed future resolver contract. +- AG-002 Repository Provider Gate standalone foundation with GitHub default and unchanged current repository logic. +- Running baseline locked at `b9019b79d1af3fe73d1a74769792ebb6958c4f4c` with immutable tag, baseline branch, source ZIP, Git bundle, and SHA-256 evidence. +- Backend CI workflow implemented at `.github/workflows/backend-ci.yml`; pull-request run `30061513976` and `Validate` job `89383928195` completed successfully with read-only contents permission and provider execution disabled. ## Current Safety Boundary @@ -92,6 +96,8 @@ The default runtime remains provider-disabled. A concrete provider pipeline can be assembled only through the Worker Runtime-owned policy decision. Worker Runtime resolves the server setting, Job Dispatcher transports the immutable policy, and deploy/redeploy handlers validate it before handing a boolean to the neutral binding. The default mode is `disabled`; job payload fields cannot control the policy or enable execution. AG-001 remains standalone and is not used by runtime execution. +AG-002 is a standalone Repository Engine decision contract. A missing provider resolves to `github`; an explicit provider remains the selected provider. The gate is not imported by the current Repository Engine service and does not change URL parsing, GitHub metadata acquisition, persistence, analysis input, provider calls, API routes, database models, migrations, or runtime execution. + Provider results and failures are now routed through the Deployment History Engine public boundary. Deterministic intent keys prevent duplicate history logs during sequential job retries, and an existing completed history record blocks duplicate provider execution. Live PostgreSQL, Redis, GitHub, and Cloudflare evidence is still required. GitHub integration is architecture-locked to a GitHub App. Vib ID / Keycloak remains the YGIT user-authentication system, and Cloudflare remains a separate OAuth-connected provider. `GITHUB_OAUTH_CLIENT_ID` and `GITHUB_OAUTH_CLIENT_SECRET` are forbidden legacy variables. GitHub webhook capability is explicitly default-disabled; its secret becomes required only after an approved receiver is enabled. @@ -106,6 +112,7 @@ Dispatcher DB regression: 5 passed Worker Runtime architecture: 4 passed Deploy/redeploy architecture: 2 passed AG-001 regression: 15 passed +AG-002 regression: 9 passed Deployment History runtime: 8 passed Deployment History idempotency: 4 passed Live-readiness tooling: 18 passed @@ -114,22 +121,32 @@ GitHub App permission capture: 7 passed Dashboard compact provider cards: 10 passed Project Open UI: 9 passed Project Deploy UI: 9 passed -Full suite: 554 passed, 1 warning +Full suite: 579 passed, 1 warning Smoke --skip-db: PASS Release gate --skip-db: PASS +Backend CI workflow: IMPLEMENTED +Backend CI / Validate: SUCCESS +Backend CI pull-request run: 30061513976 +Backend CI job: 89383928195 +Backend CI post-merge push verification: PENDING +Branch protection required-check enablement: NOT AUTHORIZED ``` Database checks were skipped. External providers were not executed. ## Remaining Critical Path -1. Redeploy the current main branch and validate the Dashboard compact provider cards, Project Open flow, and backend-readiness-gated Deploy flow. -2. Reduce the GitHub App to the approved minimum permissions, reconnect the controlled installation, and verify captured permission scopes. -3. Implement GitHub App installation-token repository acquisition with a pinned commit SHA and normalized real file-tree snapshot. -4. Implement the approved deep-analysis execution and Project reattachment boundaries. -5. Confirm `deploy_ready=true` from real repository evidence and execute one controlled Cloudflare Pages deployment. -6. Resolve only defects demonstrated by live evidence. -7. Review AG-001 runtime integration only as part of future YGIT App Engine work. +1. Close Backend CI documentation/status evidence and verify the new Draft PR workflow result. +2. Reconcile PR metadata and complete the final read-only audit. +3. Obtain explicit Ready-for-review and merge approvals; no automatic transition or merge is allowed. +4. After controlled merge, verify the `push`-triggered `Backend CI / Validate` result on `main` and record Phase 0 completion. +5. Redeploy the current `main` branch and validate the Dashboard compact provider cards, Project Open flow, and backend-readiness-gated Deploy flow. +6. Reduce the GitHub App to the approved minimum permissions, reconnect the controlled installation, and verify captured permission scopes. +7. Implement GitHub App installation-token repository acquisition with a pinned commit SHA and normalized real file-tree snapshot. +8. Implement the approved deep-analysis execution and Project reattachment boundaries. +9. Confirm `deploy_ready=true` from real repository evidence and execute one controlled Cloudflare Pages deployment. +10. Resolve only defects demonstrated by live evidence. +11. Keep AG-001 and AG-002 runtime integration deferred until separate post-MVP architecture approval. ## Documentation Authority @@ -142,6 +159,10 @@ Current-state documents: - `CHANGELOG.md` - `AUDIT_REPORT.md` - `REPOSITORY_ANALYSIS_CURRENT_STATE_AUDIT.md` +- `docs/ci/BACKEND_CI_SPECIFICATION.md` +- `docs/ci/BACKEND_CI_IMPLEMENTATION_PLAN.md` +- `docs/ci/BACKEND_CI_TESTING_AND_ROLLBACK_SPECIFICATION.md` +- `.github/workflows/backend-ci.yml` Historical release artifacts retain their original versioned purpose. Where a historical artifact conflicts with this current snapshot, this document and the current source code take precedence for development status. @@ -149,6 +170,8 @@ Historical release artifacts retain their original versioned purpose. Where a hi | Date | Revision | Summary | |---|---|---| +| 2026-07-24 | 2.1 | Recorded Backend CI implementation, successful Draft PR validation, security boundaries, and remaining post-merge Phase 0 gates | +| 2026-07-23 | 2.0 | Locked the running baseline, reconciled current status/configuration evidence, and added the standalone AG-002 Repository Provider Gate foundation without runtime wiring | | 2026-07-22 | 1.9 | Documented the current Repository Analysis input, readiness, deep-queue, recalculation, and Project attachment gaps | | 2026-07-22 | 1.8 | Made GitHub App webhook readiness conditional and locked the current webhook capability off | | 2026-07-21 | 1.7 | Locked GitHub integration to the GitHub App contract and corrected live-readiness validation | diff --git a/README.md b/README.md index 8eaaf6c..124bccd 100644 --- a/README.md +++ b/README.md @@ -83,8 +83,8 @@ Object storage target: Cloudflare R2 | Auth Engine | Implemented with OIDC/session boundaries | | Connected Accounts Module | Implemented with GitHub/Cloudflare connection state, credential references, credential acquisition boundary, metadata UI, scopes, last-sync data, and disconnect/reconnect flows | | Project Engine | Implemented | -| Repository Engine | Implemented | -| Repository Analysis Engine | Implemented for MVP quick/deep analysis contracts | +| Repository Engine | Metadata persistence implemented; AG-002 standalone provider gate foundation added but not runtime-wired; real installation-token tree acquisition remains incomplete | +| Repository Analysis Engine | Quick-analysis contract implemented; real repository tree input, deep execution, and Project reattachment remain incomplete | | Deploy Engine | Implemented for validation, queued deployment lifecycle, redeploy, cancel, and reads | | Deploy Pipeline | Contracts, build stage, Cloudflare operation plan, concrete Cloudflare Pages gateway, completion result branch, and isolated provider pipeline factory implemented | | Deployment History Engine | Pipeline completion/failure persistence, retry-safe intent consumption, logs, and provider-result storage integrated through the public engine boundary | @@ -100,7 +100,9 @@ Object storage target: Cloudflare R2 ## App Gate Foundations -AG-001 Deploy Provider Gate is implemented as a standalone Deploy Engine extension contract. +### AG-001 — Deploy Provider Gate + +AG-001 remains a standalone Deploy Engine extension contract. ```text build_target missing @@ -114,7 +116,25 @@ injected future resolver selected provider ``` -AG-001 is not runtime-wired. It does not call providers, access the database, mutate deployment state, or create a YGIT App Engine. Current Cloudflare behavior remains unchanged. +AG-001 is not runtime-wired. Current Cloudflare deployment behavior remains unchanged. + +### AG-002 — Repository Provider Gate + +AG-002 is a standalone Repository Engine decision contract. + +```text +repository provider missing + ↓ +github + +repository provider present + ↓ +selected provider +``` + +GitHub remains the current default. AG-002 does not call providers, access the database, change repository parsing or metadata acquisition, add routes or migrations, or wire future providers into runtime. GitLab, Bitbucket, Azure DevOps, and other providers remain future work requiring separate architecture approval. + +See [AG-002 Repository Provider Gate](docs/architecture/AG_002_REPOSITORY_PROVIDER_GATE.md). ## Provider Execution Safety State @@ -139,6 +159,7 @@ Still disabled or incomplete: - Default production configuration remains provider-disabled until controlled live validation. - AG-001 runtime integration and future YGIT App resolver integration. +- AG-002 runtime integration and future non-GitHub repository provider adapters. - Controlled live verification of provider-result/history persistence against PostgreSQL. - Live Cloudflare API execution from the production worker. - Controlled end-to-end PostgreSQL, Redis worker, and Cloudflare Pages validation. @@ -148,6 +169,7 @@ Still disabled or incomplete: Latest verified local run for the current foundation: ```text +Running baseline lock: PASS at b9019b79d1af3fe73d1a74769792ebb6958c4f4c Provider execution policy unit tests: 18 passed Provider policy runtime integration tests: 9 passed Handler binding regression: 5 passed @@ -155,13 +177,19 @@ Dispatcher DB regression: 5 passed Worker Runtime architecture tests: 4 passed Deploy/redeploy architecture tests: 2 passed AG-001 regression: 15 passed +AG-002 regression: 9 passed Deployment History runtime tests: 8 passed Deployment History idempotency tests: 4 passed Live-readiness tooling tests: 18 passed Runtime image packaging tests: 4 passed -Full suite: 514 passed +Full suite: 579 passed, 1 warning Smoke test with database skipped: PASS Release gate with database skipped: PASS +Backend CI workflow: IMPLEMENTED at .github/workflows/backend-ci.yml +Backend CI / Validate (pull-request run 30061513976): SUCCESS +Backend CI job 89383928195: completed / success +Backend CI post-merge push verification: PENDING +Branch-protection required-check enablement: NOT AUTHORIZED Live PostgreSQL: NOT EXECUTED Live Redis worker loop: NOT EXECUTED GitHub API integration: NOT EXECUTED @@ -171,6 +199,30 @@ Real Cloudflare Pages deployment: NOT EXECUTED The recurring `StarletteDeprecationWarning` is non-blocking and relates to the existing test-client dependency combination. +## Backend CI State + +The initial Backend CI workflow is implemented on Draft PR #1. + +```text +Workflow file: .github/workflows/backend-ci.yml +Workflow: Backend CI +Job: Validate +Stable status: Backend CI / Validate +Pull-request validation: SUCCESS +Workflow commit: 7f383ba6b0c17b92de9a27e0abe4cbeb8adbbac2 +Run ID: 30061513976 +Job ID: 89383928195 +Permissions: contents read +Python: 3.12 +MyPy required gate: DEFERRED +Provider execution: DISABLED +Production secrets: NOT USED +Post-merge push validation: PENDING +Branch protection: NOT ENABLED +``` + +Backend CI is a verification mechanism only. It does not execute providers, contact production infrastructure, modify repository state, deploy YGIT, or replace controlled live validation. + ## Local Verification ```bash @@ -183,11 +235,16 @@ Live checks must use the controlled runtime runbook and dedicated test accounts. ## Immediate Critical Path -1. Redeploy the conditional GitHub App webhook-readiness correction commit to Coolify with provider mode `disabled` and `GITHUB_APP_WEBHOOK_ENABLED=false`. -2. Run pre/post-redeploy PostgreSQL, Redis, API, authentication-shell, and configuration checks. -3. Connect dedicated GitHub and Cloudflare test accounts, then enable `cloudflare` mode for one controlled deployment. -4. Fix only defects demonstrated by live evidence. -5. Integrate AG-001 only when a reviewed future App Engine contract is approved. +1. Complete Backend CI documentation/status closure and verify `Backend CI / Validate` on the resulting Draft PR commit. +2. Reconcile PR #1 title/body, rerun the final read-only audit, and obtain explicit Ready-for-review and merge approvals. +3. After an approved merge, verify the `push`-triggered `Backend CI / Validate` result on `main` and record Phase 0 completion. +4. Redeploy the current `main` branch and validate the Dashboard compact provider cards, Project Open flow, and backend-readiness-gated Deploy flow. +5. Reduce the GitHub App to the approved minimum permissions, reconnect the controlled installation, and verify captured permission scopes. +6. Implement GitHub App installation-token repository acquisition with a pinned commit SHA and normalized real file-tree snapshot. +7. Implement the approved deep-analysis execution and Project reattachment boundaries. +8. Confirm `deploy_ready=true` from real repository evidence and execute one controlled Cloudflare Pages deployment. +9. Resolve only defects demonstrated by live evidence. +10. Keep AG-001 and AG-002 runtime integration deferred until separate post-MVP architecture approval. ## Documentation Scope @@ -199,6 +256,12 @@ The following files are current project references: - `CONTRACT_MANIFEST.json` - `CHANGELOG.md` - `AUDIT_REPORT.md` +- `REPOSITORY_ANALYSIS_CURRENT_STATE_AUDIT.md` +- `docs/architecture/AG_002_REPOSITORY_PROVIDER_GATE.md` +- `docs/ci/BACKEND_CI_SPECIFICATION.md` +- `docs/ci/BACKEND_CI_IMPLEMENTATION_PLAN.md` +- `docs/ci/BACKEND_CI_TESTING_AND_ROLLBACK_SPECIFICATION.md` +- `.github/workflows/backend-ci.yml` The MVP release-gate and live-runtime-smoke-plan documents remain historical versioned artifacts. They should not be interpreted as the complete current implementation snapshot. diff --git a/VERSION.json b/VERSION.json index 887f22c..5c32467 100644 --- a/VERSION.json +++ b/VERSION.json @@ -34,12 +34,12 @@ "migration_head": "0012_notification_engine" }, "development_snapshot": { - "date": "2026-07-21", + "date": "2026-07-24", "status": "ready_for_controlled_live_redeploy", "mvp_completion_estimate": "approximately_97_percent", "controlled_live_path_estimate": "approximately_98_percent", "authoritative_status_document": "PROJECT_STATUS.md", - "full_test_suite": "514_passed_1_warning", + "full_test_suite": "579_passed_1_warning", "release_gate_skip_db": "pass", "live_provider_execution_verified": false, "live_readiness_tooling": { @@ -75,6 +75,31 @@ "receiver_endpoint": null, "live_verified": false } + }, + "baseline_lock": { + "status": "locked", + "commit": "b9019b79d1af3fe73d1a74769792ebb6958c4f4c", + "tag": "ygit-baseline-mvp-pre-completion-2026-07-23", + "branch": "baseline/mvp-pre-completion-2026-07-23", + "full_test_suite": "570_passed_1_warning" + }, + "backend_ci": { + "status": "implemented_pr_verified_post_merge_pending", + "workflow_path": ".github/workflows/backend-ci.yml", + "workflow_name": "Backend CI", + "job_id": "validate", + "job_name": "Validate", + "required_status": "Backend CI / Validate", + "implementation_commit": "7f383ba6b0c17b92de9a27e0abe4cbeb8adbbac2", + "pull_request_number": 1, + "pull_request_run_id": 30061513976, + "pull_request_job_id": 89383928195, + "pull_request_run_verified": true, + "post_merge_push_verified": false, + "branch_protection_enabled": false, + "provider_execution": false, + "production_secrets_required": false, + "deployment_execution": false } }, "domain": { @@ -194,6 +219,27 @@ "status": "created", "script": "scripts/live_runtime_smoke_test.py", "report": "LIVE_RUNTIME_SMOKE_TEST_REPORT.json" + }, + "backend_ci": { + "version": "0.1.0", + "status": "implemented_pr_verified_post_merge_pending", + "workflow": ".github/workflows/backend-ci.yml", + "workflow_name": "Backend CI", + "job_name": "Validate", + "required_status": "Backend CI / Validate", + "python": "3.12", + "permissions": { + "contents": "read" + }, + "mypy_required_gate": "deferred", + "pull_request_run_id": 30061513976, + "pull_request_job_id": 89383928195, + "pull_request_conclusion": "success", + "post_merge_push_verified": false, + "branch_protection_enabled": false, + "provider_execution": false, + "deployment_execution": false, + "coolify_redeploy_required": false } }, "release": "0.1.0-live-runtime-smoke-test-plan", @@ -258,6 +304,26 @@ "build_target_resolution": true, "app_engine_created": false, "live_execution": false + }, + "ag_002_repository_provider_gate": { + "audit_name": "AG-002 Repository Provider Gate", + "engine": "repository_engine", + "status": "foundation_ready_not_runtime_wired", + "default_provider": "github", + "missing_provider_resolution": "github", + "explicit_provider_resolution": "selected_provider", + "current_repository_logic_changed": false, + "runtime_wired": false, + "provider_access": false, + "database_access": false, + "api_routes_added": false, + "migration_added": false, + "future_providers": [ + "github", + "gitlab", + "bitbucket", + "azure_devops" + ] } } } diff --git a/backend/engines/repository_engine/repository_provider_gate.py b/backend/engines/repository_engine/repository_provider_gate.py new file mode 100644 index 0000000..6e14431 --- /dev/null +++ b/backend/engines/repository_engine/repository_provider_gate.py @@ -0,0 +1,13 @@ +from __future__ import annotations + +from typing import Final + +DEFAULT_REPOSITORY_PROVIDER: Final[str] = "github" + + +def resolve_repository_provider(provider: str | None) -> str: + """Resolve the Repository Engine provider without changing runtime behavior.""" + selected_provider = (provider or "").strip() + if not selected_provider: + return DEFAULT_REPOSITORY_PROVIDER + return selected_provider diff --git a/backend/tests/test_ag_002_repository_provider_gate.py b/backend/tests/test_ag_002_repository_provider_gate.py new file mode 100644 index 0000000..01ea59c --- /dev/null +++ b/backend/tests/test_ag_002_repository_provider_gate.py @@ -0,0 +1,62 @@ +from __future__ import annotations + +from pathlib import Path + +import pytest + +from backend.engines.repository_engine.repository_provider_gate import ( + DEFAULT_REPOSITORY_PROVIDER, + resolve_repository_provider, +) + + +def test_missing_provider_defaults_to_github() -> None: + assert resolve_repository_provider(None) == DEFAULT_REPOSITORY_PROVIDER + + +def test_empty_provider_defaults_to_github() -> None: + assert resolve_repository_provider("") == DEFAULT_REPOSITORY_PROVIDER + + +def test_whitespace_provider_defaults_to_github() -> None: + assert resolve_repository_provider(" ") == DEFAULT_REPOSITORY_PROVIDER + + +@pytest.mark.parametrize( + "provider", + ["github", "gitlab", "bitbucket", "azure_devops"], +) +def test_explicit_provider_remains_selected(provider: str) -> None: + assert resolve_repository_provider(provider) == provider + + +def test_gate_has_no_provider_database_worker_or_pipeline_dependency() -> None: + module_path = ( + Path(__file__).resolve().parents[1] + / "engines" + / "repository_engine" + / "repository_provider_gate.py" + ) + source = module_path.read_text(encoding="utf-8") + forbidden_imports = ( + "backend.providers", + "sqlalchemy", + "backend.worker", + "backend.pipelines", + "httpx", + ) + for forbidden_import in forbidden_imports: + assert forbidden_import not in source + + +def test_current_repository_service_is_not_runtime_wired_to_ag002() -> None: + service_path = ( + Path(__file__).resolve().parents[1] + / "engines" + / "repository_engine" + / "internal" + / "service.py" + ) + source = service_path.read_text(encoding="utf-8") + assert "repository_provider_gate" not in source + assert "GitHubProviderClient" in source diff --git a/backend/tests/test_repository_analysis_current_state_audit.py b/backend/tests/test_repository_analysis_current_state_audit.py index f73facb..b09872c 100644 --- a/backend/tests/test_repository_analysis_current_state_audit.py +++ b/backend/tests/test_repository_analysis_current_state_audit.py @@ -1,6 +1,5 @@ from pathlib import Path - ANALYSIS_SERVICE = Path( "backend/engines/repository_analysis_engine/internal/service.py" ) @@ -177,4 +176,6 @@ def test_project_status_links_audit_and_states_remaining_work() -> None: assert "REPOSITORY_ANALYSIS_CURRENT_STATE_AUDIT.md" in source assert "live tree acquisition incomplete" in source assert "Project reattachment after recalculation" in source - assert "Full suite: 554 passed, 1 warning" in source + assert "Full suite:" in source + assert "passed, 1 warning" in source + assert "Full suite: 554 passed, 1 warning" not in source diff --git a/docs/architecture/AG_002_REPOSITORY_PROVIDER_GATE.md b/docs/architecture/AG_002_REPOSITORY_PROVIDER_GATE.md new file mode 100644 index 0000000..95867ee --- /dev/null +++ b/docs/architecture/AG_002_REPOSITORY_PROVIDER_GATE.md @@ -0,0 +1,72 @@ +# AG-002 — Repository Provider Gate + +Version: 0.1.0 +Status: Foundation Ready / Not Runtime-Wired +Engine: Repository Engine +Audit Name: AG-002 Repository Provider Gate +Date: 2026-07-23 + +## Purpose + +Allow the Repository Engine to resolve a repository provider while preserving GitHub as the current default. + +## Decision Contract + +```text +Repository Request + │ + ▼ +Resolve Repository Provider + │ + ├── provider missing + │ ▼ + │ github + │ + └── provider exists + ▼ + selected provider +``` + +## Current Default + +```text +github +``` + +## Future Provider Candidates + +- GitHub +- GitLab +- Bitbucket +- Azure DevOps +- Other providers approved by future architecture documentation + +## Current Runtime Boundary + +AG-002 is a standalone decision contract only. + +It does not: + +- import or call repository providers; +- access PostgreSQL or Redis; +- change repository URL parsing; +- change GitHub App installation or credential behavior; +- change metadata acquisition or persistence; +- change Repository Analysis input; +- add API routes; +- add database models or migrations; +- wire GitLab, Bitbucket, Azure DevOps, or any other future provider; +- alter deployment behavior. + +The current Repository Engine service remains GitHub-based and does not import AG-002. + +## Resolution Rules + +1. A missing, empty, or whitespace-only provider resolves to `github`. +2. An explicit provider remains the selected provider. +3. The gate does not validate provider availability or execute provider logic. +4. Runtime integration requires a separate approved post-MVP architecture and implementation phase. + +## Safety and Rollback + +The foundation consists of one pure Repository Engine module, isolated regression tests, and documentation/manifest records. Removing those additions and reverting the associated documentation restores the exact locked baseline behavior. diff --git a/docs/ci/BACKEND_CI_IMPLEMENTATION_PLAN.md b/docs/ci/BACKEND_CI_IMPLEMENTATION_PLAN.md new file mode 100644 index 0000000..ccb2458 --- /dev/null +++ b/docs/ci/BACKEND_CI_IMPLEMENTATION_PLAN.md @@ -0,0 +1,1297 @@ +# YGIT Backend CI Implementation Plan + +**Version:** 0.1.5 +**Status:** Implemented / Verified +**Product:** YGIT +**Company:** Vib Tools +**Document Type:** Engineering Implementation Plan +**Related Specification:** `BACKEND_CI_SPECIFICATION.md` +**Target Repository:** `vibtools/ygit` +**Target Branch:** `phase0/baseline-reconciliation-ag002` +**Target Pull Request:** `#1` +**Date:** 2026-07-24 + +--- + +## 1. Purpose + +This document defines the controlled implementation plan for the first YGIT Backend Continuous Integration workflow. + +The plan translates the approved Backend CI specification into an exact, reviewable, rollbackable implementation sequence. + +The controlled implementation defined by this plan has been completed and verified on Draft PR #1. + +Implementation evidence: + +```text +Workflow file: .github/workflows/backend-ci.yml +Workflow commit: 7f383ba6b0c17b92de9a27e0abe4cbeb8adbbac2 +Workflow run: 30061513976 +Validate job: 89383928195 +Required status: Backend CI / Validate +Conclusion: success +``` + +This completion record does not authorize Ready transition, merge, branch protection, deployment, or the next MVP implementation area. + +--- + +## 2. Current Repository Evidence + +The implementation plan is based on the current authoritative repository state at: + +```text +Repository: +vibtools/ygit + +Feature branch: +phase0/baseline-reconciliation-ag002 + +Pre-workflow head authority: +controlled implementation patch manifest field `expected_head_before` + +Required head alignment: +local HEAD = origin feature branch = PR head = manifest `expected_head_before` + +Base branch: +main + +Locked base: +b9019b79d1af3fe73d1a74769792ebb6958c4f4c +``` + +Completed implementation evidence: + +```text +Implementation commit: +7f383ba6b0c17b92de9a27e0abe4cbeb8adbbac2 + +Pull-request workflow run: +30061513976 + +Validate job: +89383928195 + +Conclusion: +success + +PR state after validation: +OPEN / DRAFT / UNMERGED +``` + +### 2.1 Runtime Python + +The production Docker runtime uses: + +```text +Python 3.12 +``` + +The CI workflow will therefore use: + +```yaml +python-version: "3.12" +``` + +### 2.2 Project Compatibility + +The project metadata declares: + +```text +requires-python = ">=3.11" +``` + +Static-analysis compatibility remains: + +```text +Ruff target: py311 +MyPy configured python_version: 3.11 +Full-backend MyPy status: deferred; current locked head is not type-clean +``` + +This means: + +- CI execution runtime will match the current production container at Python 3.12; +- Ruff will enforce the approved changed-file compatibility contract; +- the existing MyPy configuration remains recorded but is not an initial required CI gate; +- this CI patch will not change project runtime compatibility. + +### 2.3 Dependency Source + +The authoritative dependency source is: + +```text +pyproject.toml +``` + +Development dependencies are defined in: + +```text +[project.optional-dependencies] +dev +``` + +The approved installation command is: + +```bash +python -m pip install -e ".[dev]" +``` + +No new requirements file, lock file, or package-management system will be introduced. + +### 2.4 Existing Validation Commands + +The existing repository commands are: + +```bash +python -m compileall -q backend scripts +python -m ruff check +python -m ruff check --ignore S105 backend/core/config.py # when changed +python -m ruff check --ignore E501,I001,UP035 scripts/release_gate.py # when changed +python -m mypy backend # diagnostic only; currently non-zero and not an initial CI gate +python -m pytest -q +python scripts/smoke_test.py --skip-db +python scripts/release_gate.py --skip-db +``` + +The CI workflow will invoke these existing validation boundaries. + +It will not duplicate their internal business or architecture rules in YAML. + +### 2.5 Safe Configuration Defaults + +Current project settings provide safe local defaults for test and smoke execution. + +Relevant defaults include: + +```text +APP_ENV=development +GITHUB_APP_WEBHOOK_ENABLED=false +WORKER_PROVIDER_EXECUTION_MODE=disabled +``` + +No production credential is required for the initial CI workflow. + +--- + +## 3. Implementation Goal + +The implementation will add one GitHub Actions workflow: + +```text +.github/workflows/backend-ci.yml +``` + +The workflow will produce one stable status: + +```text +Backend CI / Validate +``` + +The implementation will verify: + +```text +Checkout +↓ +Python 3.12 setup +↓ +Development dependency installation +↓ +Python compilation +↓ +Baseline-aware Ruff +↓ +Full pytest suite +↓ +Smoke test with database skipped +↓ +Release gate with database skipped +``` + +--- + +## 4. Planned Repository Changes + +### 4.1 Required Implementation File + +```text +.github/workflows/backend-ci.yml +``` + +### 4.2 Approved Documentation Files + +The final documentation patch may also add the approved CI documentation set: + +```text +docs/ci/BACKEND_CI_SPECIFICATION.md +docs/ci/BACKEND_CI_IMPLEMENTATION_PLAN.md +``` + +Additional CI documentation may be included only after it is separately created and approved. + +### 4.3 Forbidden Changes + +The CI implementation patch must not modify: + +```text +backend/engines/ +backend/providers/ +backend/pipelines/ +backend/workers/ +backend/app/ +backend/db/ +backend/models/ +backend/migrations/ +frontend/ +scripts/smoke_test.py +scripts/release_gate.py +pyproject.toml +Dockerfile +docker-compose.yml +.env +.env.example +``` + +An exception requires a separate documented defect and explicit approval. + +--- + +## 5. Workflow Design + +### 5.1 Workflow Name + +```yaml +name: Backend CI +``` + +### 5.2 Trigger Contract + +```yaml +on: + pull_request: + branches: + - main + push: + branches: + - main +``` + +The workflow must not use: + +```text +pull_request_target +workflow_run +repository_dispatch +deployment +schedule +release +``` + +### 5.3 Permissions + +```yaml +permissions: + contents: read +``` + +No write permission is allowed. + +### 5.4 Concurrency + +The workflow should use pull-request-aware concurrency to avoid wasting runner capacity on superseded commits. + +Planned contract: + +```yaml +concurrency: + group: backend-ci-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true +``` + +This provides: + +- one active Backend CI run per pull request; +- cancellation of obsolete runs after a new push; +- one active run per pushed branch reference; +- no functional effect on repository contents. + +### 5.5 Job Identity + +```yaml +jobs: + validate: + name: Validate +``` + +The stable resulting check will be: + +```text +Backend CI / Validate +``` + +### 5.6 Runner + +```yaml +runs-on: ubuntu-latest +``` + +The workflow will use a GitHub-hosted Ubuntu x86-64 runner. + +The Python runtime itself will be explicitly pinned to `3.12`. + +### 5.7 Timeout + +A bounded timeout must prevent an indefinitely blocked validation job. + +Planned value: + +```yaml +timeout-minutes: 20 +``` + +The timeout may be adjusted only if real CI evidence proves the value insufficient. + +--- + +## 6. Environment Contract + +The workflow may define the following safe environment variables: + +```yaml +env: + PYTHONUTF8: "1" + PYTHONDONTWRITEBYTECODE: "1" + PYTHONUNBUFFERED: "1" + APP_ENV: test + GITHUB_APP_WEBHOOK_ENABLED: "false" + WORKER_PROVIDER_EXECUTION_MODE: disabled +``` + +These values provide: + +- consistent UTF-8 behavior; +- cleaner runner state; +- immediate unbuffered logs; +- explicit test mode; +- disabled GitHub webhook processing; +- disabled worker provider execution. + +The workflow must not define: + +```text +DATABASE_URL pointing to production +REDIS_URL pointing to production +SESSION_SECRET production value +TOKEN_ENCRYPTION_KEY production value +KEYCLOAK_CLIENT_SECRET +GITHUB_APP_PRIVATE_KEY +GITHUB_APP_WEBHOOK_SECRET +CLOUDFLARE_OAUTH_CLIENT_SECRET +CLOUDFLARE_API_TOKEN +R2 credentials +Coolify credentials +``` + +--- + +## 7. Planned Workflow Steps + +### 7.1 Step 1 — Checkout + +Action: + +```yaml +uses: actions/checkout@v4 +``` + +Required configuration: + +```yaml +with: + persist-credentials: false +``` + +Purpose: + +- checkout the exact event revision; +- avoid retaining write-capable Git credentials; +- preserve a read-only workflow boundary. + +### 7.2 Step 2 — Set Up Python + +Action: + +```yaml +uses: actions/setup-python@v5 +``` + +Required configuration: + +```yaml +with: + python-version: "3.12" + cache: pip + cache-dependency-path: pyproject.toml +``` + +Purpose: + +- match the current Docker runtime; +- cache pip downloads using the authoritative dependency metadata; +- avoid floating Python versions. + +### 7.3 Step 3 — Upgrade Packaging Tooling + +Command: + +```bash +python -m pip install --upgrade pip +``` + +This step must not upgrade application dependencies outside the constraints already defined in `pyproject.toml`. + +### 7.4 Step 4 — Install Project and Development Dependencies + +Command: + +```bash +python -m pip install -e ".[dev]" +``` + +Purpose: + +- install the YGIT backend package; +- install pytest, pytest-asyncio, Ruff, MyPy, Bandit, and pip-audit as currently declared; +- preserve the existing package source and dependency constraints. + +The initial CI validation job will not run Bandit or pip-audit unless separately approved. + +They are installed because they are part of the existing `dev` dependency group. + +### 7.5 Step 5 — Compile Python Sources + +Command: + +```bash +python -m compileall -q backend scripts +``` + +Purpose: + +- detect invalid Python syntax; +- cover backend source and operational scripts; +- avoid compiling irrelevant virtual-environment or runner files. + +### 7.6 Step 6 — Baseline-Aware Ruff + +The workflow must resolve changed Python files before invoking Ruff. + +#### Pull-request comparison + +```text +base: +github.event.pull_request.base.sha + +head: +github.sha +``` + +#### Push comparison + +```text +base: +github.event.before + +head: +github.sha +``` + +Checkout must use complete history for deterministic comparison: + +```yaml +with: + persist-credentials: false + fetch-depth: 0 +``` + +Candidate source roots: + +```text +backend/ +scripts/ +``` + +The workflow must obtain changed paths from Git under those roots and then retain only `.py` paths. + +It must not depend on wildcard pathspecs such as `scripts/**/*.py`, because root-level files such as `scripts/release_gate.py` can be missed. + +The Bash step must: + +1. determine the correct base SHA for the event; +2. request added, copied, modified, or renamed paths under `backend/` and `scripts/`; +3. use NUL-delimited Git output; +4. sort and deduplicate paths without converting them to whitespace-delimited text; +5. retain only paths ending in `.py`; +6. exclude deleted files; +7. preserve filenames containing spaces; +8. separate the two controlled legacy-exception files; +9. run Ruff on every remaining eligible file; +10. succeed with an explicit message when no eligible Python file changed. + +Default command: + +```bash +python -m ruff check "${general_files[@]}" +``` + +Controlled exception commands: + +```bash +python -m ruff check --ignore S105 backend/core/config.py +python -m ruff check --ignore E501,I001,UP035 scripts/release_gate.py +``` + +Each exception command runs only when its exact file changed. + +Restrictions: + +- no `--fix`; +- no repository-wide `ruff check .` required gate; +- no ignored exit code; +- no unapproved path exclusion; +- no propagation of file-specific ignores to other files; +- repository `pyproject.toml` remains authoritative. + +### 7.7 Step 7 — Verify MyPy Deferral + +The initial workflow must not execute MyPy. + +Static workflow validation must reject: + +```text +python -m mypy +mypy backend +continue-on-error applied to a MyPy step +an error-count comparison used to make MyPy appear green +``` + +Reason: + +```text +Locked head: +d89e0d8101acf4ba05dccfd4083bdc8f6915897f + +Observed full-backend result: +744 errors in 81 files +342 source files checked +``` + +A separate `Backend MyPy Baseline and Remediation Specification` is required before adding a blocking MyPy step. + +The `mypy` package remains installed through the existing `dev` dependency group, but the initial workflow does not invoke it. + +### 7.8 Step 8 — Full Test Suite + +Command: + +```bash +python -m pytest -q +``` + +Acceptance authority: + +```text +pytest exit code +``` + +The workflow must not parse or hardcode: + +```text +579 passed +``` + +The observed count remains evidence only. + +### 7.9 Step 9 — Smoke Test + +Command: + +```bash +python scripts/smoke_test.py --skip-db +``` + +Expected result: + +```text +success: true +database: skipped +``` + +The workflow must accept the existing expected protected-shell responses: + +```text +/dashboard → 401 +/admin → 401 +``` + +### 7.10 Step 10 — Release Gate + +Command: + +```bash +python scripts/release_gate.py --skip-db +``` + +Expected result: + +```text +overall_status: PASS +database_runtime: SKIPPED +``` + +The command exit code remains the CI authority. + +--- + +## 8. Proposed Workflow Structure + +The implementation will follow this structural form: + +```yaml +name: Backend CI + +on: + pull_request: + branches: + - main + push: + branches: + - main + +permissions: + contents: read + +concurrency: + group: backend-ci-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +env: + PYTHONUTF8: "1" + PYTHONDONTWRITEBYTECODE: "1" + PYTHONUNBUFFERED: "1" + APP_ENV: test + GITHUB_APP_WEBHOOK_ENABLED: "false" + WORKER_PROVIDER_EXECUTION_MODE: disabled + +jobs: + validate: + name: Validate + runs-on: ubuntu-latest + timeout-minutes: 20 + + steps: + - name: Check out repository + uses: actions/checkout@v4 + with: + persist-credentials: false + fetch-depth: 0 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.12" + cache: pip + cache-dependency-path: pyproject.toml + + - name: Upgrade pip + run: python -m pip install --upgrade pip + + - name: Install project dependencies + run: python -m pip install -e ".[dev]" + + - name: Compile Python sources + run: python -m compileall -q backend scripts + + - name: Run baseline-aware Ruff + shell: bash + run: | + set -euo pipefail + + if [[ "${{ github.event_name }}" == "pull_request" ]]; then + base_sha="${{ github.event.pull_request.base.sha }}" + else + base_sha="${{ github.event.before }}" + fi + + if [[ -z "$base_sha" || "$base_sha" =~ ^0+$ ]]; then + base_sha="$(git rev-parse HEAD^)" + fi + + all_changed_files=() + mapfile -d '' -t all_changed_files < <( + git diff \ + --name-only \ + -z \ + --diff-filter=ACMR \ + "$base_sha" \ + "$GITHUB_SHA" \ + -- \ + backend \ + scripts | + sort -zu + ) + + changed_files=() + for file in "${all_changed_files[@]}"; do + case "$file" in + *.py) + changed_files+=("$file") + ;; + esac + done + + general_files=() + config_changed=false + release_gate_changed=false + + for file in "${changed_files[@]}"; do + case "$file" in + backend/core/config.py) + config_changed=true + ;; + scripts/release_gate.py) + release_gate_changed=true + ;; + *) + general_files+=("$file") + ;; + esac + done + + if (( ${#general_files[@]} > 0 )); then + python -m ruff check "${general_files[@]}" + fi + + if [[ "$config_changed" == "true" ]]; then + python -m ruff check --ignore S105 backend/core/config.py + fi + + if [[ "$release_gate_changed" == "true" ]]; then + python -m ruff check \ + --ignore E501,I001,UP035 \ + scripts/release_gate.py + fi + + if (( ${#changed_files[@]} == 0 )); then + echo "No eligible changed Python files." + fi + + - name: Run full test suite + run: python -m pytest -q + + - name: Run smoke test + run: python scripts/smoke_test.py --skip-db + + - name: Run release gate + run: python scripts/release_gate.py --skip-db +``` + +This block is the planned implementation structure. + +The final workflow must be generated and validated through the controlled patch process rather than copied manually into the repository. + +--- + +## 9. Local Pre-Push Validation + +Before committing the workflow, the patch must verify: + +### 9.1 Repository State + +```text +Current branch: +phase0/baseline-reconciliation-ag002 + +Expected current head: +resolved from the controlled implementation patch manifest field `expected_head_before` + +Required equality: +local HEAD = origin/phase0/baseline-reconciliation-ag002 = PR #1 head SHA = `expected_head_before` + +Working tree: +clean + +Remote main: +b9019b79d1af3fe73d1a74769792ebb6958c4f4c +``` + +The versioned documentation must not hard-code a mutable feature-branch head as an operational precondition. A documentation correction commit changes that head immediately and would make the same document stale. + +The implementation patch manifest is the operation-specific immutable authority. The patch must fail closed before file creation unless all three feature-head observations match the manifest: + +```text +local HEAD +origin/phase0/baseline-reconciliation-ag002 +PR #1 head SHA +``` + +### 9.2 Workflow Syntax + +The patch must parse the YAML using a deterministic parser. + +Validation must confirm: + +- document is valid YAML; +- `name` is exactly `Backend CI`; +- trigger includes pull requests to `main`; +- trigger includes pushes to `main`; +- `permissions.contents` is `read`; +- job ID is `validate`; +- job display name is `Validate`; +- runner is Ubuntu; +- Python version is `3.12`; +- no `pull_request_target`; +- no write permission; +- no production secret reference; +- no provider execution enablement; +- no `continue-on-error`; +- no `|| true`; +- no MyPy execution step in the initial required job. + +### 9.3 Existing Project Gates + +Before the workflow commit is created, local validation must rerun: + +```bash +python -m compileall -q backend scripts +python -m ruff check backend/engines/repository_engine/repository_provider_gate.py backend/tests/test_ag_002_repository_provider_gate.py backend/tests/test_repository_analysis_current_state_audit.py +python -m pytest -q +python scripts/smoke_test.py --skip-db +python scripts/release_gate.py --skip-db +``` + +### 9.4 Exact File Scope + +The initial CI implementation commit must contain only the approved files. + +If the documentation bundle is not yet ready, the implementation commit scope must be: + +```text +.github/workflows/backend-ci.yml +``` + +If all CI documents are approved and intentionally bundled, the exact scope may be: + +```text +.github/workflows/backend-ci.yml +docs/ci/BACKEND_CI_SPECIFICATION.md +docs/ci/BACKEND_CI_IMPLEMENTATION_PLAN.md + +``` + +No unrelated file is allowed. + +--- + +## 10. Commit and Push Plan + +### 10.1 Commit Strategy + +The CI foundation must be a separate commit on the existing feature branch. + +Planned commit message: + +```text +Add backend CI validation workflow +``` + +If the documentation set is bundled in the same approved patch, the message may be: + +```text +Add backend CI workflow and documentation +``` + +The exact message will be locked in the patch manifest. + +### 10.2 Push Target + +```text +origin/phase0/baseline-reconciliation-ag002 +``` + +The patch must not push directly to: + +```text +origin/main +``` + +### 10.3 Pull Request Behavior + +Pushing the workflow commit must update: + +```text +PR #1 +``` + +The PR must remain: + +```text +OPEN +DRAFT +NOT MERGED +AUTO-MERGE DISABLED +``` + +--- + +## 11. Remote Validation Plan + +After push, GitHub must be inspected for: + +### 11.1 Workflow Discovery + +Expected workflow: + +```text +Backend CI +``` + +### 11.2 Job Discovery + +Expected job: + +```text +Validate +``` + +### 11.3 Stable Check + +Expected check name: + +```text +Backend CI / Validate +``` + +### 11.4 Required Step Results + +Every step must complete successfully: + +```text +Check out repository +Set up Python +Upgrade pip +Install project dependencies +Compile Python sources +Run Ruff +Run full test suite +Run smoke test +Run release gate +``` + +### 11.5 Pull Request Verification + +After CI completes, verify: + +```text +PR state: OPEN +PR draft: true +Base: main +Head: phase0/baseline-reconciliation-ag002 +Head SHA: exact workflow commit +Changed files: exact approved set +Review threads: none unresolved +Reviews: no requested changes +Merge performed: no +``` + +--- + +## 12. Failure Handling + +### 12.1 Workflow Fails Before Commit + +If local YAML or project validation fails: + +- no commit is created; +- no push is performed; +- workflow and documentation changes remain available for forensic review; +- staging is reset; +- evidence is preserved; +- a corrected patch version is prepared. + +### 12.2 Commit Exists but Push Fails + +If the local commit succeeds but push fails: + +- preserve the local commit; +- do not reset or rewrite it automatically; +- report the local commit SHA; +- preserve a recovery bundle; +- verify remote branch remains unchanged; +- prepare a push-recovery patch. + +### 12.3 Workflow Pushes but CI Fails + +If GitHub Actions runs and fails: + +- keep PR #1 in draft; +- do not enable auto-merge; +- do not merge; +- inspect the exact failed job and logs; +- classify the failure as: + - workflow syntax; + - dependency installation; + - Python compatibility; + - lint; + - type checking; + - test; + - smoke; + - release gate; + - GitHub-hosted runner issue; +- prepare a narrowly scoped correction; +- rerun the complete CI workflow. + +### 12.4 Workflow Does Not Trigger + +If the workflow file is present but no run appears: + +- verify file path; +- verify workflow trigger syntax; +- verify PR base branch; +- verify GitHub Actions repository settings; +- verify actions are enabled; +- do not merge without a real remote status. + +### 12.5 Check Name Differs + +If GitHub produces a status other than: + +```text +Backend CI / Validate +``` + +the implementation is not accepted for branch protection. + +The workflow identity must be corrected before proceeding. + +--- + +## 13. Rollback Plan + +Rollback is performed by reverting the CI implementation commit. + +Rollback must restore: + +- the previous PR branch state; +- absence of the CI workflow when required; +- the prior documentation state if bundled; +- unchanged AG-002 behavior; +- unchanged runtime configuration; +- unchanged provider execution state. + +Rollback does not require: + +```text +Database migration +Database rollback +Redis operation +Cloudflare operation +Coolify redeploy +Production secret rotation +``` + +--- + +## 14. Security Review Checklist + +Before push, verify: + +- [ ] `permissions` contains only `contents: read` +- [ ] checkout credentials are not persisted +- [ ] no `pull_request_target` +- [ ] no repository secrets are referenced +- [ ] no environment secrets are embedded +- [ ] no third-party action beyond approved official actions +- [ ] no provider execution is enabled +- [ ] no deployment command exists +- [ ] no Docker registry login exists +- [ ] no artifact contains credentials +- [ ] no branch write occurs +- [ ] no PR write occurs +- [ ] no auto-merge occurs +- [ ] no shell failure suppression exists + +--- + +## 15. Implementation Acceptance Criteria + +The implementation is accepted only when: + +1. the approved workflow file exists; +2. the exact workflow identity is preserved; +3. the exact job identity is preserved; +4. Python 3.12 is used; +5. project dependencies install from `pyproject.toml`; +6. compile validation passes; +7. Ruff passes; +8. MyPy execution is absent from the initial required job; +9. full pytest passes; +10. smoke test passes with database skipped; +11. release gate passes with database skipped; +12. the remote GitHub Actions run is successful; +13. the resulting check is `Backend CI / Validate`; +14. PR #1 remains draft; +15. no unexpected file is present; +16. no production secret is used; +17. no provider operation is executed; +18. no deployment is executed; +19. no merge is performed; +20. rollback evidence exists. + +--- + +## 16. Documentation Bundle Strategy + +The CI documentation set will be accumulated as downloadable Markdown artifacts. + +Each approved document will later be added to the repository through one controlled documentation patch. + +Current planned documentation paths: + +```text +docs/ci/BACKEND_CI_SPECIFICATION.md +docs/ci/BACKEND_CI_IMPLEMENTATION_PLAN.md +``` + +Future approved CI documents may include: + +```text +docs/ci/BACKEND_CI_TESTING_AND_ROLLBACK_SPECIFICATION.md +docs/ci/BRANCH_PROTECTION_SPECIFICATION.md +docs/ci/CI_OPERATIONS_RUNBOOK.md +``` + +No document will be added to the repository until the CI documentation set is complete and explicitly approved for patching. + +--- + +## 17. Next Controlled Document + +After approval of this implementation plan, the next document will be: + +```text +YGIT Backend CI Testing and Rollback Specification +``` + +That document will define: + +- test scenarios; +- expected GitHub Actions evidence; +- failure classification; +- retry policy; +- rollback execution; +- post-merge verification; +- evidence retention; +- completion criteria. + +--- + +## 18. Completion and Remaining Approval Gate + +The workflow implementation and Draft PR validation defined by this plan are complete. + +The remaining authorized activity is limited to documentation/status closure, PR metadata reconciliation, and read-only audit. + +This completion record does not authorize: + +- marking PR #1 ready; +- merging PR #1; +- enabling branch protection; +- changing secrets; +- executing providers; +- deploying to Coolify; +- beginning repository acquisition implementation. + +--- + +## 19. Revision History + +| Date | Version | Status | Summary | +|---|---|---|---| +| 2026-07-23 | 0.1.0 | Draft for Approval | Initial implementation plan locking Python 3.12, project dependency installation, workflow structure, local and remote validation, failure handling, rollback, security checks, and documentation bundling | +| 2026-07-23 | 0.1.1 | Draft for Approval | Replaced repository-wide Ruff execution with a deterministic changed-Python-file resolver and retained approved file-specific legacy exceptions | +| 2026-07-23 | 0.1.2 | Draft for Approval | Removed full-backend MyPy from the initial workflow plan after deterministic baseline failure; added static deferral verification and a separate future enablement requirement | +| 2026-07-23 | 0.1.3 | Draft for Approval | Corrected the workflow starting head to the Patch 05 documentation commit and replaced wildcard Ruff pathspecs with NUL-delimited source-root diffing plus explicit `.py` filtering | +| 2026-07-23 | 0.1.4 | Draft for Approval | Replaced the recursively stale hard-coded feature-head precondition with a manifest-driven equality contract across local HEAD, remote feature head, and PR head | +| 2026-07-24 | 0.1.5 | Implemented / Verified | Recorded the completed workflow implementation, successful Draft PR run/job evidence, and remaining Ready/merge/post-merge gates | + +--- + +## 20. Decision Summary + +```text +Implementation status: +IMPLEMENTED / PR VERIFIED + +Implementation file: +.github/workflows/backend-ci.yml + +Workflow: +Backend CI + +Job: +Validate + +Required check: +Backend CI / Validate + +Pull-request evidence: +run 30061513976 / job 89383928195 / success + +Post-merge evidence: +PENDING + +Runner: +ubuntu-latest + +Runtime Python: +3.12 + +Project compatibility: +>=3.11 + +Dependency source: +pyproject.toml + +Install command: +python -m pip install -e ".[dev]" + +Validation: +compileall +Baseline-aware changed-file Ruff +MyPy deferred and absent +pytest +smoke --skip-db +release gate --skip-db + +Permissions: +contents: read + +Production secrets: +none + +Provider execution: +disabled + +Target: +existing Draft PR #1 + +Direct push to main: +forbidden + +Automatic merge: +forbidden + +Coolify redeploy: +not required +``` diff --git a/docs/ci/BACKEND_CI_SPECIFICATION.md b/docs/ci/BACKEND_CI_SPECIFICATION.md new file mode 100644 index 0000000..8481838 --- /dev/null +++ b/docs/ci/BACKEND_CI_SPECIFICATION.md @@ -0,0 +1,1045 @@ +# YGIT Backend CI Specification + +**Version:** 0.1.4 +**Status:** Approved / Implemented +**Product:** YGIT +**Company:** Vib Tools +**Document Type:** Engineering Specification +**Applies To:** YGIT Backend Repository +**Target Branch:** `main` +**Date:** 2026-07-24 + +--- + +## 1. Purpose + +This document defines the required Continuous Integration contract for the YGIT backend repository. + +The Backend CI workflow will provide automated, repeatable verification of backend source quality, static analysis, test execution, architecture boundaries, smoke behavior, and release-gate readiness before changes are accepted into `main`. + +The workflow is a verification mechanism only. + +It must not: + +- deploy YGIT; +- connect to production infrastructure; +- execute GitHub or Cloudflare provider operations; +- require production credentials; +- modify repository contents; +- modify external systems; +- enable provider execution; +- replace controlled live validation. + +--- + +## 2. Background + +The current YGIT engineering baseline has been locally validated with: + +```text +Python compilation: PASS +Approved scoped Ruff gates: PASS +Repository-wide Ruff scan: NOT A GREEN BASELINE; legacy findings remain +Full-backend MyPy: NOT A GREEN BASELINE; 744 errors in 81 files at the locked head +AG-002 regression: 9 passed +Full test suite: 579 passed, 1 warning +Smoke test --skip-db: PASS +Release gate --skip-db: PASS +Architecture boundaries: PASS +Basic secret scan: PASS +``` + +Draft Pull Request #1 contains the Phase 0 baseline reconciliation, AG-002 Repository Provider Gate foundation, Backend CI documentation, and the implemented Backend CI workflow. + +The workflow is implemented at `.github/workflows/backend-ci.yml`. Pull-request run `30061513976` completed successfully for workflow commit `7f383ba6b0c17b92de9a27e0abe4cbeb8adbbac2`; `Validate` job `89383928195` completed with conclusion `success`. + +This specification is the approved and implemented CI contract. Post-merge push validation and any branch-protection enforcement remain separate pending gates. + +--- + +## 3. Objectives + +The Backend CI workflow must provide the following guarantees: + +1. Every pull request targeting `main` receives automated backend validation. +2. Every push to `main` receives the same backend validation. +3. The workflow uses the repository’s authoritative Python and dependency configuration. +4. Static analysis failures block the workflow. +5. Test failures block the workflow. +6. Smoke-test failures block the workflow. +7. Release-gate failures block the workflow. +8. CI does not require PostgreSQL, Redis, GitHub provider access, Cloudflare provider access, or production secrets. +9. Provider execution remains disabled. +10. The workflow exposes one stable status check suitable for branch protection. + +--- + +## 4. Scope + +### 4.1 Included + +The initial Backend CI implementation includes: + +- repository checkout; +- Python runtime setup; +- dependency installation; +- Python source compilation; +- baseline-aware Ruff validation; +- full backend test execution; +- smoke testing with database checks skipped; +- release-gate execution with database checks skipped; +- stable workflow and job naming; +- minimal GitHub token permissions; +- pull-request and `main` branch triggers. + +### 4.2 Excluded + +The initial Backend CI implementation does not include: + +- PostgreSQL service containers; +- Redis service containers; +- database migrations against a live database; +- Cloudflare API calls; +- Cloudflare Pages deployments; +- GitHub App installation-token operations; +- live repository acquisition; +- provider execution; +- Docker image publication; +- Coolify deployment; +- production smoke testing; +- browser end-to-end testing; +- performance testing; +- load testing; +- security penetration testing; +- dependency update automation; +- release creation; +- package publication; +- branch merging; +- automatic pull-request approval. + +These capabilities require separate documentation and approval. + +--- + +## 5. Workflow Identity + +The workflow must use a stable identity. + +### 5.1 Workflow File + +```text +.github/workflows/backend-ci.yml +``` + +### 5.2 Workflow Display Name + +```text +Backend CI +``` + +### 5.3 Validation Job ID + +```text +validate +``` + +### 5.4 Validation Job Display Name + +```text +Validate +``` + +### 5.5 Required Status Check + +The resulting stable GitHub status check must be: + +```text +Backend CI / Validate +``` + +This name must not be changed after branch protection begins using it unless a separate migration is approved. + +--- + +## 6. Trigger Contract + +The workflow must run for the following events. + +### 6.1 Pull Requests + +```text +Event: pull_request +Target branch: main +``` + +The workflow must execute when a pull request targeting `main` is: + +- opened; +- reopened; +- synchronized by a new commit; +- updated in a way that causes GitHub to rerun the pull-request workflow. + +The pull-request workflow must use the `pull_request` event. + +It must not use `pull_request_target` because the CI workflow does not require privileged access and must not expose elevated repository permissions to untrusted pull-request code. + +### 6.2 Pushes to Main + +```text +Event: push +Branch: main +``` + +A push to `main` must execute the same validation contract used for pull requests. + +The push workflow provides post-merge verification and detects discrepancies between pull-request validation and the final `main` state. + +### 6.3 Unsupported Triggers + +The initial workflow must not run on: + +- tags; +- scheduled intervals; +- release events; +- deployment events; +- external repository dispatch events. + +Manual execution is not required by this specification. + +--- + +## 7. Permissions + +The workflow must apply least-privilege GitHub token permissions. + +Required workflow permission: + +```yaml +permissions: + contents: read +``` + +The workflow must not request: + +- `contents: write`; +- `pull-requests: write`; +- `issues: write`; +- `actions: write`; +- `deployments: write`; +- `packages: write`; +- `id-token: write`; +- `security-events: write`. + +The workflow must not: + +- commit files; +- push branches; +- create tags; +- create releases; +- modify pull requests; +- submit reviews; +- write comments; +- upload deployment statuses. + +--- + +## 8. Runner Environment + +The initial Backend CI workflow must run on a GitHub-hosted Ubuntu runner. + +```text +Runner family: Ubuntu +Architecture: x86-64 +``` + +The workflow must not depend on: + +- Windows-specific shell behavior; +- local developer paths; +- Coolify runtime paths; +- Docker Desktop; +- user-level credentials; +- persistent runner state. + +Commands must run from the repository root. + +--- + +## 9. Python Runtime Contract + +The CI Python version must match the repository’s authoritative runtime version. + +The implementation must determine the version from the existing repository configuration, such as: + +- project metadata; +- runtime configuration; +- container configuration; +- documented backend runtime requirements. + +The workflow must not introduce an unrelated Python version. + +The Python version must be explicitly pinned in the workflow after the authoritative project version is confirmed. + +A floating version such as the following is forbidden: + +```text +latest +3.x +``` + +The exact value will be taken from the approved repository runtime configuration during implementation. + +--- + +## 10. Dependency Installation Contract + +CI must use the repository’s existing authoritative dependency declaration. + +The workflow must not introduce a second dependency-management system. + +Dependency installation must: + +1. upgrade or initialize the package installer only when required; +2. install the project’s existing backend runtime dependencies; +3. install the project’s existing development and test dependencies; +4. fail immediately when dependency resolution fails; +5. avoid production credentials; +6. avoid installing unrelated global packages. + +The implementation must identify and use the current repository-authoritative source, which may include an existing: + +- requirements file; +- development requirements file; +- project metadata file; +- lock file; +- editable project installation contract. + +The CI implementation must not silently generate or modify a dependency lock file. + +--- + +## 11. Validation Pipeline + +All required stages must execute inside the single `Validate` job. + +The required execution order is: + +```text +Checkout +↓ +Python Setup +↓ +Dependency Installation +↓ +Python Compilation +↓ +Baseline-Aware Ruff +↓ +Full Test Suite +↓ +Smoke Test --skip-db +↓ +Release Gate --skip-db +↓ +CI Success +``` + +A failed stage must stop the job and produce a failed status. + +--- + +## 12. Repository Checkout + +The workflow must check out the exact commit associated with the event. + +For pull requests, validation must correspond to the GitHub-provided pull-request revision. + +For pushes, validation must correspond to the pushed `main` commit. + +Checkout must not: + +- rewrite commit history; +- merge additional branches manually; +- modify tracked files; +- initialize credentials for later pushes; +- persist authenticated Git configuration unnecessarily. + +--- + +## 13. Python Compilation Check + +The workflow must validate that the applicable Python source can be compiled. + +The compilation command must cover the backend and operational Python source currently exercised by the project. + +The implementation must use the existing project-approved compilation scope. + +Compilation failure must fail the CI job. + +The compilation stage is intended to detect: + +- syntax errors; +- invalid Python source; +- import-time parsing failures; +- accidentally committed malformed files. + +Compilation success does not replace Ruff or tests. + +--- + +## 14. Ruff Validation + +The initial Backend CI workflow must use a baseline-aware changed-file Ruff gate. + +The repository currently contains legacy Ruff findings outside the approved green validation scope. Therefore, the initial CI workflow must not use the following repository-wide command as a merge requirement: + +```text +ruff check . +``` + +A repository-wide Ruff cleanup is a separate engineering task and requires its own approved scope. + +### 14.1 Eligible Files + +For pull requests, the workflow must identify changed Python files between the pull-request base SHA and the validated event SHA. + +For pushes to `main`, the workflow must identify changed Python files between the event's `before` SHA and the pushed SHA. + +Candidate source roots are: + +```text +backend/ +scripts/ +``` + +The resolver must first request changed paths from Git under those two roots and then retain only paths whose final suffix is `.py`. + +The initial workflow must not rely on wildcard pathspecs such as: + +```text +backend/**/*.py +scripts/**/*.py +``` + +because root-level Python files under `scripts/`, including `scripts/release_gate.py`, can be omitted by shell- or Git-pathspec interpretation differences. + +Changed paths must be transferred from Git using NUL delimiters. The resolver must preserve valid filenames containing spaces or other non-newline shell characters and must not split paths using ordinary whitespace. + +Deleted files must not be passed to Ruff. + +The resolver must correctly handle: + +- added Python files; +- copied Python files; +- modified Python files; +- renamed Python files using their resulting path; +- root-level Python files under `scripts/`; +- nested Python files under `backend/`; +- Python filenames containing spaces; +- non-Python files under either source root; +- deleted Python files; +- an event with no eligible Python change. + +When no eligible Python file changed, the Ruff stage must report that no Python lint target exists and succeed without invoking Ruff. + +### 14.2 Default Changed-File Gate + +All eligible changed Python files, except the controlled legacy-exception files listed below, must run with the repository-authoritative configuration: + +```text +python -m ruff check +``` + +The workflow must not embed a second general Ruff rule set. + +### 14.3 Controlled Legacy Exceptions + +The current approved baseline contains two file-specific exception contracts established by earlier validated YGIT work: + +```text +backend/core/config.py + ignore: S105 + +scripts/release_gate.py + ignore: E501,I001,UP035 +``` + +These exceptions apply only when the corresponding file changed. + +No other file may inherit these ignores. + +Any new exception requires separate documentation and approval. + +### 14.4 Prohibited Behavior + +The CI workflow must not: + +```text +run ruff --fix +run repository-wide ruff check . as the initial required gate +ignore the Ruff exit code +exclude an eligible changed Python file silently +apply the controlled exceptions to unrelated files +``` + +A Ruff failure within the approved changed-file scope must fail the job. + +## 15. MyPy Deferral and Enablement Gate + +The initial Backend CI required job must not run: + +```text +python -m mypy backend +``` + +At the locked Phase 0 head, that command deterministically reports: + +```text +744 errors +81 files with errors +342 source files checked +``` + +This is an existing repository type-safety baseline condition. It was not introduced by the Backend CI documentation files. + +Running MyPy only against a changed file is not automatically isolated because MyPy follows imported modules and can surface errors from unchanged dependency paths. + +Therefore, the initial required CI workflow must treat MyPy as deferred rather than: + +- suppressing errors; +- adding broad ignore flags; +- using `continue-on-error`; +- comparing against an undocumented error count; +- retrying the same deterministic failure; +- declaring the repository type-clean. + +MyPy may become a required CI stage only after a separately approved type-safety baseline and remediation specification defines: + +1. the authoritative module or package scope; +2. the dependency-following policy; +3. approved temporary exceptions, if any; +4. a zero-error or explicitly versioned baseline transition; +5. tests for the scope resolver; +6. rollback behavior; +7. the branch-protection migration. + +Until that approval, the required Backend CI job must verify that no MyPy command is present. + +The existing `[tool.mypy]` configuration remains in `pyproject.toml` and is not modified by the initial CI patch. + +--- + +## 16. Full Test Suite + +The workflow must execute the complete automated test suite using the repository’s existing pytest configuration. + +The success authority is the pytest process exit code. + +The workflow must not hardcode an exact expected test count such as: + +```text +579 passed +``` + +The current count is engineering evidence, not the CI acceptance algorithm. + +The current observed evidence is: + +```text +579 passed, 1 warning +``` + +A non-zero pytest exit code must fail CI. + +The existing Starlette TestClient deprecation warning is currently non-blocking. Warning policy may be tightened only through a separately approved change. + +--- + +## 17. Smoke Test + +The workflow must execute the existing smoke test with database validation disabled: + +```text +scripts/smoke_test.py --skip-db +``` + +The smoke stage must verify the existing smoke-test contract, including applicable checks for: + +- required imports; +- route registration; +- platform/version endpoint behavior; +- protected Dashboard shell behavior; +- protected Admin shell behavior; +- migration artifact presence; +- release-gate artifact presence; +- live-runtime smoke artifact presence. + +Expected unauthenticated responses for protected surfaces remain valid: + +```text +/dashboard → 401 Unauthorized +/admin → 401 Unauthorized +``` + +The smoke test must report success and exit with code `0`. + +The workflow must not bypass a non-zero smoke-test exit code. + +--- + +## 18. Release Gate + +The workflow must execute the existing release gate with database validation disabled: + +```text +scripts/release_gate.py --skip-db +``` + +The release gate must continue to validate its existing contract, including: + +- required import boundaries; +- API route registry; +- runtime smoke behavior; +- migration chain; +- manifest alignment; +- architecture boundaries; +- required release artifacts; +- basic committed-secret scanning. + +The release gate must report: + +```text +overall_status: PASS +``` + +and exit successfully. + +The database check is expected to remain: + +```text +SKIPPED +``` + +for this initial CI workflow. + +The release gate must not execute: + +- live PostgreSQL probes; +- GitHub API integration; +- Cloudflare API integration; +- Redis worker loops; +- production URL smoke tests; +- Cloudflare Pages deployments. + +--- + +## 19. Environment and Secret Policy + +The initial Backend CI workflow must run without repository production secrets. + +It must not require: + +- Keycloak production credentials; +- GitHub App private keys; +- GitHub App webhook secrets; +- GitHub installation tokens; +- Cloudflare OAuth tokens; +- Cloudflare API tokens; +- PostgreSQL credentials; +- Redis credentials; +- R2 credentials; +- Coolify credentials; +- production session secrets. + +The workflow may define only safe non-secret environment values required to preserve fail-closed behavior. + +Provider execution must remain disabled. + +The CI workflow must not enable: + +```text +GitHub provider execution +Cloudflare provider execution +Worker provider execution +Webhook processing +Live deployment +``` + +Pull requests originating from forks must remain safe because no privileged secrets are supplied to the workflow. + +--- + +## 20. Architecture Boundary + +The Backend CI workflow is infrastructure verification. + +It is not a YGIT engine. + +It must not contain business logic belonging to: + +- Auth Engine; +- Project Engine; +- Repository Engine; +- Repository Analysis Engine; +- Deploy Engine; +- Deployment History Engine; +- Domain Engine; +- Audit Engine; +- Platform Engine; +- Notification Engine; +- provider adapters; +- Worker Runtime. + +The workflow may invoke existing project validation commands, but it must not duplicate their internal business rules in YAML. + +Business and architecture validation must remain implemented in project code and tests. + +--- + +## 21. Failure Behavior + +The workflow must fail when any required stage fails. + +Required failure conditions include: + +- repository checkout failure; +- unsupported or unavailable Python runtime; +- dependency installation failure; +- Python compilation failure; +- baseline-aware Ruff failure; +- pytest failure; +- smoke-test failure; +- release-gate failure. + +The workflow must not: + +- continue after a required failed stage; +- convert failures into warnings; +- use unconditional success overrides; +- suppress command exit codes; +- mark the job successful when a required validation failed. + +Forbidden patterns include: + +```yaml +continue-on-error: true +``` + +for required validation stages. + +Commands must not append shell constructs that suppress failures, such as: + +```text +|| true +``` + +--- + +## 22. Required Status and Branch Protection + +After the workflow is implemented and successfully validated on Draft PR #1, the following check is intended to become required for `main`: + +```text +Backend CI / Validate +``` + +Branch-protection configuration is an administrative repository setting and is not implemented by the workflow file itself. + +The required-check policy must not be enabled until: + +1. the workflow exists on the pull-request branch; +2. the workflow runs successfully; +3. the resulting status name is confirmed; +4. the status remains stable; +5. the pull-request and push triggers are verified; +6. no unexpected privileged permission is present. + +Once required, a failed or missing Backend CI check must block merging into `main`. + +--- + +## 23. Pull Request #1 Integration Plan + +The Backend CI foundation will be implemented on: + +```text +Branch: +phase0/baseline-reconciliation-ag002 + +Pull Request: +#1 +``` + +The implementation must preserve the current approved Phase 0 and AG-002 behavior. + +The CI implementation must be added as a separate controlled commit. + +The implementation commit must not alter: + +- AG-002 resolution logic; +- Repository Engine runtime wiring; +- GitHub default-provider behavior; +- API routes; +- database models; +- migrations; +- Worker Runtime; +- Deploy Engine; +- Cloudflare behavior; +- production configuration. + +After the workflow commit is pushed: + +1. GitHub Actions must trigger on PR #1. +2. The exact workflow and job names must be verified. +3. All CI stages must pass. +4. PR changed files must be re-audited. +5. Review threads and comments must be inspected. +6. PR #1 must remain draft until final approval. +7. No automatic merge may occur. + +--- + +## 24. Acceptance Criteria + +The Backend CI implementation is accepted only when all of the following are true. + +### 24.1 Structural Acceptance + +- `.github/workflows/backend-ci.yml` exists. +- Workflow name is `Backend CI`. +- Job ID is `validate`. +- Job display name is `Validate`. +- Required status resolves to `Backend CI / Validate`. +- Workflow targets pull requests to `main`. +- Workflow targets pushes to `main`. +- Permission is limited to `contents: read`. + +### 24.2 Validation Acceptance + +- Python runtime setup succeeds. +- Dependency installation succeeds. +- Python compilation passes. +- the baseline-aware changed-file Ruff gate passes. +- the required workflow contains no MyPy execution step. +- Full pytest suite passes. +- Smoke test with `--skip-db` passes. +- Release gate with `--skip-db` passes. + +### 24.3 Safety Acceptance + +- No production secret is used. +- No database service is required. +- No Redis service is required. +- No GitHub provider call is executed. +- No Cloudflare provider call is executed. +- No deployment is executed. +- Provider execution remains disabled. +- Workflow cannot write repository contents. +- Workflow cannot merge or modify pull requests. +- No unrelated source file is changed. + +### 24.4 Pull Request Acceptance + +- PR #1 remains open. +- PR #1 remains draft during CI validation. +- Head SHA matches the approved feature-branch commit. +- Backend CI appears as a GitHub status check. +- The status check passes. +- No unresolved review thread exists. +- No unexpected file is present in the final diff. + +--- + +## 25. Rollback Strategy + +The initial CI foundation is isolated to the GitHub Actions workflow and directly associated documentation or tests approved for that patch. + +Rollback must be possible by reverting the CI implementation commit. + +A rollback must: + +- remove or restore the workflow file; +- restore any directly associated CI documentation; +- leave the Phase 0 baseline reconciliation intact; +- leave AG-002 intact; +- leave production runtime unchanged; +- leave provider execution disabled; +- leave database state unchanged. + +Because the CI workflow is not a runtime deployment component, rollback does not require: + +- database rollback; +- migration rollback; +- Cloudflare rollback; +- Coolify redeployment. + +--- + +## 26. Deployment Impact + +The Backend CI foundation does not deploy YGIT. + +Before merge: + +```text +Production runtime impact: none +main branch impact: none +Coolify redeploy required: no +``` + +After a future merge into `main`, the workflow file changes repository automation only. + +A Coolify redeploy remains unnecessary unless the merged change also modifies production runtime code or deployment configuration through a separately approved patch. + +--- + +## 27. Implementation Restrictions + +Implementation must not begin until this specification is approved. + +The implementation patch must: + +- use the exact workflow identity defined here; +- contain only the approved CI scope; +- use existing project validation commands; +- avoid unrelated cleanup; +- avoid dependency upgrades unless strictly required and separately approved; +- avoid production secrets; +- avoid external provider execution; +- include rollback evidence; +- include local validation evidence before push; +- remain reviewable as a separate commit. + +--- + +## 28. Post-CI Sequence + +After Backend CI is implemented and passes on PR #1, the approved sequence is: + +```text +Backend CI passes +↓ +Remote workflow and status verification +↓ +Final PR diff audit +↓ +Review-thread inspection +↓ +Draft PR marked ready for review +↓ +Explicit merge approval +↓ +Controlled merge into main +↓ +Post-merge Backend CI verification +↓ +Phase 0 completion record +↓ +Primary MVP blocker implementation +``` + +The next MVP implementation area after Phase 0 completion remains: + +```text +GitHub App Installation Token +↓ +Repository Metadata Acquisition +↓ +Pinned Commit SHA +↓ +Bounded Repository Tree Acquisition +↓ +Normalized Repository Snapshot +↓ +Repository Analysis +``` + +Backend CI does not implement any part of that repository-acquisition path. + +--- + +## 29. Approval and Current Gate + +The Backend CI contract has been approved, implemented, and successfully validated on Draft PR #1. + +This recorded state authorizes documentation/status closure and continued read-only audit activity. + +It does not authorize: + +- merging PR #1; +- marking PR #1 ready for review; +- enabling branch protection; +- changing repository secrets; +- running live provider tests; +- deploying to Coolify; +- starting repository acquisition implementation. + +Post-merge `push` validation and branch-protection enforcement remain separate controlled steps. + +--- + +## 30. Revision History + +| Date | Version | Status | Summary | +|---|---|---|---| +| 2026-07-23 | 0.1.0 | Draft for Approval | Initial Backend CI contract defining triggers, permissions, validation stages, security boundaries, stable required status, PR #1 integration, acceptance criteria, and rollback requirements | +| 2026-07-23 | 0.1.1 | Draft for Approval | Corrected Ruff validation from an unverified repository-wide gate to a baseline-aware changed-Python-file contract with explicit legacy exceptions | +| 2026-07-23 | 0.1.2 | Draft for Approval | Deferred full-backend MyPy from the initial required CI job after the locked head produced 744 deterministic errors across 81 files; added a separate enablement gate | +| 2026-07-23 | 0.1.3 | Draft for Approval | Corrected the changed-file Ruff resolver contract to use source-root diffing, explicit `.py` filtering, NUL-delimited paths, root-level script coverage, and deterministic rename/deletion handling | +| 2026-07-24 | 0.1.4 | Approved / Implemented | Recorded the implemented workflow, successful Draft PR run and job evidence, read-only security boundary, and pending post-merge/branch-protection gates | + +--- + +## 31. Decision Summary + +```text +Implementation status: +APPROVED / IMPLEMENTED / PR VERIFIED + +Workflow: +Backend CI + +Required status: +Backend CI / Validate + +Pull-request validation: +SUCCESS — run 30061513976 / job 89383928195 + +Post-merge push validation: +PENDING + +Triggers: +pull_request → main +push → main + +Permissions: +contents: read + +Required stages: +Python compilation +Baseline-aware changed-file Ruff +Full pytest +Smoke --skip-db +Release gate --skip-db + +Production secrets: +Forbidden + +Provider execution: +Disabled + +Database and Redis: +Not required + +Deployment: +Not allowed + +Current PR: +Remain draft + +Automatic merge: +Forbidden + +Coolify redeploy: +Not required +``` diff --git a/docs/ci/BACKEND_CI_TESTING_AND_ROLLBACK_SPECIFICATION.md b/docs/ci/BACKEND_CI_TESTING_AND_ROLLBACK_SPECIFICATION.md new file mode 100644 index 0000000..c33c5c1 --- /dev/null +++ b/docs/ci/BACKEND_CI_TESTING_AND_ROLLBACK_SPECIFICATION.md @@ -0,0 +1,1476 @@ +# YGIT Backend CI Testing and Rollback Specification + +**Version:** 0.1.5 +**Status:** PR Validation Complete / Post-Merge Pending +**Product:** YGIT +**Company:** Vib Tools +**Document Type:** Engineering Testing and Rollback Specification +**Related Documents:** +- `BACKEND_CI_SPECIFICATION.md` +- `BACKEND_CI_IMPLEMENTATION_PLAN.md` + +**Target Repository:** `vibtools/ygit` +**Target Branch:** `phase0/baseline-reconciliation-ag002` +**Target Pull Request:** `#1` +**Date:** 2026-07-24 + +--- + +## 1. Purpose + +This document defines the testing, evidence, failure-handling, retry, rollback, and post-merge verification contract for the initial YGIT Backend Continuous Integration workflow. + +The objective is to ensure that the Backend CI workflow is: + +- functionally correct; +- deterministic; +- fail-closed; +- secure; +- reviewable; +- rollbackable; +- suitable for later branch-protection enforcement. + +This document governs validation of: + +```text +.github/workflows/backend-ci.yml +``` + +It does not authorize deployment, provider execution, branch protection, pull-request merge, or production changes. + +--- + +## 2. Testing Scope + +The testing scope includes: + +- local workflow-file validation; +- local backend validation; +- GitHub Actions trigger verification; +- GitHub Actions job and step verification; +- remote status-check verification; +- failure-path verification; +- retry behavior; +- branch and pull-request safety; +- rollback preparation; +- rollback execution; +- post-merge verification; +- evidence capture and retention. + +The testing scope excludes: + +- live PostgreSQL validation; +- live Redis worker execution; +- GitHub App installation-token execution; +- GitHub provider API operations; +- Cloudflare OAuth operations; +- Cloudflare API operations; +- Cloudflare Pages deployments; +- Coolify deployments; +- production URL smoke testing; +- browser end-to-end testing; +- performance testing; +- load testing; +- penetration testing. + +--- + +## 3. Authoritative Test Baseline + +The current verified local baseline is: + +```text +Python compilation: PASS +Approved scoped Ruff gates: PASS +Repository-wide Ruff scan: NOT A GREEN BASELINE; legacy findings remain +Full-backend MyPy: DEFERRED; locked-head diagnostic reports 744 errors in 81 files +Full pytest suite: 579 passed, 1 warning +Smoke test --skip-db: PASS +Release gate --skip-db: PASS +``` + +Verified remote pull-request evidence: + +```text +Workflow: Backend CI +Required status: Backend CI / Validate +Implementation commit: 7f383ba6b0c17b92de9a27e0abe4cbeb8adbbac2 +Run ID: 30061513976 +Run status: completed +Run conclusion: success +Job ID: 89383928195 +Job name: Validate +Job conclusion: success +Post-merge push validation: PENDING +Branch protection: NOT ENABLED +``` + +The exact test count is evidence only. + +The authoritative success criteria for CI are: + +```text +Process exit code = 0 +Required workflow steps = successful +Workflow conclusion = success +Stable status check = Backend CI / Validate +``` + +The workflow must not hardcode: + +```text +579 passed +``` + +A legitimate test-count change must not require editing the CI acceptance algorithm. + +--- + +## 4. Test Environment + +### 4.1 Local Environment + +Local pre-push validation is performed from the project root on the approved feature branch. + +Expected branch: + +```text +phase0/baseline-reconciliation-ag002 +``` + +Expected pre-workflow head: + +```text +controlled implementation patch manifest field: +expected_head_before +``` + +Before any workflow file is created, validation must prove: + +```text +local HEAD += +origin/phase0/baseline-reconciliation-ag002 += +PR #1 head SHA += +manifest expected_head_before +``` + +The test contract must reject a hard-coded mutable feature-head SHA inside the versioned CI documents. The exact operation-specific SHA belongs in the controlled patch manifest and execution evidence. + +The local environment must use: + +```text +Python 3.12 +UTF-8 mode +Existing project virtual environment or clean temporary environment +Existing pyproject.toml dependency source +``` + +### 4.2 GitHub Actions Environment + +The remote workflow must use: + +```text +Runner: ubuntu-latest +Python: 3.12 +Architecture: x86-64 +Permissions: contents: read +``` + +The workflow must run without production secrets. + +### 4.3 Safe CI Environment Values + +Approved safe environment values are: + +```text +PYTHONUTF8=1 +PYTHONDONTWRITEBYTECODE=1 +PYTHONUNBUFFERED=1 +APP_ENV=test +GITHUB_APP_WEBHOOK_ENABLED=false +WORKER_PROVIDER_EXECUTION_MODE=disabled +``` + +No provider or deployment mode may be enabled during CI. + +--- + +## 5. Test Categories + +The testing contract is divided into the following categories: + +1. Static workflow validation +2. Local repository validation +3. Pull-request trigger validation +4. Push trigger validation +5. Required-step validation +6. Failure-path validation +7. Security validation +8. Pull-request safety validation +9. Rollback validation +10. Post-merge verification + +--- + +## 6. Static Workflow Validation + +Before commit, the workflow file must be parsed and inspected. + +### 6.1 YAML Parsing + +The workflow must be valid YAML. + +Validation must fail when: + +- YAML syntax is invalid; +- indentation is invalid; +- duplicate structural keys produce ambiguous behavior; +- required fields are missing. + +### 6.2 Workflow Identity + +The following values must be exact: + +```text +Workflow name: Backend CI +Job ID: validate +Job name: Validate +Expected check: Backend CI / Validate +``` + +### 6.3 Trigger Validation + +The workflow must contain: + +```text +pull_request → main +push → main +``` + +The workflow must not contain: + +```text +pull_request_target +schedule +deployment +release +repository_dispatch +workflow_run +``` + +### 6.4 Permission Validation + +Required: + +```yaml +permissions: + contents: read +``` + +Forbidden: + +```text +contents: write +pull-requests: write +issues: write +actions: write +deployments: write +packages: write +id-token: write +security-events: write +``` + +### 6.5 Runner and Runtime Validation + +Required: + +```text +runs-on: ubuntu-latest +python-version: 3.12 +``` + +Forbidden Python selectors: + +```text +latest +3.x +``` + +### 6.6 Failure-Suppression Validation + +The workflow must not contain: + +```text +continue-on-error: true +|| true +exit 0 after a failed command +error-action suppression +manual success override +``` + +### 6.7 Secret-Reference Validation + +The workflow must not reference production secrets. + +Forbidden examples include: + +```text +secrets.DATABASE_URL +secrets.REDIS_URL +secrets.GITHUB_APP_PRIVATE_KEY +secrets.GITHUB_APP_WEBHOOK_SECRET +secrets.CLOUDFLARE_API_TOKEN +secrets.CLOUDFLARE_OAUTH_CLIENT_SECRET +secrets.KEYCLOAK_CLIENT_SECRET +secrets.SESSION_SECRET +secrets.TOKEN_ENCRYPTION_KEY +secrets.COOLIFY_TOKEN +``` + +### 6.8 Action Validation + +Approved external actions: + +```text +actions/checkout@v4 +actions/setup-python@v5 +``` + +Any additional third-party action requires separate review and approval. + +--- + +## 7. Local Repository Validation + +Before the CI workflow is committed, the following commands must pass: + +```bash +python -m compileall -q backend scripts +python -m ruff check backend/engines/repository_engine/repository_provider_gate.py backend/tests/test_ag_002_repository_provider_gate.py backend/tests/test_repository_analysis_current_state_audit.py +python -m pytest -q +python scripts/smoke_test.py --skip-db +python scripts/release_gate.py --skip-db +``` + +### 7.1 Compilation Acceptance + +Accepted when: + +```text +Exit code: 0 +``` + +Rejected when: + +- any Python syntax error exists; +- any backend or script file cannot compile; +- the command scope is reduced without approval. + +### 7.2 Baseline-Aware Ruff Acceptance + +The initial CI Ruff gate is accepted when: + +```text +Every eligible changed Python file is resolved deterministically +Every required Ruff process exits with code 0 +No eligible changed Python file is silently excluded +``` + +Eligible files are changed `.py` files under: + +```text +backend/ +scripts/ +``` + +Controlled legacy exceptions: + +```text +backend/core/config.py + --ignore S105 + +scripts/release_gate.py + --ignore E501,I001,UP035 +``` + +The gate is rejected when: + +- Ruff reports a violation in the approved changed-file scope; +- the changed-file resolver omits an eligible file; +- a deleted file is passed to Ruff; +- a file-specific exception is applied to another file; +- CI uses `--fix`; +- CI uses repository-wide `ruff check .` as the initial required baseline; +- the Ruff exit code is ignored. + +When no eligible Python file changed, the Ruff stage must report that condition and pass. + +Repository-wide Ruff cleanup remains a separate engineering task. + +### 7.2.1 Resolver Contract Test Matrix + +Before the workflow commit is created, the resolver implementation must pass a deterministic temporary-repository simulation covering: + +| Scenario | Expected Result | +|---|---| +| Documentation-only change | No Ruff invocation | +| Nested `backend/` Python modification | General Ruff invocation | +| `backend/core/config.py` modification | Ruff with only `S105` ignored | +| Root-level `scripts/release_gate.py` modification | Ruff with only `E501,I001,UP035` ignored | +| Deleted Python file | Excluded from Ruff | +| Renamed Python file | Resulting path linted | +| Non-Python file under `backend/` or `scripts/` | Excluded from Ruff | +| Python filename containing spaces | Exact path preserved and linted | +| Combined general and controlled-exception changes | Every required Ruff invocation executed | +| Push event with an all-zero `before` SHA | Fallback to `HEAD^` and correct changed-file result | +| Mutable-head authority | Exact SHA supplied by patch manifest; local, remote, and PR heads match | +| Stale hard-coded feature head in versioned documents | Validation fails before workflow creation | + +The simulation must also validate the Bash block with `bash -n`. + +A root-level `scripts/release_gate.py` change that produces no Ruff invocation is a release-blocking resolver defect. + +### 7.3 MyPy Deferral Acceptance + +Accepted when: + +```text +The initial required workflow contains no MyPy command +No MyPy failure is suppressed +No MyPy error count is used as a success threshold +The existing pyproject.toml MyPy configuration remains unchanged +``` + +Rejected when: + +- the workflow runs `python -m mypy backend`; +- the workflow uses `continue-on-error` for MyPy; +- the workflow adds broad MyPy ignore flags; +- the workflow retries a deterministic MyPy failure; +- documentation claims that the full backend is type-clean. + +The locked-head diagnostic evidence is: + +```text +744 errors in 81 files +342 source files checked +``` + +MyPy enablement requires a separate approved baseline and remediation specification. + +### 7.4 Pytest Acceptance + +Accepted when: + +```text +Exit code: 0 +``` + +Rejected when: + +- any test fails; +- collection fails; +- test execution is skipped; +- tests are selectively excluded without approval. + +The existing Starlette TestClient deprecation warning remains non-blocking. + +### 7.5 Smoke Acceptance + +Accepted when: + +```text +success: true +database: skipped +failures: [] +``` + +Expected protected-shell behavior: + +```text +/dashboard → 401 Unauthorized +/admin → 401 Unauthorized +``` + +These responses are successful smoke evidence, not failures. + +### 7.6 Release-Gate Acceptance + +Accepted when: + +```text +overall_status: PASS +database_runtime: SKIPPED +failures: [] +``` + +The release gate must continue validating: + +- import boundaries; +- route registry; +- runtime smoke; +- migration chain; +- manifest alignment; +- architecture boundaries; +- release artifacts; +- basic secret scanning. + +--- + +## 8. Pull Request Trigger Test + +The first remote test occurs after the workflow commit is pushed to: + +```text +phase0/baseline-reconciliation-ag002 +``` + +The target pull request is: + +```text +PR #1 +``` + +### 8.1 Expected Trigger + +A new commit on the PR branch must produce one pull-request workflow run. + +Expected event: + +```text +pull_request +``` + +Expected base: + +```text +main +``` + +Expected head: + +```text +phase0/baseline-reconciliation-ag002 +``` + +### 8.2 Expected Workflow + +```text +Backend CI +``` + +### 8.3 Expected Job + +```text +Validate +``` + +### 8.4 Expected Check + +```text +Backend CI / Validate +``` + +### 8.5 Trigger Failure + +The trigger test fails when: + +- no workflow run appears; +- the event is not `pull_request`; +- the workflow targets the wrong branch; +- the check name differs; +- more than one unintended workflow runs; +- the workflow is skipped because of incorrect path filtering. + +--- + +## 9. Push Trigger Test + +The `push` trigger to `main` cannot be fully validated until an approved merge occurs. + +After the future controlled merge, the same workflow must run on the resulting `main` commit. + +Expected event: + +```text +push +``` + +Expected branch: + +```text +main +``` + +Expected workflow: + +```text +Backend CI +``` + +Expected job: + +```text +Validate +``` + +Expected conclusion: + +```text +success +``` + +A pull-request success does not replace post-merge push verification. + +--- + +## 10. Required Step Test Matrix + +| Step | Command or Action | Required Result | +|---|---|---| +| Check out repository | `actions/checkout@v4` | Success | +| Set up Python | `actions/setup-python@v5` | Python 3.12 available | +| Upgrade pip | `python -m pip install --upgrade pip` | Exit code 0 | +| Install dependencies | `python -m pip install -e ".[dev]"` | Exit code 0 | +| Compile sources | `python -m compileall -q backend scripts` | Exit code 0 | +| Baseline-aware Ruff | Changed eligible Python files with controlled file-specific exceptions | Exit code 0 | +| MyPy deferral audit | No MyPy execution step in the initial required job | PASS | +| Full tests | `python -m pytest -q` | Exit code 0 | +| Smoke | `python scripts/smoke_test.py --skip-db` | PASS | +| Release gate | `python scripts/release_gate.py --skip-db` | PASS | + +Any failed required step must make the job fail. + +--- + +## 11. Concurrency Test + +The workflow should define: + +```text +cancel-in-progress: true +``` + +### 11.1 Test Procedure + +1. Push workflow commit. +2. Push a follow-up correction before the first run finishes, only when a real correction is required. +3. Verify the superseded run is cancelled. +4. Verify the newest commit receives the active run. +5. Verify no successful status is copied from the older commit. + +### 11.2 Acceptance + +Accepted when: + +- obsolete run is cancelled; +- newest commit runs fully; +- status attaches to the correct SHA; +- no branch or PR state is modified. + +--- + +## 12. Failure-Path Validation + +The initial implementation should not intentionally corrupt the main feature branch merely to prove failures. + +Failure-path validation may use: + +- static workflow inspection; +- a temporary disposable branch; +- a local temporary copy; +- a later controlled test branch. + +Any deliberate remote failure test requires explicit approval. + +### 12.1 Syntax Failure + +Expected behavior: + +```text +Workflow cannot start or is rejected +PR remains draft +No merge occurs +``` + +### 12.2 Dependency Failure + +Expected behavior: + +```text +Install step fails +Later steps do not run +Job conclusion: failure +``` + +### 12.3 Baseline-Aware Ruff Failure + +Expected behavior: + +```text +Changed-file Ruff step fails +Later required steps do not run +Job conclusion: failure +``` + +### 12.4 Unexpected MyPy Execution + +Expected behavior: + +```text +Static workflow validation fails +No workflow commit is accepted +PR remains draft +No merge occurs +``` + +The initial required workflow must not contain a MyPy execution step. + +### 12.5 Test Failure + +Expected behavior: + +```text +Pytest step fails +Smoke and release gate do not run +Job conclusion: failure +``` + +### 12.6 Smoke Failure + +Expected behavior: + +```text +Smoke step fails +Release gate does not run +Job conclusion: failure +``` + +### 12.7 Release-Gate Failure + +Expected behavior: + +```text +Release gate fails +Job conclusion: failure +Check conclusion: failure +``` + +### 12.8 Runner Failure + +A GitHub-hosted runner outage or infrastructure failure is not automatically classified as a code defect. + +It must be classified separately and rerun only after evidence review. + +--- + +## 13. Failure Classification + +Every failed run must be classified into one of the following categories. + +| Code | Category | Description | +|---|---|---| +| CI-001 | Workflow Syntax | Invalid YAML or GitHub Actions structure | +| CI-002 | Trigger | Workflow did not trigger or triggered incorrectly | +| CI-003 | Permissions | Missing or excessive token permission | +| CI-004 | Runtime Setup | Python or runner setup failure | +| CI-005 | Dependency Install | Project or dev dependency installation failure | +| CI-006 | Compilation | Python source compilation failure | +| CI-007 | Baseline-Aware Ruff | Changed-file lint failure or resolver defect | +| CI-008 | MyPy Deferral Violation | MyPy was executed or suppressed before baseline approval | +| CI-009 | Pytest | Test failure or collection failure | +| CI-010 | Smoke | Smoke-test failure | +| CI-011 | Release Gate | Release-gate failure | +| CI-012 | Secret Safety | Secret reference or exposure risk | +| CI-013 | Provider Safety | Provider execution unexpectedly enabled | +| CI-014 | GitHub Infrastructure | Runner or GitHub Actions service issue | +| CI-015 | Scope Drift | Unexpected repository file or behavior change | +| CI-016 | Status Identity | Check name differs from approved stable name | + +The failure record must include: + +```text +Failure code +Workflow run ID +Commit SHA +Failed step +Relevant log excerpt +Root cause +Corrective action +Retest result +``` + +--- + +## 14. Retry Policy + +### 14.1 Code or Workflow Defect + +Do not rerun an unchanged failing commit when evidence proves a deterministic defect. + +Required action: + +1. identify root cause; +2. prepare a narrow correction; +3. run local validation; +4. commit the correction; +5. push the new commit; +6. verify a new workflow run. + +### 14.2 GitHub Infrastructure Failure + +A rerun is allowed when evidence indicates: + +- runner provisioning failure; +- GitHub-hosted service outage; +- transient package-index network failure; +- temporary action-download failure; +- non-deterministic external infrastructure problem. + +### 14.3 Retry Limit + +Maximum automatic or manual retry attempts for the same unchanged commit: + +```text +2 +``` + +After two failed infrastructure retries: + +- stop retrying; +- preserve evidence; +- classify the issue; +- wait for a corrected environment or workflow change; +- do not merge. + +### 14.4 Forbidden Retry Behavior + +Do not: + +- repeatedly rerun until a flaky result becomes green; +- hide a deterministic failure; +- use retry as a replacement for root-cause analysis; +- mark a failed run as acceptable; +- merge because local validation passed while remote CI remains failed. + +--- + +### 14.5 Patch-Runner Read-Only Retry Boundary + +Local patch automation may retry only transient, read-only control-plane operations. + +Approved retry examples: + +```text +git fetch +gh auth status +gh repo view +gh api user +gh collaborator permission lookup +gh pr view +gh pr diff --name-only +post-push read-only verification +``` + +Maximum attempts: + +```text +3 +``` + +Retry logic must not: + +```text +copy files +edit files +remove files +stage files +commit +push +run Ruff again after a lint failure +run pytest again after a test failure +run smoke or release gate again after a deterministic failure +run or suppress MyPy +``` + +Commit and push are single-attempt operations. A failed push preserves the local commit and recovery bundle for a separately controlled recovery step. + +## 15. Security Validation + +The remote run must be inspected for security compliance. + +### 15.1 Required Security Evidence + +- token permission is read-only; +- checkout credentials are not persisted; +- no secret is printed; +- no secret is requested; +- no production endpoint is contacted; +- no provider operation is executed; +- no deployment operation is executed; +- no write operation is performed. + +### 15.2 Log Inspection + +Logs must be inspected for accidental values resembling: + +```text +Private keys +Bearer tokens +OAuth secrets +API tokens +Database passwords +Redis passwords +Session secrets +Encryption keys +Webhook secrets +``` + +A suspected secret exposure is a release-blocking incident. + +### 15.3 Fork Safety + +The workflow must remain safe for pull requests from forks because: + +- it uses `pull_request`; +- it has `contents: read`; +- it receives no production secrets; +- it cannot push or modify pull requests. + +--- + +## 16. Pull Request Safety Validation + +After the workflow run, verify PR #1 remains: + +```text +State: OPEN +Draft: true +Merged: false +Auto-merge: disabled +Base: main +Head: phase0/baseline-reconciliation-ag002 +``` + +Verify: + +- no reviewer was added automatically; +- no comment was posted automatically; +- no label was changed automatically; +- no branch was deleted; +- no merge queue was enabled; +- no deployment was created. + +A successful workflow must not mutate PR state. + +--- + +## 17. Evidence Requirements + +Every implementation and rollback stage must preserve evidence. + +### 17.1 Local Evidence + +Required: + +```text +Git branch +Git HEAD +Remote main SHA +Remote feature SHA +Git status +Approved file list +Workflow file SHA-256 +YAML validation result +Compilation result +Ruff result +MyPy deferral audit result +Pytest result +Smoke result +Release-gate result +Commit SHA +Push result +``` + +### 17.2 Remote Evidence + +Required: + +```text +PR number +PR URL +Workflow run ID +Workflow URL +Event type +Head SHA +Base branch +Workflow name +Job name +Step conclusions +Overall conclusion +Check name +Check status +Review-thread state +Changed-file list +``` + +### 17.3 Rollback Evidence + +Required: + +```text +Rollback reason +Original workflow commit SHA +Rollback commit SHA +Files reverted +Local validation result +Remote workflow result +PR state +Main state +Provider execution state +Coolify redeploy requirement +``` + +--- + +## 18. Evidence Storage + +Local patch evidence should be stored under: + +```text +D:\VibTools_Workspace\14_Vib.Tools\ygit\_backups\ +``` + +Recommended directory patterns: + +```text +backend_ci_implementation_ +backend_ci_failure_ +backend_ci_rollback_ +backend_ci_post_merge_ +``` + +Each evidence directory should contain: + +```text +TRANSCRIPT.txt +GIT_STATE.txt +FILE_MANIFEST.json +VALIDATION_RESULTS.json +WORKFLOW_METADATA.json +SHA256SUMS.txt +``` + +Recovery bundles should be stored separately in the user’s Downloads directory. + +--- + +## 19. Evidence Retention + +Minimum retention contract: + +| Evidence | Minimum Retention | +|---|---:| +| Local implementation transcript | Until Phase 0 completion | +| Recovery bundle | Until Phase 0 completion | +| Failed CI logs | Until defect closure | +| Successful PR CI evidence | Permanent project audit reference | +| Rollback evidence | Permanent project audit reference | +| Post-merge CI evidence | Permanent project audit reference | + +GitHub-hosted logs may expire according to repository settings. + +Critical evidence must therefore be summarized into project-owned Markdown or JSON records before expiration. + +--- + +## 20. Rollback Triggers + +Rollback is required or considered when: + +- workflow blocks all valid pull requests because of a workflow defect; +- workflow uses excessive permissions; +- workflow exposes or requests a secret; +- workflow enables provider execution; +- workflow contacts production infrastructure; +- workflow check identity is unstable; +- workflow causes persistent false failures; +- workflow introduces unacceptable dependency behavior; +- workflow modifies repository or PR state; +- workflow conflicts with the approved architecture; +- post-merge CI fails because of the workflow itself; +- explicit project approval orders rollback. + +Rollback is not automatically required for: + +- a legitimate baseline-aware Ruff failure; +- a legitimate test failure; +- a legitimate smoke failure; +- a legitimate release-gate failure. + +Those failures indicate code or project defects, not necessarily CI defects. + +--- + +## 21. Rollback Scope + +The initial rollback scope is limited to: + +```text +.github/workflows/backend-ci.yml +``` + +If the documentation set is committed in the same patch, rollback may also include: + +```text +docs/ci/BACKEND_CI_SPECIFICATION.md +docs/ci/BACKEND_CI_IMPLEMENTATION_PLAN.md +docs/ci/BACKEND_CI_TESTING_AND_ROLLBACK_SPECIFICATION.md +``` + +Rollback must not remove or modify: + +```text +AG-002 Repository Provider Gate +Phase 0 baseline reconciliation +Repository Engine runtime behavior +Worker Runtime behavior +Deploy Engine behavior +Database models +Migrations +Provider configuration +Production configuration +``` + +--- + +## 22. Pre-Merge Rollback Procedure + +When the workflow exists only on the feature branch and PR #1 is still draft: + +1. verify current branch; +2. verify current head; +3. fetch remote state; +4. confirm `main` is unchanged; +5. identify the CI implementation commit; +6. create a revert commit or restore the approved pre-CI file state; +7. run local validation; +8. push the rollback commit to the feature branch; +9. verify PR #1 remains draft; +10. verify workflow removal or correction; +11. preserve rollback evidence. + +A destructive history rewrite is not preferred. + +The default rollback method is: + +```text +revert commit +``` + +not: + +```text +force push +``` + +Force push requires separate explicit approval. + +--- + +## 23. Post-Merge Rollback Procedure + +If the CI workflow has already been merged into `main`: + +1. create a dedicated rollback branch from current `main`; +2. revert the CI workflow commit; +3. preserve approved non-CI changes; +4. run local validation; +5. open a controlled rollback pull request; +6. verify rollback CI behavior where possible; +7. obtain explicit approval; +8. merge the rollback PR; +9. verify the `push` workflow result on `main`; +10. record the final state. + +Direct edits to `main` are forbidden. + +--- + +## 24. Rollback Validation + +A rollback is accepted only when: + +- the targeted workflow behavior is removed or corrected; +- no unrelated file changes exist; +- project tests still pass; +- smoke still passes with database skipped; +- release gate still passes with database skipped; +- AG-002 remains unchanged; +- provider execution remains disabled; +- PR and branch state are correct; +- no deployment occurs; +- evidence is preserved. + +--- + +## 25. Post-Merge Verification + +After an approved future merge of PR #1: + +### 25.1 Main Branch Verification + +Verify: + +```text +main contains the approved merge +main contains backend-ci.yml +feature branch changes match approved scope +no unexpected commit exists +``` + +### 25.2 Push Workflow Verification + +Verify: + +```text +Event: push +Branch: main +Workflow: Backend CI +Job: Validate +Check: Backend CI / Validate +Conclusion: success +``` + +### 25.3 Repository Verification + +Verify: + +- workflow file content matches approved implementation; +- documentation paths are correct; +- no production secret exists; +- no provider execution is enabled; +- no deployment action exists; +- branch protection has not changed unless separately approved. + +### 25.4 Production Impact Verification + +Expected: + +```text +Application runtime change: none +Database change: none +Provider change: none +Deployment change: none +Coolify redeploy required: no +``` + +--- + +## 26. Branch Protection Readiness + +This document does not authorize branch protection. + +Backend CI is ready to become a required check only when: + +1. PR-triggered workflow succeeds; +2. post-merge push workflow succeeds; +3. check name is stable; +4. workflow permissions are verified; +5. no secret is required; +6. no flaky behavior is observed; +7. rollback procedure is proven; +8. the required-check specification is separately approved. + +Expected required check: + +```text +Backend CI / Validate +``` + +--- + +## 27. Test Completion Criteria + +Backend CI testing is complete only when: + +- static workflow validation passes; +- all local project gates pass; +- PR workflow triggers; +- every required remote step succeeds; +- stable check name is confirmed; +- PR #1 remains draft and unmodified; +- no review thread is unresolved; +- security inspection passes; +- evidence bundle is complete; +- rollback plan is verified; +- no merge is performed without explicit approval. + +--- + +## 27.1 Pull-Request Validation Completion Record + +The initial pull-request validation contract is complete for workflow commit `7f383ba6b0c17b92de9a27e0abe4cbeb8adbbac2`. + +```text +Static workflow validation: PASS +Local project gates: PASS +Pull-request trigger: PASS +Workflow run: 30061513976 +Workflow conclusion: success +Validate job: 89383928195 +Validate conclusion: success +Stable check: Backend CI / Validate +PR state preserved: OPEN / DRAFT / UNMERGED +Unresolved review threads: none +Provider execution: disabled +Production secrets: none +Deployment: none +``` + +Testing is not fully complete for branch-protection readiness because the post-merge `push` workflow on `main` has not yet executed. + +--- + +## 28. Phase 0 Completion Dependency + +Backend CI validation is a Phase 0 completion dependency. + +The sequence remains: + +```text +Backend CI documentation approved +↓ +CI workflow implementation patch +↓ +Local validation +↓ +Push to Draft PR #1 +↓ +Remote CI success +↓ +Final diff audit +↓ +Ready-for-review decision +↓ +Explicit merge approval +↓ +Controlled merge +↓ +Post-merge CI success +↓ +Phase 0 completion record +``` + +The next MVP implementation area begins only after this sequence is complete. + +--- + +## 29. Next MVP Boundary + +After Phase 0 completion, the next implementation boundary remains: + +```text +GitHub App Installation Token +↓ +Repository Metadata Acquisition +↓ +Pinned Commit SHA +↓ +Bounded Repository Tree Acquisition +↓ +Normalized Repository Snapshot +↓ +Repository Analysis +``` + +Backend CI testing and rollback must not introduce any part of that feature. + +--- + +## 30. Current Approval Gate + +The controlled implementation, local validation, Draft PR push, and remote pull-request validation authorized by this document are complete. + +The remaining authorized activity is limited to documentation/status closure, PR metadata reconciliation, final read-only audit, and preparation for separately approved Ready/merge decisions. + +This document still does not authorize: + +- marking PR #1 ready for review; +- merging PR #1; +- enabling branch protection; +- changing repository secrets; +- provider execution; +- live database testing; +- Cloudflare deployment; +- Coolify redeployment; +- starting repository acquisition implementation. + +--- + +## 31. Revision History + +| Date | Version | Status | Summary | +|---|---|---|---| +| 2026-07-23 | 0.1.0 | Draft for Approval | Initial testing and rollback contract covering local validation, remote workflow verification, test matrix, failure classification, retry policy, evidence retention, rollback procedures, post-merge verification, and completion criteria | +| 2026-07-23 | 0.1.1 | Draft for Approval | Corrected Ruff acceptance and failure testing to use the baseline-aware changed-Python-file gate rather than the non-green repository-wide scope | +| 2026-07-23 | 0.1.2 | Draft for Approval | Replaced the invalid full-backend MyPy success requirement with a deferral audit based on the locked-head 744-error diagnostic and a separate future enablement gate | +| 2026-07-23 | 0.1.3 | Draft for Approval | Corrected the pre-workflow head and added a resolver simulation matrix covering root-level scripts, NUL-delimited paths, rename/deletion behavior, spaces, and zero-`before` fallback | +| 2026-07-23 | 0.1.4 | Draft for Approval | Replaced the recursively stale hard-coded pre-workflow SHA with a patch-manifest authority and added head-alignment and stale-document rejection tests | +| 2026-07-24 | 0.1.5 | PR Validation Complete / Post-Merge Pending | Recorded successful local and pull-request validation evidence while retaining post-merge push CI and branch-protection readiness as pending | + +--- + +## 32. Decision Summary + +```text +Testing authority: +Process exit codes and GitHub Actions conclusions + +Stable check: +Backend CI / Validate + +Local tests: +compileall +Baseline-aware changed-file Ruff +MyPy deferral audit +pytest +smoke --skip-db +release gate --skip-db + +Remote test: +pull_request workflow on PR #1 — SUCCESS (run 30061513976 / job 89383928195) + +Post-merge test: +push workflow on main — PENDING + +Production secrets: +forbidden + +Provider execution: +disabled + +Database and Redis: +not required + +Retry limit: +2 infrastructure retries per unchanged commit + +Default rollback: +revert commit + +Force push: +forbidden without separate approval + +PR state during validation: +OPEN and DRAFT + +Automatic merge: +forbidden + +Coolify redeploy: +not required +```