fix(context-bill): walk directories through their realpaths so a deep link chain cannot drop files

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
This commit is contained in:
garrytanandcapy-ai[bot] committed 2026-10-26 02:27:46 +00:00
1 parent 77fe211776
commit c7ddca62db
2 files changed
+61 -23

No files matched your search

+22
View File
@@ -391,6 +391,28 @@ describe("upstream fix b: installed-tree layout (repo-checkout subdir skip)", ()
fs.rmSync(root, { recursive: true, force: true });
});
it("walks a chain of links deeper than the kernel's link limit without losing files", () => {
if (process.platform === "win32") return;
const tmp = fs.mkdtempSync(path.join(os.tmpdir(), "context-bill-deep-chain-"));
const depth = 50;
for (let i = 0; i < depth; i++) {
fs.mkdirSync(path.join(tmp, "levels", `L${i}`), { recursive: true });
fs.writeFileSync(path.join(tmp, "levels", `L${i}`, `f${i}.md`), "x");
}
for (let i = 0; i < depth - 1; i++) {
fs.symlinkSync(path.join(tmp, "levels", `L${i + 1}`), path.join(tmp, "levels", `L${i}`, "next"));
}
const root = path.join(tmp, "skills");
fs.mkdirSync(path.join(root, "qa"), { recursive: true });
fs.writeFileSync(path.join(root, "qa", "SKILL.md"), "---\nname: qa\ndescription: d\n---\n# qa\n");
fs.symlinkSync(path.join(tmp, "levels", "L0"), path.join(root, "qa", "next"));
expect(walkMd(path.join(root, "qa")).length).toBe(depth + 1);
const qa = buildBill(root).skills.find((s) => s.name === "qa")!;
expect(qa.totalMdBytes).toBe(fileBytes(root, "qa", "SKILL.md") + depth);
fs.rmSync(tmp, { recursive: true, force: true });
});
it("refuses skill discovery past its entry cap instead of walking on", () => {
const root = fs.mkdtempSync(path.join(os.tmpdir(), "context-bill-discovery-cap-"));
fs.mkdirSync(path.join(root, "vendor"));