Files
headquarter/openspec/specs/home-path-expansion.md
T
Alex Blank 29a12bb102 feat: expand ~ and $HOME in mount target paths
- Add expand_container_path() helper that resolves ~/ and $HOME/ prefixes
- Add get_manifest_home_dir() to compute /home/{user.name} or /root from manifest
- Set ENV HOME=... and ENV USER=... in generated Dockerfile for runtime compatibility
- Pass home_dir through instance creation and startup pipeline
- Expand mount targets in apply_resolved_profile() for regular profile mounts
- Expand mapping targets in _resolve_git_mount_mappings() for git mounts
- Expand working_directory and volume targets in _modify_compose_file()
- Update _prepare_manifest_instance to return home_dir alongside image tag
- Fetch tool_type early in start_instance to determine home_dir before profile application

Quality gates: pytest 188 passed, frontend typecheck clean

Addresses: home-path-expansion
2026-05-29 00:01:04 +02:00

72 lines
2.1 KiB
Markdown

# Spec: ~ / $HOME Expansion in Mount Paths
## Requirements
### Functional
1. **FR-1**: `~` in mount target paths MUST be expanded to the container's home directory.
2. **FR-2**: `$HOME` in mount target paths MUST be expanded to the container's home directory.
3. **FR-3**: For manifest-based tools with `user.name`, home MUST be `/home/{user.name}`.
4. **FR-4**: For manifest-based tools without user block, home MUST be `/root`.
5. **FR-5**: For legacy tool types, home MUST be `/root`.
6. **FR-6**: Git mount `mapping.target_path` MUST support `~` and `$HOME`.
7. **FR-7**: The generated Dockerfile MUST set `HOME` env var.
### Non-Functional
1. **NFR-1**: No database schema changes.
2. **NFR-2**: No frontend changes.
3. **NFR-3**: Existing profiles without `~` MUST continue working.
## API Contracts
No API changes. Resolution happens server-side during compose generation.
## Scenarios
### Scenario 1: pi-agent with ~ mount
**Given** a Config Profile with:
```json
{"mounts": [{"target": "~/workspace", "mode": "rw", "files": {}}]}
```
**And** a pi-agent manifest with `user.name = "user"`
**When** the profile is applied
**Then** the compose file contains `/home/user/workspace` as the mount target.
### Scenario 2: Legacy tool with $HOME mount
**Given** a Config Profile with:
```json
{"mounts": [{"target": "$HOME/config", "mode": "ro", "files": {}}]}
```
**And** a legacy tool type (no manifest)
**When** the profile is applied
**Then** the compose file contains `/root/config` as the mount target.
### Scenario 3: Git mount with ~ target
**Given** a Config Profile with:
```json
{"git_mounts": [{"remote_url": "...", "mappings": [{"source_path": ".", "target_path": "~/repo"}]}]}
```
**And** a manifest with `user.name = "user"`
**When** the profile is applied
**Then** the compose file contains `/home/user/repo` as the mount target.
## Test Strategy
1. Unit test `expand_container_path` with `~`, `$HOME`, absolute paths, relative paths
2. Unit test `get_manifest_home_dir` with user block, without user block
3. Integration test: profile with `~` mount applied to pi-agent instance
4. Integration test: profile with `$HOME` mount applied to legacy instance