From f8542fef67c1f978ffa70912cb6f2aaab76464c6 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 14 Sep 2026 00:01:08 +0000 Subject: [PATCH] chore: promote CHANGELOG for v1.14.0 --- .changeset/3644-completion-seam.md | 7 -- .changeset/4089-minimum-solution.md | 5 - .changeset/agile-badgers-roar.md | 5 - .changeset/agile-wasps-chatter.md | 5 - .changeset/bold-cranes-rest.md | 5 - .changeset/bold-ibex-chatter.md | 5 - .changeset/bold-jaguars-parade.md | 5 - .changeset/brave-elks-glide.md | 5 - .changeset/brave-finches-zip.md | 5 - .changeset/brave-geese-sing.md | 5 - .changeset/calm-goats-bark.md | 5 - .changeset/calm-quails-snooze.md | 6 -- .changeset/clever-badgers-gather.md | 5 - .changeset/clever-rams-hop.md | 5 - .changeset/curious-dogs-dart.md | 5 - .changeset/curious-tigers-tumble.md | 5 - .changeset/daring-hawks-zip.md | 5 - .changeset/eager-badgers-bark.md | 5 - .changeset/eager-deer-hop.md | 5 - .changeset/eager-tigers-wander.md | 5 - .changeset/eager-tunas-hum.md | 5 - .changeset/fierce-elks-leap.md | 5 - .changeset/fierce-foxes-run.md | 5 - .changeset/fierce-koalas-climb.md | 5 - .changeset/fierce-pumas-dance.md | 5 - .changeset/fierce-quails-leap.md | 5 - .changeset/gallant-hawks-tumble.md | 5 - .changeset/gallant-wolves-romp.md | 5 - .changeset/gentle-dogs-climb.md | 5 - .changeset/gentle-jays-wave.md | 5 - .changeset/graceful-cats-hop.md | 5 - .changeset/graceful-dogs-bark.md | 5 - .changeset/graceful-mice-chatter.md | 5 - .changeset/happy-herons-tumble.md | 5 - .changeset/happy-sloths-rest.md | 5 - .changeset/humble-koalas-swim.md | 5 - .changeset/jolly-badgers-wake.md | 5 - .changeset/jolly-lynx-sprint.md | 5 - .changeset/jolly-moles-snooze.md | 5 - .changeset/jolly-otters-click.md | 5 - .changeset/kind-sloths-swim.md | 5 - .changeset/lively-quails-forage.md | 5 - .changeset/mellow-foxes-tumble.md | 5 - .changeset/mellow-koalas-caper.md | 5 - .changeset/mellow-koalas-frolic.md | 5 - .changeset/merry-cranes-frolic.md | 5 - .changeset/merry-otters-wave.md | 5 - .changeset/nimble-geese-zip.md | 5 - .changeset/nimble-hawks-frolic.md | 5 - .changeset/nimble-lemurs-wander.md | 5 - .changeset/noble-deer-zip.md | 5 - .changeset/noble-geese-climb.md | 5 - .changeset/noble-tunas-travel.md | 5 - .changeset/patient-moles-click.md | 5 - .changeset/patient-quails-greet.md | 5 - .changeset/patient-tunas-howl.md | 5 - .changeset/plucky-jays-travel.md | 5 - .changeset/plucky-newts-squeak.md | 5 - .changeset/proud-goats-romp.md | 5 - .changeset/proud-koalas-jump.md | 5 - .changeset/quick-bears-tumble.md | 5 - .changeset/quick-panthers-cross.md | 5 - .changeset/quick-tunas-wander.md | 5 - .changeset/quiet-lynxes-filter.md | 5 - .changeset/rapid-finches-roar.md | 5 - .changeset/rapid-pumas-parade.md | 5 - .changeset/reviewer-lane-source-review.md | 5 - .changeset/serene-foxes-hum.md | 5 - .changeset/sharp-bears-roar.md | 5 - .changeset/sharp-deer-hop.md | 5 - .changeset/sharp-tigers-sing.md | 5 - .changeset/silly-lemurs-munch.md | 5 - .changeset/silly-lynx-click.md | 5 - .changeset/silly-voles-climb.md | 5 - .changeset/silly-zebras-roar.md | 5 - .changeset/steady-elks-parade.md | 5 - .changeset/steady-moles-guard.md | 5 - .changeset/steady-sloths-parade.md | 5 - .changeset/steady-tunas-tumble.md | 5 - .changeset/sturdy-jays-cheer.md | 5 - .changeset/sunny-wasps-cheer.md | 5 - .changeset/tame-hens-jump.md | 5 - .changeset/tidy-bears-jump.md | 5 - .changeset/tidy-pandas-dart.md | 5 - .changeset/vivid-newts-march.md | 5 - .changeset/vivid-quails-roam.md | 5 - .changeset/wise-foxes-march.md | 5 - .changeset/wise-hawks-howl.md | 5 - .changeset/witty-orcas-jump.md | 5 - .changeset/witty-ravens-fly.md | 5 - .changeset/witty-wasps-romp.md | 5 - .changeset/zesty-seals-click.md | 5 - .changeset/zesty-tunas-bark.md | 5 - CHANGELOG.md | 112 ++++++++++++++++++++++ 94 files changed, 112 insertions(+), 468 deletions(-) delete mode 100644 .changeset/3644-completion-seam.md delete mode 100644 .changeset/4089-minimum-solution.md delete mode 100644 .changeset/agile-badgers-roar.md delete mode 100644 .changeset/agile-wasps-chatter.md delete mode 100644 .changeset/bold-cranes-rest.md delete mode 100644 .changeset/bold-ibex-chatter.md delete mode 100644 .changeset/bold-jaguars-parade.md delete mode 100644 .changeset/brave-elks-glide.md delete mode 100644 .changeset/brave-finches-zip.md delete mode 100644 .changeset/brave-geese-sing.md delete mode 100644 .changeset/calm-goats-bark.md delete mode 100644 .changeset/calm-quails-snooze.md delete mode 100644 .changeset/clever-badgers-gather.md delete mode 100644 .changeset/clever-rams-hop.md delete mode 100644 .changeset/curious-dogs-dart.md delete mode 100644 .changeset/curious-tigers-tumble.md delete mode 100644 .changeset/daring-hawks-zip.md delete mode 100644 .changeset/eager-badgers-bark.md delete mode 100644 .changeset/eager-deer-hop.md delete mode 100644 .changeset/eager-tigers-wander.md delete mode 100644 .changeset/eager-tunas-hum.md delete mode 100644 .changeset/fierce-elks-leap.md delete mode 100644 .changeset/fierce-foxes-run.md delete mode 100644 .changeset/fierce-koalas-climb.md delete mode 100644 .changeset/fierce-pumas-dance.md delete mode 100644 .changeset/fierce-quails-leap.md delete mode 100644 .changeset/gallant-hawks-tumble.md delete mode 100644 .changeset/gallant-wolves-romp.md delete mode 100644 .changeset/gentle-dogs-climb.md delete mode 100644 .changeset/gentle-jays-wave.md delete mode 100644 .changeset/graceful-cats-hop.md delete mode 100644 .changeset/graceful-dogs-bark.md delete mode 100644 .changeset/graceful-mice-chatter.md delete mode 100644 .changeset/happy-herons-tumble.md delete mode 100644 .changeset/happy-sloths-rest.md delete mode 100644 .changeset/humble-koalas-swim.md delete mode 100644 .changeset/jolly-badgers-wake.md delete mode 100644 .changeset/jolly-lynx-sprint.md delete mode 100644 .changeset/jolly-moles-snooze.md delete mode 100644 .changeset/jolly-otters-click.md delete mode 100644 .changeset/kind-sloths-swim.md delete mode 100644 .changeset/lively-quails-forage.md delete mode 100644 .changeset/mellow-foxes-tumble.md delete mode 100644 .changeset/mellow-koalas-caper.md delete mode 100644 .changeset/mellow-koalas-frolic.md delete mode 100644 .changeset/merry-cranes-frolic.md delete mode 100644 .changeset/merry-otters-wave.md delete mode 100644 .changeset/nimble-geese-zip.md delete mode 100644 .changeset/nimble-hawks-frolic.md delete mode 100644 .changeset/nimble-lemurs-wander.md delete mode 100644 .changeset/noble-deer-zip.md delete mode 100644 .changeset/noble-geese-climb.md delete mode 100644 .changeset/noble-tunas-travel.md delete mode 100644 .changeset/patient-moles-click.md delete mode 100644 .changeset/patient-quails-greet.md delete mode 100644 .changeset/patient-tunas-howl.md delete mode 100644 .changeset/plucky-jays-travel.md delete mode 100644 .changeset/plucky-newts-squeak.md delete mode 100644 .changeset/proud-goats-romp.md delete mode 100644 .changeset/proud-koalas-jump.md delete mode 100644 .changeset/quick-bears-tumble.md delete mode 100644 .changeset/quick-panthers-cross.md delete mode 100644 .changeset/quick-tunas-wander.md delete mode 100644 .changeset/quiet-lynxes-filter.md delete mode 100644 .changeset/rapid-finches-roar.md delete mode 100644 .changeset/rapid-pumas-parade.md delete mode 100644 .changeset/reviewer-lane-source-review.md delete mode 100644 .changeset/serene-foxes-hum.md delete mode 100644 .changeset/sharp-bears-roar.md delete mode 100644 .changeset/sharp-deer-hop.md delete mode 100644 .changeset/sharp-tigers-sing.md delete mode 100644 .changeset/silly-lemurs-munch.md delete mode 100644 .changeset/silly-lynx-click.md delete mode 100644 .changeset/silly-voles-climb.md delete mode 100644 .changeset/silly-zebras-roar.md delete mode 100644 .changeset/steady-elks-parade.md delete mode 100644 .changeset/steady-moles-guard.md delete mode 100644 .changeset/steady-sloths-parade.md delete mode 100644 .changeset/steady-tunas-tumble.md delete mode 100644 .changeset/sturdy-jays-cheer.md delete mode 100644 .changeset/sunny-wasps-cheer.md delete mode 100644 .changeset/tame-hens-jump.md delete mode 100644 .changeset/tidy-bears-jump.md delete mode 100644 .changeset/tidy-pandas-dart.md delete mode 100644 .changeset/vivid-newts-march.md delete mode 100644 .changeset/vivid-quails-roam.md delete mode 100644 .changeset/wise-foxes-march.md delete mode 100644 .changeset/wise-hawks-howl.md delete mode 100644 .changeset/witty-orcas-jump.md delete mode 100644 .changeset/witty-ravens-fly.md delete mode 100644 .changeset/witty-wasps-romp.md delete mode 100644 .changeset/zesty-seals-click.md delete mode 100644 .changeset/zesty-tunas-bark.md diff --git a/.changeset/3644-completion-seam.md b/.changeset/3644-completion-seam.md deleted file mode 100644 index fd63b25de..000000000 --- a/.changeset/3644-completion-seam.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -type: Added -pr: 3644 ---- -**The phase-directory membership seam threads the phase ID convention through the completion chain** — the #3511 seam (`isPhaseArtifact` / `scopeToPhase`) now takes the same optional convention every other read-path helper does, and the completion chain threads it: `state json` / `state sync`'s completed-phase counting, the planning snapshot, roadmap analysis, `state validate`'s drift scan, the verification-report resolver, and `phase complete`'s actual completion gate. A bracket directory therefore scopes its listing by its real phase token instead of the include-everything ambiguity fail-safe, so a cross-phase stray (`01-VERIFICATION.md` misfiled into phase 03's directory) can no longer supply the pass/fail verdict for a bracket phase — the same protection #3511 already gives legacy directories, **on the call sites this PR threads**. - -Call sites that do not yet resolve a convention keep the documented include-everything fail-safe on bracket directories, and this PR changes nothing for them: the aggregate scans (`uat`, `audit`, `init`'s projections, `gap-checker`, `phase-locator`); **`phase complete`'s advisory pre-scan** (`cmdPhaseComplete`, `src/phase.cts`), whose UAT and VERIFICATION warning sweeps still call the seam convention-lessly and can therefore surface a spurious warning for a cross-phase stray, although that scan cannot pass or block completion; and **the workstream inventory's per-phase completion projection** (`src/workstream-inventory.cts`), which calls the now-convention-aware `isPhaseComplete` without resolving a convention to pass it and can therefore still project a bracket phase complete or incomplete from a cross-phase stray. Threading those readers is follow-up-slice work alongside the epic's other convention-less readers. A project on any convention other than `"bracket"` is unaffected. (#4142) diff --git a/.changeset/4089-minimum-solution.md b/.changeset/4089-minimum-solution.md deleted file mode 100644 index 7acd3ff9b..000000000 --- a/.changeset/4089-minimum-solution.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Changed -pr: 4118 ---- -**Planning guidance now prefers the first sufficient implementation option** — existing project behavior, standard-library or native platform capability, installed dependencies, and only then minimum new implementation, without reducing required scope or verification. diff --git a/.changeset/agile-badgers-roar.md b/.changeset/agile-badgers-roar.md deleted file mode 100644 index 7cc52c6da..000000000 --- a/.changeset/agile-badgers-roar.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4380 ---- -**`gsd-tools state begin-phase` without `--phase` now exits non-zero and writes nothing** — previously a missing, empty, or flag-shaped phase argument was silently accepted and wrote a null-phase STATE.md (removing `current_phase`/`current_phase_name` from frontmatter and serialising the literal `Phase null` into three body locations), and took a milestone claim for the phase "null". (#4138) diff --git a/.changeset/agile-wasps-chatter.md b/.changeset/agile-wasps-chatter.md deleted file mode 100644 index f8e383d9f..000000000 --- a/.changeset/agile-wasps-chatter.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4373 ---- -**`/gsd-update --reapply` no longer re-grafts customizations that upstream already adopted** — the documented `Incorporated` per-file status is now computed by a deterministic pre-flight classifier (hash-validated pristine baseline + every significant user-added line already present verbatim in the new version), so superseded patches are reported as already upstream instead of being silently re-applied on every future update cycle. (#4136) diff --git a/.changeset/bold-cranes-rest.md b/.changeset/bold-cranes-rest.md deleted file mode 100644 index 647ccfcf2..000000000 --- a/.changeset/bold-cranes-rest.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4357 ---- -**The decision-coverage gate now reads phase-prefixed decision IDs** — a CONTEXT.md whose decisions use D4-01-style IDs (a digit-run phase prefix) no longer reports could-not-parse for the whole file; its decisions are counted and coverage-checked like any other, and a typo'd prefix (D4x-01) still fails loud. (#4130) diff --git a/.changeset/bold-ibex-chatter.md b/.changeset/bold-ibex-chatter.md deleted file mode 100644 index 254951d2a..000000000 --- a/.changeset/bold-ibex-chatter.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Security -pr: 4659 ---- -**The secret-read guard no longer lets a trailing dot or space alias past it** — Windows strips trailing dots and spaces from every path component, so `.env.`, `.env ` and `.secrets.` all resolve to the protected file while the guard treated them as unrelated names and allowed the read. Names are now normalized before classification, and the Read, Grep and Bash arms share one path-segmentation rule instead of two that disagreed on backslash paths. (#4651) diff --git a/.changeset/bold-jaguars-parade.md b/.changeset/bold-jaguars-parade.md deleted file mode 100644 index ca1bc696f..000000000 --- a/.changeset/bold-jaguars-parade.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4413 ---- -**`/gsd:update` no longer misreports a global install as LOCAL when the shell sits in $HOME** — running the update from a home-directory shell drove the installer's --local arm (settings.local.json + the #338 relocation) against a global install; the preferred-config-dir fast path now applies the same same-path dedup the rest of the detection cascade always has. (#4197) diff --git a/.changeset/brave-elks-glide.md b/.changeset/brave-elks-glide.md deleted file mode 100644 index 31003f20f..000000000 --- a/.changeset/brave-elks-glide.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4473 ---- -**A progress bar is full only at 100%** — every bar-drawing surface (`progress` in table and bar format, `stats`, `state update-progress`, the STATE.md progress line written by `state sync`, and the gsd2 import writer) now draws through one render kernel, `renderProgressBar`, beside the completion-ratio kernel in `phase-lifecycle`. The six inline copies of `Math.round((percent / 100) * width)` each rounded to a full bar before the percent reached 100: at the 10-cell width every percent from 95 up drew `[██████████]`, at the 20-cell width every percent from 98 up, so a project at 19/20 plans was visually indistinguishable from a shipped one beside a number that said otherwise. Below 100 the fill is now held one cell short; only those percents move (95-99 at width 10, 98-99 at width 20), every other value in 0-100 renders exactly as before. A null or non-finite percent still renders an empty bar, and an out-of-range percent is clamped instead of throwing `RangeError` from `'░'.repeat` as the inline form did at 120%. diff --git a/.changeset/brave-finches-zip.md b/.changeset/brave-finches-zip.md deleted file mode 100644 index bcbc31548..000000000 --- a/.changeset/brave-finches-zip.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4468 ---- -**`roadmap update-plan-progress` no longer false-greens on checklist-form ROADMAPs** — a phase whose entry is a `- [ ] **Phase N: …**` checklist bullet with no writable Progress-table row or detail section now declines with `updated: false` and a typed `missing_phase_details` reason, leaving ROADMAP.md byte-identical, instead of reporting success off an unrelated checkbox mark while the phase row stayed untouched and blank lines were injected mid-sentence in other phases' entries. (#4247) diff --git a/.changeset/brave-geese-sing.md b/.changeset/brave-geese-sing.md deleted file mode 100644 index bd16c3fef..000000000 --- a/.changeset/brave-geese-sing.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4618 ---- -**`validate.health` no longer flags `.planning/PATTERNS.md` as an unrecognized file.** The graduation workflow (`/gsd-extract-learnings`) writes this file on gsd-core's own instruction, but the artifact registry was never updated to recognize it -- every repo that had run the graduation scan sat permanently at `status: degraded`. (#4282) diff --git a/.changeset/calm-goats-bark.md b/.changeset/calm-goats-bark.md deleted file mode 100644 index fa9021cbf..000000000 --- a/.changeset/calm-goats-bark.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4453 ---- -**`state begin-phase` no longer rewrites prose that merely quotes a bold field label** — a `**Status:**` (or any served field label) quoted mid-sentence inside prose captured the field rewrite and silently destroyed the rest of its line; the bold form is now anchored to line start, so only the real field updates. Frontmatter round-trip through begin-phase (custom keys, progress subkeys, milestone identity without a ROADMAP) is pinned with regression tests. (#4243) diff --git a/.changeset/calm-quails-snooze.md b/.changeset/calm-quails-snooze.md deleted file mode 100644 index c0962c607..000000000 --- a/.changeset/calm-quails-snooze.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -type: Changed -pr: 4397 ---- - -**21 GSD skills now declare `Grep` in `allowed-tools`** — cleanup, complete-milestone, config, debug, graphify, health, mempalace-capture, mempalace-recall, new-milestone, new-project, next, pause-work, phase, pr-branch, resume-work, review-backlog, settings, stats, thread, workspace, and workstreams can now use the dedicated structured-search tool instead of shelling out through Bash grep. diff --git a/.changeset/clever-badgers-gather.md b/.changeset/clever-badgers-gather.md deleted file mode 100644 index f5b79edcd..000000000 --- a/.changeset/clever-badgers-gather.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4376 ---- -**The reapply verifier now headlines its baseline coverage instead of reading as fully verified when most files were skipped** — after a multi-version update, /gsd-update --reapply reports 'Baseline coverage: N of M file(s)' in the verifier summary, the reapply output, and the installer's update log; on git-managed config dirs the verifier additionally recovers pristine baselines from history by recorded hash, so files upstream heavily changed are diff-verified instead of skipped; an opt-in --min-baseline-coverage <0..1> flag lets cautious operators fail the gate (exit 3) below a coverage threshold. (#4135) diff --git a/.changeset/clever-rams-hop.md b/.changeset/clever-rams-hop.md deleted file mode 100644 index f5fa9d336..000000000 --- a/.changeset/clever-rams-hop.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4537 ---- -**`/gsd-pr-branch` no longer silently drops a planning-only commit that mixes a structural `.planning/` path (STATE.md, ROADMAP.md, etc.) with a transient or other planning path** — such a commit matched none of the classification's four arms and was excluded, which could break `STATE.md`'s per-commit revision chain in default mode. A fifth arm now covers this shape and includes it, same as a mixed code+planning commit. (#4447) diff --git a/.changeset/curious-dogs-dart.md b/.changeset/curious-dogs-dart.md deleted file mode 100644 index a63e7ca6d..000000000 --- a/.changeset/curious-dogs-dart.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Added -pr: 4471 ---- -**`workflow.compact_content` now actually does something: `plan-phase` is the first workflow split into a spine + detail file.** With the key off (default), nothing changes — the spine reads the deferred elaboration back in before continuing, so the instruction set is identical to today. With it on, that read is skipped and the orchestrator runs on the terser spine alone, which is complete enough to plan a phase correctly on its own. The check and the resolution rule live in one shared reference (`gsd-core/references/compact-content-gate.md`) that future splits reference instead of restating. (#4402) diff --git a/.changeset/curious-tigers-tumble.md b/.changeset/curious-tigers-tumble.md deleted file mode 100644 index a5b861193..000000000 --- a/.changeset/curious-tigers-tumble.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Changed -pr: 4366 ---- -**Context-monitor WARNING/CRITICAL fire-points are now readable from `.planning/config.json`** — `hooks.context_warning_threshold` (default 35) and `hooks.context_critical_threshold` (default 25) move the two rungs per project, so a tuned fire-point survives an update instead of being re-staged away with the managed hook file. Absent keys resolve to today's 35/25, so existing projects are unchanged. An unusable value falls back per key; both revert to their defaults only when the resolved pair violates `critical < warning`. The keys are root-project settings — the hook reads `/.planning/config.json` only, and they are read by that hook and nothing else, so on a runtime where it is not installed (Codex, per #2586) both keys are stored and validated but inert. `config-set` refuses the two endpoints that can never take effect — a warning of 0 and a critical of 100 — because `critical < warning` has no legal partner for either, and an absent key now reports the shipped default (35/25) instead of "Key not found". (#4285) diff --git a/.changeset/daring-hawks-zip.md b/.changeset/daring-hawks-zip.md deleted file mode 100644 index ba3a47243..000000000 --- a/.changeset/daring-hawks-zip.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4358 ---- -**`milestone_name` no longer corrupts to ")" for a first-milestone ROADMAP whose H1 puts the version after the name** — a punctuation-only heading remainder (e.g. the closing paren of `# Roadmap: Project — Name (v1.13)`) is refused as a name, so `init.*` output reports `null` instead of garbage, and the roadmapper agent now templates the canonical version-free H1. (#4134) diff --git a/.changeset/eager-badgers-bark.md b/.changeset/eager-badgers-bark.md deleted file mode 100644 index ab8071b6a..000000000 --- a/.changeset/eager-badgers-bark.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Changed -pr: 4672 ---- -**The path-containment predicate is now a single exported seam** — `security.cjs` no longer exports `validatePath`. Containment is decided in exactly one place and resolved two ways: `assertWithinRoot` (throws) and `tryWithinRoot` (returns null) resolve symlinks, while `assertWithinRootLexical` and `tryWithinRootLexical` use string resolution alone and never touch the filesystem, for the few callers that must preserve a symlink rather than resolve it or that validate a destination before it exists. `requireSafePath` is preserved as an alias of the throwing form. All of them 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 `