Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions docs/case-studies/issue-77/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Case Study: Isolation Environment Stacking (Issue #77)

## Overview

This case study analyzes the implementation of stacking/queuing multiple isolation environments in sequence for the start-command CLI tool.

## Problem Statement

Currently, start-command supports running commands in a single isolation environment:
- `--isolated screen` - Run in GNU Screen
- `--isolated tmux` - Run in tmux
- `--isolated docker` - Run in Docker container
- `--isolated ssh` - Run via SSH on remote server

The request is to support **stacking** multiple isolation environments in sequence:

```bash
$ --isolated "screen ssh tmux ssh docker" -- npm test
```

This would create a nested execution environment where:
1. Start in a screen session
2. SSH to a remote server
3. Start a tmux session on that server
4. SSH to another server
5. Run in a Docker container

## Related Documents

- [Requirements Analysis](./requirements.md) - Detailed analysis of all requirements
- [Options Analysis](./options-analysis.md) - Analysis of options that need stacking support
- [Solution Proposals](./solutions.md) - Proposed implementation approaches
- [Timeline Visualization](./timeline.md) - Execution timeline considerations
- [Research Findings](./research.md) - External research and related tools

## Key Concepts

### Links Notation
The sequence syntax is based on [Links Notation](https://github.com/link-foundation/links-notation), a format for representing structured data through references and links.

### Underscore Placeholder
The underscore (`_`) serves as a placeholder for "default" or "skip this level":

```bash
--image "_ _ _ _ oven/bun:latest" # Only 5th level uses custom image
--endpoint "_ user@server1 _ user@server2 _" # SSH endpoints for levels 2 and 4
```

## Implementation Summary

See [solutions.md](./solutions.md) for detailed implementation proposals.
179 changes: 179 additions & 0 deletions docs/case-studies/issue-77/options-analysis.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
# Options Analysis for Isolation Stacking

## Current Wrapper Options

Based on the current implementation in `args-parser.js`:

| Option | Current Usage | Stack Support Needed | Notes |
|--------|--------------|---------------------|-------|
| `--isolated, -i` | Single backend | **Primary target** | Becomes sequence |
| `--attached, -a` | Boolean flag | No | Global setting |
| `--detached, -d` | Boolean flag | No | Global setting |
| `--session, -s` | Session name | Maybe | Could be per-level |
| `--session-id` | UUID tracking | No | Global tracking |
| `--image` | Docker image | **Yes** | Only applies to docker levels |
| `--endpoint` | SSH target | **Yes** | Only applies to ssh levels |
| `--isolated-user, -u` | Username | Maybe | Per-level or global |
| `--keep-user` | Boolean flag | No | Global setting |
| `--keep-alive, -k` | Boolean flag | Maybe | Could be per-level |
| `--auto-remove-docker-container` | Boolean flag | Maybe | Per docker level |
| `--use-command-stream` | Boolean flag | No | Global experimental |
| `--status` | UUID query | N/A | Query mode, not execution |
| `--output-format` | Format string | N/A | Query mode |
| `--cleanup` | Boolean flag | N/A | Cleanup mode |

## Options Requiring Stacking Support

### 1. `--isolated` (Primary)

**Current:** Single value from `[screen, tmux, docker, ssh]`

**Proposed:** Space-separated sequence parsed with Links Notation

```bash
--isolated "screen ssh tmux ssh docker"
```

**Parsing:**
```javascript
// Single value (backward compatible)
"docker" → ["docker"]

// Multiple values
"screen ssh docker" → ["screen", "ssh", "docker"]
```

### 2. `--image`

**Current:** Single Docker image name

**Proposed:** Space-separated sequence with `_` placeholders

```bash
--image "_ _ _ _ oven/bun:latest" # 5-level stack, only last is docker
--image "ubuntu:22.04" # Single value applies to all docker levels
```

**Parsing:**
```javascript
// Single value (applies to all docker levels)
"ubuntu:22.04" → ["ubuntu:22.04"] // replicate for each docker level

// Sequence with placeholders
"_ _ ubuntu:22.04" → [null, null, "ubuntu:22.04"]
```

### 3. `--endpoint`

**Current:** Single SSH endpoint (user@host)

**Proposed:** Space-separated sequence with `_` placeholders

```bash
--endpoint "_ user@server1 _ user@server2 _" # SSH at levels 2 and 4
--endpoint "user@host" # Single value for all SSH levels
```

**Parsing:**
```javascript
// Single value (applies to all ssh levels)
"user@host" → ["user@host"]

// Sequence with placeholders
"_ user@host1 _ user@host2" → [null, "user@host1", null, "user@host2"]
```

## Options with Optional Stacking Support

### 4. `--session`

Could support per-level session names:

```bash
--session "myscreen _ mytmux _ mycontainer"
```

**Recommendation:** Keep simple for now, auto-generate per-level names.

### 5. `--keep-alive`

Could be per-level:

```bash
--keep-alive "true _ true _ false"
```

**Recommendation:** Keep as global flag for simplicity. When set, applies to all levels.

### 6. `--auto-remove-docker-container`

Could be per docker level:

```bash
--auto-remove-docker-container "true false" # For two docker levels
```

**Recommendation:** Keep as global flag for simplicity.

## Validation Rules for Stacked Options

### Rule 1: Length Matching

When both `--isolated` and option sequences are provided, lengths should match:

```bash
# Valid: 5 isolation levels, 5 image specs (using _ for non-docker)
--isolated "screen ssh tmux ssh docker" --image "_ _ _ _ ubuntu:22.04"

# Invalid: Mismatched lengths
--isolated "screen ssh docker" --image "_ _ ubuntu:22.04 ubuntu:24.04" # 3 vs 4
```

### Rule 2: Type Compatibility

Options should only have non-placeholder values for compatible isolation types:

```bash
# Valid: --image only has value for docker level (5th)
--isolated "screen ssh tmux ssh docker" --image "_ _ _ _ ubuntu:22.04"

# Warning/Error: --image has value for non-docker level
--isolated "screen ssh tmux ssh docker" --image "ubuntu:22.04 _ _ _ _" # screen doesn't use image
```

### Rule 3: Required Options

SSH isolation still requires endpoint, Docker still works with default image:

```bash
# Error: SSH level 2 missing endpoint
--isolated "screen ssh docker" --endpoint "_ _ _"

# Valid: SSH level 2 has endpoint
--isolated "screen ssh docker" --endpoint "_ user@host _"
```

## Implementation Considerations

### Parsing Strategy

1. Check if value contains spaces
2. If spaces: parse as Links Notation sequence
3. If no spaces: treat as single value (backward compatible)

### Default Value Handling

- For single values: replicate to match isolation stack length
- For sequences with `_`: substitute defaults at runtime

### Error Messages

Provide clear feedback for configuration errors:

```
Error: Isolation stack has 5 levels but --image has 3 values
--isolated "screen ssh tmux ssh docker"
--image "_ _ ubuntu:22.04"

Consider: --image "_ _ _ _ ubuntu:22.04" (5 values to match isolation levels)
```
111 changes: 111 additions & 0 deletions docs/case-studies/issue-77/requirements.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
# Requirements Analysis for Issue #77

## Functional Requirements

### FR1: Multi-Level Isolation Stacking

**Requirement:** Support specifying multiple isolation environments in a single `--isolated` argument.

**Syntax:**
```bash
$ --isolated "screen ssh tmux ssh docker" -- command
```

**Behavior:**
- Parse space-separated sequence of isolation backends
- Execute command through each level in sequence
- Each level wraps the next level's execution

### FR2: Per-Level Option Distribution

**Requirement:** Support specifying options (like `--image`, `--endpoint`) for specific levels in the stack.

**Syntax with placeholders:**
```bash
# Custom image only for the 5th (docker) level
$ --isolated "screen ssh tmux ssh docker" --image "_ _ _ _ oven/bun:latest" -- command

# SSH endpoints for levels 2 and 4
$ --isolated "screen ssh tmux ssh docker" --endpoint "_ user@server1 _ user@server2 _" -- command
```

**Placeholder semantics:**
- `_` (underscore) means "use default" or "not applicable" for that level
- Non-underscore values apply to corresponding levels

### FR3: Recursive Execution

**Requirement:** Each isolation level should call `$` with remaining levels.

**Example transformation:**
```bash
# Original command
$ --isolated "screen ssh tmux ssh docker" --image "_ _ _ _ oven/bun:latest" -- npm test

# Level 1 (screen) executes:
$ --isolated "ssh tmux ssh docker" --image "_ _ _ oven/bun:latest" -- npm test

# Level 2 (ssh) executes:
$ --isolated "tmux ssh docker" --image "_ _ oven/bun:latest" -- npm test

# Level 3 (tmux) executes:
$ --isolated "ssh docker" --image "_ oven/bun:latest" -- npm test

# Level 4 (ssh) executes:
$ --isolated "docker" --image "oven/bun:latest" -- npm test

# Level 5 (docker) executes:
npm test
```

### FR4: Timeline Visualization

**Requirement:** Show execution timeline that traces through all isolation levels.

**Example output:**
```
│ session abc-123-def-456-ghi
│ start 2024-01-15 10:30:45
│ isolation screen → ssh → tmux → ssh → docker
$ npm test
<output>

│ finish 2024-01-15 10:30:52
│ duration 7.456s
│ exit 0
```

### FR5: Backward Compatibility

**Requirement:** Existing single-level isolation commands must continue to work unchanged.

**Verification:**
```bash
# These must work exactly as before
$ --isolated screen -- echo hello
$ --isolated docker --image ubuntu:22.04 -- npm test
$ --isolated ssh --endpoint user@host -- ls
```

## Non-Functional Requirements

### NFR1: Links Notation Parsing

Use Links Notation for parsing sequences, providing a consistent syntax with other link-foundation projects.

### NFR2: Error Handling

- Validate that stacked environments make sense (e.g., can't have docker inside docker without special configuration)
- Provide clear error messages for invalid sequences
- Handle connection failures at any level gracefully

### NFR3: Performance

- Minimal overhead for single-level isolation (backward compatibility)
- Efficient parsing of multi-level specifications

## Options Analysis

See [options-analysis.md](./options-analysis.md) for detailed analysis of which options need stacking support.
Loading
Loading