diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..0ca585f --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,22 @@ +# AGENTS.md + +Guidance for AI agents working in this repo. + +## Agent skills + +### Issue tracker + +Issues live in **Gitea** at , created/read via +the Gitea REST API (or the `tea` CLI) with a PAT that has `issue` scope, kept in `.secrets/` and +never committed. See `docs/agents/issue-tracker.md`. + +### Triage labels + +Canonical roles, used verbatim as Gitea labels: categories `bug` / `enhancement`; states +`needs-triage` · `needs-info` · `ready-for-agent` · `ready-for-human` · `wontfix`. Invoke triage +with `/mattpocock-skills:triage`. See `docs/agents/triage-labels.md`. + +### Domain docs + +Single-context: one `CONTEXT.md` + `docs/adr/` at the repo root (created lazily when terms or +decisions get resolved). See `docs/agents/domain.md`. diff --git a/docs/agents/domain.md b/docs/agents/domain.md new file mode 100644 index 0000000..658fede --- /dev/null +++ b/docs/agents/domain.md @@ -0,0 +1,36 @@ +# Domain Docs + +How the engineering skills should consume this repo's domain documentation when exploring the codebase. + +## Before exploring, read these + +- **`CONTEXT.md`** at the repo root, or +- **`CONTEXT-MAP.md`** at the repo root if it exists — it points at one `CONTEXT.md` per context. Read each one relevant to the topic. +- **`docs/adr/`** — read ADRs that touch the area you're about to work in. + +If any of these files don't exist, **proceed silently**. Don't flag their absence; don't suggest creating them upfront. The `/domain-modeling` skill creates them lazily when terms or decisions actually get resolved. + +## File structure + +This is a **single-context** repo: + +``` +/ +├── CONTEXT.md +├── docs/adr/ +│ ├── 0001-....md +│ └── 0002-....md +└── ... +``` + +## Use the glossary's vocabulary + +When your output names a domain concept (in an issue title, a refactor proposal, a hypothesis, a test name), use the term as defined in `CONTEXT.md`. Don't drift to synonyms the glossary explicitly avoids. + +If the concept you need isn't in the glossary yet, that's a signal — either you're inventing language the project doesn't use (reconsider) or there's a real gap (note it for `/domain-modeling`). + +## Flag ADR conflicts + +If your output contradicts an existing ADR, surface it explicitly rather than silently overriding: + +> _Contradicts ADR-0007 (…) — but worth reopening because…_ diff --git a/docs/agents/issue-tracker.md b/docs/agents/issue-tracker.md new file mode 100644 index 0000000..7088242 --- /dev/null +++ b/docs/agents/issue-tracker.md @@ -0,0 +1,70 @@ +# Issue tracker: Gitea (self-hosted) + +Issues and PRDs for this repo live as **Gitea issues** on the self-hosted instance at +`git.mivanchenko.de`, repo **`BPPP/smb-online`**: + + +Gitea is not GitHub/GitLab, so `gh` / `glab` do **not** work here. Use the **Gitea REST API** +(or the [`tea`](https://gitea.com/gitea/tea) CLI, if installed). The API is GitHub-shaped. + +## Auth + +All write operations need a **personal access token with `issue` scope** (add `repository` scope +for label management). Generate one in the Gitea UI → *Settings → Applications → Generate New +Token* (scopes: `issue` Read+Write, `repository` Read+Write). + +- **Never commit the token.** Keep it in the gitignored vault (`.secrets/`, e.g. `.secrets/gitea.env` + as `GITEA_TOKEN=...`) and load it into the shell (`source .secrets/gitea.env`), or export it for + the session. `.gitignore` already excludes `.secrets/`. +- A leaked token must be revoked in *Settings → Applications* and rotated. + +Set these once per shell: + +```bash +export GITEA_TOKEN=... # from .secrets/, never inline in committed files +API=https://git.mivanchenko.de/api/v1/repos/BPPP/smb-online +AUTH="Authorization: token $GITEA_TOKEN" +``` + +## Conventions + +- **Create an issue**: + ```bash + curl -s -H "$AUTH" -H "Content-Type: application/json" -X POST "$API/issues" \ + -d '{"title":"...","body":"...","labels":[]}' + ``` + `labels` takes numeric **label IDs**, not names — list them first (see below). Use a heredoc / + a JSON file for long bodies. +- **Read an issue**: `curl -s -H "$AUTH" "$API/issues/"` ; + comments: `curl -s -H "$AUTH" "$API/issues//comments"`. +- **List issues**: `curl -s -H "$AUTH" "$API/issues?state=open&limit=50"` (JSON). Filter with + `&labels=` and `&state=all|open|closed`. +- **Comment on an issue**: + `curl -s -H "$AUTH" -H "Content-Type: application/json" -X POST "$API/issues//comments" -d '{"body":"..."}'` +- **Close an issue** (post the explanation first, then close): + `curl -s -H "$AUTH" -H "Content-Type: application/json" -X PATCH "$API/issues/" -d '{"state":"closed"}'` +- **Labels** — list: `curl -s -H "$AUTH" "$API/labels"` (gives id↔name). Create: + `curl ... -X POST "$API/labels" -d '{"name":"...","color":"rrggbb","description":"..."}'`. + Attach by id: `curl ... -X POST "$API/issues//labels" -d '{"labels":[]}'`. + +The `tea` CLI (`tea issue create|list|comment ...`) is a friendlier alternative once configured +against this instance with `tea login add`. + +## Current label vocabulary + +`bug` · `enhancement` · `security` · `ops` · `infra` · `crm` · `booking` · `n8n` · `tech-debt` +(list live IDs via `GET $API/labels`). + +## When a skill says "publish to the issue tracker" + +Create a Gitea issue via `POST $API/issues`. + +## When a skill says "fetch the relevant ticket" + +`GET $API/issues/` plus `GET $API/issues//comments`. + +## Pull requests as a request surface + +**PRs as a request surface: no.** _(Set to `yes` if this repo treats external PRs as feature +requests; a triage skill would read this flag. Gitea PR endpoints mirror the issue ones under +`$API/pulls/...`.)_ diff --git a/docs/agents/triage-labels.md b/docs/agents/triage-labels.md new file mode 100644 index 0000000..3440dee --- /dev/null +++ b/docs/agents/triage-labels.md @@ -0,0 +1,28 @@ +# Triage Labels + +The skills speak in terms of canonical triage roles. This file maps those roles to the actual +label strings used in this repo's Gitea tracker (`BPPP/smb-online`). We use the canonical names +verbatim, so the mapping is 1:1. + +## Category roles (exactly one per triaged issue) + +| Role in mattpocock/skills | Label in our tracker | Meaning | +| ------------------------- | -------------------- | ------------------------------ | +| `bug` | `bug` | Something is broken | +| `enhancement` | `enhancement` | New feature or improvement | + +## State roles (exactly one per triaged issue) + +| Role in mattpocock/skills | Label in our tracker | Meaning | +| ------------------------- | -------------------- | ---------------------------------------- | +| `needs-triage` | `needs-triage` | Maintainer needs to evaluate this issue | +| `needs-info` | `needs-info` | Waiting on reporter for more information | +| `ready-for-agent` | `ready-for-agent` | Fully specified, ready for an AFK agent | +| `ready-for-human` | `ready-for-human` | Requires human implementation | +| `wontfix` | `wontfix` | Will not be actioned | + +When a skill mentions a role (e.g. "apply the AFK-ready triage label"), use the corresponding +label string from these tables. Attach labels via the Gitea API by **label id** — see +`docs/agents/issue-tracker.md` and `GET $API/labels` for the live id↔name mapping. + +Edit the right-hand column if the vocabulary ever diverges.