# okstra-container-build AI Manual

## Source

- Skill source: [`skills/okstra-container-build/SKILL.md`](../../../skills/okstra-container-build/SKILL.md)
- container CLI wrapper: [`src/commands/inspect/container.mjs`](../../../src/commands/inspect/container.mjs)
- container runtime: [`scripts/okstra_ctl/container.py`](../../../scripts/okstra_ctl/container.py)
- container registry: [`scripts/okstra_ctl/container_registry.py`](../../../scripts/okstra_ctl/container_registry.py)
- stage integration gate: [`scripts/okstra_ctl/stage_targets.py`](../../../scripts/okstra_ctl/stage_targets.py)

## Purpose

`okstra-container-build` manages a user-test container group using the `docker-compose.yml` in an implementation task worktree. okstra labels the compose group with the task/run trace and observes logs/status through a tmux watcher pane.

## sub-command

| Sub-command | Role | side effect |
|---|---|---|
| `up` | Integrate the implementation stages into the task worktree, then `docker compose up -d`, poll healthchecks, attach the watcher pane | create/start containers, create watcher pane |
| `status` | Check running containers (by label query) plus watcher metadata | read |
| `logs` | Point at the watcher findings dir and watcher entries | read |
| `stop-watcher` | Reap the watcher/tail tmux panes only | keep containers, remove panes |
| `down` | Remove the container group by label query, reap orphan watcher panes | stop/remove containers |

## Preflight

Single call:

```bash
okstra preflight --runtime claude-code
```

On `Okstra preflight: ready`, carry the fixed `Project root` line. On
`Okstra preflight: failed`, show `Reason` and `Recovery`, then stop. A Docker
daemon is required. On a Docker connection error, tell the user to start Docker
Desktop/daemon; do not start Docker yourself.

## task-key resolution

Most sub-commands need a full task-key.

1. If a full task-key is given, use it as-is.
2. For a bare task-id, use the resolver:

```bash
okstra model-io task-selection-input --project-root <projectRoot> --task-ref <task-id>
```

3. On multiple matches, show the candidates and let the user pick.
4. Only `down --all` can run without a task-key.

## intent routing

Clear verbs:

- "bring up/deploy", "up": `up`
- "status": `status`
- "logs": `logs`
- "stop watcher", "stop-watcher": `stop-watcher`
- "tear down", "down": `down`

If ambiguous, show the full facet list and offer an Enter directly option. When multiple facets are in one message, run Step 0 once and execute the sub-commands sequentially.

## up

Run:

```bash
okstra container up --project-root <projectRoot> --task-key <task-key> --text
```

Preconditions:

- The task must have an implementation worktree registered in the registry.
- The worktree root must contain a `docker-compose.yml`.
- Every stage of the approved plan must be `done`. Do not deploy a partial-stage state as if it were a complete task.

Handling failure messages:

- Message that the task worktree is not in the registry: tell the user to run the implementation phase first.
- No compose file: show the CLI message verbatim.
- `final-verification(whole-task): stage N not done`: tell the user to finish that stage via implementation.
- healthcheck failure: relay the failing service and the `docker compose ... logs` line the CLI provides, verbatim.

On success, read the fixed `Service` and `Watcher` rows, then run the `status --text` command below and read its numbered container `ports` fields. Tell the user that management from here is via `okstra container status <task-key>` and `down <task-key>`. For *what to verify* once it is up, point to the implementation report's §5.7.9 Manual User Test (Draft) — those steps and expected results are the manual test script for this build.

## status

Run:

```bash
okstra container status --project-root <projectRoot> --task-key <task-key> --text
```

Fixed fields:

- `projectName`: compose project name
- `containers`: running containers found by run-trace label
- `watchers`: watcher metadata from the registry

The `containers` label query is authoritative for whether it is alive. The watcher registry can lag. If `containers` is empty, say the group is not running and offer `up`.

## logs

Run:

```bash
okstra container logs --project-root <projectRoot> --task-key <task-key> --text
```

service scope:

```bash
okstra container logs --project-root <projectRoot> --task-key <task-key> --service <service> --text
```

Show the fixed `Watchers dir` and numbered `Watchers` rows. The live stream is in the tmux watcher pane, not a file. If raw compose logs are needed, get `Project name` from `status`, then tell the user they can run `docker compose -p <projectName> logs -f <service>`.

## stop-watcher

Run:

```bash
okstra container stop-watcher --project-root <projectRoot> --task-key <task-key> --text
```

Remove only the watcher/tail panes and keep the containers. Summarize the fixed `Reaped panes` and `Note` rows. If the user actually intends to bring the containers down, route to `down`.

## down

Single task:

```bash
okstra container down --project-root <projectRoot> --task-key <task-key> --text
```

Whole project:

```bash
okstra container down --project-root <projectRoot> --all --text
```

A single-task down is fine to run after resolving the task-key. `--all` takes down every okstra container group in the project, so confirm with the user before running it.

Report the fixed `Downed` and `Orphan panes reaped` rows. Show each project name and the reaped panes.

## Output rules

- The fixed text fields are the source of truth.
- Do not second-guess it with raw `docker` commands. The only exception is when the CLI failed and the user asked for a manual fallback.
- Show the resolved task-key in the heading or on the first line.
- Show CLI failure messages verbatim, including the remediation line.
- Show container/service state as the fixed values, without normalizing.

## Forbidden patterns

- Trying to start the Docker daemon yourself.
- Guessing the cause of an `up` failure and editing the compose file.
- Dressing up a partial-stage task as deployable.
- Judging a container as alive from the watcher registry alone.
- Running `down --all` without user confirmation.
- Overriding the CLI result arbitrarily with a raw docker query.
