## ADDED Requirements

### Requirement: Filesystem API matching node:fs/promises

The system SHALL provide `sandbox.fs` implementing the Node.js `fs/promises` API:

- `readFile(path, encoding?)` → `Buffer | string`
- `writeFile(path, data)` → `void`
- `appendFile(path, data)` → `void`
- `mkdir(path, { recursive? })` → `void`
- `readdir(path, { withFileTypes? })` → `string[] | Dirent[]`
- `stat(path)` / `lstat(path)` → `Stats`
- `unlink(path)`, `rm(path, { recursive?, force? })`, `rmdir(path)` → `void`
- `rename(oldPath, newPath)` → `void`
- `copyFile(src, dest)` → `void`
- `chmod(path, mode)`, `chown(path, uid, gid)` → `void`
- `symlink(target, path)`, `readlink(path)` → `void`
- `realpath(path)`, `truncate(path, len?)` → `void`
- `mkdtemp(prefix)` → `string`
- `access(path)`, `exists(path)` → `boolean`

#### Scenario: ReadFile returns correct content

- **WHEN** `sandbox.fs.readFile("/etc/hostname", "utf8")` is called
- **THEN** it SHALL return the file content as a string

#### Scenario: WriteFile creates new file

- **WHEN** `sandbox.fs.writeFile("/tmp/test.txt", "hello")` is called
- **THEN** subsequent `sandbox.fs.readFile("/tmp/test.txt", "utf8")` SHALL return `"hello"`

#### Scenario: Readdir lists directory contents

- **WHEN** `sandbox.fs.readdir("/")` is called
- **THEN** it SHALL return an array of filenames

#### Scenario: Stat returns file metadata

- **WHEN** `sandbox.fs.stat("/etc/hostname")` is called
- **THEN** it SHALL return a `Stats`-compatible object with `size`, `isFile()`, `isDirectory()`, `mode`, `uid`, `gid`, `mtime`, etc.

#### Scenario: Mkdir creates intermediate directories

- **WHEN** `sandbox.fs.mkdir("/tmp/a/b/c", { recursive: true })` is called
- **THEN** the directory `/tmp/a/b/c` SHALL exist

#### Scenario: Exists returns false for missing files

- **WHEN** `sandbox.fs.exists("/nonexistent")` is called
- **THEN** it SHALL return `false`
