Skip to content

docs: clarify feature directories may live outside the project root - #4739

Open
chelsealong wants to merge 3 commits into
github:mainfrom
chelsealong:docs/4738-clarify-feature-directory-outside-root
Open

chelsealong wants to merge 3 commits into
github:mainfrom
chelsealong:docs/4738-clarify-feature-directory-outside-root

Conversation

@chelsealong

Copy link
Copy Markdown
Contributor

Summary

Fixes #4738.

docs/reference/core.md described SPECIFY_FEATURE_DIRECTORY as selecting a feature directory "within" the resolved project, and docs/guides/monorepo.md said the same ("the feature within it"). This implies a containment rule that is not intended or enforced.

Verified against the actual resolver (scripts/bash/common.sh, get_feature_paths, lines ~191-215):

if [[ -n "${SPECIFY_FEATURE_DIRECTORY:-}" ]]; then
    feature_dir="$SPECIFY_FEATURE_DIRECTORY"
    # Normalize relative paths to absolute under repo root
    [[ "$feature_dir" != /* ]] && feature_dir="$repo_root/$feature_dir"

An absolute SPECIFY_FEATURE_DIRECTORY is used as-is — it can point anywhere on disk, including outside the project root. Only a relative path is resolved under the project root. scripts/python/common.py does the same. So "within the resolved project" was inaccurate: feature directories hold documentation artifacts (spec.md, plan.md, …) and may legitimately live outside the project root, while the project root itself still identifies the Spec Kit project and its command/configuration context.

Changes

  • docs/reference/core.md: reworded the SPECIFY_FEATURE_DIRECTORY table row and the "Two resolution axes" callout to state that a relative path resolves under the project root, an absolute path is used as-is and may point outside it, and the default feature location (specs/) is a default, not a containment boundary.
  • docs/guides/monorepo.md: reworded the equivalent "selects the feature within it" sentence to the same effect, keeping the existing pointer to the full reference doc.

This is documentation-only, as requested by the issue: no runtime behavior, containment enforcement, or script logic was changed.

Test plan

Docs-only change; no unit tests apply to these files (grep -rl "core.md\|monorepo.md" tests/ returns nothing).

Ran the repo's markdown lint locally to confirm no new issues were introduced:

$ npx --yes markdownlint-cli2 "docs/reference/core.md" "docs/guides/monorepo.md"
markdownlint-cli2 v0.23.3 (markdownlint v0.41.1)
Finding: docs/reference/core.md docs/guides/monorepo.md !.genreleases/
Linting: 2 files
Summary: 2 issues in 1 file
docs/reference/core.md:60 error MD028/no-blanks-blockquote Blank line inside blockquote
docs/reference/core.md:62 error MD028/no-blanks-blockquote Blank line inside blockquote

Confirmed these two MD028 findings are pre-existing on main (same output with git stash applied, unrelated blockquote formatting a few lines below my edit) — not introduced by this change.

AI disclosure

This PR was authored by an autonomous AI agent (Claude Code, model Claude Sonnet 5, running non-interactively/autonomously) on behalf of the repository owner. The agent read the issue, verified the containment claim against the current scripts/bash/common.sh/scripts/python/common.py resolver logic, and made the minimal documentation wording change described above.

🤖 Generated with Claude Code

SPECIFY_FEATURE_DIRECTORY previously described the selected feature
directory as being "within" the resolved project, which implies a
containment rule that neither the Bash nor Python core scripts
enforce. An absolute SPECIFY_FEATURE_DIRECTORY is used as-is (see
scripts/bash/common.sh get_feature_paths), so it may legitimately
point outside the project root; only relative paths resolve under it.
Clarify that the project root identifies the Spec Kit project and its
command/configuration context, while the default feature location
(specs/) is just that — a default, not a boundary.

Fixes github#4738

Assisted-by: Claude Code (model: Claude Sonnet 5, autonomous)
@chelsealong
chelsealong requested a review from mnriem as a code owner September 24, 2026 15:57
@mnriem mnriem added the triage-nice-to-have Verdict: evidence-backed fix or greenlit feature — land after review label Sep 24, 2026
@mnriem
mnriem requested a balanced review from Copilot September 24, 2026 17:29

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Both pages must explicitly document that relative paths may also resolve outside the project root.

Get a fresh assessment by requesting another Copilot review.

Review effort: Balanced
Findings: 2 Low severity

Open (2)
What changed in this PR

Clarifies that feature directories are not confined to the Spec Kit project root.

Changes:

  • Documents external absolute feature paths.
  • Separates project context from feature-document location.
  • Still omits explicit external relative paths such as ../shared-feature.
File Description
docs/​reference/​core.md Updates feature-directory resolution documentation.
docs/​guides/​monorepo.md Clarifies project and feature selection in monorepos.

💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread docs/guides/monorepo.md Outdated
Comment thread docs/reference/core.md Outdated
…ject root

Copilot review on github#4739 noted the previous wording only called out
absolute paths as able to escape the project root, while a relative
path like ../shared-feature is joined without a containment check and
resolves outside it too.

Assisted-by: Claude Code (model: Claude Sonnet 5, autonomous)
@chelsealong

Copy link
Copy Markdown
Contributor Author

Posted on behalf of @chelsealong by Claude Code (model: Claude Sonnet 5, autonomous); comment fully AI-drafted.

Addressed both inline comments in ae3dda9: docs/reference/core.md and docs/guides/monorepo.md now state that a relative SPECIFY_FEATURE_DIRECTORY is joined to the project root without a containment check, so a value like ../shared-feature still resolves outside it — not just absolute paths. Verified against get_feature_paths in scripts/bash/common.sh (feature_dir="$repo_root/$feature_dir" with no normalization).

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟢 Approval recommended

The documentation accurately reflects the Bash, PowerShell, and Python resolver behavior.

Review effort: Balanced
Findings: None

Resolved since last review (2)

…eature-directory-outside-root

# Conflicts:
#	docs/reference/core.md
@chelsealong

Copy link
Copy Markdown
Contributor Author

Posted on behalf of @chelsealong by Claude Code (model: Claude Sonnet 5, autonomous); comment fully AI-drafted.

Merged upstream main into this branch (638023c) to resolve a conflict in docs/reference/core.md — main had picked up an unrelated blockquote-formatting fix (#4584) on the same lines this PR edits. Kept this PR's wording (relative paths resolve under the project root but aren't containment-restricted) and combined it with main's blank-line-in-blockquote fix. Confirmed main still describes SPECIFY_FEATURE_DIRECTORY as selecting the feature "within that project," so this fix is not superseded. Re-ran npx markdownlint-cli2 docs/reference/core.md docs/guides/monorepo.md post-merge: 0 issues.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

triage-nice-to-have Verdict: evidence-backed fix or greenlit feature — land after review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

docs: clarify that feature directories may be outside the project root

3 participants