# Tasks: Tool Container Home Directory

## Overview

This task extends the earlier `home-path-expansion` work into a full configurable workspace/home directory for tool containers. It is tracked as the implementation of `openspec/designs/tool-container-home-directory.md`.

## T1: Schema and migration

### T1.1: Add `home_directory` column to `ToolType`

**File**: `apps/api/src/models/tool/tool_type.py`

- [x] Add `home_directory: Mapped[str]` column.
- [x] Non-nullable with server default `"/home/user"`.

### T1.2: Alembic migration for legacy tool types

**File**: `apps/api/alembic/versions/<new>_add_tool_type_home_directory.py`

- [x] Add the column.
- [x] Set existing rows to `/home/user`.
- [x] Rewrite `compose_template` and `dockerfile_template` to replace `/workspace` with `/home/user/{{WORKSPACE_NAME}}` where applicable.
- [x] Provide downgrade that reverses rewrites and drops the column.

## T2: Manifest compiler

### T2.1: Honor `manifest.home_directory`

**File**: `apps/api/src/services/build/manifest_compiler.py`

- [x] Update `get_manifest_home_dir()` to return `manifest.home_directory` if present, else derive from `user.name`, else `/root`.

### T2.2: Dockerfile generation

**File**: `apps/api/src/services/build/manifest_compiler.py`

- [x] Set `ENV HOME={home_directory}` and `ENV USER={user.name}`.
- [x] Set `WORKDIR {home_directory}` unless overridden by `runtime.working_dir`.
- [x] Create `/workspace` symlink pointing to `{home_directory}/{{WORKSPACE_NAME}}` placeholder or create it at runtime.

### T2.3: Compose generation

**File**: `apps/api/src/services/build/manifest_compiler.py`

- [x] Use `{home_directory}/{repo_name}` as default repo mount target when the manifest has no explicit repo mount.
- [x] Keep `~`/`$HOME` expansion base equal to `home_directory`.

## T3: Legacy instance generation

### T3.1: Dockerfile-based tools

**File**: `apps/api/src/services/tool/instance_service.py`

- [x] Use `tool_type.home_directory` (default `/home/user`).
- [x] Mount `{repo_path}:{home_directory}/{repo_name}`.
- [x] Ensure `/workspace` symlink exists.

### T3.2: Compose-based tools

**File**: `apps/api/src/services/docker/compose.py`, `apps/api/src/services/tool/instance_service.py`

- [x] Add `WORKSPACE_NAME` and `HOME_DIRECTORY` to template variables.
- [x] Validate migrated templates render correctly.

## T4: Config-profile and git mount expansion

### T4.1: Thread `home_dir` through startup

**File**: `apps/api/src/services/tool/instance_service.py`

- [x] Compute `home_dir` from ToolType/manifest in `start_tool_instance()`.
- [x] Pass to `apply_resolved_profile()` and `resolve_git_mounts()`.

### T4.2: Verify `~`/`$HOME` expansion

**File**: `apps/api/src/services/config/config_profile_resolver.py`

- [x] Ensure `expand_container_path()` is called with the resolved `home_dir`.

## T5: Entrypoint permission fixer

### T5.1: Generate permission-fixing entrypoint

**File**: `apps/api/src/services/build/manifest_compiler.py`

- [x] Generate a startup script that chowns `{home_directory}` and mounted paths to the container user.
- [x] Create `/workspace` symlink at runtime if needed.
- [x] Avoid recursive chown of large repo subtrees.

### T5.2: Base image support

**File**: `tool-images/base.dockerfile` (optional)

- [x] Ensure `sudo` is available and the runtime user can elevate if the fixer runs inside the base image.

## T6: Tests

### T6.1: Unit tests

**Files**:
- `apps/api/tests/unit/test_home_path_expansion.py`
- `apps/api/tests/unit/test_manifest_compiler.py`
- `apps/api/tests/unit/test_instance_service.py`
- `apps/api/tests/unit/test_alembic_migrations.py`

Cover:
- [x] `expand_container_path` edge cases.
- [x] `get_manifest_home_dir` precedence.
- [x] `compile_dockerfile`/`compile_compose` behavior.
- [x] Legacy instance mount target.
- [x] Alembic migration round-trip (round-trip against Postgres skipped in this environment).

### T6.2: Integration tests

**File**: `apps/api/tests/integration/test_tool_instance_lifecycle.py`

Cover:
- [ ] Container starts with `HOME=/home/user` and repo at `/home/user/{repo_name}`.
- [ ] `/workspace` symlink works.
- [ ] Config-profile and git mounts under `~` are writable.
- [ ] Explicit manifest repo mount target is preserved.

## T7: Verification

### T7.1: Run affected tests

```bash
cd apps/api
pytest tests/unit/test_home_path_expansion.py tests/unit/test_manifest_compiler.py tests/unit/test_instance_service.py tests/unit/test_alembic_migrations.py -xvs
pytest tests/integration/test_tool_instance_lifecycle.py -xvs
```

- [x] Unit tests passed (32 passed).
- [ ] Integration tests require Docker/Postgres.

### T7.2: Alembic round-trip

```bash
cd apps/api
alembic upgrade head
alembic downgrade -1
alembic upgrade head
```

- [ ] Alembic round-trip requires PostgreSQL.
- [x] Single head confirmed (`fc8f1a20cbf6`).
- [x] Migration imports verified.

### T7.3: Frontend typecheck

```bash
cd apps/web && npm run typecheck
```

- [x] No frontend changes made.

## Estimation

| Task | Effort | Files |
|------|--------|-------|
| T1 | 1h | 2 |
| T2 | 2h | 1 |
| T3 | 2h | 2 |
| T4 | 1h | 2 |
| T5 | 2h | 2 |
| T6 | 3h | 4 |
| T7 | 1h | — |
| **Total** | **12h** | **13** |

## Related Documents

- `openspec/designs/tool-container-home-directory.md`
- `docs/superpowers/plans/tool-container-home-directory.md`
- `docs/superpowers/specs/tool-container-home-directory-test-plan.md`
- `openspec/designs/home-path-expansion.md`
- `openspec/specs/home-path-expansion.md`
