diff --git a/.agent-loop/initiatives/WS-CI-001-backend-ci-acceleration/CHUNK_MAP.md b/.agent-loop/initiatives/WS-CI-001-backend-ci-acceleration/CHUNK_MAP.md index 3156ae6b..ea79bc58 100644 --- a/.agent-loop/initiatives/WS-CI-001-backend-ci-acceleration/CHUNK_MAP.md +++ b/.agent-loop/initiatives/WS-CI-001-backend-ci-acceleration/CHUNK_MAP.md @@ -2,9 +2,11 @@ | Chunk | Title | Risk | Status | |---|---|---:|---| -| `WS-CI-001-01` | Parallel Full-Suite Coverage | L1 | Implemented and internally reviewed; awaiting hosted PR proof/human review | +| `WS-CI-001-01` | Parallel Full-Suite Coverage | L1 | Completed and merged in PR #163 | +| `WS-CI-001-01R1` | Timeout Cleanup Repair | L1 | Implemented and internally reviewed; awaiting hosted repair PR proof/human review | | `WS-CI-001-02` | Safe Routing, Cache, and Timing Refinement | L1 | Future; not started and requires separate approval | Each chunk maps to one PR. Chunk 01 preserves the full suite and every coverage -gate. Chunk 02 may be planned only from measured 01 evidence and cannot be named -as 01's successor unless its reviewed contract is complete. +gate. Chunk 01R1 is the bounded post-merge response to CodeRabbit's timeout +cleanup finding. Chunk 02 may be planned only from measured 01 evidence and +cannot be activated without separate human approval. diff --git a/.agent-loop/initiatives/WS-CI-001-backend-ci-acceleration/STATUS.md b/.agent-loop/initiatives/WS-CI-001-backend-ci-acceleration/STATUS.md index f52a98e5..08d75b0c 100644 --- a/.agent-loop/initiatives/WS-CI-001-backend-ci-acceleration/STATUS.md +++ b/.agent-loop/initiatives/WS-CI-001-backend-ci-acceleration/STATUS.md @@ -1,9 +1,9 @@ # STATUS: WS-CI-001 - Backend CI Acceleration -- Phase: implementation proof complete; awaiting human PR review -- Active implementation chunk: `WS-CI-001-01` +- Phase: post-merge timeout cleanup repair +- Active implementation chunk: `WS-CI-001-01R1` - Proposed first chunk: `WS-CI-001-01` - Human direction: prioritize full-suite CI acceleration before `WS-ENG-001-04B` -- Current gate: final evidence-only exact-head CI and human PR review +- Current gate: exact rebased-head review, repair PR CI, and human review - `WS-ENG-001-04B`: remains inactive diff --git a/.agent-loop/initiatives/WS-CI-001-backend-ci-acceleration/chunks/WS-CI-001-01R1-timeout-cleanup.md b/.agent-loop/initiatives/WS-CI-001-backend-ci-acceleration/chunks/WS-CI-001-01R1-timeout-cleanup.md new file mode 100644 index 00000000..1f587d86 --- /dev/null +++ b/.agent-loop/initiatives/WS-CI-001-backend-ci-acceleration/chunks/WS-CI-001-01R1-timeout-cleanup.md @@ -0,0 +1,84 @@ +# Chunk Contract: WS-CI-001-01R1 — Timeout Cleanup Repair + +## Parent initiative + +`WS-CI-001` — Backend CI Acceleration + +## Goal + +Ensure repository-owned isolated runners time out before their enclosing GitHub +jobs so they retain operational headroom to terminate child processes and clean +up exact owned database resources. + +## Why this chunk exists + +PR #163 merged before its final CodeRabbit comment was repaired. The comment +correctly identified child timeouts longer than their enclosing job budgets. + +## Risk class + +L1 + +## Allowed files + +```text +.github/workflows/backend.yml +backend/scripts/ci_test_shards.py +scripts/test_agent_gates.py +.agent-loop/initiatives/WS-CI-001-backend-ci-acceleration/** +.agent-loop/merge-intents/WS-CI-001-01R1.json +``` + +## Not allowed + +```text +backend/app/** +backend/alembic/** +dependency changes +test skips or coverage threshold changes +job timeout increases +path-based workflow suppression +WS-CI-001-02 activation +``` + +## Acceptance criteria + +- [x] Shard child timeout is below the 90-minute job budget with a configured + gap of at least 10 minutes. +- [x] API E2E child timeout is below the 30-minute job budget with a configured + gap of at least 5 minutes. +- [x] Workflow regression tests bind the timeout values and budget gaps. +- [x] Real isolated-runner cleanup tests pass against PostgreSQL. +- [x] External review response and PR trust evidence are updated. +- [x] Required internal reviewers confirm the exact rebased repair head. +- [ ] Hosted Backend, Agent Gates, and external review pass. + +## Verification commands + +```text +cd backend && python -m pytest -q tests/test_ci_test_shards.py tests/test_coverage_contract.py +cd backend && WORKSTREAM_TEST_ADMIN_DATABASE_URL= python -m pytest -q tests/test_isolated_database_runner.py +python -m pytest -q scripts/test_agent_gates.py +python scripts/check_markdown_links.py +python scripts/check_stale_workstream_wording.py +python scripts/check_loop_memory_state.py +git diff --check +``` + +## Required reviewers + +- senior engineering +- QA/test +- security/auth +- product/ops +- architecture +- CI integrity +- docs +- reuse/dedup +- test delta + +## Human review focus + +Confirm the child budgets remain operationally sufficient, are strictly below +the job budgets, and preserve cleanup and failure propagation without weakening +the full-suite proof. diff --git a/.agent-loop/initiatives/WS-CI-001-backend-ci-acceleration/reviews/WS-CI-001-01R1-external-review-response.md b/.agent-loop/initiatives/WS-CI-001-backend-ci-acceleration/reviews/WS-CI-001-01R1-external-review-response.md new file mode 100644 index 00000000..41337a56 --- /dev/null +++ b/.agent-loop/initiatives/WS-CI-001-backend-ci-acceleration/reviews/WS-CI-001-01R1-external-review-response.md @@ -0,0 +1,38 @@ +# External Review Response: WS-CI-001-01R1 + +## Comments addressed + +- CodeRabbit major stability finding on PR #163: the isolated child-runner + timeout exceeded its enclosing GitHub job timeout for both shard execution + and API E2E. +- Shard child timeout is now 4,800 seconds inside a 90-minute job, preserving a + 10-minute configured budget gap and operational cleanup headroom. +- API E2E child timeout is now 1,500 seconds inside a 30-minute job, preserving + a 5-minute configured budget gap and operational cleanup headroom. +- Workflow regression tests assert both child timeouts remain below their job + budgets. + +## Comments deferred + +None. + +## Human decisions needed + +None. The finding is a clear in-scope cleanup and failure-propagation defect. + +## Commands rerun + +- Ruff formatting and lint: passed. +- Shard and coverage-contract tests: 204 passed. +- Isolated database runner against local PostgreSQL: 16 passed. +- Agent-gate workflow tests: 91 passed. +- Markdown links, stale wording, loop-memory state, and diff integrity: passed. +- Required internal review: all nine tracks passed the rebased repair; senior, + architecture, docs, and reuse/dedup then confirmed the chunk-map repair. + +## Remaining risks + +GitHub may still terminate a runner for infrastructure reasons, but configured +test timeouts now leave operational headroom for the repository-owned isolation +runner to terminate its child and drop its exact owned database and role. The +configured gaps are not guarantees because job setup also consumes wall time. diff --git a/.agent-loop/initiatives/WS-CI-001-backend-ci-acceleration/reviews/WS-CI-001-01R1-internal-review-evidence.md b/.agent-loop/initiatives/WS-CI-001-backend-ci-acceleration/reviews/WS-CI-001-01R1-internal-review-evidence.md new file mode 100644 index 00000000..7761e272 --- /dev/null +++ b/.agent-loop/initiatives/WS-CI-001-backend-ci-acceleration/reviews/WS-CI-001-01R1-internal-review-evidence.md @@ -0,0 +1,69 @@ +# Internal Review Evidence: WS-CI-001-01R1 + +Open sub-agent sessions: none + +Valid findings addressed: yes + +Reviewed code SHA: `5ec228960392cb87cf35852392ba25971a991f6f` + +Reviewed at: 2026-07-20T18:28:58Z + +Reviewer run IDs: senior-engineering/architecture/docs/reuse-dedup=`timeout_senior_docs`; QA/test/CI-integrity/test-delta=`timeout_ci_qa`; security/auth/product/ops=`timeout_sec_ops` + +Final evidence head: `5ec228960392cb87cf35852392ba25971a991f6f` + +## Binding + +- Base: `b0f9ad6476bb836a99c0adac7073705eb5206f4c` +- Contract: `WS-CI-001-01R1 — Timeout Cleanup Repair` +- Scope: two child-timeout reductions, workflow regression assertions, and + bounded R1 process evidence; no backend product runtime change + +## Reviewer results + +| Reviewer | Result | Blocking findings | Notes | +|---|---|---|---| +| senior engineering | PASS | None | Minimal repair with operationally sufficient observed runtime headroom. | +| QA/test | PASS | None | Values and minimum configured gaps are regression-bound. | +| security/auth | PASS | None | Cleanup remains exact; no auth, secret, or permission change. | +| product/ops | PASS | None | Operational headroom is distinguished from guaranteed cleanup duration. | +| architecture | PASS AFTER FIXES | None | R1 was added to the durable chunk map after PR #163 merge state was corrected. | +| CI integrity | PASS | None | No threshold, selection, required-check, or propagation weakening. | +| docs | PASS AFTER FIXES | None | Contract, chunk map, external response, and trust bundle agree. | +| reuse/dedup | PASS | None | Existing runner and workflow test boundary were reused. | +| test delta | PASS | None | One assertion set strengthened; no tests removed or skipped. | + +## Findings repaired + +- CodeRabbit found shard/API child timeouts exceeding their GitHub job budgets. +- Reduced shard child timeout from 12,600 to 4,800 seconds within 90 minutes. +- Reduced API child timeout from 3,600 to 1,500 seconds within 30 minutes. +- Added assertions binding both values and configured 600/300-second gaps. +- After PR #163 merged, rebased the repair onto trusted `main`, created bounded + R1 artifacts and exactly one merge intent, and corrected the chunk map. +- Clarified that configured gaps provide operational headroom but are not + guaranteed cleanup durations because setup consumes job time. + +## Deterministic evidence + +```text +Ruff formatting and lint: passed +shard + coverage-contract tests: 204 passed +isolated database runner against PostgreSQL: 16 passed +agent-gate workflow tests: 91 passed +Markdown links: passed +stale wording: passed +loop-memory state: passed +git diff --check: passed +``` + +## Hosted evidence + +Initial repair PR #164 runs `29767792824` and `29767792536` failed fast because +this R1-specific internal-review evidence file was missing. No shard ran. This +file repairs that process-evidence gate; exact-head hosted rerun remains pending. + +## Remaining gate + +Hosted Backend, Agent Gates, CodeRabbit, human review, and explicit merge +approval remain mandatory. diff --git a/.agent-loop/initiatives/WS-CI-001-backend-ci-acceleration/reviews/WS-CI-001-01R1-pr-trust-bundle.md b/.agent-loop/initiatives/WS-CI-001-backend-ci-acceleration/reviews/WS-CI-001-01R1-pr-trust-bundle.md new file mode 100644 index 00000000..0cf3014d --- /dev/null +++ b/.agent-loop/initiatives/WS-CI-001-backend-ci-acceleration/reviews/WS-CI-001-01R1-pr-trust-bundle.md @@ -0,0 +1,53 @@ +# WS-CI-001-01R1 PR Trust Bundle + +## Goal + +Repair the merged backend CI workflow so isolated child-runner timeouts remain +below GitHub job budgets and cleanup can run before hard cancellation. + +## Trigger + +CodeRabbit posted one valid major stability finding on PR #163 after its final +review cycle. PR #163 was merged before the repair commits were pushed, so this +bounded follow-up is based on trusted merged `main` and has its own merge intent. + +## What changed + +- Shard child timeout: 12,600 seconds to 4,800 seconds inside a 90-minute job. +- API E2E child timeout: 3,600 seconds to 1,500 seconds inside a 30-minute job. +- Agent-gate assertions bind both values and minimum configured budget gaps. +- External review evidence records the finding, response, proof, and residual + infrastructure risk. + +These gaps provide operational cleanup headroom but are not guaranteed cleanup +durations because checkout, installation, and migration also consume job time. + +## Scope control + +No application code, schema, dependency, test selection, coverage threshold, +required check, permission, authentication, authorization, product lifecycle, +or merge authority changed. `WS-CI-001-02` remains inactive. + +## Evidence + +- Ruff formatting and lint passed. +- Shard and coverage-contract tests: 204 passed. +- Real PostgreSQL isolation and cleanup tests: 16 passed. +- Agent-gate workflow tests: 91 passed. +- Markdown links, stale wording, loop state, and diff integrity passed. + +## Internal review + +All nine tracks passed the rebased repair. Senior engineering, architecture, +docs, and reuse/dedup then confirmed the valid chunk-map repair. + +## Remaining gates + +Hosted Backend, Agent Gates, CodeRabbit, human review, and explicit merge +approval remain mandatory. + +## Human review focus + +Confirm timeout values remain sufficient for observed workloads, strictly below +job budgets, and preserve child termination, database cleanup, and fail-closed +propagation. diff --git a/.agent-loop/merge-intents/WS-CI-001-01R1.json b/.agent-loop/merge-intents/WS-CI-001-01R1.json new file mode 100644 index 00000000..3d7bcb5d --- /dev/null +++ b/.agent-loop/merge-intents/WS-CI-001-01R1.json @@ -0,0 +1,9 @@ +{ + "chunk_id": "WS-CI-001-01R1", + "chunk_title": "Timeout Cleanup Repair", + "initiative_id": "WS-CI-001", + "next_chunk_id": null, + "next_chunk_title": null, + "next_requires_explicit_start": true, + "schema_version": 2 +} diff --git a/.github/workflows/backend.yml b/.github/workflows/backend.yml index 5adced8a..3b5c50af 100644 --- a/.github/workflows/backend.yml +++ b/.github/workflows/backend.yml @@ -228,7 +228,7 @@ jobs: run: >- python scripts/run_isolated_tests.py --metadata-json "${RUNNER_TEMP}/api-database.json" - --timeout-seconds 3600 + --timeout-seconds 1500 -- python scripts/api_contract_e2e.py test: diff --git a/backend/scripts/ci_test_shards.py b/backend/scripts/ci_test_shards.py index 50974a33..601f5c61 100644 --- a/backend/scripts/ci_test_shards.py +++ b/backend/scripts/ci_test_shards.py @@ -386,7 +386,7 @@ def run_shard( "--metadata-json", str(database_metadata), "--timeout-seconds", - "12600", + "4800", "--", sys.executable, "-m", diff --git a/scripts/test_agent_gates.py b/scripts/test_agent_gates.py index 11dbeee6..35310554 100644 --- a/scripts/test_agent_gates.py +++ b/scripts/test_agent_gates.py @@ -103,7 +103,7 @@ 'metadata_dir="$(mktemp -d)"', "trap 'rm -rf \"$metadata_dir\"' EXIT", "python scripts/run_isolated_tests.py " - '--metadata-json "$metadata_dir/result.json" --timeout-seconds 12600 -- ' + '--metadata-json "$metadata_dir/result.json" --timeout-seconds 4800 -- ' "python -m pytest -q --ignore=tests/test_isolated_database_runner.py " "--cov=app --cov-report=term-missing --cov-fail-under=78", ) @@ -113,7 +113,7 @@ 'metadata_dir="$(mktemp -d)"', "trap 'rm -rf \"$metadata_dir\"' EXIT", "python scripts/run_isolated_tests.py " - '--metadata-json "$metadata_dir/result.json" --timeout-seconds 3600 -- ' + '--metadata-json "$metadata_dir/result.json" --timeout-seconds 1500 -- ' "python scripts/api_contract_e2e.py", ) ) @@ -5258,6 +5258,11 @@ def test_backend_coverage_thresholds_are_regression_protected() -> None: assert len(api_e2e_steps) == 1 assert "scripts/run_isolated_tests.py" in str(api_e2e_steps[0]["run"]) assert "scripts/api_contract_e2e.py" in str(api_e2e_steps[0]["run"]) + shard_tool = (ROOT / "backend/scripts/ci_test_shards.py").read_text(encoding="utf-8") + assert 4800 <= jobs["shards"]["timeout-minutes"] * 60 - 600 + assert '"4800"' in shard_tool + assert 1500 <= jobs["api_e2e"]["timeout-minutes"] * 60 - 300 + assert "--timeout-seconds 1500" in str(api_e2e_steps[0]["run"]) test_job = parsed_workflow["jobs"]["test"] assert set(test_job) == {"if", "needs", "runs-on", "timeout-minutes", "steps"}