1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
// Machine default profile. Selects the builtin trivial `pi`; agent config
// (AGENTS.md, skills) rides in through the binary allowlist off ~/.pi/agent,
// so nothing needs restating here. `-p claude` for the other builtin.
profile "pi"
// Apple's `container` CLI instead of Docker; needs `container system start`.
runtime "apple"
// Pi against Amazon Bedrock. Pi selects the provider by flag (no env
// equivalent); the model is left to pi at run time. AWS creds come from an
// SSO profile — fill in the placeholders and `aws sso login` on the host.
// ~/.aws mounts read-only, so an expired SSO token means re-logging in on
// the host rather than a silent in-container refresh.
profile "pi-bedrock" {
agent "pi"
args "--provider" "amazon-bedrock"
env {
AWS_PROFILE "bedrock-users"
}
mounts { "~/.aws" }
}
env {
LANG "en_US.UTF-8"
}
mounts {
// Agent config that sits outside the binary allowlist but is still config,
// kept deliberately. Targets derive from the ~/ source.
"~/.claude/statusline.sh"
"~/.claude/output-styles"
// Pi's settings.json points `skills` here rather than at ~/.pi/agent/skills,
// but settings.json isn't in the binary allowlist, so pi inside reads only
// the default dir. Retarget the mount to shadow the (empty) inherited bind.
"~/.dotfiles/ai/skills" target="/root/.pi/agent/skills"
// Shadow the workspace's .envrc so repo secrets never reach the agent.
"/dev/null" target=".envrc"
// jj is the version control in here, and it carries its own identity and
// signing config, so it needs nothing from git. ~/.config/git deliberately
// stays out: its https→ssh rewrites can't be followed (no ssh binary, no
// keys) and can't be revoked either, since insteadOf only accumulates.
"~/.config/jj"
// Writable so jj can record repos it sees.
"~/.config/jj/repos" writable=#true
// ranger state and pi's pinch dir don't exist on this machine yet, so both
// stay inert (skip-if-missing) until something creates them.
"~/.local/share/ranger" writable=#true
// Cargo's download caches, keyed by crate and version, so every Rust
// project wants the same ones and none of them conflict. Concurrent
// sessions only contend briefly, while cargo holds the package-cache lock
// to fetch. Build directories can't be shared this way — they take an
// exclusive lock and a differing rustc invalidates them — so those are a
// per-repo `cache` in .ramekin/config.kdl instead.
//
// Not under ~/.cache/ramekin: that is the base image's Docker build
// context. Skip-if-missing means an absent dir just silently costs cold
// fetches, so: mkdir -p ~/.cache/ramekin-rust/{registry,git}
"~/.cache/ramekin-rust/registry" target="/root/.cargo/registry" writable=#true
"~/.cache/ramekin-rust/git" target="/root/.cargo/git" writable=#true
}