From e831c0793fec981dc567acdf18eaf182931b858f Mon Sep 17 00:00:00 2001 From: Sebastian Mendel Date: Sat, 22 Aug 2026 08:53:05 +0200 Subject: [PATCH] docs(multi-repo): probing paths cannot tell absent from unlooked-at MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The section on enumerating structurally recommends probing each repository for a marker file with contents/. That is right about the search index, but a sweep assembled from plausible paths reports the same "absent" for a file that does not exist and one that sits at a path the list does not name. Measured across 25 extensions: five probed php-cs-fixer paths reported 11 repositories without a config; ten had one, at a sixth path that was the most common layout there. The tracked defect reached 13 repositories, not 3, and the fix under review had been built from the same guessed list — it repaired the flag and left ten repositories unchanged. Adds the tree listing as the alternative, and asks that an empty bucket be named "none of the paths checked" with the list, where probing is unavoidable. The documented command was run as written against a repository with the awkward layout and returns Build/.php-cs-fixer.dist.php. Assisted-by: claude-code:claude-opus-5 Agent-Session: https://claude.ai/code/session_01GSptxPLHWsttu9FuqVkvYZ Agent-Host: 0493f0 Signed-off-by: Sebastian Mendel --- .../references/multi-repo-operations.md | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/skills/github-project/references/multi-repo-operations.md b/skills/github-project/references/multi-repo-operations.md index 95f023a..39869a3 100644 --- a/skills/github-project/references/multi-repo-operations.md +++ b/skills/github-project/references/multi-repo-operations.md @@ -248,6 +248,37 @@ declaration other repos depend on), enumerate structurally instead: probe each repo for the marker file with `gh api repos/OWNER/REPO/contents/`, which reads the live tree rather than an index. +### Probing paths answers a narrower question than it looks + +The `contents/` probe above is right about the index, but it only ever +answers *is the file at this path*. A sweep built from a list of plausible paths +reports the same "absent" for a file that does not exist and for one that sits +somewhere the list does not name — and the resulting count reads like a +measurement. + +Measured across 25 extensions: a sweep of five plausible `php-cs-fixer` config +paths reported 11 repositories with no config. Ten of them had one, at a sixth +path that was the single most common layout in that fleet. The real figure for +the defect being tracked was 13 repositories, not 3, and the number had already +reached an issue and a colleague. Worse, the fix under review had been built +from the same guessed list, so it repaired the flag and left ten repositories +exactly as broken as before. + +A candidate list is assembled from the layouts you already know. The layouts you +do not know are the reason the sweep exists. So list the tree and classify what +comes back: + +```bash +# Every matching path, whatever the layout — one request per repo +gh api "repos/OWNER/REPO/git/trees/BRANCH?recursive=1" \ + --jq '[.tree[] | select(.path|test("php-cs-fixer";"i")) + | select(.path|test("^vendor/|^\\.Build/")|not) | .path] | join(" ")' +``` + +Where probing is genuinely the only option, do not name the empty bucket +"absent". Call it "none of the paths checked" and print which ones were checked, +so the next reader can see the hole instead of inheriting the number. + ## Cache-Safety for Batch Operations When iterating across many local worktrees, it's easy to edit an installed skill/plugin cache by mistake. Before any write in a multi-repo loop: