The Matt Pocock engineering skills (triage, to-tickets, to-spec, research, implement) assume per-repo config for three things: where work items live, what the triage label vocabulary is, and where domain docs sit. Nothing here declared any of them, so every skill run re-guessed. Frank's decisions, 2026-10-20: Gitea on Dankclaw as the tracker (no gh, no tea on any box, so it is recorded as prose — auth via a 600 curl config, the endpoint table, the 404-on-empty-token / form-encoded-merge / empty-200-on-merge traps, and the AGENTS.md laws a skill must not renegotiate); the canonical triage label vocabulary kept as-is, with the five labels created on the tracker (the repo had zero, so nothing collides); single-context domain docs. The configuration moved out of the skill's default docs/agents/ and into the one knowledge base this repo allows: three pages under omp-docs/skills/, an empty omp-docs/decisions/ carrying the ADR format rule, an "## Agent skills" pointer block in AGENTS.md, index entries, and a log entry. The glossary is deliberately not created — every candidate term already has an owner in system/, core/ or skills/, and a term list that paraphrases them is a second owner of facts already written down. Known cost: re-running setup-matt-pocock-skills will not recognise omp-docs/skills/* and will offer to recreate docs/agents/; the AGENTS.md pointer is what stops that. Also closes a verification gap found on the way: kb-lint.bats only ever points the linter at fixtures, so a page with no frontmatter or an index that stops listing a file passes the suite silently. Two tests now run the linter and the coverage checker against the shipped omp-docs/ tree. Refs #18
3.5 KiB
type, title, description, tags, timestamp, verified
| type | title | description | tags | timestamp | verified | ||||
|---|---|---|---|---|---|---|---|---|---|
| reference | Issue tracker for engineering skills | Where work items live for dank/command-center — Gitea on Dankclaw — with the exact API mechanics, traps, and laws the engineering skills must follow. |
|
2026-10-20 | 2026-10-20 |
Issue tracker: Gitea on Dankclaw
Issues and PRs for this repo live in Gitea: dank/command-center at
http://192.168.0.143:3000. There is no gh and no tea on any box — talk to
the REST API with curl.
Authentication
The token lives in ~/.config/secrets/gitea (never embedded in a remote URL,
never committed). Hand it to curl as a 600-permission config file: -H puts it
in world-readable /proc/<pid>/cmdline.
tok=$(sed -nE 's#^https?://[^:/@]+:([^@]+)@192\.168\.0\.143.*#\1#p' ~/.config/secrets/gitea | head -1)
[ "${#tok}" -ge 40 ] || { echo "token extraction failed"; exit 1; }
cfg=$(mktemp); chmod 600 "$cfg"; printf 'header = "Authorization: token %s"\n' "$tok" > "$cfg"
curl -sS -K "$cfg" … ; shred -u "$cfg"
Assert the length before posting anything. An empty token answers 404 not found, not 401 — Gitea hides the private repo, so a 404 on a path that worked
yesterday is an auth failure rather than a typo. The awk-style alternative that
splits the store line on / silently yields an empty variable, because the host
sits in field three. Deeper detail: Gitea client access.
Multi-line bodies: build the JSON with python3 -c 'json.dumps(...)' reading the
body from a file. Never pass --- as a bare jq argument (it parses as a flag),
and never escape quotes inside a single-quoted python3 -c.
Endpoints the skills use
| Action | Call |
|---|---|
| Open a work item | POST /api/v1/repos/dank/command-center/issues {title, body} |
| Correct a body afterwards | PATCH …/issues/N (works on PRs too — a PR is an issue) |
| Open a PR | POST …/pulls {title, body, base: "main", head: <branch>} — JSON accepted here |
| Merge | POST …/pulls/N/merge form-encoded: do=merge, merge_style=no-ff |
| Labels | GET / POST …/labels |
Three traps that cost time before:
POST /pullsanswers409 … already exists for these targetswhen the branch already has a PR (Frank clicks Create from the push message).GET /pulls?state=all, find it,PATCHit — do not re-post.- A JSON merge body (
{"Do":"merge"}) returns422 {"message":"[Do]: Required"}. The field name is lowercasedoand the body must be form-encoded. - A successful merge returns
200with an empty body. Verify by landing a checkout (git merge --ff-only origin/main), never by re-reading the PR.
Laws inherited from AGENTS.md
A skill working in this repo does not get to renegotiate these:
- A work item is a Gitea issue. Anything with more than one moving part gets the
issue before the branch. Branch naming
<type>/<issue#>-<slug>, PRs targetmaindirectly, merge with--no-ff. - Never merge without Frank's explicit per-PR OK, and
xdg-openthe PR URL into his browser the moment it exists — he should not have to hunt for it. - Every issue and PR body ends with
---, thencwd: <session cwd> · session: <session id>. The session id is the UUID of the transcript file being appended to right now (ls -l --time-style=+%H:%M:%S ~/.omp/agent/sessions/<cwd-dir>/*.jsonl), not the session directory name — one cwd can hold several sessions. git * --no-verifyis forbidden; the pre-commit hook is the secret gate.