From 2a6f74027fa61f1e994547285ff62964ac9770a2 Mon Sep 17 00:00:00 2001 From: sim Date: Sat, 12 Sep 2026 18:49:48 -0400 Subject: [PATCH] chore(#4653): backfill PR 4672 into both changesets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also corrects the Changed fragment: it named three containment exports as the only ones, which stopped being true when the lexical family was added to close DW1/DW9. It now describes one decision resolved two ways, and says why the lexical pair exists rather than leaving a reader to assume it is a weaker alternative to the realpath form. scripts/lint-docs-required.cjs now passes (ok_docs_updated) — it could not evaluate against the mandated pr:0 placeholder. Co-Authored-By: Claude Opus 5 --- .changeset/eager-badgers-bark.md | 4 ++-- .changeset/gallant-hawks-tumble.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.changeset/eager-badgers-bark.md b/.changeset/eager-badgers-bark.md index 7882a6145..ab8071b6a 100644 --- a/.changeset/eager-badgers-bark.md +++ b/.changeset/eager-badgers-bark.md @@ -1,5 +1,5 @@ --- type: Changed -pr: 0 +pr: 4672 --- -**The path-containment predicate is now a single exported seam** — `security.cjs` no longer exports `validatePath`; `assertWithinRoot` (throws), `tryWithinRoot` (returns null) and `requireSafePath` are the only containment exports, and all three return a branded `ContainedPath` so a validated path cannot be silently swapped for an unvalidated one. The per-call-site `{ allowAbsolute: true }` flag is replaced by the named `PathAcceptance` policy, which states what it actually permits: an absolute path outside the root was always rejected and still is. The traversal rejection text `Path escapes allowed directory: is outside ` is preserved verbatim, and no command changes what it accepts or rejects. Three rejection MESSAGES are reworded, none of which now reveals a host path it previously hid: `state.cts`'s `