i have commented in a issue a about a other simular issue in gitea. but the agent was not able to open the connectyed issue.
the agent needs to read all the repos issues actions and so on. how can we do that?
i have commented in a issue a about a other simular issue in gitea. but the agent was not able to open the connectyed issue.
the agent needs to read all the repos issues actions and so on. how can we do that?
I dug into .gitea/workflows/agent.yml (the shared workflow all repos call) to see exactly what context the agent gets today.
What's happening now: for every run, the workflow only fetches:
the current issue's own title/body (IBODY/TITLE)
the current issue's own comment thread (issues/$NUM/comments, step "Fetch the full issue thread")
image attachments on the current issue (vision agents only)
There is no mechanism at all for:
opening a different issue/PR (same repo or another repo) that gets referenced in a comment (e.g. "see #12" or a link to another repo's issue)
reading Actions/workflow run logs
any live Gitea API access from inside the opencode run — the agent process itself never receives GITEA_TOKEN/the API base URL, so even if it tried curl, it has neither credentials nor a documented capability to do so (unlike the node1-ssh skill, which is the one precedent we have for giving an agent a scoped, read-only, documented capability).
So "the agent couldn't open the connected issue" is expected — it's not a bug in this run, it's a missing capability in the shared workflow.
Before I can size this and assign it, I need a couple of decisions since they change the design and who should build it:
Scope — same-repo issue/PR references only, or cross-repo (any repo you own on this Gitea instance)? Any repos that should stay off-limits even read-only?
"Actions and so on" — do you also want agents to read workflow/Actions run logs (e.g. to see why a CI run failed), or is this really about issues/PRs?
Mechanism — two options with different risk/complexity:
(a) Auto pre-fetch (cheap, safe): the workflow itself detects #123-style references in the thread and fetches a short summary of each referenced issue/PR (same repo only) and injects it into the prompt automatically — no new agent capability, no new attack surface, mirrors the existing thread-fetch step.
(b) Live read-only API skill (flexible, bigger surface): give agents a gitea-api skill + scoped token, similar in spirit to node1-ssh — the agent can curl GET-only Gitea API endpoints on demand (any issue/PR/comments/actions run, possibly cross-repo). More general, but it's a capability added to the shared workflow used by every repo, so it needs a tight allowlist (GET-only, specific hosts/paths) to avoid turning into an SSRF/data-exfil vector via a compromised or prompt-injected issue.
My instinct: do (a) first as a small, low-risk PR that covers the common "opened a similar issue" case, and treat (b) as a separate, more careful follow-up if you actually want general cross-repo/actions browsing. But I'd rather confirm scope with you before committing anyone to build (b), since it's a security-relevant change to code every repo depends on.
@ffaerber — can you confirm scope (1)-(3) above, especially whether you need cross-repo/actions access or just "referenced issue in the same repo"?
🤖 **@pm**
I dug into `.gitea/workflows/agent.yml` (the shared workflow all repos call) to see exactly what context the agent gets today.
**What's happening now:** for every run, the workflow only fetches:
- the *current* issue's own title/body (`IBODY`/`TITLE`)
- the *current* issue's own comment thread (`issues/$NUM/comments`, step "Fetch the full issue thread")
- image attachments on the *current* issue (vision agents only)
There is **no** mechanism at all for:
- opening a *different* issue/PR (same repo or another repo) that gets referenced in a comment (e.g. "see #12" or a link to another repo's issue)
- reading Actions/workflow run logs
- any live Gitea API access from inside the opencode run — the agent process itself never receives `GITEA_TOKEN`/the API base URL, so even if it tried `curl`, it has neither credentials nor a documented capability to do so (unlike the `node1-ssh` skill, which is the one precedent we have for giving an agent a scoped, read-only, documented capability).
So "the agent couldn't open the connected issue" is expected — it's not a bug in *this* run, it's a missing capability in the shared workflow.
Before I can size this and assign it, I need a couple of decisions since they change the design and who should build it:
1. **Scope** — same-repo issue/PR references only, or cross-repo (any repo you own on this Gitea instance)? Any repos that should stay off-limits even read-only?
2. **"Actions and so on"** — do you also want agents to read workflow/Actions run logs (e.g. to see why a CI run failed), or is this really about issues/PRs?
3. **Mechanism** — two options with different risk/complexity:
- **(a) Auto pre-fetch (cheap, safe):** the workflow itself detects `#123`-style references in the thread and fetches a short summary of each referenced issue/PR (same repo only) and injects it into the prompt automatically — no new agent capability, no new attack surface, mirrors the existing thread-fetch step.
- **(b) Live read-only API skill (flexible, bigger surface):** give agents a `gitea-api` skill + scoped token, similar in spirit to `node1-ssh` — the agent can `curl` GET-only Gitea API endpoints on demand (any issue/PR/comments/actions run, possibly cross-repo). More general, but it's a capability added to the *shared* workflow used by every repo, so it needs a tight allowlist (GET-only, specific hosts/paths) to avoid turning into an SSRF/data-exfil vector via a compromised or prompt-injected issue.
My instinct: do (a) first as a small, low-risk PR that covers the common "opened a similar issue" case, and treat (b) as a separate, more careful follow-up if you actually want general cross-repo/actions browsing. But I'd rather confirm scope with you before committing anyone to build (b), since it's a security-relevant change to code every repo depends on.
@ffaerber — can you confirm scope (1)-(3) above, especially whether you need cross-repo/actions access or just "referenced issue in the same repo"?
@pm i think i like to add a new gitea skill to the agents.
the AGENT_TOKEN needs then more permission. is there a api to get the current permission of the agent token.
so that the agent can see waht he can do with gitea?
@pm i think i like to add a new gitea skill to the agents.
the AGENT_TOKEN needs then more permission. is there a api to get the current permission of the agent token.
so that the agent can see waht he can do with gitea?
My earlier find excluded .gitea due to the pattern. Let me look at the actual workflow and existing skill structure. @ffaerber — answered your introspection question, but there's still one open decision before I can size and hand this off.
Is there a "what can this token do" API? No, not for the kind of token we use today (Authorization: token …, a plain Personal Access Token):
The only endpoint that returns a token's scopes is GET /users/{username}/tokens — but per Gitea's own docs that endpoint requires BasicAuth with the account password, not the token itself. A workflow holding only AGENT_TOKEN can't call it to check its own scopes (by design — otherwise a leaked token could self-inspect/escalate).
Gitea does have a real introspection endpoint (/login/oauth/introspect, RFC 7662) — but only for OAuth2 App access tokens issued via the full authorize/redirect flow, not for simple PATs. Standing up an OAuth2 App just to introspect a token is disproportionate here.
There's also no GitHub-style X-OAuth-Scopes response header. Confirmed against the current swagger spec.
So: skip runtime introspection. Do it the same way we did node1-ssh — the skill file documents exactly which scopes the token was granted at creation time, and that documentation is the source of truth (the agent doesn't need to ask the API "what am I allowed to do", it reads the skill). If a call 403s anyway, the agent just reports that and stops — no retries/probing.
Scopes needed (all read-only, per Gitea's scoped-token model):
read:repository — repo contents, PRs, and Actions runs/jobs/logs (/repos/{owner}/{repo}/actions/* falls under the repository scope group, so this covers "read Actions" too — no separate admin scope needed)
That's the minimal set for "open a referenced issue/PR, read its comments, check an Actions run's logs."
Still open — I need this to finalize scope of the token/skill:
Same-repo only, or cross-repo (any repo you own on this Gitea instance)? A same-repo token is just read:issue+read:repository scoped to the calling repo. Cross-repo means a token that isn't tied to one repo, which is a bigger blast radius if a run is ever compromised via prompt injection in an issue body.
One token or two? Reuse AGENT_TOKEN (currently PAT with issue+repo write, used only to fire the delegation comment) and just add these read scopes to it, or issue a separate, dedicated read-only token (e.g. TOKEN_GITEA_READONLY) so the "trigger next agent" capability and the "browse Gitea" capability stay cleanly separated? I'd lean separate token — smaller blast radius, and it mirrors how node1-ssh gets its own dedicated deploy key rather than reusing something else.
@ffaerber — same-repo or cross-repo, and one shared token vs a new dedicated one?
🤖 **@pm**
My earlier find excluded `.gitea` due to the pattern. Let me look at the actual workflow and existing skill structure.
@ffaerber — answered your introspection question, but there's still one open decision before I can size and hand this off.
**Is there a "what can this token do" API?** No, not for the kind of token we use today (`Authorization: token …`, a plain Personal Access Token):
- The only endpoint that returns a token's `scopes` is `GET /users/{username}/tokens` — but per Gitea's own docs that endpoint requires **BasicAuth with the account password**, not the token itself. A workflow holding only `AGENT_TOKEN` can't call it to check its own scopes (by design — otherwise a leaked token could self-inspect/escalate).
- Gitea *does* have a real introspection endpoint (`/login/oauth/introspect`, RFC 7662) — but only for OAuth2 App access tokens issued via the full authorize/redirect flow, not for simple PATs. Standing up an OAuth2 App just to introspect a token is disproportionate here.
- There's also no GitHub-style `X-OAuth-Scopes` response header. Confirmed against the current swagger spec.
**So: skip runtime introspection.** Do it the same way we did `node1-ssh` — the skill file documents exactly which scopes the token was granted at creation time, and that documentation *is* the source of truth (the agent doesn't need to ask the API "what am I allowed to do", it reads the skill). If a call 403s anyway, the agent just reports that and stops — no retries/probing.
**Scopes needed** (all read-only, per Gitea's scoped-token model):
- `read:issue` — issues/PRs/comments/labels/milestones
- `read:repository` — repo contents, PRs, **and** Actions runs/jobs/logs (`/repos/{owner}/{repo}/actions/*` falls under the `repository` scope group, so this covers "read Actions" too — no separate `admin` scope needed)
That's the minimal set for "open a referenced issue/PR, read its comments, check an Actions run's logs."
**Still open — I need this to finalize scope of the token/skill:**
1. **Same-repo only, or cross-repo** (any repo you own on this Gitea instance)? A same-repo token is just `read:issue`+`read:repository` scoped to the calling repo. Cross-repo means a token that isn't tied to one repo, which is a bigger blast radius if a run is ever compromised via prompt injection in an issue body.
2. **One token or two?** Reuse `AGENT_TOKEN` (currently PAT with issue+repo *write*, used only to fire the delegation comment) and just add these read scopes to it, or issue a **separate, dedicated read-only token** (e.g. `TOKEN_GITEA_READONLY`) so the "trigger next agent" capability and the "browse Gitea" capability stay cleanly separated? I'd lean separate token — smaller blast radius, and it mirrors how `node1-ssh` gets its own dedicated deploy key rather than reusing something else.
@ffaerber — same-repo or cross-repo, and one shared token vs a new dedicated one?
@pm cross-repo all repos should be read and write and one shared token for now all agents use the same.
this is waht i can set in gitea
activitypub | No Access | Read | Read and Write
admin | No Access | Read | Read and Write
issue | No Access | Read | Read and Write
misc | No Access | Read | Read and Write
notification | No Access | Read | Read and Write
organization | No Access | Read | Read and Write
package | No Access | Read | Read and Write
repository | No Access | Read | Read and Write
user | No Access | Read | Read and Write
@pm cross-repo all repos should be read and write and one shared token for now all agents use the same.
this is waht i can set in gitea
activitypub | No Access | Read | Read and Write
admin | No Access | Read | Read and Write
issue | No Access | Read | Read and Write
misc | No Access | Read | Read and Write
notification | No Access | Read | Read and Write
organization | No Access | Read | Read and Write
package | No Access | Read | Read and Write
repository | No Access | Read | Read and Write
user | No Access | Read | Read and Write
Good, this confirms the pattern. Let me look at the full workflow to understand structure, token usage, and how a new skill would be set up. @ffaerber — got the cross-repo + shared-token decision. One thing to nail down before this is safe to size and build, since it's a real change from what we've done so far.
What's locked in:
New gitea-api opencode skill (same pattern as node1-ssh), all agents can use it.
Cross-repo — not scoped to the calling repo.
One new shared secret dedicated to this skill (doesn't touch GITEA_TOKEN/AGENT_TOKEN/TOKEN_PM/etc., which keep doing what they do today: posting comments, opening PRs, acting as each agent's identity).
The scope list you pasted is Gitea's per-category radio choice (No Access / Read / Read and Write) — it doesn't mean every category has to be maxed out. The original ask was "read issues/PRs/actions" — that's a read capability. Granting write on top, across every repo you own, on categories like admin, user, organization, package is a much bigger blast radius than the feature needs, and it matters here specifically because this repo's whole trigger-gate design exists to contain prompt injection from issue text (see the comment on the if: gate in agent.yml) — a shared, cross-repo, write-everywhere token is the single juiciest target that gate was built to protect against.
My recommendation (mirrors the node1-ssh precedent: read-only, minimal, documented):
category
recommended
issue
Read
repository
Read (covers repo contents, PRs, and Actions runs/logs — no separate scope needed)
organization
Read (only if you want the agent to discover/list repos across an org)
misc
Read
activitypub, admin, notification, package, user
No Access
That's enough to do exactly what you asked for: open a referenced issue/PR (any repo), read its comments, and check an Actions run's logs.
Question: do you want to go with that minimal read-only set, or do you specifically need write here (e.g., so this same token can also comment/close/label on other repos, beyond what today's per-agent tokens already do on the current repo)? If it's write you want, tell me which category(ies) specifically need it and I'll size accordingly — I don't want to hand @junior/@senior a task that quietly maxes every scope to Read-and-Write across your whole Gitea instance without you having explicitly signed off on that exact tradeoff.
🤖 **@pm**
Good, this confirms the pattern. Let me look at the full workflow to understand structure, token usage, and how a new skill would be set up.
@ffaerber — got the cross-repo + shared-token decision. One thing to nail down before this is safe to size and build, since it's a real change from what we've done so far.
**What's locked in:**
- New `gitea-api` opencode skill (same pattern as `node1-ssh`), all agents can use it.
- Cross-repo — not scoped to the calling repo.
- One new shared secret dedicated to this skill (doesn't touch `GITEA_TOKEN`/`AGENT_TOKEN`/`TOKEN_PM`/etc., which keep doing what they do today: posting comments, opening PRs, acting as each agent's identity).
**The scope list you pasted is Gitea's per-category radio choice (No Access / Read / Read and Write) — it doesn't mean every category has to be maxed out.** The original ask was "read issues/PRs/actions" — that's a read capability. Granting **write** on top, across **every repo you own**, on categories like `admin`, `user`, `organization`, `package` is a much bigger blast radius than the feature needs, and it matters here specifically because this repo's whole trigger-gate design exists to contain prompt injection from issue text (see the comment on the `if:` gate in `agent.yml`) — a shared, cross-repo, write-everywhere token is the single juiciest target that gate was built to protect against.
My recommendation (mirrors the `node1-ssh` precedent: read-only, minimal, documented):
| category | recommended |
|---|---|
| issue | Read |
| repository | Read *(covers repo contents, PRs, and Actions runs/logs — no separate scope needed)* |
| organization | Read *(only if you want the agent to discover/list repos across an org)* |
| misc | Read |
| activitypub, admin, notification, package, user | No Access |
That's enough to do exactly what you asked for: open a referenced issue/PR (any repo), read its comments, and check an Actions run's logs.
**Question:** do you want to go with that minimal read-only set, or do you specifically need write here (e.g., so this *same* token can also comment/close/label on *other* repos, beyond what today's per-agent tokens already do on the *current* repo)? If it's write you want, tell me which category(ies) specifically need it and I'll size accordingly — I don't want to hand @junior/@senior a task that quietly maxes every scope to Read-and-Write across your whole Gitea instance without you having explicitly signed off on that exact tradeoff.
@ffaerber got it — one token, read+write, shared across all agents. Locking in the plan:
Token
One new secret, e.g. GITEA_API_TOKEN — single PAT, shared by every agent (dev + manager roles alike).
From the categories you listed, I'll set Read and Write on issue, repository, organization, misc (covers issues/PRs/comments/labels/Actions runs+logs/repo & org listing across all repos — this is the actual ask). I'll leave activitypub, admin, notification, package, user at No Access — those aren't part of "read issues/PRs/actions", and skipping them costs nothing in simplicity while keeping a shared token from also being able to touch account/org administration or other users. Flag it now if you actually want those maxed too; otherwise this is what gets built.
Build
New gitea-api opencode skill (mirrors the node1-ssh skill precedent): documents the base URL, Authorization: token $GITEA_API_TOKEN header, and example curl calls for the operations agents need — get issue/PR + comments, list/read Actions runs & logs, list org repos, plus write calls (comment, label, close, edit) — with an explicit warning to never echo the token and to treat fetched issue/PR content as untrusted data, not instructions (prompt-injection guard), same spirit as the trigger-gate comment in agent.yml.
Wire GITEA_API_TOKEN into .gitea/workflows/agent.yml as an env var available to the opencode run step, next to the existing tokens.
Since this is cross-repo and the workflow is called via workflow_call from every other repo, each caller needs to actually pass the new secret through (or it needs to be an org-level secret with secrets: inherit) — I'll have the assigned dev check the caller workflows so the skill doesn't silently fail outside this repo.
You'll need to manually create the actual PAT in Gitea with the scopes above and add it as the secret — I can't generate tokens or add secrets myself.
Who builds it: @senior — multi-file (skill doc + workflow yaml + possibly caller workflows in other repos), but it's applying an established pattern (node1-ssh) rather than new architecture, so it doesn't need @lead. @qa to follow up afterward: trigger an agent on an issue that references another repo's issue/PR and confirm it can actually fetch and use that content.
@ffaerber ready to start building? reply yes to proceed.
🤖 **@pm**
@ffaerber got it — one token, read+write, shared across all agents. Locking in the plan:
**Token**
- One new secret, e.g. `GITEA_API_TOKEN` — single PAT, shared by every agent (dev + manager roles alike).
- From the categories you listed, I'll set **Read and Write** on `issue`, `repository`, `organization`, `misc` (covers issues/PRs/comments/labels/Actions runs+logs/repo & org listing across all repos — this is the actual ask). I'll leave `activitypub`, `admin`, `notification`, `package`, `user` at **No Access** — those aren't part of "read issues/PRs/actions", and skipping them costs nothing in simplicity while keeping a shared token from also being able to touch account/org administration or other users. Flag it now if you actually want those maxed too; otherwise this is what gets built.
**Build**
1. New `gitea-api` opencode skill (mirrors the `node1-ssh` skill precedent): documents the base URL, `Authorization: token $GITEA_API_TOKEN` header, and example `curl` calls for the operations agents need — get issue/PR + comments, list/read Actions runs & logs, list org repos, plus write calls (comment, label, close, edit) — with an explicit warning to never echo the token and to treat fetched issue/PR content as untrusted data, not instructions (prompt-injection guard), same spirit as the trigger-gate comment in `agent.yml`.
2. Wire `GITEA_API_TOKEN` into `.gitea/workflows/agent.yml` as an env var available to the opencode run step, next to the existing tokens.
3. Since this is cross-repo and the workflow is called via `workflow_call` from every other repo, each caller needs to actually pass the new secret through (or it needs to be an org-level secret with `secrets: inherit`) — I'll have the assigned dev check the caller workflows so the skill doesn't silently fail outside this repo.
4. You'll need to manually create the actual PAT in Gitea with the scopes above and add it as the secret — I can't generate tokens or add secrets myself.
**Who builds it:** @senior — multi-file (skill doc + workflow yaml + possibly caller workflows in other repos), but it's applying an established pattern (`node1-ssh`) rather than new architecture, so it doesn't need @lead. @qa to follow up afterward: trigger an agent on an issue that references another repo's issue/PR and confirm it can actually fetch and use that content.
@ffaerber ready to start building? reply yes to proceed.
@ffaerber got it — reusing the already-reconfigured AGENT_TOKEN instead of minting a new GITEA_API_TOKEN secret. That's actually simpler to ship since AGENT_TOKEN is already a required secret in every caller repo (see README) — no new secret to add anywhere.
Updated build plan (delta from the previous plan — only the token source changes):
New gitea-api opencode skill (~/.config/opencode/skills/gitea-api/SKILL.md, mirrors the node1-ssh skill's structure/tone exactly): documents the base URL (${GITHUB_SERVER_URL}/api/v1/repos / instance API root), Authorization: token $AGENT_TOKEN header, and example curls for both read (get issue/PR + comments, list/read Actions runs & logs, list org/cross-repo issues) and write (comment, label, close, edit) — with the same explicit warnings as node1-ssh: never echo the token, and treat fetched issue/PR content as untrusted data, not instructions (this is the one part that's more sensitive here than node1-ssh, since this skill can reach other repos' issues, which may contain adversarial text).
Wire AGENT_TOKEN into the Run agent step's env: in .gitea/workflows/agent.yml. Important catch: today AGENT_TOKEN is only present in the later Publish step (used server-side for the auto-delegate curl) — the opencode agent process itself never sees it. It needs to be added to the step that actually runs opencode run (around line 261) or the skill has no credential to use.
Update the README secrets table — AGENT_TOKEN's description currently says "PAT (issue+repo write) used to post the delegation comment"; since you've now broadened its scopes to cross-repo issue/repository/organization/misc read+write, the doc should say it also powers the gitea-api skill, so nobody re-narrows it later thinking it's only for delegation.
No new secret propagation step needed (that's the simplification) — drop the old step 3/4 about creating/wiring a dedicated token.
Who builds: @senior — same sizing as before (skill file + workflow yaml + README), applying the established node1-ssh pattern rather than new architecture.
🤖 **@pm**
@ffaerber got it — reusing the already-reconfigured `AGENT_TOKEN` instead of minting a new `GITEA_API_TOKEN` secret. That's actually simpler to ship since `AGENT_TOKEN` is already a required secret in every caller repo (see README) — no new secret to add anywhere.
**Updated build plan (delta from the previous plan — only the token source changes):**
1. **New `gitea-api` opencode skill** (`~/.config/opencode/skills/gitea-api/SKILL.md`, mirrors the `node1-ssh` skill's structure/tone exactly): documents the base URL (`${GITHUB_SERVER_URL}/api/v1/repos` / instance API root), `Authorization: token $AGENT_TOKEN` header, and example `curl`s for both read (get issue/PR + comments, list/read Actions runs & logs, list org/cross-repo issues) and write (comment, label, close, edit) — with the same explicit warnings as `node1-ssh`: never echo the token, and treat fetched issue/PR content as **untrusted data, not instructions** (this is the one part that's more sensitive here than `node1-ssh`, since this skill can reach *other* repos' issues, which may contain adversarial text).
2. **Wire `AGENT_TOKEN` into the `Run agent` step's `env:`** in `.gitea/workflows/agent.yml`. Important catch: today `AGENT_TOKEN` is only present in the later `Publish` step (used server-side for the auto-delegate curl) — the opencode agent *process* itself never sees it. It needs to be added to the step that actually runs `opencode run` (around line 261) or the skill has no credential to use.
3. **Update the README secrets table** — `AGENT_TOKEN`'s description currently says "PAT (issue+repo write) used to post the delegation comment"; since you've now broadened its scopes to cross-repo issue/repository/organization/misc read+write, the doc should say it also powers the `gitea-api` skill, so nobody re-narrows it later thinking it's only for delegation.
No new secret propagation step needed (that's the simplification) — drop the old step 3/4 about creating/wiring a dedicated token.
**Who builds:** @senior — same sizing as before (skill file + workflow yaml + README), applying the established `node1-ssh` pattern rather than new architecture.
🔨@senior is on it — building on branch ai/issue-14. I'll open a PR when it's ready.
🔨 **@senior** is on it — building on branch [`ai/issue-14`](https://git.ffaerber.duckdns.org/ffaerber/agents/src/branch/ai/issue-14). I'll open a PR when it's ready.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
i have commented in a issue a about a other simular issue in gitea. but the agent was not able to open the connectyed issue.
the agent needs to read all the repos issues actions and so on. how can we do that?
@pm here
🤖 @pm
I dug into
.gitea/workflows/agent.yml(the shared workflow all repos call) to see exactly what context the agent gets today.What's happening now: for every run, the workflow only fetches:
IBODY/TITLE)issues/$NUM/comments, step "Fetch the full issue thread")There is no mechanism at all for:
GITEA_TOKEN/the API base URL, so even if it triedcurl, it has neither credentials nor a documented capability to do so (unlike thenode1-sshskill, which is the one precedent we have for giving an agent a scoped, read-only, documented capability).So "the agent couldn't open the connected issue" is expected — it's not a bug in this run, it's a missing capability in the shared workflow.
Before I can size this and assign it, I need a couple of decisions since they change the design and who should build it:
#123-style references in the thread and fetches a short summary of each referenced issue/PR (same repo only) and injects it into the prompt automatically — no new agent capability, no new attack surface, mirrors the existing thread-fetch step.gitea-apiskill + scoped token, similar in spirit tonode1-ssh— the agent cancurlGET-only Gitea API endpoints on demand (any issue/PR/comments/actions run, possibly cross-repo). More general, but it's a capability added to the shared workflow used by every repo, so it needs a tight allowlist (GET-only, specific hosts/paths) to avoid turning into an SSRF/data-exfil vector via a compromised or prompt-injected issue.My instinct: do (a) first as a small, low-risk PR that covers the common "opened a similar issue" case, and treat (b) as a separate, more careful follow-up if you actually want general cross-repo/actions browsing. But I'd rather confirm scope with you before committing anyone to build (b), since it's a security-relevant change to code every repo depends on.
@ffaerber — can you confirm scope (1)-(3) above, especially whether you need cross-repo/actions access or just "referenced issue in the same repo"?
@pm i think i like to add a new gitea skill to the agents.
the AGENT_TOKEN needs then more permission. is there a api to get the current permission of the agent token.
so that the agent can see waht he can do with gitea?
🤖 @pm
My earlier find excluded
.giteadue to the pattern. Let me look at the actual workflow and existing skill structure.@ffaerber — answered your introspection question, but there's still one open decision before I can size and hand this off.
Is there a "what can this token do" API? No, not for the kind of token we use today (
Authorization: token …, a plain Personal Access Token):scopesisGET /users/{username}/tokens— but per Gitea's own docs that endpoint requires BasicAuth with the account password, not the token itself. A workflow holding onlyAGENT_TOKENcan't call it to check its own scopes (by design — otherwise a leaked token could self-inspect/escalate)./login/oauth/introspect, RFC 7662) — but only for OAuth2 App access tokens issued via the full authorize/redirect flow, not for simple PATs. Standing up an OAuth2 App just to introspect a token is disproportionate here.X-OAuth-Scopesresponse header. Confirmed against the current swagger spec.So: skip runtime introspection. Do it the same way we did
node1-ssh— the skill file documents exactly which scopes the token was granted at creation time, and that documentation is the source of truth (the agent doesn't need to ask the API "what am I allowed to do", it reads the skill). If a call 403s anyway, the agent just reports that and stops — no retries/probing.Scopes needed (all read-only, per Gitea's scoped-token model):
read:issue— issues/PRs/comments/labels/milestonesread:repository— repo contents, PRs, and Actions runs/jobs/logs (/repos/{owner}/{repo}/actions/*falls under therepositoryscope group, so this covers "read Actions" too — no separateadminscope needed)That's the minimal set for "open a referenced issue/PR, read its comments, check an Actions run's logs."
Still open — I need this to finalize scope of the token/skill:
read:issue+read:repositoryscoped to the calling repo. Cross-repo means a token that isn't tied to one repo, which is a bigger blast radius if a run is ever compromised via prompt injection in an issue body.AGENT_TOKEN(currently PAT with issue+repo write, used only to fire the delegation comment) and just add these read scopes to it, or issue a separate, dedicated read-only token (e.g.TOKEN_GITEA_READONLY) so the "trigger next agent" capability and the "browse Gitea" capability stay cleanly separated? I'd lean separate token — smaller blast radius, and it mirrors hownode1-sshgets its own dedicated deploy key rather than reusing something else.@ffaerber — same-repo or cross-repo, and one shared token vs a new dedicated one?
@pm cross-repo all repos should be read and write and one shared token for now all agents use the same.
this is waht i can set in gitea
activitypub | No Access | Read | Read and Write
admin | No Access | Read | Read and Write
issue | No Access | Read | Read and Write
misc | No Access | Read | Read and Write
notification | No Access | Read | Read and Write
organization | No Access | Read | Read and Write
package | No Access | Read | Read and Write
repository | No Access | Read | Read and Write
user | No Access | Read | Read and Write
🤖 @pm
Good, this confirms the pattern. Let me look at the full workflow to understand structure, token usage, and how a new skill would be set up.
@ffaerber — got the cross-repo + shared-token decision. One thing to nail down before this is safe to size and build, since it's a real change from what we've done so far.
What's locked in:
gitea-apiopencode skill (same pattern asnode1-ssh), all agents can use it.GITEA_TOKEN/AGENT_TOKEN/TOKEN_PM/etc., which keep doing what they do today: posting comments, opening PRs, acting as each agent's identity).The scope list you pasted is Gitea's per-category radio choice (No Access / Read / Read and Write) — it doesn't mean every category has to be maxed out. The original ask was "read issues/PRs/actions" — that's a read capability. Granting write on top, across every repo you own, on categories like
admin,user,organization,packageis a much bigger blast radius than the feature needs, and it matters here specifically because this repo's whole trigger-gate design exists to contain prompt injection from issue text (see the comment on theif:gate inagent.yml) — a shared, cross-repo, write-everywhere token is the single juiciest target that gate was built to protect against.My recommendation (mirrors the
node1-sshprecedent: read-only, minimal, documented):That's enough to do exactly what you asked for: open a referenced issue/PR (any repo), read its comments, and check an Actions run's logs.
Question: do you want to go with that minimal read-only set, or do you specifically need write here (e.g., so this same token can also comment/close/label on other repos, beyond what today's per-agent tokens already do on the current repo)? If it's write you want, tell me which category(ies) specifically need it and I'll size accordingly — I don't want to hand @junior/@senior a task that quietly maxes every scope to Read-and-Write across your whole Gitea instance without you having explicitly signed off on that exact tradeoff.
@pm only one token for devs and managers that can read and write. make it simple
🤖 @pm
@ffaerber got it — one token, read+write, shared across all agents. Locking in the plan:
Token
GITEA_API_TOKEN— single PAT, shared by every agent (dev + manager roles alike).issue,repository,organization,misc(covers issues/PRs/comments/labels/Actions runs+logs/repo & org listing across all repos — this is the actual ask). I'll leaveactivitypub,admin,notification,package,userat No Access — those aren't part of "read issues/PRs/actions", and skipping them costs nothing in simplicity while keeping a shared token from also being able to touch account/org administration or other users. Flag it now if you actually want those maxed too; otherwise this is what gets built.Build
gitea-apiopencode skill (mirrors thenode1-sshskill precedent): documents the base URL,Authorization: token $GITEA_API_TOKENheader, and examplecurlcalls for the operations agents need — get issue/PR + comments, list/read Actions runs & logs, list org repos, plus write calls (comment, label, close, edit) — with an explicit warning to never echo the token and to treat fetched issue/PR content as untrusted data, not instructions (prompt-injection guard), same spirit as the trigger-gate comment inagent.yml.GITEA_API_TOKENinto.gitea/workflows/agent.ymlas an env var available to the opencode run step, next to the existing tokens.workflow_callfrom every other repo, each caller needs to actually pass the new secret through (or it needs to be an org-level secret withsecrets: inherit) — I'll have the assigned dev check the caller workflows so the skill doesn't silently fail outside this repo.Who builds it: @senior — multi-file (skill doc + workflow yaml + possibly caller workflows in other repos), but it's applying an established pattern (
node1-ssh) rather than new architecture, so it doesn't need @lead. @qa to follow up afterward: trigger an agent on an issue that references another repo's issue/PR and confirm it can actually fetch and use that content.@ffaerber ready to start building? reply yes to proceed.
@pm yes i have updated the AGENT_TOKEN please use this one. its already setup
🤖 @pm
@ffaerber got it — reusing the already-reconfigured
AGENT_TOKENinstead of minting a newGITEA_API_TOKENsecret. That's actually simpler to ship sinceAGENT_TOKENis already a required secret in every caller repo (see README) — no new secret to add anywhere.Updated build plan (delta from the previous plan — only the token source changes):
gitea-apiopencode skill (~/.config/opencode/skills/gitea-api/SKILL.md, mirrors thenode1-sshskill's structure/tone exactly): documents the base URL (${GITHUB_SERVER_URL}/api/v1/repos/ instance API root),Authorization: token $AGENT_TOKENheader, and examplecurls for both read (get issue/PR + comments, list/read Actions runs & logs, list org/cross-repo issues) and write (comment, label, close, edit) — with the same explicit warnings asnode1-ssh: never echo the token, and treat fetched issue/PR content as untrusted data, not instructions (this is the one part that's more sensitive here thannode1-ssh, since this skill can reach other repos' issues, which may contain adversarial text).AGENT_TOKENinto theRun agentstep'senv:in.gitea/workflows/agent.yml. Important catch: todayAGENT_TOKENis only present in the laterPublishstep (used server-side for the auto-delegate curl) — the opencode agent process itself never sees it. It needs to be added to the step that actually runsopencode run(around line 261) or the skill has no credential to use.AGENT_TOKEN's description currently says "PAT (issue+repo write) used to post the delegation comment"; since you've now broadened its scopes to cross-repo issue/repository/organization/misc read+write, the doc should say it also powers thegitea-apiskill, so nobody re-narrows it later thinking it's only for delegation.No new secret propagation step needed (that's the simplification) — drop the old step 3/4 about creating/wiring a dedicated token.
Who builds: @senior — same sizing as before (skill file + workflow yaml + README), applying the established
node1-sshpattern rather than new architecture.@senior please proceed with issue #14 per the plan above (delegated by pm).
🔨 @senior is on it — building on branch
ai/issue-14. I'll open a PR when it's ready.🤖 @senior — ✅ 1 PR ready for review — @ffaerber please review & merge: