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
}