Files
command-center/agent/managed-skills/gitea-issue-labels-and-pr-curl-traps/SKILL.md
T
Frank 8af40c402b chore(agent): commit the machine tier and the doctrine text the checkout was already running
Landing blocker for #61 and #63: the deployment checkout is 12 commits behind and
`merge --ff-only` refuses while tracked paths are dirty. Discard is not available here
(workspace policy: no `checkout`/`stash` on shared state), so the dirt is committed.

- `agent/APPEND_SYSTEM.md`: the point-of-use / one-work-log / PR-link doctrine, already
  byte-identical to `origin/main` (`cmp` against the trunk blob: no difference). No new
  prose — the commit exists so the trunk merge can proceed.
- `agent/config.yml` and `agent/managed-skills/**`: the machine-live tier the heartbeat
  owns (AGENTS.md § Live-sync tiers).

`ALLOW_SECRETS=1` was used, deliberately and after auditing the staged diff by hand: the
only credential-shaped strings in it are two copies of `AKIA0000000000000EXAMPLE` — the
inert all-zero AWS example id — and they appear inside the two skill pages that teach
that exact placeholder shape. This checkout is still running the pre-#61 hook; the merged
gate (value-scoped placeholder filter, `71601f7`) exempts this value, so the refusal
dies with this landing. No `--no-verify` was used: the gate ran and its verdict is
recorded here.

Refs #61
2026-10-21 01:44:51 -07:00

54 lines
2.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
name: gitea-issue-labels-and-pr-curl-traps
description: "Dankclaw Gitea API curl traps: PR create needs Content-Type application/json (fake \"[Head]: Required\"), issue labels only via POST /issues/N/labels (PATCH labels silently dropped), token from URL-format secret file."
---
Operate Dankclaw Gitea (`http://192.168.0.143:3000`, repo `dank/franksign` and siblings) with curl without the three traps that produce misleading errors.
## Token extraction (URL-format store, NOT key=value)
`~/.config/secrets/gitea` is one line: `http://user:TOKEN@192.168.0.143:3000`. `cat`-ing it yields the whole URL, not the token.
```bash
TOK=$(sed -n 's|.*://[^:]*:\([^@]*\)@.*|\1|p' ~/.config/secrets/gitea | head -1)
```
Never pass the token as a `-H` argument (world-readable in `/proc/<pid>/cmdline`). Write a 600-perm curl config:
```bash
printf 'header = "Authorization: token %s"\n' "$TOK" > /tmp/g.cfg
```
## Trap 1 — PR create answers `"[Head]: Required"` when the body is the problem
Two independent causes, both look like a missing field:
1. No `Content-Type: application/json` header → Gitea parses the raw JSON as form data, sees no `head`, returns 422 `[Head]: Required`.
2. Putting `data = "@/tmp/body.json"` inside a `-K` curl config does **not** expand the `@`.
Fix: add `header = "Content-Type: application/json"` to the config and pass `--data @/tmp/body.json` on the command line:
```bash
curl -s -K /tmp/g.cfg -X POST --data @/tmp/pr.json \
"http://192.168.0.143:3000/api/v1/repos/dank/franksign/pulls"
```
## Trap 2 — issue label assignment via PATCH /issues/N is silently dropped
`PATCH /api/v1/repos/{o}/{r}/issues/{n}` with `{"labels":[id]}` returns **200/201 with the issue JSON**, yet a follow-up GET shows `labels: []` (it can even clear existing labels). Labels are a subresource:
```bash
curl -s -K /tmp/g.cfg -X POST --data '{"labels":[4]}' \
"http://192.168.0.143:3000/api/v1/repos/dank/franksign/issues/18/labels"
```
200 returns the assigned label array. Resolve label names→ids via `GET /repos/{o}/{r}/labels` (franksign canonical five: ids 2–6; `ready-for-agent` = 4).
## Verification law
Both traps fail *successfully*. After any label/PR write, GET the resource and check the field changed; never trust the status code alone.
## Cleanup
`rm -f` the temp config + body files (config holds the token).