---
description: Pull master, read open issues, pick one, branch, implement, test, commit, PR, and comment.
---

# Solve a Gitea Issue

## Current repo state

```!
git status --short
echo "Current branch: $(git branch --show-current)"
echo "Remote: $(git remote get-url origin 2>/dev/null || echo 'none')"
```

## Open issues (with full body)

```!
echo "Fetching open issues..."
issue_ids=$(tea issues list --output simple 2>/dev/null | awk 'NF && $1 ~ /^[0-9]+$/ {print $1}')
if [ -z "$issue_ids" ]; then
  echo "No open issues found (or tea is not logged in)."
else
  for id in $issue_ids; do
    echo ""
    echo "══════════════════════════════════════"
    tea issues view "$id" --fields index,title,body 2>/dev/null \
      || tea issue "$id" 2>/dev/null \
      || echo "  (could not read issue #$id)"
    echo "══════════════════════════════════════"
  done
fi
```

---

## Your task

Follow these steps **in order**. Do not skip steps.

### 1 — Choose an issue

Present the issues above to the user as a numbered list (index, one-line title). Ask which one to work on. Wait for the answer before continuing.

### 2 — Sync master

```bash
git checkout master
git pull
```

Confirm you are on master and up to date.

### 3 — Create a branch

Name the branch `benvin/issue-<N>-<short-slug>` where `<short-slug>` is 2–4 kebab-case words from the issue title.

```bash
git checkout -b benvin/issue-<N>-<slug>
```

### 4 — Read the issue in full

Re-read the full issue body shown above. If any part is ambiguous, state your interpretation before coding.

**If you discover other problems while working:** do NOT solve them inline. Create a new Gitea issue with `tea issues create --title "..." --description "..."` and stay focused on the assigned issue.

### 5 — Implement the solution

Make the code changes needed to resolve the issue. Follow the conventions already in the repo:
- `main.py` route handlers each contain a single function call; logic lives in submodules.
- No comments unless the WHY is non-obvious.
- No new files unless the issue or architecture requires it.
- Security: no command injection, XSS, SQL injection, or secrets in code.
- **For performance improvements:** implement at the most generic call site possible so the fix applies to all current and future implementations, not just the one being tested.

### 6 — Update tests

Add or update tests that cover the new behaviour. Tests live in `tests/`. Check existing test structure before writing new ones — mirror the style and fixture patterns already in use.

### 7 — Update README

If the feature introduces new config keys, endpoints, or user-facing behaviour, document it in `README.md`. Keep additions concise — follow the existing section style.

### 8 — Run the full test suite

```bash
make test
```

All tests must pass. If any fail, fix them before proceeding. Do not skip or suppress failing tests.

### 9 — Live Docker test (new package type only)

**Skip this step if the issue does not add a new remote package type.**

If the issue adds a new package type (e.g. `deb`, `conda`, `cargo`, `rubygems`, or any type not already in `remotes.yaml`), do the following before committing.

#### 9a — Add a real test remote to remotes.yaml

Append a valid, publicly accessible remote of the new type to `remotes.yaml`. Use a real upstream URL and patterns that cover both an immutable file (versioned artifact) and a mutable file (index/metadata). Add a comment explaining which URLs to use for manual testing.

#### 9b — Start the stack

```bash
make docker-up
```

Wait until `curl -s http://localhost:8000/health` returns `{"status":"healthy"}`.

#### 9c — Test a mutable file (first fetch — cache miss)

Download the index or metadata file for the new remote. Confirm:
- HTTP 200
- `X-Artifact-Source: remote` header (or equivalent log line confirming a cache miss)
- Content looks correct (not empty, not an error page)

```bash
curl -sv "http://localhost:8000/api/v1/remote/<new-remote>/<mutable-path>" 2>&1 | grep -E "< HTTP|X-Artifact"
```

#### 9d — Test a mutable file (second fetch — cache hit)

Repeat the exact same request. Confirm:
- HTTP 200
- `X-Artifact-Source: cache`

```bash
curl -sv "http://localhost:8000/api/v1/remote/<new-remote>/<mutable-path>" 2>&1 | grep -E "< HTTP|X-Artifact"
```

#### 9e — Test an immutable file (first fetch — cache miss)

Download a versioned/immutable artifact. Confirm HTTP 200 and a cache-miss log line.

```bash
curl -sv "http://localhost:8000/api/v1/remote/<new-remote>/<immutable-path>" 2>&1 | grep -E "< HTTP|X-Artifact"
```

#### 9f — Test an immutable file (second fetch — cache hit)

Repeat. Confirm `X-Artifact-Source: cache`.

#### 9g — Check container logs

```bash
make docker-logs
```

Scan for:
- `Cache MISS` on first fetches, `Cache HIT` on second fetches
- `Cache ADD SUCCESS` with correct sizes
- No unhandled exceptions or ERROR lines

#### 9h — Exercise package-type tooling against the proxy

Use the native tooling for this package type to verify end-to-end behaviour. Examples:

| Package type | Command |
|---|---|
| `pypi` | `uv run --index-url http://localhost:8000/api/v1/remote/<remote>/simple <tool>` |
| `npm` | `npm install --registry http://localhost:8000/api/v1/remote/<remote>/ <pkg>` |
| `helm` | `helm repo add test http://localhost:8000/api/v1/remote/<remote> && helm search repo test && helm template test/<chart>` |
| `alpine` | `apk fetch --repository http://localhost:8000/api/v1/remote/<remote>/<branch>/<arch> <pkg>` |
| `rpm` | `dnf install --repofrompath ... <pkg>` or `repoquery` |
| `generic` | `curl` / `wget` as appropriate |

Confirm the tool resolves and downloads correctly through the proxy.

#### 9i — Tear down

```bash
make docker-down
```

Fix any failures found during 9b–9h before moving on.

### 9.5 — Performance issues: measure before/after and gate the PR

**Skip this step if the issue is not a performance improvement.**

For performance issues, a PR is only warranted if there is a measurable gain. Use the Docker stack to compare before and after.

#### 9.5a — Baseline measurement (before)

Start the stack with the **unmodified** code (temporarily revert your change):

```bash
make docker-up
```

Warm or clear the cache as appropriate, then measure the relevant metric — e.g. concurrent request latency during a slow operation, response time for a specific endpoint, or throughput. Record the numbers.

#### 9.5b — Apply your change and rebuild

```bash
make docker-up   # rebuilds the image
```

Repeat exactly the same measurement. Record the numbers.

#### 9.5c — Decide

If the improvement is not clearly measurable, **do not open a PR**. Instead:
1. Update the issue with your findings.
2. Note any conditions under which the improvement would be observable.
3. Skip steps 11–14.

If the improvement is clear, proceed with the commit and PR. Include the before/after numbers in the PR description and the issue comment.

#### 9.5d — Tear down

```bash
make docker-down
```

### 10 — Build the wheel (smoke check)

```bash
uv build --wheel
```

Confirm the build succeeds.

### 11 — Stage and commit

Stage only the files you changed. Do not use `git add -A` or `git add .` — list files explicitly. Run:

```bash
git add <file1> <file2> ...
git commit
```

The commit message must:
- Start with a conventional-commit prefix (`feat:`, `fix:`, `refactor:`, `chore:`, etc.)
- Summarise the change in ≤ 72 characters on the first line
- Optionally include a short body explaining *why* (not *what*)

If the pre-commit hook auto-fixes files, re-stage the fixed files and commit again.

### 12 — Push the branch

```bash
git push origin <branch-name>
```

### 13 — Open a pull request

```bash
tea pulls create \
  --base master \
  --head <branch-name> \
  --title "<same as commit subject>" \
  --description "Closes #<N>\n\n## Summary\n<bullet points>\n\n## Test plan\n<what was verified>"
```

### 14 — Comment on the issue

```bash
tea comment <N> "<resolution comment>"
```

The comment must cover:
- **How it was resolved** — what changed and why
- **Issues encountered** — any non-obvious problems hit during implementation
- **Potential future improvements** — what could be done next

### 15 — Return to master

```bash
git checkout master
```

Report the PR URL and a one-sentence summary to the user.
