137 lines
4.4 KiB
Markdown
137 lines
4.4 KiB
Markdown
# Verify Done — Confirming Task Completion
|
|||
|
|
|
||
|
|
## Principle
|
||
|
|
A task is NOT done until it's verified with real data against the real service. Code review + CI green is necessary but not sufficient.
|
||
|
|
|
||
|
|
## Definition of Done Checklist
|
||
|
|
1. **Code compiles** — `cargo build` / `go build` passes with no errors
|
||
|
|
2. **Tests pass** — `cargo test` / `go test ./...` all green
|
||
|
|
3. **CI green** — `tea actions runs list` shows latest run succeeded
|
||
|
|
4. **API accessible** — `curl` the endpoint, get expected response
|
||
|
|
5. **Auth works** — requests without token return 401, with token return 200
|
||
|
|
6. **Error paths tested** — bad input returns proper error codes
|
||
|
|
7. **Deployed** — ArgoCD synced, pod running, ingress reachable
|
||
|
|
8. **Documented** — endpoint added to API docs or CLAUDE.md
|
||
|
|
|
||
|
|
## Verification Flow
|
||
|
|
```
|
||
|
|
Code change → Push → CI passes → ArgoCD deploys → curl test → Done
|
||
|
|
↓
|
||
|
|
If fails → fix → repeat
|
||
|
|
```
|
||
|
|
|
||
|
|
## API Endpoint Verification Template
|
||
|
|
For every new or changed endpoint, run:
|
||
|
|
```bash
|
||
|
|
ENDPOINT="https://api.riotpiao.com"
|
||
|
|
|
||
|
|
# 1. Is it alive?
|
||
|
|
curl -s -o /dev/null -w "%{http_code}" $ENDPOINT/health
|
||
|
|
# Expect: 200
|
||
|
|
|
||
|
|
# 2. Does the new endpoint exist?
|
||
|
|
curl -s -o /dev/null -w "%{http_code}" $ENDPOINT/new-endpoint
|
||
|
|
# Expect: NOT 404
|
||
|
|
|
||
|
|
# 3. Does auth gate work?
|
||
|
|
curl -s -o /dev/null -w "%{http_code}" $ENDPOINT/new-endpoint
|
||
|
|
# Expect: 401 (no token)
|
||
|
|
|
||
|
|
# 4. Does it return correct data?
|
||
|
|
curl -s -H "Authorization: Bearer $TOKEN" $ENDPOINT/new-endpoint | jq .
|
||
|
|
# Expect: meaningful JSON response
|
||
|
|
|
||
|
|
# 5. Does it handle bad input?
|
||
|
|
curl -s -o /dev/null -w "%{http_code}" -X POST $ENDPOINT/new-endpoint \
|
||
|
|
-H "Content-Type: application/json" -d '{}'
|
||
|
|
# Expect: 400
|
||
|
|
```
|
||
|
|
|
||
|
|
## CI Verification
|
||
|
|
```bash
|
||
|
|
# Check last CI run status
|
||
|
|
tea actions runs list --repo rock/poimen-memory --limit 1
|
||
|
|
|
||
|
|
# If failed, check logs
|
||
|
|
tea actions runs view <run-id> --repo rock/poimen-memory
|
||
|
|
|
||
|
|
# Check if ArgoCD synced
|
||
|
|
kubectl get application -n argocd poimen-memory-app -o jsonpath='{.status.sync.status}'
|
||
|
|
# Expect: Synced
|
||
|
|
|
||
|
|
# Check pod health
|
||
|
|
kubectl get pods -n poimen | grep poimen-memory
|
||
|
|
# Expect: Running, no restarts
|
||
|
|
```
|
||
|
|
|
||
|
|
## Deployment Verification
|
||
|
|
```bash
|
||
|
|
# Pod running and ready
|
||
|
|
kubectl get pods -n poimen -l app.kubernetes.io/name=poimen-memory
|
||
|
|
# Expect: 1/1 Running
|
||
|
|
|
||
|
|
# Service reachable internally
|
||
|
|
kubectl exec -n poimen deploy/poimen-memory -- curl -s http://localhost:8080/health
|
||
|
|
|
||
|
|
# Ingress reachable externally
|
||
|
|
curl -sk https://api.riotpiao.com/health
|
||
|
|
|
||
|
|
# Logs clean (no panics, no errors on startup)
|
||
|
|
kubectl logs -n poimen deploy/poimen-memory --tail=20
|
||
|
|
```
|
||
|
|
|
||
|
|
## Git Commit Verification
|
||
|
|
Before pushing, confirm:
|
||
|
|
```bash
|
||
|
|
# Commit message follows conventional commits
|
||
|
|
git log -1 --oneline
|
||
|
|
# Expect: feat: / fix: / docs: / refactor: prefix
|
||
|
|
|
||
|
|
# No secrets in diff
|
||
|
|
git diff --cached | grep -iE "password|secret|token|api_key"
|
||
|
|
# Expect: empty (no matches)
|
||
|
|
|
||
|
|
# No .env or key files staged
|
||
|
|
git diff --cached --name-only | grep -iE "\.env|\.key|\.pem"
|
||
|
|
# Expect: empty
|
||
|
|
```
|
||
|
|
|
||
|
|
## Memory System Specific Verification
|
||
|
|
```bash
|
||
|
|
# After ingest changes
|
||
|
|
curl -s -X POST https://api.riotpiao.com/memory/ingest \
|
||
|
|
-H "Authorization: Bearer $TOKEN" \
|
||
|
|
-H "Content-Type: application/json" \
|
||
|
|
-d '{"project":"test","text":"verify ingest","kind":"L1"}' | jq .
|
||
|
|
# Expect: 201 with chunk ID
|
||
|
|
|
||
|
|
# After query changes
|
||
|
|
curl -s -X POST https://api.riotpiao.com/memory/query \
|
||
|
|
-H "Authorization: Bearer $TOKEN" \
|
||
|
|
-H "Content-Type: application/json" \
|
||
|
|
-d '{"project":"test","query":"verify"}' | jq .
|
||
|
|
# Expect: 200 with results array
|
||
|
|
|
||
|
|
# After context endpoint changes
|
||
|
|
curl -s -X POST https://api.riotpiao.com/memory/context \
|
||
|
|
-H "Authorization: Bearer $TOKEN" \
|
||
|
|
-H "Content-Type: application/json" \
|
||
|
|
-d '{"project":"test","tool":"cargo","task":"build"}' | jq .
|
||
|
|
# Expect: 200 with tier, lessons, budget
|
||
|
|
|
||
|
|
# After rebuild changes
|
||
|
|
curl -s -X POST https://api.riotpiao.com/memory/rebuild \
|
||
|
|
-H "Authorization: Bearer $TOKEN" \
|
||
|
|
-H "Content-Type: application/json" \
|
||
|
|
-d '{"project":"test","dry_run":true}' | jq .
|
||
|
|
# Expect: 200 with records_processed count
|
||
|
|
```
|
||
|
|
|
||
|
|
## Anti-Patterns
|
||
|
|
- ❌ "CI passed so it's done" — CI doesn't test the real deployment
|
||
|
|
- ❌ "It works on my machine" — must work in-cluster
|
||
|
|
- ❌ Marking done without curl-testing the endpoint
|
||
|
|
- ❌ Skipping error path testing (400, 401, 404, 429)
|
||
|
|
- ❌ Not checking ArgoCD sync status after push
|
||
|
|
- ❌ Trusting `kubectl apply` over ArgoCD (let ArgoCD manage state)
|