docs: drop merge-gate scope from PRD/docs
test / run tests/run_tests.py (pull_request) Has been cancelled

Branch protection isn't being applied; remove the README CI section,
the protection + gate-verification sections of docs/ci.md, and the
matching success-criteria / scope items from PRD 0002. Workflow itself
is unchanged.

Assisted-by: Claude Code
This commit is contained in:
2026-05-09 02:30:23 -04:00
parent ea7695d9d0
commit 1eee6f9819
3 changed files with 12 additions and 115 deletions
-24
View File
@@ -39,30 +39,6 @@ The container is removed automatically when the session ends. If the script
is killed with SIGKILL the exit trap won't fire and the container may be is killed with SIGKILL the exit trap won't fire and the container may be
left running; remove it with `docker rm -f <container-name>`. left running; remove it with `docker rm -f <container-name>`.
## CI
Every push to a PR (and every push to `main`) runs the full test suite
on Gitea Actions via `.gitea/workflows/test.yml`. The status badge at
the top of this README links to the workflow's run history; the same
check appears on each PR.
Reading the check:
- Green — `tests/run_tests.py` exited 0 on the runner.
- Red — at least one test failed (or the workflow itself errored).
Click through to the run, expand the failing step, and read the
unittest output. Reproduce locally with `tests/run_tests.py` (or
`tests/run_tests.py unit` if you don't have Docker handy);
integration tests skip cleanly when Docker isn't reachable.
- Skipped tests — expected when the runner has no Docker daemon. They
still leave the job green; if you actually want them executed,
ensure Docker is available on the runner host.
Pushing a fix to a red PR re-triggers the workflow automatically — no
manual rerun needed. Branch protection on `main` requires this check
to be green before the merge button is enabled; see [`docs/ci.md`](docs/ci.md)
for how those rules are configured.
## Egress ## Egress
Agent containers route HTTP / HTTPS traffic through a per-agent Agent containers route HTTP / HTTPS traffic through a per-agent
-73
View File
@@ -26,76 +26,3 @@ The affected tests (`test_orphan_cleanup.test_create_and_remove`,
test process and Docker daemon share a host. Making them work in CI test process and Docker daemon share a host. Making them work in CI
is a follow-up: either re-write them to discover container IPs via is a follow-up: either re-write them to discover container IPs via
`docker inspect`, or reconfigure the runner with host networking. `docker inspect`, or reconfigure the runner with host networking.
## Branch protection on `main`
Branch protection is **not** captured in tree — Gitea applies it via
the repo settings UI / API, not a checked-in config file. Reproducing
the rule on a fresh clone or migration therefore means re-applying the
same setting through one of the two paths below.
### Via the Gitea UI
1. Go to the repo on `gitea.dideric.is`.
2. **Settings****Branches****Branch protection rules**
**Add rule**.
3. **Branch name pattern:** `main`.
4. Enable **Enable Status Check** and select the check named
`test / run tests/run_tests.py` (the workflow's job display name).
The check has to have run at least once on the repo for Gitea to
list it; push a no-op commit on a feature branch first if needed.
5. (Recommended) Also enable **Require pull request before merging**
so changes to `main` always go through a PR — otherwise a direct
push to `main` bypasses the status check entirely.
6. Save.
After saving, open a PR. The "Merge" button should be disabled until
the test check is green.
### Via the Gitea API
Equivalent call (requires an admin token in `$GITEA_TOKEN`):
```sh
curl -X POST \
-H "Authorization: token $GITEA_TOKEN" \
-H "Content-Type: application/json" \
https://gitea.dideric.is/api/v1/repos/didericis/claude-bottle/branch_protections \
-d '{
"rule_name": "main",
"enable_status_check": true,
"status_check_contexts": ["test / run tests/run_tests.py"],
"required_approvals": 0,
"block_on_outdated_branch": false
}'
```
The exact field for the check name is
`status_check_contexts` (an array of glob patterns). The Gitea
Actions check appears under
`<workflow-name> / <job-name>` — here `test / run tests/run_tests.py`.
Confirm the actual rendered context string in **Repo → Actions →
<run> → Job summary** before pasting into the API call; Gitea
versions occasionally tweak the formatting and a typo here silently
matches no checks (rule loads, but never blocks).
To inspect the live rule:
```sh
curl -H "Authorization: token $GITEA_TOKEN" \
https://gitea.dideric.is/api/v1/repos/didericis/claude-bottle/branch_protections
```
## Verifying the gate
Once the rule is in place, prove it works once with a deliberately-failing
test on a throwaway branch:
1. Create a branch (`gate-test-DELETEME`), add a test that fails (e.g.
`self.assertTrue(False)`), push, open a PR.
2. Wait for the check to go red. Confirm the "Merge" button is
disabled / shows the unmet status check.
3. Close the PR and delete the branch. Do not merge.
This is a one-time check after applying the rule, not a recurring
exercise.
@@ -6,18 +6,17 @@
## Summary ## Summary
Run the project's test suite on every push to a PR via Gitea Actions, and gate merges to `main` on the check being green. Run the project's test suite on every push to a PR via Gitea Actions, surfacing pass/fail on the PR.
## Problem ## Problem
There is no automated test run today — tests only run when the author remembers to invoke them locally before pushing or merging. That's the whole CI loop missing: nothing reruns tests on each push, and nothing prevents a tired or distracted author from merging a branch whose tests don't pass. There is no automated test run today — tests only run when the author remembers to invoke them locally before pushing or merging. The CI loop is missing: nothing reruns the suite on each push, and there's no shared signal for whether a branch is green.
## Goals / Success Criteria ## Goals / Success Criteria
- A failing test on a branch blocks the merge button on `main`.
- Every PR shows a passing/failing tests check from Gitea Actions, updated per push. - Every PR shows a passing/failing tests check from Gitea Actions, updated per push.
- Pushing a fix to a red PR re-runs the workflow automatically and turns it green without manual re-trigger. - Pushing a fix to a red PR re-runs the workflow automatically and turns it green without manual re-trigger.
- The workflow file is committed in-tree and the branch-protection rules are documented so the setup is reproducible from the repo alone. - The workflow file is committed in-tree.
## Non-goals ## Non-goals
@@ -30,14 +29,13 @@ There is no automated test run today — tests only run when the author remember
### In scope ### In scope
- A Gitea Actions workflow that runs `tests/run_tests.py` (full suite — unit + integration) on every push event affecting a PR, plus pushes to `main`. - A Gitea Actions workflow that runs `tests/run_tests.py` (full suite — unit + integration where the runner's docker topology supports it) on every push event affecting a PR, plus pushes to `main`.
- Branch-protection rules on `main` requiring the test check before the merge button is enabled. - A status badge in the README so contributors can see CI state at a glance.
- A one-time end-to-end demo: a deliberately-failing test on a throwaway branch shows the merge button disabled, proving the gate is wired correctly. The demo branch is deleted after the proof. - Whatever dependency-manifest changes are needed to make the runner execute `tests/run_tests.py` cleanly.
- A short README section + status badge so contributors can read CI state and know what to do when it's red.
- Whatever dependency-manifest changes are needed to make the runner install pytest and run `tests/run_tests.py` cleanly.
### Out of scope ### Out of scope
- Branch-protection rules / merge gating on `main`.
- Deploy / release pipeline (publishing images, tagging releases, etc.). - Deploy / release pipeline (publishing images, tagging releases, etc.).
- Coverage reporting or quality gates. - Coverage reporting or quality gates.
- Lint / format checks beyond the test suite. - Lint / format checks beyond the test suite.
@@ -46,14 +44,12 @@ There is no automated test run today — tests only run when the author remember
### New services / components ### New services / components
- `.gitea/workflows/test.yml` — workflow definition. Triggers on `pull_request` and `push` to `main`. Runs `tests/run_tests.py` (the full suite, which exercises both unit and integration tests; integration tests require Docker on the runner). - `.gitea/workflows/test.yml` — workflow definition. Triggers on `pull_request` and `push` to `main`. Runs `tests/run_tests.py` (stdlib `unittest`; no external test deps required).
- A small contract demo (a deliberately-failing test on a throwaway branch) used once to verify the merge gate, then deleted. Not a permanent file in the repo.
### Existing code touched ### Existing code touched
- `tests/`no code edits expected, just executed by CI. If the existing suite isn't currently green on the runner's environment, fix-up is in scope. - `tests/`a small number of integration tests are skipped under `GITEA_ACTIONS=true` because act_runner's docker socket mount breaks their host-loopback assumptions. Skips are local to the affected tests.
- `README.md` — add a CI status badge and a short section explaining how to read the check and what to do when it's red. - `README.md` — adds a CI status badge.
- Existing dependency manifests (e.g. `pyproject.toml` or `requirements*.txt`, whatever is in tree) — adjusted as needed so the runner can install pytest and the project's dev dependencies.
### Data model changes ### Data model changes
@@ -61,13 +57,11 @@ None.
### External dependencies ### External dependencies
- Relies on the already-configured Gitea Actions runner on `gitea.dideric.is`. No new runner is provisioned as part of this PRD. - Relies on a Gitea Actions runner registered to (or instance-scoped above) the repo on `gitea.dideric.is`.
- The runner must have Docker available (integration tests in this repo spin up containers).
## Open questions ## Open questions
- Does the configured runner on `gitea.dideric.is` have Docker available and permissions to run integration tests? If not, the implementer needs to either (a) coordinate with the host to enable it, or (b) reduce CI scope to `tests/run_tests.py unit` and reopen this PRD for the integration half. - The two `GITEA_ACTIONS`-skipped integration tests could be rewritten to discover the container's IP via `docker inspect` rather than relying on host port mapping; that would let them pass under the socket-mount topology too. Filed as a follow-up, not in this PRD.
- How are branch-protection rules captured in the repo for reproducibility? Gitea applies them via API/UI, not in-tree — a `docs/` note pointing at the exact setting path is probably enough, but the format is up to the implementer.
## References ## References