Skip to content

Project Root

Z-M-Huang edited this page Apr 27, 2026 · 3 revisions

Project Root

How core decides whether the current working directory has a project layer. The rule is deliberately narrow: project root is <cwd>/.stud/ only. There is no walk-up.


The invariant

Project root resolution does not walk up the directory tree.

Starting a session in /a/b/c/:

  • If /a/b/c/.stud/ exists → it is the project root.
  • If /a/b/c/.stud/ does not exist → there is no project layer, even if /a/b/.stud/ exists.

This is a deliberate choice. Pros and cons are both loud.


Why no walk-up

flowchart LR
    CWD[cwd] --> Check{cwd/.stud<br/>exists?}
    Check -->|yes| Found[project root]
    Check -->|no| None[no project layer]
Loading
Reason Consequence
Trust clarity The user's choice to work in a directory with .stud/ is the signal. Walking up would silently activate code the user may not know about.
Predictability "What loaded?" has a simple answer — what's in <cwd>/.stud/.
Monorepos Different subprojects can have different .stud/. A user must cd into the one they mean.
Parent-hierarchy surprises Avoids the "I'm in a subdir of a cloned repo I forgot had stud config" case.

The walk-up design is rejected for v1. Users who want shared extensions across sibling projects put them in global scope (~/.stud/) or symlink.


The resolution flow

flowchart TD
    Start[session start] --> Cwd[read cwd]
    Cwd --> Probe{".stud directory<br/>exists under cwd?"}
    Probe -->|no| NoProj[no project layer;<br/>continue with bundled + global]
    Probe -->|yes| Trust{project<br/>trusted?}
    Trust -->|no| Prompt[project trust prompt]
    Trust -->|yes| Discover[discover project extensions]
    Prompt -->|granted| Discover
    Prompt -->|declined| Skip[skip project layer]
Loading

The trust check happens after finding .stud/, not before. See Project Trust.


What "exists" means

<cwd>/.stud/ must be a directory (not a file, not a symlink to a file). Symlinks to directories are followed.

A completely empty .stud/ directory still triggers the trust prompt (because an empty .stud/ can be populated later). Declining means the session ignores that directory for the session lifetime.


Project root vs session directory

The session's working directory and the project root are usually the same. They are not required to be:

  • A session may run in /a/b/c/sub/ with the project root at /a/b/c/.stud/ — but no, because walk-up is disabled. In practice, the project root is <cwd>/.stud/ or none.
  • The distinction matters for tools reading files: file-reading tools use the session's working directory. They do not walk up to find a project to anchor to.

cwd canonicalization

cwd is canonicalized before the probe:

  • Absolute path.
  • Symlinks in the path resolved.
  • Trailing separators stripped.

The canonical path is the key used in the Project Trust trust list. A second entry to the same project via a different path (e.g., through a symlink) still hits the same trust list entry.


No auto-creation

Core does not create .stud/ on its own. If the user wants to add project extensions, they create the directory and populate it. On first re-entry, core prompts for trust.

There is no stud init command in v1 that creates a .stud/ and elevates trust. The user must act deliberately.


Interaction with MCP and settings

<cwd>/.stud/mcp.json and <cwd>/.stud/settings.json are project-scope inputs — only picked up when the project layer is trusted and active. See Configuration Scopes and MCP.


Related pages

Introduction

Reading

Core runtime

Contracts

Category contracts

Context

Security

Runtime behavior

Operations

Providers (bundled)

Integrations

Reference extensions

Tools

UI

Session Stores

Loggers

Providers

Hooks

Context Providers

Commands

Case studies

Flows

Maintainers

Clone this wiki locally