## Multi-Perspective Code Review

**Files Reviewed:** 12 (src: 3, tests: 3, docs: 3, config: 3)
**Overall Verdict:** ✅ Approved

| Perspective | Findings | Severity | Auto-fixable |
|---|---|---|---|
| Security | 0 | — | — |
| Performance | 1 | LOW | 0 |
| Maintainability | 2 | 1 MEDIUM, 1 LOW | 0 |
| Test & Reliability | 1 | MEDIUM | 0 |
| Domain & Architecture | 0 | — | — |
| Style & Consistency | 0 | — | — |

### Security Sentinel

No issues. All paths are resolved via \`Path.resolve()\`, no user input flows into shell commands unsanitized (rsync args are list-based, not shell-interpolated), no secrets touched. The \`container_path\` used in \`docker exec\` commands is derived from \`constants.CONTAINER_HOME\` + sanitized dir name — no injection vector.

### Performance & Scalability Architect

**P1 (LOW): Redundant docker cp staging for add-dir**
\`add_dir\` and the \`--add-dir\` loop in \`create\` both use a staging directory pattern: rsync source -> host clone -> iterate files -> copytree to staging -> docker cp staging. The host clone already excludes \`.git/\`, so the staging step that re-filters \`.git/\` is redundant (the host clone was created with \`--exclude .git/\`). The staging dir could docker cp directly from the host clone. Not a real performance issue for typical directory sizes — it just does one extra copy. No fix needed.

### Maintainability & Craftsmanship Lead

**M1 (MEDIUM): Duplicated file-copy-to-container pattern**
The "rsync to host clone -> staging dir -> copytree excluding .git -> docker cp -> chown -> git init" sequence appears three times:
1. \`create\` command (main project, lines 305-363)
2. \`create\` command (\`--add-dir\` loop, lines 385-440)
3. \`add_dir\` command (lines 839-889)

Cases 2 and 3 are nearly identical. This could be extracted into a helper like \`_copy_dir_to_container(meta, source, host_clone, container_path)\`. However, this is a judgment call — the create command's main project flow has git config setup and messaging init interleaved, making extraction non-trivial. The current state is readable and each instance is self-contained. Flagging for awareness, not blocking.

**M2 (LOW): \`_sync_one\` meta parameter untyped**
\`_sync_one(meta, ...)\` accepts \`meta\` without a type annotation. Should be \`meta: MetaJson\`. Cosmetic.

### Test & Reliability Engineer

**T1 (MEDIUM): No test for \`--all\` flag on export/diff/sync**
The \`--dir\` flag is tested on export, diff, and sync. The \`--all\` flag is not directly tested in unit tests. The \`--all\` code path was verified in E2E testing (and the logic is structurally similar to \`--dir\`), so the risk is low, but a unit test for \`--all\` would close this gap. Not blocking.

198 unit tests pass. 30 new tests added covering: AdditionalDir dataclass, MetaJson with additional_dirs, container_create multi-volume, container_recreate, add-dir (6 tests including error paths), remove-dir (3 tests), create --add-dir, export --dir, sync --dir, diff --dir, destroy with additional dirs, list --json with additional dirs.

### Domain & Architecture Guardian

Design aligns well with existing patterns:
- \`meta.json\` remains the sole source of truth (no docker inspect)
- Volume naming follows \`VOLUME_PREFIX + name\` convention
- Container recreation is deterministic from meta
- \`_build_volume_mounts\` centralizes mount construction
- Error handling follows the established \`rprint + typer.Exit(1)\` pattern
- All new commands registered via \`@app.command()\` with consistent argument/option structure

The \`additional_dirs: list[dict]\` field storing raw dicts (not \`AdditionalDir\` objects) is a pragmatic choice — it avoids nested dataclass serialization complexity and aligns with how \`meta.json\` is written/read. The \`get_additional_dir()\` method provides typed access when needed.

No breaking changes to existing commands. All existing tests pass unmodified (except one expected key-set update in \`test_list_json_with_envs\`).

### Style & Consistency Enforcer

Ruff format and lint pass clean. Import ordering follows existing pattern (stdlib, third-party, local). No stale TODOs. New code follows the established naming conventions (\`_private_helpers\`, \`snake_case\` commands).

### Summary

Clean implementation. The two MEDIUM findings (duplicated copy pattern, missing \`--all\` unit tests) are non-blocking — the code is correct, tested via E2E, and follows project conventions. The rsync itemize parsing fix (\`split(None, 1)\` instead of hardcoded offsets) is a genuine improvement that fixes a pre-existing macOS compatibility bug.

**Verdict: ✅ Approved — ship it.**