Repository navigation
fix(github): hide every request of a redacted target, and read an empty repository as unproven - #589
Merged
Merged
Conversation
…ty repository as unproven A redacted target's debug trace printed any request whose path named no repository: the owner probe GET /orgs/<owner> the teams and custom_properties sections send, and the app lookup GET /apps/<slug> the branches section sends. The trace collapsed a path only when it found a masked /repos/<owner>/<name> slug in it. The run now says which requests serve a redacted target. A redacted target's channel hands the engine the client's redacted view (redactedClient), which marks every request redactTrace, and GitHubApi seals the whole trace while a marked request is in flight, so the request-log plugin's lines collapse with the client's own. The four places a flow hands a target's client to the engine (single, multi, snapshot-file, snapshot-dir) go through the channel. The slug-keyed hold and its refusal of a slug-free path are gone. An empty repository answers its ref read 409 "Git Repository is empty.", which getRepoFile read as a failure and told the operator to re-run. It is now the inconclusive proof the file already had for a denied grant, which names the uninitialized branch. The throttle callback printed "retry N/2 after Ns" before deciding, so the line announced a retry for a wait over the 60 s cap and for the attempt after the last retry. It now writes the line where it decides: a retry, or giving up and why.
Contributor
File size check0 over a hard cap (fails), 6 warning(s).
Split the file, wrap the line, shorten or exempt the comment, or list the path in 5 managed file(s) skipped; repo-platform owns them. |
Contributor
Member shape check2 finding(s).
Add the blank lines, make the comment one line directly above the item, comment every field or none, or list the path in 4 generated file(s) skipped. |
There was a problem hiding this comment.
🟢 Approval recommended
No active review issues are reported for the trace-redaction and repository-handling changes.
No open issues 🎉
What changed in this PR
Strengthens private-target trace redaction across the action's execution flows and improves handling of empty repositories and rate-limit diagnostics.
Changes:
- Marks all requests serving redacted targets and suppresses routes and payloads throughout their execution, including plugin logs.
- Treats an empty repository's ref-read 409 as inconclusive, preventing defaults from being applied without proven file absence.
- Aligns throttle messages with actual retry decisions and adds regression coverage.
| File | Description |
|---|---|
test/github/stub.ts |
Adds reusable JSON response and trace-timing helpers. |
test/github/repo-file.test.ts |
Covers empty repositories as inconclusive file reads. |
test/github/redacted-target-trace.test.ts |
Tests private-target traces across all four flow paths. |
test/github/api.test.ts |
Covers request marks, overlapping redaction, client views, and retry diagnostics. |
src/github/trace-redaction.ts |
Seals traces while marked requests are in flight, retaining persistent masks. |
src/github/repo-file.ts |
Classifies ref-read 409 responses as inconclusive. |
src/github/api.ts |
Adds cached redacted client views and accurate throttle messages. |
src/flows/snapshot.ts |
Uses channel-selected clients for both snapshot forms. |
src/flows/single.ts |
Passes the channel-selected client to single-repository execution. |
src/flows/redact.ts |
Adds client selection to public and redacted target channels. |
src/flows/multi.ts |
Uses the channel-selected client for target reads and execution. |
Review effort: Balanced
The flow tests answered GitHub with a hand-written route table. They now run against the e2e mock server (startMockServer), which already serves the visibility probe, the contents read, the owner probe, and the teams list, and records every request. The four flows and the mixed-fleet control still fail on the unfixed flow lines. The library reference names redactTrace on the RequestMark and ListOptions rows, and the troubleshooting page says the trace collapse holds in single-repository, multi-repo, and snapshot runs. Comments only in src/: RequestMark documents both of its members, the redacted constant is commented beside its neighbour, and the visibility probe's comment says what the mark does now that the slug-keyed hold is gone.
Vivswan
marked this pull request as ready for review
November 12, 2026 02:16
This was referenced Nov 12, 2026
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.
Before
After
How
RequestMarkandListOptionsgain the optionalredactTrace, an additive public field.@octokit/plugin-throttling, covers the retry decision, which stays with it.Proof
unprovenvalue for an empty repository, the throttle lines.bun test test/github, 138 pass, 0 fail.Technical details
capture-run.ts: the built bundle over the e2e mock, with a publicacme/appand a privatesecret-org/private-repo, inmode: apply.capture-client.ts:runMultiandGitHubApiover a stubbedfetchthat answers as GitHub does for an empty repository and for a rate limit.origin/main, After on this branch....line, Before: 14 lines of the same run: 5 barerequestlines of the request-log plugin, 5<redacted>, 3GET <redacted> -> <status>, and 1POST /graphql - 200 with id undefined in 3ms....line, After: the same 14 lines, now 11<redacted>and 3GET <redacted> -> <status>.GET /orgs/acme, in both states.test/github/redacted-target-trace.test.tsruns the flows in process againststartMockServer(), in check mode and in both snapshot forms.GET /orgs/secret-orgwith no contract violation, and the trace holds only the forms<redacted>andGET <redacted> -> <status>.secret-orgorprivate-repo.test/github/api.test.tsasserts a marked request leaves two<redacted>plugin lines and its own redacted line on six routes,/apps/internal-deploy-botamong them, then prints legibly unmarked.test/github/repo-file.test.tsassertsgetRepoFilereturns theunprovenvalue for GitHub's 404 then 409, not the run's::error::line.test/github/api.test.tsasserts the request count and the throttle lines, with the wait's number folded toNs.origin/main'ssrc/, the five flow tests fail on the printed probe.src/flowsfromorigin/mainunder this branch's client, the same five fail.origin/mainfor the missing export, and on a view that drops a mark.bun test/e2e/run.ts --sections teams,custom_properties, 20/20.--scenario:multi-private-redact-default,multi-private-drift-redacted,multi-private-probe-denied,multi-private-self-carveout,multi-report-issue-delivery,multi-report-artifact-delivery,multi-report-secret-withheld,snapshot-private-notes-redacted,snapshot-dir-multi-repo, each 1/1.TargetChannelis internal: neithersrc/index.tsnorsrc/internal.tsexports it, soclient()adds no public API.src/flows/multi.ts(processTarget, which feedsrunForRepoandgetRepoFile),src/flows/single.ts(runForRepo),src/flows/snapshot.ts(bothsnapshotTargetcalls, which feedsnapshotRepository).grep -rnE "\b(runForRepo|snapshotRepository|readSnapshot|getRepoFile|processTarget|snapshotTarget)\(" src, less the engine, the sections, and the definitions.src/flows/library.tsandsrc/cli/init.ts, which have no redaction policy.src/flows/deliver.ts, whose routes all name/repos/<slug>, which the masked slug collapses.TraceRedaction.hold(slug), therepoSlugOfexport, theBUG: redactTrace needs a /repos/<owner>/<repo> paththrow.redactTrace holds the slug for the request onlyis now six rows ofa request marked as serving a redacted target leaves no route or payload in the trace.overlapping holds on one slug are independentis nowoverlapping requests for redacted targets keep the trace sealed until the last one settles.docs/reference/library.mdnamesredactTraceon theRequestMarkandListOptionsrows.docs/operate/troubleshooting.mdsays the trace collapse holds in single-repository, multi-repo, and snapshot runs.src/github/{api.ts,trace-redaction.ts,repo-file.ts,repo-visibility.ts},src/flows/{redact.ts,multi.ts,single.ts,snapshot.ts},test/github/{api.test.ts,repo-file.test.ts,redacted-target-trace.test.ts,stub.ts},docs/{reference/library.md,operate/troubleshooting.md}.