Session directory access
本頁內容尚未翻譯。
CodingSession owns directory authorization for one session. Its workspace
resolver carries the live DirectoryAccessPolicy, separate from the primary
workspace root and approval grants. Immutable DirectoryAccess values contain
canonical absolute path and mode (read or write), plus optional sourcePath
for the absolute, lexically normalized entry path when it differs from the target.
The entry path is revocation metadata only; authorization always matches path.
Write includes read.
The implicit workspace is writable; the most-specific directory rule wins,
including an explicit read-only rule for the workspace or one of its children.
Matching uses directory boundaries and Windows case-insensitivity, resolves tool
paths through symlinks, and checks credential paths independently.
/access lists the primary workspace and session rules. /access add <path> read|write validates an existing directory and adds or replaces its canonical
rule; /access remove <path> first matches the recorded entry path, then the
canonical target, even if the directory or entry symlink no longer exists. A
retargeted entry revokes the original rule, not the new target’s independent rule.
Path resolution failures report the path error, not command usage. Paths containing
spaces can be double-quoted. Mutations are refused during a turn
or compaction. Changes immediately save SessionDocument.access, refresh the
live model instructions and the {{directories}} placeholder, and affect the already-bound executor through the shared
policy. On a new session, any --allow-read or --allow-write flag makes
those flags the complete seed. They replace workspace defaults, are not merged
with them, and are recorded only as session access metadata, never as
preferences in config.json or access.json. A resumed session keeps its
saved rules; flags still overlay those rules, and defaults are not loaded.
Conflicting modes for the same canonical root are rejected at launch. When no
flag is set and the session is not resuming, ~/.crystal/access.json supplies
the seed. That file
is keyed by the canonical workspace root, not the git trust root, and lives
under Home so a project cannot grant itself extra directories. A missing file
seeds nothing. A corrupt file or two modes for one directory seeds nothing and
reports an error; the session still opens. A missing directory, a credential
path, or a bad mode is skipped with a visible error and left in the file.
/access default lists the stored rules. /access default add <path> read|write
validates like /access add, writes the file, and adds the rule to the current
session. /access default remove <path> removes the stored rule and the same
canonical rule from the current session only. Other saved sessions are left
alone. Mutations are refused during a turn or compaction.
Built-in file reads in authorized directories use ordinary workspace read
approval. Writes in writable directories follow the current approval mode.
ApprovalPolicy rejects explicit read-only writes before classification hooks,
grants, or review; write and edit recheck at path resolution before file I/O.
Unlisted outside paths retain their existing approval behavior. Credential paths
remain forbidden. Relative paths stay relative to the one primary workspace.
Search and enumeration keep their existing root fence and do not automatically
search all authorized directories or traverse cross-root links. The glob, grep,
and search tool descriptions and path schemas explicitly allow workspace-relative
or absolute roots, default to the workspace, and explain session access versus
approval for unlisted outside roots.
Resume restores the saved absolute rules and entry paths, including rules for
missing directories; it never resolves a saved entry to a newly retargeted root.
Invalid saved rules fail closed rather than silently losing read-only restrictions.
SessionResume.TryLoad validates access before returning a document, and direct
session construction validates it before allocating session resources. Interactive
startup reports a red error and exits with code 1; in-session resume reports an
error without changing the current session or its rules. Resume does not
reapply workspace defaults, so a default removed during that session stays
removed. Fork does not copy the source session’s access. Clear, fork, and a
successful workspace change start from the destination workspace’s defaults.
A refused or no-op change does not. Additional roots do not discover
prompts, instructions, plugins, tools, or skills. Existing session files with no
access field load with an empty rule list; rules without sourcePath remain valid
and can be removed by their listed canonical target. Shell, background shell, external tools,
and plugins retain their existing approval behavior and are not sandboxed by this
policy. An operating-system sandbox remains deferred.