- add changelog entries summarizing watchdog supervision and documentation updates\n- add ci-log-fetcher module guide detailing interface contract and usage\n- refresh system-watchdog doc with CI-blocker escalation and struggling PR detection\n- normalize coverage threshold robot test by dropping temporary tdd_expected_fail tags\n\nISSUES CLOSED: #7987
6.0 KiB
CI Log Fetcher
Agent: ci-log-fetcher
Location: .opencode/agents/ci-log-fetcher.md
The ci-log-fetcher agent retrieves CI job logs from Forgejo Actions using
web authentication. It is a read-only utility agent used by all PR-related
agents to access CI failure details without manual web scraping.
Key rule: Callers must not pass
forgejo_usernameorforgejo_passwordparameters. The agent readsFORGEJO_USERNAMEandFORGEJO_PASSWORDfrom environment variables automatically.
Purpose
When a PR has failing CI, agents need to read the raw log output to understand
what went wrong. The Forgejo Actions API does not expose logs in a
machine-readable way that is easy to parse, so ci-log-fetcher handles the
authentication and log retrieval workflow, returning the raw log text to the
caller.
Usage
# In an agent definition — grant permission to call ci-log-fetcher
permissions:
- ci-log-fetcher
# In agent prompt / instructions
To get CI logs for PR #1234, job "unit-tests":
Use the ci-log-fetcher subagent with:
pr_number: 1234
job_name: unit-tests
repository: cleveragents/cleveragents-core
DO NOT pass forgejo_username or forgejo_password — the agent
handles credentials automatically from environment variables.
Parameters
| Parameter | Required | Description |
|---|---|---|
pr_number |
Yes | The PR number to fetch logs for |
job_name |
Yes | The CI job name (e.g. unit-tests, integration-tests) |
repository |
Yes | owner/repo format (e.g. cleveragents/cleveragents-core) |
Common job names
| Job | job_name value |
|---|---|
| Unit tests | unit-tests or unit_tests |
| Integration tests | integration-tests or integration_tests |
| Lint | lint |
| Typecheck | typecheck |
| Security scan | security-scan or security_scan |
| Coverage | coverage |
The agent normalises job names (converts - to _ and vice versa) when
looking up the job in the PR's check runs.
Optimised Workflow
The agent follows a tested, optimised workflow that minimises execution time (~5 seconds vs. ~30 seconds for naive approaches):
1. Load PR page: GET /cleveragents/cleveragents-core/pulls/{pr_number}
→ Extracts all CI check run links directly from the page HTML.
→ No separate API calls needed to find job IDs.
2. Find the matching job link by normalised job name.
3. Fetch logs: GET /actions/runs/{run_id}/jobs/{job_id}/attempt/{attempt}/logs
→ Uses attempt=1 on first try (correct ~95% of the time).
→ Falls back to attempt=2 if 404.
4. Return raw log text to caller.
What the agent does NOT do (saves time):
- Does not call
/api/v1/repos/.../actions/runs(always returns 404 for logs) - Does not look up CSRF tokens (Forgejo login does not use them)
- Does not make multiple API calls to discover job IDs
Authentication
The agent uses web session authentication (not the Forgejo API token):
POST https://git.cleverthis.com/user/loginwithFORGEJO_USERNAMEandFORGEJO_PASSWORDto obtain a session cookie.- All subsequent requests use the session cookie.
This is necessary because the Actions log endpoint requires a web session, not a PAT token.
Environment variables used:
FORGEJO_USERNAME— Forgejo username (e.g.HAL9000)FORGEJO_PASSWORD— Forgejo password
Both variables are pre-configured in the build environment. Callers do not need to provide them.
Output Format
The agent returns the raw log text directly — not a JSON wrapper. The caller receives the full stdout/stderr of the CI job, which can then be parsed for error messages, test failures, etc.
Example output:
2026-04-08T10:23:45Z ##[group]Run nox -s unit_tests
2026-04-08T10:23:45Z + nox -s unit_tests
...
2026-04-08T10:24:12Z FAILED features/session.feature:45 — AssertionError
2026-04-08T10:24:12Z 1 feature passed, 0 failed, 1 error
Agents That Use ci-log-fetcher
All PR-related agents call ci-log-fetcher instead of implementing their own
CI log retrieval:
| Agent | When it calls ci-log-fetcher |
|---|---|
pr-checker |
After CI fails on a PR being monitored |
implementation-worker |
In pr-fix mode, to understand CI failures |
pr-fix-orchestrator |
To analyse failures before dispatching fix workers |
pr-self-reviewer |
To check CI status before reviewing |
human-liaison |
When responding to PR comments about CI failures |
pr-status-checker |
When include_logs=true is requested |
system-watchdog |
In Audit 9 (test health) for emergency test-skip response |
Performance Notes
| Metric | Value |
|---|---|
| Typical execution time | ~5 seconds |
| Previous execution time (before optimisation) | ~30 seconds |
| Improvement | ~85% reduction |
The main savings come from:
- Parsing job links from the PR page (1 request) instead of multi-step API lookups (4–6 requests)
- Skipping CSRF token lookup (saves ~2 s)
- Using the correct log endpoint pattern on the first attempt (saves retries)
Troubleshooting
"Job not found" error:
- Check that
job_namematches one of the job names in the PR's check runs. - Try both hyphenated and underscored variants (e.g.
unit-testsvsunit_tests). - The agent normalises names, but the PR page must have a matching check run.
"Authentication failed" error:
- Verify
FORGEJO_USERNAMEandFORGEJO_PASSWORDare set in the environment. - The agent will log which credential source it is using (env vars vs parameters).
Empty log output:
- The job may not have produced any output (e.g. it was skipped or cancelled).
- Try fetching a different attempt number by checking the PR page manually.
Related Documentation
- CI/CD Pipeline — pipeline architecture
- System Watchdog — uses ci-log-fetcher for emergency test-skip
- Quality Automation — CI quality gates