@senior: issues as knowledge base #18

Closed
gitea-actions wants to merge 1 commits from ai/issue-17 into main

Summary

Stop @pm (and dev agents) from re-asking the maintainer questions already answered on past issues. The gitea-api skill already had cross-repo read access via AGENT_TOKEN (added in #14) but no "search for similar issues" example, and the PM prompt never told it to look at past issues. Both gaps are fixed in the shared reusable workflow (agent.yml), so every caller repo benefits.

Changes

  • .gitea/workflows/agent.ymlgitea-api skill SKILL.md heredoc: added a "Search for similar/related past issues by keyword" example with the same-repo issue-list endpoint (?q=<keywords>&type=issues&state=all&limit=20) and the cross-repo /repos/issues/search?q=... variant, plus tips (pick keywords from the new issue, state=all to surface closed/answered issues, open matched threads, cite issue numbers, only ask what precedent doesn't cover). Existing examples left intact.
  • .gitea/workflows/agent.yml — PM ACTION prompt block: added a KNOWLEDGE-BASE phase before the existing PLAN phase instructing @pm to search this repo and other repos on the instance (e.g. homelab) for similar past issues before presenting a plan or asking clarifying questions, reuse the maintainer's prior answers, cite matched issue numbers (e.g. homelab#103), and only ask about things genuinely not covered by precedent.
  • No trigger-gate, loop-guard, secret, or routing changes. YAML re-parses cleanly; PM prompt string kept free of backticks/$ to avoid shell expansion in the double-quoted bash string.

Resolves #17 · 🤖 @senior

## Summary Stop `@pm` (and dev agents) from re-asking the maintainer questions already answered on past issues. The `gitea-api` skill already had cross-repo read access via `AGENT_TOKEN` (added in #14) but no "search for similar issues" example, and the PM prompt never told it to look at past issues. Both gaps are fixed in the shared reusable workflow (`agent.yml`), so every caller repo benefits. ## Changes - `.gitea/workflows/agent.yml` — `gitea-api` skill SKILL.md heredoc: added a "Search for similar/related past issues by keyword" example with the same-repo issue-list endpoint (`?q=<keywords>&type=issues&state=all&limit=20`) and the cross-repo `/repos/issues/search?q=...` variant, plus tips (pick keywords from the new issue, `state=all` to surface closed/answered issues, open matched threads, cite issue numbers, only ask what precedent doesn't cover). Existing examples left intact. - `.gitea/workflows/agent.yml` — PM `ACTION` prompt block: added a `KNOWLEDGE-BASE` phase before the existing `PLAN` phase instructing `@pm` to search this repo and other repos on the instance (e.g. homelab) for similar past issues *before* presenting a plan or asking clarifying questions, reuse the maintainer's prior answers, cite matched issue numbers (e.g. `homelab#103`), and only ask about things genuinely not covered by precedent. - No trigger-gate, loop-guard, secret, or routing changes. YAML re-parses cleanly; PM prompt string kept free of backticks/`$` to avoid shell expansion in the double-quoted bash string. --- Resolves #17 · 🤖 @senior
gitea-actions bot added 1 commit 2026-07-03 13:56:00 +02:00

🤖 @senior PR ready for review — @ffaerber please review & merge:


🤖 @senior — activity log (93 entries):

tool calls & reasoning

🔧 bash: git branch --show-current && git log --oneline -10 && git status
🔧 read: .gitea/workflows/agent.yml
🔧 bash: ls -la .gitea/workflows/scripts/
🔧 read: .gitea/workflows/scripts/skill-gitea-api.sh
🔧 bash: git log --oneline main..ai/issue-17; echo "---"; git log --oneline ai/issue-17..main; echo "--- remote ---"; git branch -r | head -20
🔧 bash: git log --oneline origin/ai/issue-17 -10
🔧 bash: git log --oneline origin/main -5
🔧 bash: git log --oneline --all | grep -i "issue-17\|knowledge\|capability\|#17" | head; echo "---"; git log --oneline origin/main | grep -i "17\|knowledge\|capability" | head
🔧 bash: git show 644cf85 --stat; echo "==="; git log --oneline origin/main | head -30
🔧 bash: git show 644cf85
🔧 bash: git log --oneline origin/main | head -3; echo "---"; git fetch origin; git log --oneline origin/main..origin/ai/issue-17; echo "==="; git log --oneline origin/ai/issue-17..origin/main | head -40
🔧 read: .gitea/workflows/scripts/run-agent.sh
🔧 read: .gitea/workflows/scripts/skill-node1-ssh.sh
🔧 read: .gitea/workflows/scripts/route.sh
🔧 read: .gitea/workflows/scripts/agents.json
🔧 read: .gitea/workflows/scripts/install-opencode.sh
🔧 bash: git log --oneline -3 HEAD; echo "--- origin/ai/issue-17 ---"; git log --oneline -3 origin/ai/issue-17; echo "--- is 644cf85 in HEAD? ---"; git merge-base --is-ancestor 644cf85 HEAD && echo "YES" || echo "NO"
🔧 bash: git reset --hard origin/ai/issue-17 && git log --oneline -3
🔧 bash: git checkout main && git pull --ff-only origin main && git checkout -b ai/issue-17-capabilities && git log --oneline -3
💬 I've got the full picture now. Let me note the state:

  • ai/issue-17 has a stale commit (644cf85) from PR #18 — it edited agent.yml inline, but agent.yml has since been refactored to externalize scripts into .gitea/workflows/scripts/*.sh. So PR #18 is stale/conflicted.
  • The newly-delegated plan (Live Agent Capability Table via Gitea 1.27's GET /api/v1/token) is independent of the search-example work, so per AGENTS.md it gets its own branch/PR.
  • Least-privilege gating (plan point #2) is already done via agents.json skills arrays + install-opencode.sh permission.skill scoping (issue #22) — @junior has skills:[], etc. I won't redo it.

Let me create a fresh branch off main for the capability table.
💬 Now let me verify the /api/v1/token endpoint shape before coding against it.
🔧 skill: Loaded skill: gitea-api
🔧 bash: curl -sS -H "Authorization: token $AGENT_TOKEN" "$GITHUB_SERVER_URL/api/v1/version"; echo; curl -sS -H "Authorization: token $AGENT_TOKEN" "$GITHUB_SERVER_URL/api/v1/token" | jq '.' 2>&1 | head -40
🔧 bash: echo "GITHUB_SERVER_URL=$GITHUB_SERVER_URL"; echo "AGENT_TOKEN set? $([ -n "$AGENT_TOKEN" ] && echo yes || echo no)"; env | grep -iE "TOKEN_(PM|SENIOR|JUNIOR|LEAD|QA)" | sed 's/=.*/=***/'
🔧 write: .gitea/workflows/scripts/skill-gitea-api.sh
💬 Got it. The /api/v1/token endpoint works on this 1.27 instance and returns scopes. Now implementing. The existing ai/issue-17 branch has a stale PR #18 (edited agent.yml inline before the scripts refactor) — I'll leave that alone and put the capability-table work on a fresh branch.

Plan for this branch:

  1. skill-gitea-api.sh — introspect each agent token via GET /api/v1/token, build a live capability matrix table into SKILL.md.
  2. agent.yml — pass the TOKEN_* env vars into the gitea-api skill step so the script can introspect them.
  3. run-agent.sh — one roster note pointing agents to the capability matrix.

Note: least-privilege gating (plan point #3) is already done via agents.json skills arrays + install-opencode.sh permission.skill scoping (issue #22) — @junior has skills:[], denied skills are fully hidden. No redundant case gates needed.
🔧 bash: chmod +x .gitea/workflows/scripts/skill-gitea-api.sh && bash -n .gitea/workflows/scripts/skill-gitea-api.sh && echo "syntax OK"
🔧 edit: .gitea/workflows/agent.yml
💬 Now update agent.yml to pass the TOKEN_* env vars and GITHUB_SERVER_URL into the gitea-api skill step:
🔧 edit: .gitea/workflows/scripts/run-agent.sh
💬 Now add a roster note in run-agent.sh pointing agents to the capability matrix in the skill:
🔧 bash: rm -rf /tmp/skilltest && mkdir -p /tmp/skilltest && HOME=/tmp/skilltest GITHUB_SERVER_URL="https://git.ffaerber.duckdns.org" AGENT_TOKEN="$AGENT_TOKEN" bash .gitea/workflows/scripts/skill-gitea-api.sh && echo "=== SKILL.md (head 60) ===" &&…
💬 Now let me verify the whole pipeline works locally by simulating the script:
🔧 bash: rm -rf /tmp/skilltest2 && mkdir -p /tmp/skilltest2 && HOME=/tmp/skilltest2 GITHUB_SERVER_URL="https://git.ffaerber.duckdns.org" AGENT_TOKEN="$AGENT_TOKEN" TOKEN_PM="" TOKEN_SENIOR="" TOKEN_JUNIOR="" TOKEN_LEAD="" TOKEN_QA="" bash .gitea/wor…
💬 Live matrix works. Only @shared (AGENT_TOKEN) row appears because the TOKEN_* per-agent secrets aren't set in my local env — in CI they will be. Let me also test the fallback path (no tokens at all) and that the static body survives intact:
🔧 bash: rm -rf /tmp/skilltest3 && mkdir -p /tmp/skilltest3 && HOME=/tmp/skilltest3 GITHUB_SERVER_URL="https://git.ffaerber.duckdns.org" AGENT_TOKEN="invalid-token-xyz" bash .gitea/workflows/scripts/skill-gitea-api.sh 2>&1 | tail -2; echo "=== fallb…
🔧 edit: .gitea/workflows/scripts/skill-gitea-api.sh
🔧 bash: rm -rf /tmp/skilltest3 && mkdir -p /tmp/skilltest3 && HOME=/tmp/skilltest3 GITHUB_SERVER_URL="https://git.ffaerber.duckdns.org" AGENT_TOKEN="invalid-token-xyz" bash .gitea/workflows/scripts/skill-gitea-api.sh 2>&1 | tail -1; echo "=== fallb…
🔧 bash: rm -rf /tmp/skilltest && mkdir -p /tmp/skilltest && HOME=/tmp/skilltest GITHUB_SERVER_URL="https://git.ffaerber.duckdns.org" AGENT_TOKEN="$AGENT_TOKEN" bash .gitea/workflows/scripts/skill-gitea-api.sh 2>&1 | tail -1; echo "=== examples pres…
💬 Fallback now triggers correctly when introspection fails. Let me re-confirm the valid-token path still works and the static examples survived:
🔧 bash: python3 -c "import yaml,sys; yaml.safe_load(open('.gitea/workflows/agent.yml')); print('YAML OK')" 2>&1 || echo "no pyyaml, trying shell"; bash -n .gitea/workflows/scripts/skill-gitea-api.sh && echo "script syntax OK"; bash -n .gitea/workfl…
💬 All 6 examples + the search example (from PR #18's earlier work, now folded into the canonical script) + live matrix. Let me verify the YAML is still valid and check final diff:
🔧 bash: pip install pyyaml -q 2>&1 | tail -1; python3 -c "import yaml; yaml.safe_load(open('.gitea/workflows/agent.yml')); print('YAML OK')"
🔧 bash: which yamllint yq 2>/dev/null; python3 -m venv /tmp/yv 2>&1 | tail -1 && /tmp/yv/bin/pip install pyyaml -q 2>&1 | tail -1 && /tmp/yv/bin/python -c "import yaml; yaml.safe_load(open('.gitea/workflows/agent.yml')); print('YAML OK')"
🔧 bash: yq '.jobs.agent.steps[] | select(.name | test("gitea-api")) | .env' .gitea/workflows/agent.yml
🔧 bash: git add .gitea/workflows/agent.yml .gitea/workflows/scripts/skill-gitea-api.sh .gitea/workflows/scripts/run-agent.sh && git status --short && git diff --cached --stat
💬 YAML parses, env block correct. Now commit and push:
🔧 bash: `git commit -m "@senior: issue #17 — live agent capability table via Gitea 1.27 /api/v1/token

skill-gitea-api.sh now introspects each agent's own PAT (AGENT_TOKEN +
TOKEN_PM/SENIOR/JUNIOR/LEAD/QA) via GET /api/v1/token — a Gitea 1.27+
self-…`
💬 Pushed. The automation will open the PR from the branch. Here's the summary for the issue thread:

🤖 @senior — done, on a fresh branch ai/issue-17-capabilities (the old ai/issue-17/PR #18 predates the scripts refactor and is stale).

What I built (live Agent Capability Table, per @pm's approved plan):

  1. skill-gitea-api.sh — now introspects each agent's own PAT (AGENT_TOKEN + TOKEN_PM/SENIOR/JUNIOR/LEAD/QA) via Gitea 1.27's GET /api/v1/token (self-introspection: token-in, {name,scopes,user}-out, no password) and bakes a live matrix into SKILL.md:

    | Agent | Gitea user | Token name | Scopes |
    | @shared (AGENT_TOKEN) | ffaerber | full | read:organization, read:user, write:issue, write:repository, … |
    

    Verified against the real instance (1.27.0+rc0): the endpoint returns real scopes, never the token string. Falls back to a static note on <1.27 or unset tokens (tested both paths locally). The existing static scope description + all examples (incl. the keyword-search "knowledge base" example from PR #18) are preserved.

  2. agent.yml — passes GITHUB_SERVER_URL + the per-agent TOKEN_* secrets into the gitea-api skill step so the script can introspect them.

  3. run-agent.sh — one roster note pointing agents to the live matrix for capability-based routing.

On plan point #3 (least-privilege gating): already done in issue #22agents.json skills arrays + install-opencode.sh permission.skill scoping mean @junior (skills:[]) never even sees the gitea-api summary line, and denied skills are fully hidden. No redundant case gates added.

Verified: shell syntax, YAML parses (yq + pyyaml), live-introspection path, fallback path, and that all 6 examples + the search example survive. PR will be auto-opened from the branch.

BEGIN_PR_DESCRIPTION

Summary

Implements the live Agent Capability Table approved in issue #17: every agent that loads the gitea-api skill now sees a live, always-accurate matrix of every teammate's real Gitea scopes, auto-introspected at workflow start via Gitea 1.27's GET /api/v1/token endpoint. No hand-maintained table to drift when scopes rotate. Also folds in the keyword-search "knowledge base" example so PM can look up similar past issues instead of re-asking settled questions.

Changes

  • .gitea/workflows/scripts/skill-gitea-api.sh: introspect AGENT_TOKEN + TOKEN_PM/SENIOR/JUNIOR/LEAD/QA via GET /api/v1/token, render a live capability matrix table into SKILL.md; graceful fallback on <1.27/unset tokens; preserves all existing examples + adds the keyword-search example.
  • .gitea/workflows/agent.yml: pass GITHUB_SERVER_URL + per-agent TOKEN_* secrets into the gitea-api skill step.
  • .gitea/workflows/scripts/run-agent.sh: roster note pointing agents to the live matrix for capability-based routing.
    END_PR_DESCRIPTION
🤖 **@senior** — ✅ PR ready for review — @ffaerber please review & merge: - https://git.ffaerber.duckdns.org/ffaerber/agents/pulls/18 --- 🤖 **@senior** — activity log (93 entries): <details> <summary>tool calls & reasoning</summary> 🔧 **bash**: `git branch --show-current && git log --oneline -10 && git status` 🔧 **read**: `.gitea/workflows/agent.yml` 🔧 **bash**: `ls -la .gitea/workflows/scripts/` 🔧 **read**: `.gitea/workflows/scripts/skill-gitea-api.sh` 🔧 **bash**: `git log --oneline main..ai/issue-17; echo "---"; git log --oneline ai/issue-17..main; echo "--- remote ---"; git branch -r | head -20` 🔧 **bash**: `git log --oneline origin/ai/issue-17 -10` 🔧 **bash**: `git log --oneline origin/main -5` 🔧 **bash**: `git log --oneline --all | grep -i "issue-17\|knowledge\|capability\|#17" | head; echo "---"; git log --oneline origin/main | grep -i "17\|knowledge\|capability" | head` 🔧 **bash**: `git show 644cf85 --stat; echo "==="; git log --oneline origin/main | head -30` 🔧 **bash**: `git show 644cf85` 🔧 **bash**: `git log --oneline origin/main | head -3; echo "---"; git fetch origin; git log --oneline origin/main..origin/ai/issue-17; echo "==="; git log --oneline origin/ai/issue-17..origin/main | head -40` 🔧 **read**: `.gitea/workflows/scripts/run-agent.sh` 🔧 **read**: `.gitea/workflows/scripts/skill-node1-ssh.sh` 🔧 **read**: `.gitea/workflows/scripts/route.sh` 🔧 **read**: `.gitea/workflows/scripts/agents.json` 🔧 **read**: `.gitea/workflows/scripts/install-opencode.sh` 🔧 **bash**: `git log --oneline -3 HEAD; echo "--- origin/ai/issue-17 ---"; git log --oneline -3 origin/ai/issue-17; echo "--- is 644cf85 in HEAD? ---"; git merge-base --is-ancestor 644cf85 HEAD && echo "YES" || echo "NO"` 🔧 **bash**: `git reset --hard origin/ai/issue-17 && git log --oneline -3` 🔧 **bash**: `git checkout main && git pull --ff-only origin main && git checkout -b ai/issue-17-capabilities && git log --oneline -3` 💬 I've got the full picture now. Let me note the state: - `ai/issue-17` has a stale commit (644cf85) from PR #18 — it edited `agent.yml` inline, but `agent.yml` has since been refactored to externalize scripts into `.gitea/workflows/scripts/*.sh`. So PR #18 is stale/conflicted. - The **newly-delegated** plan (Live Agent Capability Table via Gitea 1.27's `GET /api/v1/token`) is independent of the search-example work, so per AGENTS.md it gets its own branch/PR. - Least-privilege gating (plan point #2) is **already done** via `agents.json` `skills` arrays + `install-opencode.sh` `permission.skill` scoping (issue #22) — `@junior` has `skills:[]`, etc. I won't redo it. Let me create a fresh branch off main for the capability table. 💬 Now let me verify the `/api/v1/token` endpoint shape before coding against it. 🔧 **skill**: `Loaded skill: gitea-api` 🔧 **bash**: `curl -sS -H "Authorization: token $AGENT_TOKEN" "$GITHUB_SERVER_URL/api/v1/version"; echo; curl -sS -H "Authorization: token $AGENT_TOKEN" "$GITHUB_SERVER_URL/api/v1/token" | jq '.' 2>&1 | head -40` 🔧 **bash**: `echo "GITHUB_SERVER_URL=$GITHUB_SERVER_URL"; echo "AGENT_TOKEN set? $([ -n "$AGENT_TOKEN" ] && echo yes || echo no)"; env | grep -iE "TOKEN_(PM|SENIOR|JUNIOR|LEAD|QA)" | sed 's/=.*/=***/'` 🔧 **write**: `.gitea/workflows/scripts/skill-gitea-api.sh` 💬 Got it. The `/api/v1/token` endpoint works on this 1.27 instance and returns `scopes`. Now implementing. The existing `ai/issue-17` branch has a stale PR #18 (edited `agent.yml` inline before the scripts refactor) — I'll leave that alone and put the capability-table work on a fresh branch. Plan for this branch: 1. `skill-gitea-api.sh` — introspect each agent token via `GET /api/v1/token`, build a live capability matrix table into `SKILL.md`. 2. `agent.yml` — pass the `TOKEN_*` env vars into the gitea-api skill step so the script can introspect them. 3. `run-agent.sh` — one roster note pointing agents to the capability matrix. Note: least-privilege gating (plan point #3) is already done via `agents.json` `skills` arrays + `install-opencode.sh` `permission.skill` scoping (issue #22) — `@junior` has `skills:[]`, denied skills are fully hidden. No redundant `case` gates needed. 🔧 **bash**: `chmod +x .gitea/workflows/scripts/skill-gitea-api.sh && bash -n .gitea/workflows/scripts/skill-gitea-api.sh && echo "syntax OK"` 🔧 **edit**: `.gitea/workflows/agent.yml` 💬 Now update `agent.yml` to pass the `TOKEN_*` env vars and `GITHUB_SERVER_URL` into the gitea-api skill step: 🔧 **edit**: `.gitea/workflows/scripts/run-agent.sh` 💬 Now add a roster note in `run-agent.sh` pointing agents to the capability matrix in the skill: 🔧 **bash**: `rm -rf /tmp/skilltest && mkdir -p /tmp/skilltest && HOME=/tmp/skilltest GITHUB_SERVER_URL="https://git.ffaerber.duckdns.org" AGENT_TOKEN="$AGENT_TOKEN" bash .gitea/workflows/scripts/skill-gitea-api.sh && echo "=== SKILL.md (head 60) ===" &&…` 💬 Now let me verify the whole pipeline works locally by simulating the script: 🔧 **bash**: `rm -rf /tmp/skilltest2 && mkdir -p /tmp/skilltest2 && HOME=/tmp/skilltest2 GITHUB_SERVER_URL="https://git.ffaerber.duckdns.org" AGENT_TOKEN="$AGENT_TOKEN" TOKEN_PM="" TOKEN_SENIOR="" TOKEN_JUNIOR="" TOKEN_LEAD="" TOKEN_QA="" bash .gitea/wor…` 💬 Live matrix works. Only `@shared (AGENT_TOKEN)` row appears because the `TOKEN_*` per-agent secrets aren't set in my local env — in CI they will be. Let me also test the fallback path (no tokens at all) and that the static body survives intact: 🔧 **bash**: `rm -rf /tmp/skilltest3 && mkdir -p /tmp/skilltest3 && HOME=/tmp/skilltest3 GITHUB_SERVER_URL="https://git.ffaerber.duckdns.org" AGENT_TOKEN="invalid-token-xyz" bash .gitea/workflows/scripts/skill-gitea-api.sh 2>&1 | tail -2; echo "=== fallb…` 🔧 **edit**: `.gitea/workflows/scripts/skill-gitea-api.sh` 🔧 **bash**: `rm -rf /tmp/skilltest3 && mkdir -p /tmp/skilltest3 && HOME=/tmp/skilltest3 GITHUB_SERVER_URL="https://git.ffaerber.duckdns.org" AGENT_TOKEN="invalid-token-xyz" bash .gitea/workflows/scripts/skill-gitea-api.sh 2>&1 | tail -1; echo "=== fallb…` 🔧 **bash**: `rm -rf /tmp/skilltest && mkdir -p /tmp/skilltest && HOME=/tmp/skilltest GITHUB_SERVER_URL="https://git.ffaerber.duckdns.org" AGENT_TOKEN="$AGENT_TOKEN" bash .gitea/workflows/scripts/skill-gitea-api.sh 2>&1 | tail -1; echo "=== examples pres…` 💬 Fallback now triggers correctly when introspection fails. Let me re-confirm the valid-token path still works and the static examples survived: 🔧 **bash**: `python3 -c "import yaml,sys; yaml.safe_load(open('.gitea/workflows/agent.yml')); print('YAML OK')" 2>&1 || echo "no pyyaml, trying shell"; bash -n .gitea/workflows/scripts/skill-gitea-api.sh && echo "script syntax OK"; bash -n .gitea/workfl…` 💬 All 6 examples + the search example (from PR #18's earlier work, now folded into the canonical script) + live matrix. Let me verify the YAML is still valid and check final diff: 🔧 **bash**: `pip install pyyaml -q 2>&1 | tail -1; python3 -c "import yaml; yaml.safe_load(open('.gitea/workflows/agent.yml')); print('YAML OK')"` 🔧 **bash**: `which yamllint yq 2>/dev/null; python3 -m venv /tmp/yv 2>&1 | tail -1 && /tmp/yv/bin/pip install pyyaml -q 2>&1 | tail -1 && /tmp/yv/bin/python -c "import yaml; yaml.safe_load(open('.gitea/workflows/agent.yml')); print('YAML OK')"` 🔧 **bash**: `yq '.jobs.agent.steps[] | select(.name | test("gitea-api")) | .env' .gitea/workflows/agent.yml` 🔧 **bash**: `git add .gitea/workflows/agent.yml .gitea/workflows/scripts/skill-gitea-api.sh .gitea/workflows/scripts/run-agent.sh && git status --short && git diff --cached --stat` 💬 YAML parses, env block correct. Now commit and push: 🔧 **bash**: `git commit -m "@senior: issue #17 — live agent capability table via Gitea 1.27 /api/v1/token skill-gitea-api.sh now introspects each agent's own PAT (AGENT_TOKEN + TOKEN_PM/SENIOR/JUNIOR/LEAD/QA) via GET /api/v1/token — a Gitea 1.27+ self-…` 💬 Pushed. The automation will open the PR from the branch. Here's the summary for the issue thread: 🤖 **@senior** — done, on a fresh branch `ai/issue-17-capabilities` (the old `ai/issue-17`/PR #18 predates the scripts refactor and is stale). **What I built (live Agent Capability Table, per @pm's approved plan):** 1. **`skill-gitea-api.sh`** — now introspects each agent's own PAT (`AGENT_TOKEN` + `TOKEN_PM/SENIOR/JUNIOR/LEAD/QA`) via Gitea 1.27's `GET /api/v1/token` (self-introspection: token-in, `{name,scopes,user}`-out, no password) and bakes a **live matrix** into `SKILL.md`: ``` | Agent | Gitea user | Token name | Scopes | | @shared (AGENT_TOKEN) | ffaerber | full | read:organization, read:user, write:issue, write:repository, … | ``` Verified against the real instance (`1.27.0+rc0`): the endpoint returns real scopes, never the token string. Falls back to a static note on `<1.27` or unset tokens (tested both paths locally). The existing static scope description + all examples (incl. the keyword-search "knowledge base" example from PR #18) are preserved. 2. **`agent.yml`** — passes `GITHUB_SERVER_URL` + the per-agent `TOKEN_*` secrets into the gitea-api skill step so the script can introspect them. 3. **`run-agent.sh`** — one roster note pointing agents to the live matrix for capability-based routing. **On plan point #3 (least-privilege gating):** already done in issue #22 — `agents.json` `skills` arrays + `install-opencode.sh` `permission.skill` scoping mean `@junior` (`skills:[]`) never even sees the `gitea-api` summary line, and denied skills are fully hidden. No redundant `case` gates added. Verified: shell syntax, YAML parses (`yq` + `pyyaml`), live-introspection path, fallback path, and that all 6 examples + the search example survive. PR will be auto-opened from the branch. BEGIN_PR_DESCRIPTION ## Summary Implements the live Agent Capability Table approved in issue #17: every agent that loads the `gitea-api` skill now sees a live, always-accurate matrix of every teammate's real Gitea scopes, auto-introspected at workflow start via Gitea 1.27's `GET /api/v1/token` endpoint. No hand-maintained table to drift when scopes rotate. Also folds in the keyword-search "knowledge base" example so PM can look up similar past issues instead of re-asking settled questions. ## Changes - `.gitea/workflows/scripts/skill-gitea-api.sh`: introspect `AGENT_TOKEN` + `TOKEN_PM/SENIOR/JUNIOR/LEAD/QA` via `GET /api/v1/token`, render a live capability matrix table into `SKILL.md`; graceful fallback on `<1.27`/unset tokens; preserves all existing examples + adds the keyword-search example. - `.gitea/workflows/agent.yml`: pass `GITHUB_SERVER_URL` + per-agent `TOKEN_*` secrets into the gitea-api skill step. - `.gitea/workflows/scripts/run-agent.sh`: roster note pointing agents to the live matrix for capability-based routing. END_PR_DESCRIPTION </details>
ffaerber closed this pull request 2026-07-06 10:20:18 +02:00

Pull request closed

This pull request cannot be reopened because the branch was deleted.
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: gitea/agents#18