Skip to content

Commit aa1ba96

Browse files
committed
docs: First draft of the devcontainer specs
1 parent 31adfba commit aa1ba96

File tree

4 files changed

+274
-0
lines changed

4 files changed

+274
-0
lines changed

docs/agents/_template.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
## <Agent Tool> — Integration Notes
2+
3+
### Overview
4+
5+
Summarize what this tool does and how Agents‑Workflow uses it.
6+
7+
### Credentials
8+
9+
- Environment variables: list supported vars and precedence.
10+
- Config files/locations: paths to mount read‑only if available.
11+
- Host agents/sockets: whether forwarding is supported.
12+
- Minimal test/probe command to validate auth.
13+
14+
### Execution Hooks
15+
16+
- How commands are invoked inside sessions.
17+
- Points where timeline markers should be emitted.
18+
- Any stderr/stdout peculiarities affecting recording.
19+
20+
### Time‑Travel Considerations
21+
22+
- Side effects on the filesystem and how to snapshot effectively.
23+
- Required quiesce/flush operations before anchoring (if any).
24+
25+
### Known Issues
26+
27+
- Platform quirks, rate limits, stability notes.
28+
29+

docs/devcontainer-design.md

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
## Devcontainer Design — Requirements, Rationale, Implementation
2+
3+
### Scope
4+
5+
Define a layered devcontainer architecture for Agents‑Workflow:
6+
7+
- A lower‑level Nix devcontainer base that standardizes Nix, caches, and host↔guest cache sharing.
8+
- An Agents Base Image that builds on the Nix base and ships all supported agentic CLIs plus the framework glue for task execution, recording, and credential propagation.
9+
- Downstream project images that extend the Agents Base Image by adding a project‑specific Nix devshell for building/testing that codebase.
10+
11+
This document describes requirements, rationale, and implementation details. Nix base specifications live under `docs/nix-devcontainer/`.
12+
13+
### Requirements
14+
15+
- Provide a consistent developer experience across Linux, macOS, and Windows (Docker Desktop/WSL) with minimal host prerequisites.
16+
- Support all agentic CLIs integrated by agents‑workflow (see per‑agent docs under `docs/agents/`).
17+
- Implement credential propagation: when host is authenticated to a provider, the guest resolves the same credentials without re‑login.
18+
- Provide persistent build caches and Nix store layers across container rebuilds; enable optional host↔guest cache sharing for language package managers.
19+
- Integrate execution hooks needed by Agent Time‑Travel (timeline markers, snapshot triggers) without interfering with normal shell use.
20+
- Keep secrets out of images; use runtime env/secrets and read‑only mounts; be auditable.
21+
22+
### Design Rationale
23+
24+
- Layering separates concerns:
25+
- Nix base focuses on reproducibility and performant builds via shared caches.
26+
- Agents base concentrates agent tools, shell setup, recording hooks, and credential bridges.
27+
- Projects remain small: generally a `devcontainer.json` and a Nix devshell.
28+
- Nix is the lingua franca for project dependencies and toolchains; downstream projects reuse the same workflow regardless of language.
29+
- Cache sharing is opt‑in and explicit per package manager to avoid accidental leakage and permission issues.
30+
- Credential propagation prioritizes agent‑approved mechanisms (env vars, config files, OS agents) and relies on read‑only host mounts or forwarded sockets where feasible.
31+
32+
### Layered Images
33+
34+
1) Nix Devcontainer Base (see `docs/nix-devcontainer/`)
35+
- Installs Nix (flakes enabled), configures substituters/cachix.
36+
- Declares persistent volumes for `/nix`, Nix DB, and general caches.
37+
- Provides optional shared cache mounts for common package managers (npm/pnpm/yarn, pip/pipx, cargo, go, maven/gradle, etc.).
38+
- Exposes a thin entrypoint that sources project devshell when present.
39+
40+
2) Agents Base Image
41+
- FROM: Nix Devcontainer Base.
42+
- Installs agentic CLIs supported by Agents‑Workflow (see `docs/agents/`). Examples include: OpenAI/Anthropic CLI tooling, GitHub CLI, and other agent runners referenced by `bin/*` and `*-setup` scripts.
43+
- Copies `bin/`, `common-pre-setup`, `common-post-setup`, and setup shims (`codex-setup`, `copilot-setup`, `open-hands-setup`, `goose-setup`, `jules-setup`).
44+
- Configures shell integration (zsh/bash/fish) to emit execution markers via preexec/DEBUG traps in support of time‑travel anchors.
45+
- Prepares netrc/SSH/gh credential bridges (runtime only; nothing baked into the image).
46+
47+
3) Project Image
48+
- FROM: Agents Base Image.
49+
- Adds project `flake.nix`/`devshell` and any extra tools.
50+
- Optionally extends cache mounts for project‑specific package managers.
51+
52+
### devcontainer.json (reference)
53+
54+
Downstream projects consume the base like this (illustrative):
55+
56+
```json
57+
{
58+
"name": "agents-workflow-dev",
59+
"image": "ghcr.io/blocksense/agents-workflow-agents-base:latest",
60+
"features": {},
61+
"remoteUser": "vscode",
62+
"updateRemoteUserUID": true,
63+
"containerEnv": {
64+
"ZDOTDIR": "/home/vscode/.zsh",
65+
"NIX_CONFIG": "experimental-features = nix-command flakes"
66+
},
67+
"mounts": [
68+
"source=aw-nix-store,target=/nix,type=volume",
69+
"source=aw-cache-home,target=/home/vscode/.cache,type=volume",
70+
"source=aw-cargo,target=/home/vscode/.cargo,type=volume",
71+
"source=aw-go-cache,target=/home/vscode/.cache/go-build,type=volume",
72+
"source=aw-go-mod,target=/home/vscode/go/pkg/mod,type=volume"
73+
],
74+
"runArgs": ["--init"],
75+
"customizations": {
76+
"vscode": {
77+
"settings": {
78+
"terminal.integrated.defaultProfile.linux": "zsh"
79+
},
80+
"extensions": ["ms-vscode-remote.remote-containers"]
81+
}
82+
},
83+
"postCreateCommand": "./codex-setup || true"
84+
}
85+
```
86+
87+
### Credential Propagation Framework
88+
89+
Principles:
90+
91+
- Never bake secrets into images. Use runtime environment variables, forwarded agents/sockets, and read‑only mounts of host config where safe.
92+
- Normalize through the shell setup scripts so agent CLIs find credentials predictably.
93+
94+
Mechanisms:
95+
96+
- Env pass‑through: Allowlist known vars (examples: `OPENAI_API_KEY`, `ANTHROPIC_API_KEY`, `OPENROUTER_API_KEY`, `HUGGING_FACE_HUB_TOKEN`, `GITHUB_TOKEN`, `GITLAB_TOKEN`, `BITBUCKET_TOKEN`).
97+
- Git hosting: generate `~/.netrc` from `GITHUB_TOKEN`/`GITLAB_TOKEN`/`BITBUCKET_TOKEN` (as in `codex-setup`).
98+
- GitHub CLI and Copilot CLI: prefer `gh auth` state by mounting `~/.config/gh/hosts.yml` read‑only or exporting `GH_TOKEN` if org policy allows.
99+
- SSH agent forwarding: mount `SSH_AUTH_SOCK` and pass through `~/.ssh/known_hosts` read‑only; avoid copying private keys.
100+
- Cloud SDKs: allow optional read‑only mounts of provider config (e.g., `~/.aws`, `~/.config/gcloud`) when required by a specific agent; otherwise rely on env‑based credentials.
101+
102+
Each agent’s exact mapping is captured in `docs/agents/<tool>.md` and validated in CI with probe commands (e.g., `gh auth status`, minimal API ping for OpenAI/Anthropic).
103+
104+
### Time‑Travel Execution Hooks in Devcontainer
105+
106+
- zsh: `preexec` emits a timeline marker before execution; `precmd` after. bash: `trap DEBUG` + `PROMPT_COMMAND`. fish: `fish_preexec`/`fish_postexec`.
107+
- The hook writes a small JSON event (`{ts, cmd, cwd, session}`) to a FIFO/log consumed by the runner to align markers with snapshot anchors.
108+
- Hooks are opt‑out via config key (see `docs/configuration.md`), and no‑op for non‑interactive shells.
109+
110+
### Caching and Host↔Guest Cache Sharing
111+
112+
- Persistent volumes for: `/nix`, language caches (Cargo, Go, npm/pnpm/yarn, pip, maven/gradle), and compiler caches (sccache/ccache).
113+
- Host↔guest sharing guidelines and test plans are defined in `docs/nix-devcontainer/cache-guidelines.md` and `test-suite.md`.
114+
- For Windows hosts, prefer Docker volumes over bind mounts to avoid permission/line‑ending pitfalls; on macOS/Linux, bind mounts are acceptable for read‑only config.
115+
116+
### Implementation Details
117+
118+
- User/UID: set `remoteUser` to a non‑root user matching host UID to simplify shared cache permissions.
119+
- Entrypoint: minimal init (tini), run `common-pre-setup`, source project hooks if present `.agents/*-setup`, then `common-post-setup`.
120+
- Health: ship `aw doctor` checks for snapshot providers, Nix, caches, gh/ssh/auth readiness.
121+
- Security: secrets via env or forwarded sockets; config mounts read‑only; no tokens written to image layers.
122+
123+
### Testing and CI
124+
125+
- Cold/warm build benchmarks with and without caches.
126+
- Credential probes for each agent (non‑destructive): `gh auth status`, short `curl` to model/provider endpoints when keys present.
127+
- Time‑travel hook smoke tests: run a few commands and verify markers are emitted.
128+
- Cross‑platform matrix: Linux, macOS (Docker Desktop), Windows (WSL2/Hyper‑V).
129+
130+
### Migration Plan
131+
132+
- Phase 1 (this repo): build and publish `agents‑workflow‑nix‑base` and `agents‑workflow‑agents‑base` images to a registry (e.g., GHCR).
133+
- Phase 2 (extraction): split Nix base to a standalone repo; keep Agents base here, pinning base by digest.
134+
135+
### Open Questions
136+
137+
- Exact per‑agent credential files and minimal scopes (document in `docs/agents/`).
138+
- Which package manager caches to enable by default vs opt‑in.
139+
- Windows credential manager integrations (e.g., Git Credential Manager) via bind vs env.
140+
141+
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
## Host↔Guest Cache Sharing — Guidelines and Goals
2+
3+
### Goals
4+
5+
- Reduce build/install times across container rebuilds and branches.
6+
- Avoid secret/material leakage via shared caches.
7+
- Keep cache consistency and correctness (no silent corruption, deterministic rebuilds when needed).
8+
9+
### General Principles
10+
11+
- Prefer Docker volumes for persistence; use bind mounts for read‑only configs when necessary.
12+
- Set clear ownership/permissions by aligning container user UID/GID with host where possible.
13+
- Use content‑addressed caches (where supported) and verify cache keys include OS/arch/toolchain.
14+
- Provide a kill‑switch env/flag to disable cache sharing when debugging purity issues.
15+
16+
### Package Manager Patterns
17+
18+
- Node (npm/pnpm/yarn):
19+
- Volumes: `~/.npm`, `~/.cache/pnpm`, `~/.yarn`, project `.pnpm-store`.
20+
- Ensure lockfiles are honored; enable `corepack` where applicable.
21+
- Tests: cold vs warm install; lockfile change invalidation.
22+
23+
- Python (pip/pipx/poetry):
24+
- Volumes: `~/.cache/pip`, `~/.cache/pipx`, virtualenv directories under project `.venv`.
25+
- Pin interpreter from Nix; ensure ABI compatibility.
26+
- Tests: wheel reuse, virtualenv isolation, hash mismatch behavior.
27+
28+
- Rust (cargo):
29+
- Volumes: `~/.cargo`, `~/.cargo/registry`, `~/.cargo/git`.
30+
- Consider `sccache` for compiler outputs; volume for `~/.cache/sccache`.
31+
- Tests: build twice, ensure network disabled on second run.
32+
33+
- Go:
34+
- Volumes: `~/go/pkg/mod`, `~/.cache/go-build`.
35+
- Module proxy configuration via env; verify GOPATH hygiene.
36+
- Tests: module reuse and build cache hit rate across rebuilds.
37+
38+
- Java (Maven/Gradle):
39+
- Volumes: `~/.m2`, `~/.gradle`.
40+
- Ensure Gradle Gradle Enterprise/daemon settings sane for containers.
41+
- Tests: offline build viability after warm run.
42+
43+
- System Caches (ccache/sccache):
44+
- Volumes: `~/.ccache`, `~/.cache/sccache`.
45+
- Configure size limits and compression; record hit/miss metrics.
46+
47+
### Security Considerations
48+
49+
- Treat caches as untrusted inputs when switching branches or contributors; prefer read‑write volumes scoped per project or per user.
50+
- Do not mount credential stores (e.g., `~/.aws`) as caches; keep those separate and read‑only.
51+
- Avoid mounting host package manager sockets/daemons unless required.
52+
53+
### Observability
54+
55+
- Expose cache directories and sizes via `aw doctor`.
56+
- Emit basic metrics (hits/misses) where tools provide them (cargo, sccache).
57+
58+
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
## Nix Devcontainer — Cache Sharing Test Suite
2+
3+
### Purpose
4+
5+
Validate cache persistence and correctness for supported package managers and toolchains across container rebuilds and typical workflows.
6+
7+
### Test Matrix
8+
9+
- Platforms: Linux, macOS (Docker Desktop), Windows (WSL2)
10+
- Images: Nix Base, Agents Base, representative project images
11+
- Package Managers: npm/pnpm/yarn, pip/pipx/poetry, cargo, go, maven/gradle, ccache/sccache
12+
13+
### Scenarios
14+
15+
1) Cold → Warm Install
16+
- Cold: clear volumes; install dependencies; record time/size.
17+
- Warm: rebuild container; reinstall; expect significant speedup and no network fetches where offline cache applies.
18+
19+
2) Lockfile Change Invalidation
20+
- Modify lockfile (add dependency); ensure caches do not cause stale results; verify correct new graph.
21+
22+
3) Toolchain Change
23+
- Change Nix devshell tool versions; validate caches with different ABI get invalidated as needed.
24+
25+
4) Concurrent Builds
26+
- Run two builds concurrently in separate containers sharing volumes; ensure no corruption.
27+
28+
5) Security Hygiene
29+
- Verify no secrets present in cache volumes; permissions are scoped to devcontainer user.
30+
31+
6) Offline Build
32+
- Disable network; confirm warm caches enable successful builds where expected (cargo/go/java).
33+
34+
### Measurements
35+
36+
- Wall‑clock durations (cold vs warm)
37+
- Network requests count/bytes (where observable)
38+
- Cache sizes before/after
39+
- Hit/miss metrics (cargo, sccache)
40+
41+
### Automation
42+
43+
- Provide `aw doctor --caches` to print configured mounts and sizes.
44+
- CI jobs per package manager with synthetic sample projects.
45+
46+

0 commit comments

Comments
 (0)