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
2 changes: 1 addition & 1 deletion .agents/skills/add-mission/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Read [references/mission-checklist.md](references/mission-checklist.md) before e
1. Inspect the current state.
- Read `git status` and preserve unrelated changes.
- Read the missions immediately before and after the intended catalog position in `internal/mission/data/`.
- Read `internal/mission/mission.go`, `internal/mission/catalog.go`, `internal/game/validator.go`, `internal/mission/catalog_test.go`, and `internal/game/missions_test.go`.
- Read `internal/mission/mission.go`, `validate.go`, `conditions.go`, `docker_rules.go`, `internal/game/validator.go`, the matching `internal/mission/*_test.go`, and `internal/game/missions_test.go` with the Linux or Docker route tests.
- Check the track-local world/campaign order, stage placement, difficulty and XP progression, existing validators, and test patterns before choosing an implementation.

2. State the learning objective before writing JSON.
Expand Down
2 changes: 1 addition & 1 deletion .agents/skills/add-mission/references/mission-checklist.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Current content model

Missions are embedded JSON files under `internal/mission/data/`. `internal/mission/catalog.go` decodes them with unknown fields rejected, validates each item, sorts by `number`, and requires a contiguous catalog beginning at 1. `internal/mission/world.go` derives track-local worlds from contiguous campaign runs; a campaign cannot disappear and later reappear in the same track.
Missions are embedded JSON files under `internal/mission/data/`. `internal/mission/catalog.go` decodes them with unknown fields rejected, validates each item through `validate.go`, `conditions.go`, and `docker_rules.go`, sorts by `number`, and requires a contiguous catalog beginning at 1. `internal/mission/world.go` derives track-local worlds from contiguous campaign runs; a campaign cannot disappear and later reappear in the same track.

Every mission supplies:

Expand Down
4 changes: 2 additions & 2 deletions .agents/skills/extend-sandbox-command/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Read [references/shell-semantics.md](references/shell-semantics.md) before chang
## Workflow

1. Map the existing behavior.
- Inspect `internal/sandbox/shell.go`, `sandbox.go`, `filesystem.go`, the relevant `commands_*.go`, and `shell_test.go`.
- Inspect `internal/sandbox/shell.go` (execution stages), `lexer.go`, `command_line.go`, `dispatch.go` (command registration), `manuals.go` (help), `sandbox.go`, `filesystem*.go`, the relevant `commands_*.go`, and `shell_test.go`.
- Trace lexing, parsing, word expansion, stage execution, dispatcher registration, virtual path resolution, and error wrapping.
- Compare a semantically similar command and read its focused manual entry. Check missions and canonical solutions that already depend on the affected behavior.

Expand All @@ -28,7 +28,7 @@ Read [references/shell-semantics.md](references/shell-semantics.md) before chang
- Put command behavior in the closest `commands_*.go` file or a narrowly named new file.
- Register the command in `Sandbox.run` and in the no-argument command list.
- Add or update its `commandManuals` entry so `help COMMAND` and `man COMMAND` describe the actual subset.
- Keep reusable virtual-filesystem behavior in `filesystem.go`; do not bypass it inside a command handler.
- Keep reusable virtual-filesystem behavior in `filesystem*.go`; do not bypass it inside a command handler.

5. Add tests before relying on the command in content.
- Cover successful direct use and stdin/pipeline use where applicable.
Expand Down
2 changes: 1 addition & 1 deletion .agents/skills/prepare-iteration/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Use [references/iteration-template.md](references/iteration-template.md) for the
## Workflow

1. Establish the milestone boundary.
- Read the reports in `project/history/iterations/`, README, `internal/cli/app.go`, and the milestone request.
- Read the reports in `project/history/iterations/`, README, the command files in `internal/cli/`, and the milestone request.
- Identify the next iteration number and intended version. Do not change version strings or roadmap claims unless the milestone requires it.

2. Review the complete change set.
Expand Down
14 changes: 7 additions & 7 deletions docs/technical/sandbox-and-safety.md
Original file line number Diff line number Diff line change
Expand Up @@ -171,20 +171,20 @@ The Docker-compatible engine remains a powerful external dependency; OpsQuest re

| Threat | Primary controls | Evidence location |
| --- | --- | --- |
| Player launches a host command | Closed Go dispatcher; no fallback process lookup; raw line never reaches a shell | `internal/sandbox/shell.go`, hardening tests |
| Player reads or writes a host path | Independent in-memory root and virtual path resolver | `internal/sandbox/filesystem.go`, regression tests |
| Player launches a host command | Closed Go dispatcher; no fallback process lookup; raw line never reaches a shell | `internal/sandbox/shell.go`, `dispatch.go`, hardening tests |
| Player reads or writes a host path | Independent in-memory root and virtual path resolver | `internal/sandbox/filesystem*.go`, regression tests |
| Expansion exhausts memory | Line, token, argument, output, entry, and aggregate budgets | quota tests in `internal/sandbox` |
| Archive escapes extraction target | Strict metadata validation and destination containment | archive and hardening tests |
| Script bypasses shell restrictions | Same parser/dispatcher, bounded nesting and steps, unsupported syntax rejection | `commands_script.go` and tests |
| Docker input becomes arbitrary CLI flags | Typed parser accepts only exact actions and validated logical aliases | `internal/dockerlab/parser.go` and tests |
| Cleanup removes another container | Exact ID plus managed/schema/session/mission/alias label verification | `internal/dockerlab/environment.go` and tests |
| Partial Docker setup leaks resources silently | Factory may return a partial environment; managed cleanup and retryable `Close` | `internal/dockerlab/factory.go`, environment contract tests |
| Cleanup removes another container | Exact ID plus managed/schema/session/mission/alias label verification | `internal/dockerlab/cleanup.go`, `ownership.go` and tests |
| Partial Docker setup leaks resources silently | Factory may return a partial environment; managed cleanup and retryable `Close` | `internal/dockerlab/factory.go`, `fixtures.go`, environment contract tests |
| A killed process leaks running fixtures | 24-hour fixture lifetime; owner-process and age-based sweep with complete label and generated-name proof | `internal/dockerlab/janitor.go` and tests |
| Orphan sweep removes a live or foreign container | Live same-host owners are never swept; unknown owners only after the fixture lifetime; exact IDs only | `internal/dockerlab/janitor_test.go` |
| Removed containers leak engine identity | Missing-container errors mapped to the alias; tracked IDs and names redacted from engine errors | `internal/dockerlab/environment.go` and tests |
| Removed containers leak engine identity | Missing-container errors mapped to the alias; tracked IDs and names redacted from engine errors | `internal/dockerlab/transport.go`, `container_commands.go` and tests |
| Lab network reaches the host network or internet | Fixed `--internal` bridge networks; no network options; no in-container command execution | `internal/dockerlab/network.go`, `network_test.go` |
| Player attaches a lab container to a host or foreign network | Built-in names rejected by the parser; only tracked attempt networks resolve; exact IDs only | `internal/dockerlab/parser.go`, `network.go` and tests |
| Network cleanup strands or removes the wrong network | Containers removed first; label and generated-name verification; retryable unresolved set; janitor sweeps networks after containers | `internal/dockerlab/network.go`, `janitor.go` and tests |
| Player attaches a lab container to a host or foreign network | Built-in names rejected by the parser; only tracked attempt networks resolve; exact IDs only | `internal/dockerlab/parser.go`, `network_commands.go` and tests |
| Network cleanup strands or removes the wrong network | Containers removed first; label and generated-name verification; retryable unresolved set; janitor sweeps networks after containers | `internal/dockerlab/cleanup.go`, `janitor.go` and tests |
| Persisted display text injects terminal controls | Profile names reject non-printable characters and normalize legacy values | `internal/profile/profile.go` and tests |
| Another site reaches the loopback companion | One-time capability pairing, exact Host/Origin checks, same-site HTTP-only cookie, no permissive CORS | `internal/webapp/server.go` and tests |
| Browser input reaches a mission environment | Companion exposes only read-only state and SSE routes; `game.Session` has no companion command callback | `internal/webapp`, `internal/game/companion.go` |
Expand Down
Loading
Loading