Files
msd-core/docs
sim c7956c162b fix(#4652): a todo name must be a basename — containment alone cannot say that
The verification checkpoint caught a real design gap, not a flaky test.

Confining sourcePath/targetPath within todosRoot correctly rejects
`../../escaped`, which leaves the root. It does NOT reject these, because they
all land inside it:

  ../sibling.md   -> <todosRoot>/sibling.md     escapes pending/, not the root
  a/../../b.md    -> <todosRoot>/b.md           same
  sub/name.md     -> <pendingDir>/sub/name.md   inside pending/, but nested

Three committed tests asserted these must be rejected and were right: the
design says "a todo name is a basename, not a path", and #4327 requires the
resolved path stay inside "the todos root (pending and completed subdirs)".
Containment against a root is structurally incapable of expressing "basename" —
it answers "is this inside?", and all three are. The wrong tool was reaching
for the wrong question.

A basename guard now runs BEFORE any path is joined: reject on a `/` or `\`
separator, on a path.basename / path.win32.basename mismatch, on `.` / `..`,
and on a NUL byte. Both separators are checked explicitly because on POSIX a
literal backslash is an ordinary filename character to path.basename but not to
path.win32.basename or to the user's intent — this repo has a documented bug
class for exactly that asymmetry. Same predicate shape as findPhaseArtifact in
check-command-router.cts, so the two agree.

Containment is kept as defense-in-depth rather than replaced. The basename
guard is the specific rule; containment is the backstop.

Message wording matters here and is deliberate: `sub/name.md` does NOT escape
its allowed directory, so reusing the escape message would have stated
something false. It now says the name must be a plain filename, not a path.

docs/CLI-TOOLS.md corrected again, in the opposite direction from last time.
The previous revision said an absolute filename is "folded under the root" and
404s — true then, false now: the basename guard rejects it before any join
happens. Two corrections to one paragraph in one phase is the cost of
documenting behavior while it is still moving; the paragraph now matches the
shipped code.

Verified through the real CLI, not by calling the built function directly:
all eight rejection cases produce the new USAGE message; `ok.md` still
completes and moves to completed/; `missing.md` still gives "Todo not found".

Also corrected the now-stale comment above the isFile() check — it described
`.`/`..` reaching that line, which the basename guard now prevents. The check
itself stays: a bare basename can still name a directory, FIFO or socket in
pending/.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-12 10:07:40 -04:00
..

GSD Core documentation

Documentation is organised into four quadrants: tutorials help you learn by doing, how-to guides solve specific tasks, reference states authoritative facts, and explanation explores concepts and design decisions.

Language versions: English · Português (pt-BR) · 日本語 · 简体中文


Tutorials


How-to guides


Reference

  • Commands — every command with flags and examples
  • Configuration — full config schema, model profiles, git branching strategies
  • CLI tools — gsd-tools.cjs programmatic API for workflows and agents
  • JSON error mode — gsd-tools failure channels: faults (stderr, exit 1) vs degraded results (stdout, exit 0), and the reason-code taxonomy
  • Features — complete feature index
  • Inventory — installed skills and surface map
  • STATE.md schema — field-by-field reference for .planning/STATE.md
  • CONTEXT.md schema — field-by-field reference for .planning/phases/<N>/CONTEXT.md
  • PLAN.md schema — field-by-field reference for .planning/phases/<N>/PLAN.md
  • Planning artifacts — all .planning/ files and their roles
  • Review and verification capabilities — code review, security, and Nyquist capability ownership and hook contracts
  • Gate predicates — canonical specification of the phase-gate predicate vocabulary
  • Capability matrix — generated catalogue of every capability's role, tier, extension points, hook kinds, and engines.gsd
  • Exit code reference — generated catalogue of every registered process exit code, its name, meaning, and owning module, plus the reserved bands and the v1/v2 exit contract
  • Capability manifest — the full capability.json schema and validation rules
  • gsd capability command — install / update / remove / list reference for third-party capabilities
  • Workflow fragments — in-file <!-- gsd:section --> marker grammar for fragmentizing workflow markdown at emission time
  • Partition rules for compact-content splits — the protected-content list, sentinel syntax, and the five CI checks a workflow.compact_content spine/detail split must obey
  • Reviewer Lane Registry — generated catalogue of third-party reviewer lanes, with their flags, transport, and install commands

Explanation