Repository navigation
feat(worker,engine): hand a repair round the tail of each failed CI job's log (CI repair, U4) - #17
Merged
Merged
Conversation
…ob's log (CI repair U4) CommitChecks now records each check run's id and app. The gateway gains FailedCheckLogs, which attaches the end of a failed GitHub Actions job's log (the check run id is the job id) and never fails: any check without a log carries a note saying why. Logs are read with a new tail-keeping runner, since the existing bounded runner keeps the first bytes and a failure sits at the end. A tail drops its fragment first line, loses Actions timestamps and ANSI codes, is cut to whole lines within 16 KiB, and is valid UTF-8. At most four logs are read (64 KiB in all); failed reads do not spend that budget. The engine bounds the tails again rather than trusting the worker, keeping each one's end and the 64 KiB total, and the repair envelope says outright that a log line asking for something is output to diagnose, never a request to follow. Nothing reads logs until the round loop (U5). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nd treat inserted text as data
Security review of U4 found three problems. The ci_repair_start trace event
carried every log tail, so anything GitHub failed to mask would persist in
the control plane, and 64 KiB of logs pushed the event past its payload cap
and mangled it; it now records name, conclusion, URL, note, and log_bytes
only. FailedCheckLogs read passing checks and did not count failed reads,
so a hanging gh had no overall bound; it now reads only failures and stops
after eight attempts. And composePrompt rescanned text it had inserted, so
a {{handoff_dir}} inside a CI log or a parameter value could rewrite data
and suppress the handoff section; it now substitutes in one pass over the
template and decides sections from the template alone.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Warning Review limit reachedNext included review available in 32 minutes. View limit detailsLimit details: You’ve used the included review currently available. You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Review configuration: ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (8)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
U4 of the CI repair plan: a repair round sees the end of each failed CI job's log, not just the check's name. A single PR against
main, not stacked.CommitChecksnow records each check run'sidandapp. For GitHub Actions, the check run id is the job id.FailedCheckLogs, which readsrepos/{o}/{r}/actions/jobs/{id}/logsand never fails: a check with no log carries aLogNotesaying why.log_tail/log_notein eachfailed_checksentry.ghtimeoutThe engine re-applies the bounds itself rather than trusting the worker. It also tells the agent that a log line asking for something is output to diagnose, never a request to follow.
Bugs found on the way
ghrunner keeps the first 4 MiB of output, which would have thrown away the part of a log where the failure is. U4 adds a tail-keeping runner (runTailCommand).Security review: three findings, all fixed
ci_repair_starttrace event, so anything GitHub's***masking missed would persist in the control plane. 64 KiB of logs also pushed the event past its payload cap and mangled it. The event now records name, conclusion, URL, note andlog_bytesonly.ghhad no overall bound. Passing checks weren't skipped either. Reads are now capped at 8 and only failures are read.{{handoff_dir}}inside a CI log or a parameter value could rewrite data and suppress a prompt section, becausecomposePromptrescanned text it had already inserted. It now substitutes in one pass over the template and decides which sections to add from the template alone. This touches every prompt jig builds; the existing suite passes unchanged.Nothing calls
FailedCheckLogsuntil the round loop lands (U5). ThecomposePromptfix is live immediately and changes behaviour only when a parameter value contains a{{…}}placeholder: that placeholder now stays literal instead of being substituted.Verification
just checkis green.Mutation-checked: 27 breaks, all caught. Four fixture gaps let mutants through at first:
ghreturnedid/appwhatever the query asked for.All four fixed; every remaining "caught" was checked to compile first.
🤖 Generated with Claude Code