Repository navigation
feat(pr-pipeline): let a trusted fix request name a same-plugin file to edit - #8470
Conversation
…to edit A write-access fix request on a kept review thread may name files; the select step records each one that sits in the thread path's plugins/<p>/ directory, is in normal form, is not under .github/ or an instruction path, and is a regular file at the gated head, as the thread's named_paths. thread-scope.mjs, the promote step, the reply job and check-paths accept changes to them. The instruction-path list moves from apply-ci-fix.mjs into thread-scope.mjs and now also bounds the plugin-wide part of a thread's scope, so a plugin's .mcp.json, .gitmodules or CODEOWNERS is refused there. Closes #8461 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… and non-ASCII paths From the security review of the named-path change: - The promote step refuses a lane branch that adds or changes a symbolic link or gitlink, read from the lane tip's tree entry modes. - Instruction paths match a hooks, .claude or .claude-plugin segment with nothing after it, and also cover a plugin's monitors/ and bin/ and .lsp.json, for apply-ci-fix and thread scope alike. - Thread scope refuses any path outside plain ASCII segments, so JS and the jq copy agree and no case-folding lookalike reaches a checkout, and its plugin-wide part refuses more script and code extensions. Refs: #8461 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
claude-security-review reviewed Security review (incremental, 3b1f117 → 6d6ed2d)No security issues found. The incremental change adds
No instruction-surface deletions in this diff, so the protected-class register was not needed. |
|
claude-review reviewed No findings. I read the incremental diff ( Change reviewed. What I checked.
I did not review the other files of this pull request, which are unchanged since the last review. |
|
The pr-unblock lane stopped on this pull request and needs a person: the merge stages a change under .github/workflows/, which the lane does not push.
To resume, deal with the reason above, remove the gh workflow run pr-unblock.yml -R melodic-software/claude-code-plugins -f pr-number=8470 -f activity=resolve-conflicts |
address-feedback.mjs: keep main's past-the-cap fix-request round and attach named paths to the threads that round works. pr-pipeline.schema.json: take main's prepare description, which moved the refused-path list to the patch rules; the list's monitors/, bin/ and .lsp.json additions stay in README.md, pr-run-activity.md and pr-pipeline.yaml. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xk7Lz7d2twxvA3LfRxnLkT
…d file A fix request naming _utils.js read as utils.js, and __init__.py as init__.py, so the lane could name in a file the requester did not name or drop the one they did. Strip _ only as a matched pair. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xk7Lz7d2twxvA3LfRxnLkT
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xk7Lz7d2twxvA3LfRxnLkT
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xk7Lz7d2twxvA3LfRxnLkT
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xk7Lz7d2twxvA3LfRxnLkT
|
Review note for the merge (from GitHub Security & Cost's pass at 9c2af24, P5, not blocking): |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xk7Lz7d2twxvA3LfRxnLkT
Words that pathTokens keeps but that are not files (obj.field, v1.2) took slots in the 10-path cap before the tree check, pushing a real named file out. Check every candidate and stop once 10 existing files are confirmed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xk7Lz7d2twxvA3LfRxnLkT
With the cap counting only existing files, nothing limited listTree calls: one per distinct parent directory, bounded only by comment length. Stop reading new directories after TREE_READ_CAP (2 x NAMED_CAP); names in directories already read still count. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xk7Lz7d2twxvA3LfRxnLkT
Closes #8461
Hold: a human merges this
Summary
A fix request by a trusted person with write access can now name files to add to its review thread's edit scope. A named file joins the scope only when it is in the same
plugins/<p>/directory as the thread's path. The owner decided this on #8461. The case that prompted it is #8116's threadPRRT_kwDOTCGFQM6tojDu: the owner's request onwrite-transcript.jsnamedrun-transcript.js, and the lane refused that file at 2026-10-19T02:31Z as outside every kept thread's scope.Fix
address-feedback.mjsselect: for each kept thread, reads the fix requests (isFixRequest) that write-access requesters (fixers) wrote. It takes each file-shaped word outside fenced code and quoted lines, with wrapping punctuation and a:linesuffix removed. A word with a/is read from the repository root; a bare file name is read from the thread path's directory. A path is kept as one of the thread'snamed_pathswhennamedInScopeallows it and the GraphQL tree at the gated head lists it as a regular file (mode100644or100755, exact name). At most 10 per thread.thread-scope.mjs:namedInScoperequires plain ASCII segments in normal form, the thread's ownplugins/<p>/prefix (case-sensitive), no.github/and no instruction path.inThreadScope(path, threadPaths, threads)accepts a path in a thread'snamed_pathsthatnamedInScopeallows for that thread.apply-ci-fix.mjs(isInstructionPath), so fix-ci and thread scope share one list.pr-run-activity-write.yml, the reply job (publish-feedback.mjs, which validatesnamed_pathsinrun.json) and thecheck-paths/recordjq copy infeedback-thread.shall apply the same rule.hooks,.claudeor.claude-pluginsegment, and also cover a plugin'smonitors/andbin/and.lsp.json._@+.-. That closes the JS-versus-jq case-folding gap for characters such as U+212A KELVIN SIGN; no tracked path today has such a character..mcp.json,.gitmodulesandCODEOWNERS, and.bash,.zsh,.ps1,.cjs,.mtsand.ctsfiles.docs/conventions/pr-pipeline/pr-run-activity.md(where thread scope is described),comments-ci.md, and the fix-ci instruction lists inREADME.md,pr-pipeline.yamlandpr-pipeline.schema.json. Fragments are in.changes/pr-pipeline/and.changes/source-control/.Verification
node --testin.github/scripts/pr-unblock: 437 pass, 0 fail.feedback-thread.test.sh: all pass.scripts/check-affected.sh: 7 passed, 1 skipped (ruff, no.py), over 18 files.actionlintonpr-run-activity-write.yml: clean.shellcheckon both shell files: clean.run-transcript.js);.github/and instruction paths are refused;../and absolute names are refused;review:security-reviewer): no traversal escape and no escape at name time. It reported a symlink gap at promote time, missing instruction paths, and a non-ASCII case-folding gap; all three are fixed in the second commit.Related
PRRT_kwDOTCGFQM6tojDu: the failing case.also edit <path>line would be stricter, but the fix(knowledge): feed ASR transcript cues to video-digest frame densification #8116 request does not use one.threads.json) is not hash-pinned between the select step and the promote step, as it was before this change.🤖 Generated with Claude Code