8ff74b1a-e539-4d3e-8644-5601097d01c7
Ran for 1m 19s (finished about 2 months ago)
State
Statussucceeded
Current statesuccess
Trace idccb28d2623ca49e382fc872e32dd13f1
Error—
Agent timeline
- post-comment1 attempt
- review2 attempts
- status-pending-review1 attempt
- status-success-review1 attempt
Event trace (0)
No events yet.
Scratchpad
Expand JSON
{
"repo": "Levanto/Levanto-Aion",
"review": {
"summary": "This PR makes the CI and review pipelines actually functional end-to-end: scopes ci-quality-agent to changed files (fixing docs-only-PR perma-red), pins writable cache dirs, filters mypy from hyphenated dirs, populates changed_files in the webhook with correct GitHub truncation handling (>20 commit guard, 2000-file fallback), installs a version+arch-pinned docker CLI in the worker image, and — most importantly — hardens the review-agent against prompt injection with a per-request 128-bit nonce on UNTRUSTED-PR-DATA markers, defensive scrubbing of any literal marker substring in PR content, and a strong system-prompt trust-boundary section. The review-agent also now fetches per-file diffs and full file content at head SHA, with bounded concurrency (8) to avoid GitHub secondary rate limits. Test coverage was added for all four ci-quality regressions. Findings are all minor (image bloat, error-distinguishability nits, mypy suppression hygiene); no security, correctness, or privacy blockers. High confidence in this review — I reviewed the head-SHA full-file content for the security-critical review-agent and webhook changes and verified the nonce-based marker design is sound.",
"verdict": "approved",
"findings": [
{
"file": "agents/build-agent/agent.py",
"lens": "architecture",
"line": 145,
"finding": "The comment says 'use a targeted replacement instead' but the code still uses `.removesuffix(\"/.\")` — comment is misleading vs. the actual implementation (though `removesuffix` is in fact the correct targeted approach, unlike the original `.rstrip`).",
"severity": "minor"
},
{
"file": "agents/ci-quality-agent/agent.py",
"lens": "operational",
"line": 95,
"finding": "When changed_files contains zero .py paths the per-check `output` field starts with 'skipped: ...' but `passed=True`; the report-level `passed=True` could mask a future bug where the filter incorrectly drops all .py files — consider also surfacing the original changed_files count in the skip-report output for debuggability.",
"severity": "minor"
},
{
"file": "agents/review-agent/agent.py",
"lens": "architecture",
"line": 105,
"finding": "`_fetch_one` swallows all exceptions from `get_file_contents` and returns `None`, which is rendered identically to 'binary/oversized' in the prompt; on a transient 5xx burst the model can't distinguish 'we couldn't fetch' from 'unfetchable', degrading review quality silently. Consider distinguishing fetch-error from null-content in the rendered output.",
"severity": "minor"
},
{
"file": "apps/orchestrator-api/app/api/routes/webhooks.py",
"lens": "operational",
"line": 108,
"finding": "The bare `except Exception` on `list_pull_request_files` swallows any exception including KeyboardInterrupt-adjacent issues like asyncio.CancelledError on older Python versions; on 3.12 CancelledError doesn't inherit from Exception so this is fine, but consider narrowing to httpx.HTTPError / asyncio.TimeoutError for clarity.",
"severity": "minor"
},
{
"file": "apps/worker-runtime/Dockerfile",
"lens": "operational",
"line": 78,
"finding": "Installing both the `docker.io` apt package (which pulls in the daemon ~200+ MB) AND a static docker CLI binary is wasteful — only the CLI is needed since the worker shells through a bind-mounted host socket. Consider dropping `docker.io` from the apt install list to slim the image and reduce attack surface.",
"severity": "minor"
},
{
"file": "tools/github/tool.py",
"lens": "architecture",
"line": 38,
"finding": "Stacking three mypy ignore codes (`import-not-found,import-untyped,unused-ignore`) is a code smell hiding a structural issue (hyphenated runtime/ dir lacks py.typed). The cleanup is acknowledged in the comment, but pinning a single mypy version in pyproject.toml would be a more targeted short-term fix than version-agnostic suppression.",
"severity": "minor"
}
]
},
"base_ref": "main",
"head_sha": "71e59d1d02c2e5a809ce60963474223c3e0fe80d",
"pr_number": 16,
"post-comment": {
"posted": {
"posted": true,
"pr_number": 16,
"body_chars": 3920,
"comment_id": 4532653715
}
},
"changed_files": [
"agents/build-agent/agent.py",
"agents/ci-quality-agent/agent.py",
"agents/ci-quality-agent/tests/test_agent.py",
"agents/review-agent/agent.py",
"agents/review-agent/prompts/system.md",
"apps/orchestrator-api/app/api/routes/webhooks.py",
"apps/worker-runtime/Dockerfile",
"docs/MODEL_ROUTING.md",
"docs/QUICKSTART.md",
"docs/README.md",
"infra/scripts/sync-claude-credentials.sh",
"pyproject.toml",
"tools/github/tool.py",
"workflows/ci-pipeline/workflow.py"
],
"dashboard_url": "http://aion.levanto.in/runs/8ff74b1a-e539-4d3e-8644-5601097d01c7",
"status-pending-review": {
"posted": {
"sha": "71e59d1d02c2e5a809ce60963474223c3e0fe80d",
"state": "pending",
"posted": true,
"context": "aion/review",
"target_url": "http://aion.levanto.in/runs/8ff74b1a-e539-4d3e-8644-5601097d01c7"
}
},
"status-success-review": {
"posted": {
"sha": "71e59d1d02c2e5a809ce60963474223c3e0fe80d",
"state": "success",
"posted": true,
"context": "aion/review",
"target_url": "http://aion.levanto.in/runs/8ff74b1a-e539-4d3e-8644-5601097d01c7"
}
}
}