docs: Update handover and add lessons learned

- Update HANDOVER.md with AI agent skill section, API gotchas, session log
- Add lessons-learned.md with Gitea API findings and debugging insights

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-18 14:01:38 +01:00
parent 1637782273
commit de9f6bc3ff
2 changed files with 150 additions and 0 deletions
+65
View File
@@ -0,0 +1,65 @@
# Lessons Learned
## Session: 2026-02-18 -- Gitea Agent Skill Implementation
### Technical Discoveries
1. **Gitea 1.22.6 has no project board REST API**
- `/api/v1/user/projects` returns 404
- The existing SKILL.md had endpoints that do not exist
- Project board API is tracked in Gitea issue #14299, targeted for 1.26+
- **Mitigation:** Use milestones as project containers -- they have built-in progress tracking
2. **Scoped label exclusivity is UI-only in Gitea 1.22.6**
- Labels with `exclusive: true` display mutual exclusivity in the web UI
- The API `POST /repos/{owner}/{repo}/issues/{index}/labels` only appends -- it does NOT remove conflicting scoped labels
- **Fix:** Use a swap pattern: GET current labels, filter out old scope, add new label ID, PUT full set atomically
- This was the single biggest "gotcha" -- the documentation implies API enforcement that does not exist
3. **POST /issues/{index}/assignees does not exist in Gitea 1.22.6**
- Returns 404
- **Fix:** Use `PATCH /repos/{owner}/{repo}/issues/{index}` with `{"assignees": ["username"]}`
- This is a general issue edit endpoint, not a dedicated assignee endpoint
4. **Issue dependency format is IssueMeta, not simple ID**
- Wrong: `{"depends_on_id": 2}` -- returns "repository does not exist [id: 0]"
- Correct: `{"owner": "terraphim", "repo": "agent-tasks", "index": 2}`
- Must check the Swagger spec for exact body format rather than guessing
### Debugging Approaches That Worked
1. **Test against live API first, then write code**
- Verified all 7 open questions against the live Gitea instance before writing any helper functions
- This caught the project board API gap before writing fake endpoints
2. **Integration tests with real cleanup**
- Each test run creates a timestamped repo (`skill-test-{timestamp}`), runs all tests, then deletes it
- Trap on EXIT ensures cleanup even on failure
- No mocks -- tests prove the actual API behavior
3. **Incremental testing (run, fail, fix, rerun)**
- First test run: 23/26 pass, 3 fail -- immediately identified the label/assignee issues
- Fixed the swap pattern and PATCH approach, second run: 26/26 pass
### Pitfalls to Avoid
1. **Do not trust Gitea documentation for API behavior** -- always verify against the live instance. The swagger spec is the source of truth, but even that can be misleading for edge cases like scoped label exclusivity.
2. **Do not assume POST endpoints exist for every resource subpath** -- Gitea's API is inconsistent. Some resources (labels) have POST, others (assignees) only work via PATCH on the parent resource.
3. **Do not rely on UBS scanner for infrastructure projects** -- UBS found no scannable language files (expected for a project with only shell scripts, YAML, and markdown). Pre-commit hooks are more useful here.
4. **Pre-commit python version** -- The system may not have the Python version specified in `.pre-commit-config.yaml`. Changed from `python3.9` to `python3.12` to match the system. Also needed `python3.12-venv` apt package for virtualenv support.
### Best Practices Discovered
1. **Disciplined development phases work well for API integration**
- Phase 1 (Research): Discovered the project board API gap before design
- Phase 2 (Design): Created the label swap architecture before implementation
- Phase 3 (Implementation): Tests caught 3 API bugs on first run
2. **Default repository pattern** -- Using env vars with defaults (`GITEA_OWNER=${GITEA_OWNER:-terraphim}`) lets agents work out of the box while remaining configurable.
3. **JSON output from all helpers** -- Every shell function outputs valid JSON, making it trivial for agents to parse results with jq.
4. **Idempotent setup scripts** -- `setup-labels.sh` checks for existing resources before creating, making it safe to run repeatedly.