Skip to content
Crystal CodeDocs
ENEnglish

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.