31| Variabel | Deskripsi |31| Variabel | Deskripsi |
32| :- | :- |32| :- | :- |
33| `CLAUDE_CODE_SESSION_ACCESS_TOKEN` | JWT sesi, diawali dengan `sk-ant-cc-`. Klaim `act` mengidentifikasi pembuat sesi, dengan email pembuat ketika surface pembuatan merekamnya. Nilainya adalah token pada waktu pemijahan; penyegaran tiba melalui stdin anak, jadi wrapper hanya melihat nilai awal. Lihat [Verify session identity](/docs/id/self-hosted-environments-identity). |33| `CLAUDE_CODE_SESSION_ACCESS_TOKEN` | JWT sesi, diawali dengan `sk-ant-cc-`. Klaim `act` mengidentifikasi pembuat sesi, dengan email pembuat ketika surface pembuatan merekamnya. Nilainya adalah token pada waktu pemijahan; penyegaran tiba melalui stdin anak, jadi wrapper hanya melihat nilai awal. Lihat [Verify session identity](/docs/id/self-hosted-environments-identity). |
34| `CCR_SESSION_ACCOUNT_EMAIL` | Email pembuat sesi, pra-ekstrak oleh runner dari klaim `act.email` token tanpa verifikasi tanda tangan. Cocok untuk pelabelan, seperti trailer commit. Ketika email membuka akses penyediaan kredensial, verifikasi token dan baca klaim darinya; lihat [Provision credentials scoped to the session creator](#provision-credentials-scoped-to-the-session-creator). Tidak diatur ketika token tidak membawa email pembuat. Perlakukan sebagai informasi yang dapat diidentifikasi secara pribadi. |34| `CCR_SESSION_ACCOUNT_EMAIL` | Email pembuat sesi, pra-ekstrak oleh runner dari klaim `act.email` token tanpa verifikasi tanda tangan. Cocok untuk pelabelan, seperti trailer commit. Ketika email membuka akses penyediaan kredensial, verifikasi token dan baca klaim darinya sebagai gantinya. Lihat [Provision credentials scoped to the session creator](#provision-credentials-scoped-to-the-session-creator). Tidak diatur ketika token tidak membawa email pembuat, misalnya pada sesi yang dibuat oleh identitas layanan organisasi Anda. Perlakukan sebagai informasi yang dapat diidentifikasi secara pribadi. |
35| `CLAUDE_RUNNER_CLIENT_PLATFORM` | Surface klien yang membuat sesi, seperti `web_claude_ai`, `desktop_app`, `ios`, `claude_code_cli`, atau `scheduled_trigger`. Anthropic merekam nilainya sekali saat pembuatan sesi, jadi wrapper dan setiap hook siklus hidup melihat nilai yang sama. Gunakan untuk analitik adopsi dan pelabelan saja, bukan sebagai sinyal otorisasi. Tidak diatur ketika sesi tidak memiliki surface yang tercatat atau dikenali, jadi referensikan sebagai `${CLAUDE_RUNNER_CLIENT_PLATFORM:-}` di bawah `set -u`. Memerlukan Claude Code v2.1.229 atau lebih baru. |35| `CLAUDE_RUNNER_CLIENT_PLATFORM` | Surface klien yang membuat sesi, seperti `web_claude_ai`, `desktop_app`, `ios`, `claude_code_cli`, atau `scheduled_trigger`. Anthropic merekam nilainya sekali saat pembuatan sesi, jadi wrapper dan setiap hook siklus hidup melihat nilai yang sama. Gunakan untuk analitik adopsi dan pelabelan saja, bukan sebagai sinyal otorisasi. Tidak diatur ketika sesi tidak memiliki surface yang tercatat atau dikenali. Memerlukan Claude Code v2.1.229 atau lebih baru. |
36| `CLAUDE_RUNNER_CLAUDE_BIN` | Jalur absolut ke biner Claude Code runner sendiri. Akhiri wrapper Anda dengan `exec "$CLAUDE_RUNNER_CLAUDE_BIN" "$@"` untuk menyerahkan ke biner yang disematkan tanpa hardcoding jalur instalasi. |36| `CLAUDE_RUNNER_CLAUDE_BIN` | Jalur absolut ke biner Claude Code runner sendiri. Akhiri wrapper Anda dengan `exec "$CLAUDE_RUNNER_CLAUDE_BIN" "$@"` untuk menyerahkan ke biner yang disematkan tanpa hardcoding jalur instalasi. |
37| `CLAUDE_CODE_REMOTE_SESSION_ID` | ID sesi dalam bentuk `cse_...` yang ditandai. Ini adalah sesi yang sama yang dilihat [lifecycle hooks](#lifecycle-hooks) sebagai `CLAUDE_RUNNER_SESSION_ID` dalam bentuk `session_...`; variabel UUID cocok di kedua sisi, dan mengganti awalan `cse_` dengan `session_` menghasilkan ID yang ditampilkan di URL sesi. |37| `CLAUDE_CODE_REMOTE_SESSION_ID` | ID sesi dalam bentuk `cse_...` yang ditandai. Ini adalah sesi yang sama yang dilihat [lifecycle hooks](#lifecycle-hooks) sebagai `CLAUDE_RUNNER_SESSION_ID` dalam bentuk `session_...`; variabel UUID cocok di kedua sisi, dan mengganti awalan `cse_` dengan `session_` menghasilkan ID yang ditampilkan di URL sesi. |
38| `CLAUDE_CODE_REMOTE_SESSION_UUID` | ID sesi yang sama dalam bentuk UUID kanonik, untuk sistem yang menggunakan UUID sebagai kunci. |38| `CLAUDE_CODE_REMOTE_SESSION_UUID` | ID sesi yang sama dalam bentuk UUID kanonik, untuk sistem yang menggunakan UUID sebagai kunci. |
39| `CLAUDE_CODE_REMOTE_SLACK_THREAD_URL` | Untuk sesi [Claude Tag](https://claude.com/docs/claude-tag/overview) yang dimiliki oleh satu thread Slack, tautan ke thread tersebut. Tidak diatur untuk sesi lain, dan dapat juga tidak diatur untuk sesi thread. |
40| `CLAUDE_CODE_REMOTE_SLACK_THREAD_TS` | Untuk sesi Claude Tag yang dimiliki oleh satu thread Slack, timestamp Slack thread tersebut, seperti `1700000000.000100`. Dapat tidak diatur, dan dapat diatur ketika `CLAUDE_CODE_REMOTE_SLACK_THREAD_URL` tidak diatur, jadi periksa setiap variabel secara terpisah. |
39| `CLAUDE_SESSION_INGRESS_TOKEN_FILE` | Jalur absolut ke file per-sesi yang menyimpan JWT sesi saat ini, tetap segar di seluruh penyegaran token. Subproses shell membacanya untuk header `Authorization` mereka saat mengunduh lampiran yang ditambahkan pengguna ke sesi. `exec` menyimpan variabel secara otomatis; wrapper yang membangun kembali lingkungan anak harus membawa variabel, atau unduhan lampiran berhenti bekerja diam-diam. |41| `CLAUDE_SESSION_INGRESS_TOKEN_FILE` | Jalur absolut ke file per-sesi yang menyimpan JWT sesi saat ini, tetap segar di seluruh penyegaran token. Subproses shell membacanya untuk header `Authorization` mereka saat mengunduh lampiran yang ditambahkan pengguna ke sesi. `exec` menyimpan variabel secara otomatis; wrapper yang membangun kembali lingkungan anak harus membawa variabel, atau unduhan lampiran berhenti bekerja diam-diam. |
40| `CLAUDE_CONFIG_DIR` | Direktori konfigurasi Claude per-sesi, ditulis saat awal sesi dari snapshot konfigurasi host runner yang ditangkap runner saat startup; lihat [Permissions and tool approval](#permissions-and-tool-approval). Penulisan di sini terisolasi ke sesi ini. Direktori tetap di bawah `<base-dir>/_sessions/` setelah sesi berakhir kecuali Anda memulai runner dengan [`--remove-session-state`](/docs/id/self-hosted-environments-reference#runner-cli-flags); lihat [Reuse a pre-warmed checkout](/docs/id/self-hosted-environments-deploy#reuse-a-pre-warmed-checkout). |42| `CLAUDE_CONFIG_DIR` | Direktori konfigurasi Claude per-sesi, ditulis saat awal sesi dari snapshot konfigurasi host runner yang ditangkap runner saat startup; lihat [Permissions and tool approval](#permissions-and-tool-approval). Penulisan di sini terisolasi ke sesi ini. Direktori tetap di bawah `<base-dir>/_sessions/` setelah sesi berakhir kecuali Anda memulai runner dengan [`--remove-session-state`](/docs/id/self-hosted-environments-reference#runner-cli-flags); lihat [Reuse a pre-warmed checkout](/docs/id/self-hosted-environments-deploy#reuse-a-pre-warmed-checkout). |
41| `ANTHROPIC_BASE_URL` | URL dasar API yang akan digunakan anak, dikirimkan oleh bidang kontrol per sesi dan biasanya `https://api.anthropic.com`. Jangan timpa: kredensial inferensi sesi adalah token OAuth yang dikeluarkan Anthropic yang tidak diterima penyedia lain. |43| `ANTHROPIC_BASE_URL` | URL dasar API yang akan digunakan anak, dikirimkan oleh bidang kontrol per sesi dan biasanya `https://api.anthropic.com`. Jangan timpa: kredensial inferensi sesi adalah token OAuth yang dikeluarkan Anthropic yang tidak diterima penyedia lain. |
43 45
44Wrapper juga mewarisi sisa lingkungan anak yang dikelola, termasuk environment variable yang disediakan server. `exec` menyebarkan semuanya secara otomatis; jika wrapper Anda memijahkan anak dengan cara lain, teruskan lingkungan lengkap.46Wrapper juga mewarisi sisa lingkungan anak yang dikelola, termasuk environment variable yang disediakan server. `exec` menyebarkan semuanya secara otomatis; jika wrapper Anda memijahkan anak dengan cara lain, teruskan lingkungan lengkap.
45 47
48`CLAUDE_CODE_REMOTE_SLACK_THREAD_URL` dan `CLAUDE_CODE_REMOTE_SLACK_THREAD_TS` sampai ke wrapper Anda atau [hook `command`](#command). Variabel tersebut juga sampai ke apa yang dijalankan sesi, seperti perintah shell, hook git, dan hook Claude Code. Hook `checkout`, `post-session`, dan `spawn-runner` tidak menerimanya.
49
50<h3 id="give-a-default-to-variables-that-can-be-unset">
51 Berikan nilai default untuk variabel yang dapat tidak diatur
52</h3>
53
54`CCR_SESSION_ACCOUNT_EMAIL`, `CLAUDE_RUNNER_CLIENT_PLATFORM`, `CLAUDE_CODE_REMOTE_SLACK_THREAD_URL`, dan `CLAUDE_CODE_REMOTE_SLACK_THREAD_TS` masing-masing dapat tidak diatur. Jika skrip Anda menggunakan `set -u`, Bash berhenti dengan `unbound variable` ketika mengekspansi variabel yang tidak diatur, jadi ekspansikan dengan nilai default, seperti `${CCR_SESSION_ACCOUNT_EMAIL:-}`.
55
56Di mana pun shell mengekspansi tautan thread Slack, lakukan tindakan pencegahan berikut:
57
58* **Beri tanda kutip**: tautan dapat berisi karakter yang diproses shell, seperti `?` dan `&`, jadi beri tanda kutip pada variabel, seperti dalam `"${CLAUDE_CODE_REMOTE_SLACK_THREAD_URL:-}"`.
59* **Jauhkan nilainya dari string `eval` dan `sh -c`**: jangan substitusikan nilainya ke dalam string yang dijalankan `eval` atau `sh -c`, bahkan di dalam tanda kutip. Buat string tersebut mereferensikan variabelnya sebagai gantinya.
60
46<h3 id="keep-stdin-and-file-descriptor-3-attached">61<h3 id="keep-stdin-and-file-descriptor-3-attached">
47 Jaga stdin dan file descriptor 3 terlampir62 Jaga stdin dan file descriptor 3 terlampir
48</h3>63</h3>
49 64
50Stdin anak adalah saluran kontrol runner. Rotasi token dan sinyal akhir sesi tiba di atasnya. Runner juga membuka pipa pada file descriptor 3 dan membaca sinyal aktivitas anak darinya untuk mendorong timeout idle dan startup. `exec "$CLAUDE_RUNNER_CLAUDE_BIN" "$@"` biasa menyimpan keduanya secara otomatis.65Stdin anak adalah saluran kontrol runner. Rotasi token dan sinyal akhir sesi tiba di atasnya. Runner juga membuka pipa pada file descriptor 3 dan membaca sinyal aktivitas anak darinya untuk mendorong timeout idle dan startup. `exec "$CLAUDE_RUNNER_CLAUDE_BIN" "$@"` biasa menyimpan keduanya secara otomatis.
51 66
52Jika wrapper Anda menempatkan anak di latar belakang dengan `&` telanjang, itu memutus stdin anak: sesi terlihat sehat sampai masa pakai token OAuth awal sekitar 30 menit berakhir, kemudian setiap panggilan API gagal dengan `401 authentication_error`. Jika wrapper Anda harus menempatkan anak di latar belakang, misalnya untuk menjaga perangkap pembongkaran tetap hidup, simpan stdin pada file descriptor 4 atau lebih tinggi dan lampirkan kembali secara eksplisit:67Jika wrapper Anda menempatkan anak di latar belakang dengan `&` telanjang, itu memutus stdin anak. Sesi terlihat sehat sampai masa pakai token OAuth awal sekitar 30 menit berakhir, kemudian setiap panggilan API yang menggunakan token tersebut gagal dengan `401 authentication_error`. Jika wrapper Anda harus menempatkan anak di latar belakang, misalnya untuk menjaga perangkap pembongkaran tetap hidup, simpan stdin pada file descriptor 4 atau lebih tinggi dan lampirkan kembali secara eksplisit:
53 68
54```bash theme={null}69```bash theme={null}
55exec 4<&070exec 4<&0
59wait "$CHILD"74wait "$CHILD"
60```75```
61 76
62Jangan tutup atau gunakan kembali file descriptor 3 di wrapper. Mengalihkan stdout dan stderr anak tidak apa-apa.77Anda dapat mengalihkan stdout anak. Jaga file descriptor 3 dan stderr tetap terlampir ke runner:
78
79* **File descriptor 3**: membawa sinyal aktivitas anak ke runner. Jangan tutup atau gunakan kembali di wrapper.
80* **stderr**: ketika wrapper atau anak keluar dengan kode bukan nol, runner mengirimkan baris-baris terakhir stderr ke sesi dan mencetaknya di log-nya sendiri. Pengguna sesi melihat baris-baris tersebut, jadi jangan cetak rahasia ke stderr, dan hapus `set -x` sebelum Anda men-deploy wrapper. Jika Anda mengalihkan stderr, sesi tetap berjalan, tetapi runner melaporkan kegagalan hanya dengan exit code.
63 81
64<h3 id="pass-the-system-prompt-flags-through">82<h3 id="pass-the-system-prompt-flags-through">
65 Teruskan flag system prompt83 Teruskan flag system prompt
108 checkout126 checkout
109</h3>127</h3>
110 128
111Berjalan sekali per repositori, sebagai pengganti klon dan fetch bawaan runner. Gunakan hook untuk mengkloning dari mirror read-through, mengisi working tree dari arsip, atau menerapkan autentikasi git per-sesi. Runner menetapkan variabel-variabel ini, dan dapat menetapkan variabel `CLAUDE_RUNNER_` lain yang tidak tercantum dalam tabel:129Berjalan sekali per repositori, sebagai pengganti clone dan fetch bawaan runner. Gunakan hook untuk melakukan clone dari mirror read-through yang Anda jangkau melalui HTTPS atau SSH, mengisi working tree dari arsip, atau menerapkan autentikasi git per-sesi. Runner menetapkan variabel-variabel ini, dan dapat menetapkan variabel `CLAUDE_RUNNER_` lain yang tidak tercantum dalam tabel:
112 130
113| Variabel | Deskripsi |131| Variabel | Deskripsi |
114| :- | :- |132| :- | :- |
115| `CLAUDE_RUNNER_REPO_URL` | URL repositori untuk mengkloning, setelah `--git-host-rewrite` dan `--git-ssh-rewrite` apa pun telah diterapkan |133| `CLAUDE_RUNNER_REPO_URL` | URL repositori untuk mengkloning, setelah `--git-host-rewrite` dan `--git-ssh-rewrite` apa pun telah diterapkan |
116| `CLAUDE_RUNNER_REPO_REF` | Revisi untuk checkout: cabang, tag, atau commit SHA seperti yang diminta sesi. Kosong berarti cabang default repositori. |134| `CLAUDE_RUNNER_REPO_REF` | Revisi untuk di-checkout, sebagaimana diminta oleh sesi: branch, tag, commit SHA, atau nama referensi lengkap seperti `refs/pull/<number>/head`. Kosong berarti branch default repositori. |
117| `CLAUDE_RUNNER_CHECKOUT_PATH` | Jalur absolut di mana pohon kerja harus ditinggalkan |135| `CLAUDE_RUNNER_CHECKOUT_PATH` | Jalur absolut di mana pohon kerja harus ditinggalkan |
118| `CLAUDE_RUNNER_SESSION_ID` | ID sesi dalam bentuk `session_...` yang ditandai, untuk logging dan korelasi |136| `CLAUDE_RUNNER_SESSION_ID` | ID sesi dalam bentuk `session_...` yang ditandai, untuk logging dan korelasi |
119| `CLAUDE_RUNNER_SESSION_UUID` | ID sesi yang sama dalam bentuk UUID kanonik |137| `CLAUDE_RUNNER_SESSION_UUID` | ID sesi yang sama dalam bentuk UUID kanonik |
120| `CLAUDE_RUNNER_API_BASE_URL` | URL dasar API Anthropic untuk panggilan yang dibatasi sesi |138| `CLAUDE_RUNNER_API_BASE_URL` | URL dasar API Anthropic untuk panggilan yang dibatasi sesi |
121| `CLAUDE_RUNNER_CLIENT_PLATFORM` | Permukaan klien yang membuat sesi, seperti `web_claude_ai`, `desktop_app`, atau `ios`. Tidak diatur ketika sesi tidak memiliki permukaan yang tercatat atau dikenali. |139| `CLAUDE_RUNNER_CLIENT_PLATFORM` | Surface klien yang membuat sesi, seperti `web_claude_ai`, `desktop_app`, atau `ios`. Tidak diatur ketika sesi tidak memiliki surface yang tercatat atau dikenali, jadi rujuk sebagai `${CLAUDE_RUNNER_CLIENT_PLATFORM:-}` di bawah `set -u`. Memerlukan Claude Code v2.1.229 atau lebih baru. |
122| `CLAUDE_CODE_SESSION_ACCESS_TOKEN` | Token akses sesi, untuk panggilan API yang dibatasi sesi |140| `CLAUDE_CODE_SESSION_ACCESS_TOKEN` | Token akses sesi, untuk panggilan API yang dibatasi sesi |
123| `GIT_CONFIG_COUNT`, `GIT_CONFIG_KEY_n`, `GIT_CONFIG_VALUE_n` | Pengaturan git yang ditetapkan runner untuk git yang dijalankan hook Anda. [Konfigurasi Git di dalam lifecycle hooks](#git-configuration-inside-lifecycle-hooks) menjelaskannya. Memerlukan Claude Code v2.1.280 atau lebih baru. |141| `GIT_CONFIG_COUNT`, `GIT_CONFIG_KEY_n`, `GIT_CONFIG_VALUE_n` | Pengaturan git yang ditetapkan runner untuk git yang dijalankan hook Anda. [Konfigurasi Git di dalam lifecycle hooks](#git-configuration-inside-lifecycle-hooks) menjelaskannya. Memerlukan Claude Code v2.1.280 atau lebih baru. |
124 142
125Skrip harus meninggalkan pohon kerja di `CLAUDE_RUNNER_CHECKOUT_PATH` yang diperiksa pada revisi yang diminta. Detached HEAD tidak apa-apa; runner membuat cabang kerja sesi di atasnya. Runner memverifikasi jalur berisi `.git` sesudahnya; jika hook Anda mewujudkan sumber non-git seperti Perforce atau tarball yang dibuka, atur `CLAUDE_RUNNER_SKIP_GIT_VERIFY=1` di lingkungan runner untuk melewati pemeriksaan itu. Alur berbasis Git seperti pembuatan cabang kerja dan hasil push memerlukan checkout git, jadi ekspor hasil dari pohon non-git dengan hook [`post-session`](#post-session).143Skrip harus meninggalkan working tree di `CLAUDE_RUNNER_CHECKOUT_PATH` yang di-checkout pada revisi yang diminta. Detached HEAD dapat digunakan, karena runner membuat branch kerja sesi di atasnya.
126 144
127Runner tidak melewatkan kredensial git ke hook. Sebaliknya, cetak kredensial klon per-sesi dari identitas sesi: verifikasi `CLAUDE_CODE_SESSION_ACCESS_TOKEN` dengan perpustakaan JWT standar terhadap titik akhir JWKS di bawah `CLAUDE_RUNNER_API_BASE_URL`, seperti yang dijelaskan dalam [Verify the token from your service](/docs/id/self-hosted-environments-identity#verify-the-token-from-your-service), kemudian buat layanan kredensial Anda mengeluarkan kredensial klon jangka pendek untuk identitas dalam klaim `act` token. `CLAUDE_RUNNER_CLAUDE_BIN` tidak diatur di lingkungan checkout-hook, jadi subperintah `decode-token` tidak tersedia di sini. Kembali ke apa pun autentikasi git yang sudah dimiliki host, seperti agen SSH, pembantu kredensial, atau `.netrc`, juga merupakan pilihan.145Setelah hook Anda selesai, runner memverifikasi bahwa `CLAUDE_RUNNER_CHECKOUT_PATH` berisi `.git`. Jika hook Anda mewujudkan sumber non-git seperti Perforce atau tarball yang telah dibongkar, atur `CLAUDE_RUNNER_SKIP_GIT_VERIFY=1` di lingkungan runner untuk melewati pemeriksaan itu. Alur berbasis Git seperti pembuatan branch kerja dan push hasil memerlukan checkout git, jadi ekspor hasil dari tree non-git dengan [hook `post-session`](#post-session).
128 146
129Ketika hook keluar bukan nol, atau keluar 0 tanpa meninggalkan checkout yang dapat digunakan di belakang, apa yang dilakukan runner tergantung pada repositori:147<h4 id="get-git-credentials-in-the-hook">
148 Mendapatkan kredensial git di dalam hook
149</h4>
130 150
131* **Repositori yang sesi dorong hasil ke**: runner gagal sesi, dan pada keluar bukan nol permukaan ekor stderr skrip ke pengguna.151Runner tidak meneruskan kredensial git ke hook. Subperintah `decode-token` juga tidak tersedia di sini, karena `CLAUDE_RUNNER_CLAUDE_BIN` tidak diatur di lingkungan checkout-hook. Sebagai gantinya, buat kredensial clone per-sesi dari identitas sesi, atau gunakan autentikasi git milik host sendiri sebagai alternatif:
132* **Repositori yang hanya dibaca sesi**, seperti repositori yang ditambahkan ke sesi yang berjalan: runner mencatat baris `[runner:warn]` dengan detail kegagalan, memposting langkah `Skipped` ke sesi, menghapus apa pun yang ditinggalkan hook di jalur checkout, dan melanjutkan dengan repositori yang tersisa. Ketika runner tidak dapat menghapus jalur segera, itu mencoba penghapusan lagi saat akhir sesi. Jika melewati meninggalkan sesi tanpa repositori sama sekali, runner gagal sesi pula.
133 152
134Sebelum v2.1.228, runner gagal sesi pada kegagalan hook untuk repositori apa pun, jadi repositori hanya-baca yang tidak dapat dilayani hook gagal sesi lagi pada setiap runner segar yang dilanjutkan sesi.153* **Kredensial clone per-sesi**: verifikasi `CLAUDE_CODE_SESSION_ACCESS_TOKEN` dengan library JWT standar terhadap endpoint JWKS di bawah `CLAUDE_RUNNER_API_BASE_URL`, seperti yang dijelaskan dalam [Verify the token from your service](/docs/id/self-hosted-environments-identity#verify-the-token-from-your-service). Kemudian minta layanan kredensial Anda menerbitkan kredensial clone berumur pendek untuk identitas dalam klaim `act` token. Kaitkan kredensial tersebut dengan `act.sub`, dan jangan mewajibkan `act.email`.
154* **Autentikasi git host**: gunakan autentikasi git apa pun yang sudah dimiliki host, seperti SSH agent, credential helper, atau `.netrc`.
135 155
136Runner menghapus jalur checkout setelah sesi berakhir.156<h4 id="when-the-hook-fails">
157 Ketika hook gagal
158</h4>
159
160Hook gagal ketika keluar dengan kode bukan nol, atau keluar dengan 0 tanpa meninggalkan checkout yang dapat digunakan:
161
162* **Repositori yang sesi dorong hasil ke**: runner gagal sesi, dan pada keluar bukan nol permukaan ekor stderr skrip ke pengguna.
163* **Repositori yang hanya dibaca sesi**, seperti repositori yang ditambahkan ke sesi yang sedang berjalan: runner mencatat baris `[runner:warn]` dengan detail kegagalan, memposting langkah `Skipped` ke sesi, menghapus apa pun yang ditinggalkan hook di jalur checkout, dan melanjutkan dengan repositori yang tersisa. Jika proses melewati ini membuat sesi tidak memiliki repositori sama sekali, runner tetap menggagalkan sesi.
164
165Ketika hook berhasil, runner menghapus jalur checkout setelah sesi berakhir.
137 166
138<h3 id="post-session">167<h3 id="post-session">
139 post-session168 post-session
151| `CLAUDE_RUNNER_WORKSPACE_PATHS` | Jalur absolut yang dipisahkan titik dua dari pohon kerja sesi. Kosong untuk sesi tanpa repo. |180| `CLAUDE_RUNNER_WORKSPACE_PATHS` | Jalur absolut yang dipisahkan titik dua dari pohon kerja sesi. Kosong untuk sesi tanpa repo. |
152| `CLAUDE_RUNNER_DEBUG_LOG_PATH` | Jalur ke log debug sesi, masih di disk saat hook berjalan |181| `CLAUDE_RUNNER_DEBUG_LOG_PATH` | Jalur ke log debug sesi, masih di disk saat hook berjalan |
153| `CLAUDE_RUNNER_API_BASE_URL` | URL dasar API Anthropic untuk panggilan yang dibatasi sesi |182| `CLAUDE_RUNNER_API_BASE_URL` | URL dasar API Anthropic untuk panggilan yang dibatasi sesi |
154| `CLAUDE_RUNNER_CLIENT_PLATFORM` | Permukaan klien yang membuat sesi, seperti `web_claude_ai`, `desktop_app`, atau `ios`. Tidak diatur ketika sesi tidak memiliki permukaan yang tercatat atau dikenali. Memerlukan Claude Code v2.1.229 atau lebih baru. |183| `CLAUDE_RUNNER_CLIENT_PLATFORM` | Surface klien yang membuat sesi, seperti `web_claude_ai`, `desktop_app`, atau `ios`. Tidak diatur ketika sesi tidak memiliki surface yang tercatat atau dikenali, jadi rujuk sebagai `${CLAUDE_RUNNER_CLIENT_PLATFORM:-}` di bawah `set -u`. Memerlukan Claude Code v2.1.229 atau lebih baru. |
155| `CLAUDE_CODE_SESSION_ACCESS_TOKEN` | Token akses sesi, untuk panggilan API yang dibatasi sesi |184| `CLAUDE_CODE_SESSION_ACCESS_TOKEN` | Token akses sesi, untuk panggilan API yang dibatasi sesi |
156| `GIT_CONFIG_COUNT`, `GIT_CONFIG_KEY_n`, `GIT_CONFIG_VALUE_n` | Pengaturan git yang ditetapkan runner untuk git yang dijalankan hook Anda. [Konfigurasi Git di dalam lifecycle hooks](#git-configuration-inside-lifecycle-hooks) menjelaskannya. Memerlukan Claude Code v2.1.280 atau lebih baru. |185| `GIT_CONFIG_COUNT`, `GIT_CONFIG_KEY_n`, `GIT_CONFIG_VALUE_n` | Pengaturan git yang ditetapkan runner untuk git yang dijalankan hook Anda. [Konfigurasi Git di dalam lifecycle hooks](#git-configuration-inside-lifecycle-hooks) menjelaskannya. Memerlukan Claude Code v2.1.280 atau lebih baru. |
157 186
158`CLAUDE_RUNNER_EXIT_REASON` mengambil salah satu dari empat nilai:187`CLAUDE_RUNNER_EXIT_REASON` mengambil salah satu dari empat nilai:
159 188
160* `completed`: sesi berakhir dengan bersih. Proses Claude Code keluar secara normal, atau sesi diarsipkan atau dihapus saat masih berjalan.189* `completed`: sesi berakhir dengan bersih. Proses Claude Code keluar secara normal, atau keluar dengan sendirinya setelah sesi diarsipkan atau dihapus.
161* `failed`: proses Claude Code mogok, atau setup gagal setelah dimulai.190* `failed`: proses Claude Code mogok, atau setup gagal setelah dimulai.
162* `interrupted`: runner menghentikan sesi. Itu merilis sesi untuk membebaskan slot, sesi timeout saat startup, server memindahkan sesi dari runner ini, runner sedang mengalirkan, atau sesi melampaui batas [`--kill-session-after-min`](/docs/id/self-hosted-environments-reference#runner-cli-flags) nya.191* `interrupted`: runner menghentikan sesi, dalam salah satu kasus berikut:
192 * Runner melepaskan sesi untuk membebaskan slot.
193 * Sesi mengalami timeout saat startup.
194 * Server memindahkan sesi dari runner ini.
195 * Polling runner mendeteksi pengarsipan atau penghapusan sebelum proses keluar.
196 * Runner sedang melakukan drain.
197 * Sesi melampaui batas [`--kill-session-after-min`](/docs/id/self-hosted-environments-reference#runner-cli-flags) miliknya.
163* `abandoned`: dicadangkan untuk sesi yang diklaim runner lain. Hook saat ini tidak menyala dalam kasus itu.198* `abandoned`: dicadangkan untuk sesi yang diklaim runner lain. Hook saat ini tidak menyala dalam kasus itu.
164 199
165[Penghitung siklus hidup sesi](/docs/id/self-hosted-environments-reference#session-lifecycle-counter-semantics) menghitung rilis, timeout startup, dan perpindahan server sebagai `completed` daripada `interrupted`, karena runner menyerahkan slot kembali dengan bersih. Harapkan perbedaan itu jika Anda membandingkan penerimaan hook dengan penghitung.200Jika Anda membandingkan catatan penerimaan hook dengan [penghitung siklus hidup sesi](/docs/id/self-hosted-environments-reference#session-lifecycle-counter-semantics), perkirakan beberapa catatan `interrupted` dihitung sebagai `completed` di sana. Penghitung menghitung pelepasan, timeout startup, perpindahan server, serta pengarsipan atau penghapusan yang lebih dulu dideteksi polling runner sebagai `completed`, karena runner mengembalikan slot dengan bersih.
166 201
167Status keluar hook tidak pernah mempengaruhi hasil sesi; kegagalan dicatat dan diabaikan. Runner menunggu hingga `--post-session-hook-timeout-sec`, 60 detik secara default, pada setiap akhir sesi termasuk shutdown runner. Contoh ini menyimpan pekerjaan yang tidak dikomit ke cabang penyelamatan:202Status keluar hook tidak pernah mempengaruhi hasil sesi; kegagalan dicatat dan diabaikan. Runner menunggu hingga `--post-session-hook-timeout-sec`, 60 detik secara default, pada setiap akhir sesi termasuk shutdown runner. Contoh ini menyimpan pekerjaan yang tidak dikomit ke cabang penyelamatan:
168 203
169```bash theme={null}204```bash theme={null}
170#!/usr/bin/env bash205#!/usr/bin/env bash
171set -u206set -u
207export GIT_ALLOW_PROTOCOL=${GIT_ALLOW_PROTOCOL:-https:http:ssh}
172IFS=':'208IFS=':'
173# Override -c mengalahkan pengaturan lokal repo, memblokir konfigurasi fsmonitor,209# -c overrides beat repo-local settings, blocking session-written fsmonitor,
174# hook-path, dan gpg-program yang ditulis sesi agar tidak mengeksekusi kode dengan210# hook-path, and gpg-program config from executing code with the hook's
175# hak istimewa hook. -c commit.gpgsign=false juga membuat commit penyelamatan ini211# privileges. -c commit.gpgsign=false also leaves these rescue commits
176# tidak ditandatangani di bawah --configure-git.212# unsigned under --configure-git.
177# credential.helper dan pushurl lokal repo masih berlaku, dan pada runner213# Repo-local credential.helper and pushurl still apply, and on a runner
178# sebelum v2.1.280 begitu pula core.sshCommand; jika hook menyimpan kredensial214# before v2.1.280 so does core.sshCommand; see the note below the script
179# yang tidak dimiliki sesi, lihat catatan di bawah skrip.215# before you give this push a credential.
180g() { git -c core.fsmonitor=false -c core.hooksPath=/dev/null \216g() { git -c core.fsmonitor=false -c core.hooksPath=/dev/null \
181 -c commit.gpgsign=false "$@"; }217 -c commit.gpgsign=false "$@"; }
182for ws in $CLAUDE_RUNNER_WORKSPACE_PATHS; do218for ws in $CLAUDE_RUNNER_WORKSPACE_PATHS; do
188done224done
189```225```
190 226
191Hook melakukan push dengan kredensial git apa pun yang tersedia di lingkungannya sendiri di host runner. Di bawah [postur tanpa-kredensial-dalam-image](/docs/id/self-hosted-environments-deploy#configure-git), termasuk ketika klon bawaan melewati proxy git Anthropic, tidak ada kredensial, jadi buat kredensial push jangka pendek di dalam hook sebelum melakukan push: tukarkan token sesi yang diterima hook di `CLAUDE_CODE_SESSION_ACCESS_TOKEN` dengan layanan token Anda sendiri, dengan memverifikasinya seperti yang dijelaskan di [Verify session identity](/docs/id/self-hosted-environments-identity). Ketika hook menyimpan kredensial yang tidak dimiliki sesi, ganti `origin` dengan URL yang disediakan operator dan teruskan `-c credential.helper=` ditambah helper Anda sendiri. [Konfigurasi Git di dalam lifecycle hooks](#git-configuration-inside-lifecycle-hooks) menjelaskan apa yang masih dapat dipengaruhi oleh konfigurasi yang ditulis sesi.227Baris `GIT_ALLOW_PROTOCOL` dalam skrip membatasi git pada remote HTTPS, HTTP, dan SSH. Jika lingkungan runner sudah menetapkan daftar `GIT_ALLOW_PROTOCOL` sendiri yang tidak kosong, skrip mempertahankan daftar tersebut.
228
229Hook melakukan push dengan kredensial git apa pun yang tersedia di lingkungannya sendiri di host runner. Di bawah [postur tanpa-kredensial-dalam-image](/docs/id/self-hosted-environments-deploy#configure-git), termasuk ketika klon bawaan melewati proxy git Anthropic, tidak ada kredensial, jadi buat kredensial push jangka pendek di dalam hook sebelum melakukan push: tukarkan token sesi yang diterima hook di `CLAUDE_CODE_SESSION_ACCESS_TOKEN` dengan layanan token Anda sendiri, dengan memverifikasinya seperti yang dijelaskan di [Verify session identity](/docs/id/self-hosted-environments-identity).
230
231Perlakukan setiap kredensial yang diberikan hook Anda kepada git sebagai kredensial yang dapat diperoleh sesi, dan buat kredensial tersebut sehingga tidak dapat melakukan lebih dari push ini. Git di hook Anda membaca file konfigurasi yang dapat ditulis oleh sesi, dan credential helper atau filter driver yang disebutkan di salah satunya berjalan dengan hak istimewa hook Anda. Pengaturan dalam file tersebut juga dapat mengubah tujuan push, remote apa pun yang Anda sebutkan. Untuk pengaturan git yang ditetapkan runner di hook Anda dan pengaturan yang diserahkan ke file tersebut, lihat [Konfigurasi Git di dalam lifecycle hooks](#git-configuration-inside-lifecycle-hooks).
192 232
193<h4 id="hook-timing-when-the-runner-releases-a-session">233<h4 id="hook-timing-when-the-runner-releases-a-session">
194 Hook timing when the runner releases a session234 Hook timing when the runner releases a session
264| `CLAUDE_RUNNER_ORDER_ID` | Kunci idempotency yang buram, unik per permintaan pemijahan dan aman untuk nama sumber daya Kubernetes. Gunakan hanya order ID sebagai kunci dedup provisioner Anda. |304| `CLAUDE_RUNNER_ORDER_ID` | Kunci idempotency yang buram, unik per permintaan pemijahan dan aman untuk nama sumber daya Kubernetes. Gunakan hanya order ID sebagai kunci dedup provisioner Anda. |
265| `CLAUDE_RUNNER_SESSION_ID` | Sesi yang diminta ini untuk. Ini berulang pada setiap permintaan ulang untuk sesi, jadi gunakan untuk logging dan routing, bukan sebagai kunci dedup. Kosong untuk permintaan pre-warming, yang boot runner standby sebelum sesi spesifik apa pun ketika [`--min-idle`](/docs/id/self-hosted-environments-reference#orchestrator-cli-flags) diatur, jadi jangan asumsikan variabel diatur. |305| `CLAUDE_RUNNER_SESSION_ID` | Sesi yang diminta ini untuk. Ini berulang pada setiap permintaan ulang untuk sesi, jadi gunakan untuk logging dan routing, bukan sebagai kunci dedup. Kosong untuk permintaan pre-warming, yang boot runner standby sebelum sesi spesifik apa pun ketika [`--min-idle`](/docs/id/self-hosted-environments-reference#orchestrator-cli-flags) diatur, jadi jangan asumsikan variabel diatur. |
266| `CLAUDE_RUNNER_SESSION_UUID` | ID sesi yang sama dalam bentuk UUID kanonik. Kosong untuk permintaan pre-warming. |306| `CLAUDE_RUNNER_SESSION_UUID` | ID sesi yang sama dalam bentuk UUID kanonik. Kosong untuk permintaan pre-warming. |
267| `CLAUDE_RUNNER_ATTEMPT` | Berapa banyak permintaan pemijahan yang dimiliki sesi ini. `0` untuk permintaan pre-warming. |307| `CLAUDE_RUNNER_ATTEMPT` | Penghitung per sesi untuk digunakan dalam logging. Ini bukan jumlah retry maupun jumlah permintaan. `0` untuk permintaan pre-warming, meskipun permintaan untuk suatu sesi juga dapat membawa `0`. |
268| `CLAUDE_RUNNER_ORDER_SERVER_TIME` | Waktu server dari header HTTP `Date` respons polling. Ketika hook memverifikasi `exp` JWT pesanan kerja, bandingkan terhadap nilai ini daripada jam lokal untuk mentoleransi skew. Kosong ketika gateway menghilangkan header. |308| `CLAUDE_RUNNER_ORDER_SERVER_TIME` | Waktu server dari header HTTP `Date` respons polling. Ketika hook memverifikasi `exp` JWT pesanan kerja, bandingkan terhadap nilai ini daripada jam lokal untuk mentoleransi skew. Kosong ketika gateway menghilangkan header. |
269| `CLAUDE_RUNNER_POOL_ID` | ID lingkungan yang harus diikuti runner baru, dalam bentuk `ccpool_...` |309| `CLAUDE_RUNNER_POOL_ID` | ID lingkungan yang harus diikuti runner baru, dalam bentuk `ccpool_...` |
270| `CLAUDE_RUNNER_ACCOUNT_ID` | ID yang ditandai dari akun yang antri sesi, untuk routing per-akun, kuota, atau chargeback. Kosong ketika tidak tersedia, dan selalu kosong untuk sesi saluran Claude Tag, yang tidak ada akun antri. |310| `CLAUDE_RUNNER_ACCOUNT_ID` | ID yang ditandai dari akun yang antri sesi, untuk routing per-akun, kuota, atau chargeback. Kosong ketika tidak tersedia, dan selalu kosong untuk sesi saluran Claude Tag, yang tidak ada akun antri. |
271| `CLAUDE_RUNNER_ACCOUNT_EMAIL` | Email akun yang antri sesi. Kosong ketika tidak tersedia. Perlakukan email sebagai informasi yang dapat diidentifikasi secara pribadi dan jangan catat. |311| `CLAUDE_RUNNER_ACCOUNT_EMAIL` | Email akun yang antri sesi. Kosong ketika tidak tersedia. Perlakukan email sebagai informasi yang dapat diidentifikasi secara pribadi dan jangan catat. |
272| `CLAUDE_RUNNER_PRIMARY_REPO_URL` | URL sumber git pertama sesi, untuk routing ke runner dengan repositori itu pre-warmed. Kosong ketika sesi tidak memiliki sumber git. |312| `CLAUDE_RUNNER_PRIMARY_REPO_URL` | URL sumber git pertama sesi, untuk routing ke runner dengan repositori itu pre-warmed. Kosong ketika sesi tidak memiliki sumber git. |
273| `CLAUDE_RUNNER_PRIMARY_REPO_REVISION` | Revisi sumber git pertama sesi: cabang, SHA, atau tag. Kosong ketika tidak ditentukan. |313| `CLAUDE_RUNNER_PRIMARY_REPO_REVISION` | Revisi sumber git pertama sesi: branch, SHA, tag, atau nama referensi lengkap. Kosong ketika tidak ditentukan. |
274| `CLAUDE_RUNNER_REPO_SOURCES` | Array JSON dari `{url, revision}` untuk semua sumber git sesi, untuk hook yang route pada repositori sekunder. Kosong ketika tidak ada sumber. |314| `CLAUDE_RUNNER_REPO_SOURCES` | Array JSON dari `{url, revision}` untuk semua sumber git sesi, untuk hook yang route pada repositori sekunder. Kosong ketika tidak ada sumber. |
275| `CLAUDE_RUNNER_CORRELATION_ID` | ID korelasi yang disediakan saat pembuatan sesi, digemakan kembali sehingga hook dapat memetakan pesanan kerja ini ke permintaan yang membuat sesi. Kosong ketika sesi tidak memiliki satu. |315| `CLAUDE_RUNNER_CORRELATION_ID` | ID korelasi yang disediakan saat pembuatan sesi, digemakan kembali sehingga hook dapat memetakan pesanan kerja ini ke permintaan yang membuat sesi. Kosong ketika sesi tidak memiliki satu. |
276| `CLAUDE_RUNNER_CLIENT_PLATFORM` | Permukaan klien yang membuat sesi, seperti `web_claude_ai`, `desktop_app`, `ios`, atau `scheduled_trigger`, untuk analitik adopsi. Tidak diatur ketika sesi tidak memiliki permukaan yang tercatat atau dikenali, dan untuk permintaan pre-warming; periksa dengan `[ -n "${CLAUDE_RUNNER_CLIENT_PLATFORM:-}" ]`, yang tetap aman di bawah `set -u`. |316| `CLAUDE_RUNNER_CLIENT_PLATFORM` | Permukaan klien yang membuat sesi, seperti `web_claude_ai`, `desktop_app`, `ios`, atau `scheduled_trigger`, untuk analitik adopsi. Tidak diatur ketika sesi tidak memiliki permukaan yang tercatat atau dikenali, dan untuk permintaan pre-warming; periksa dengan `[ -n "${CLAUDE_RUNNER_CLIENT_PLATFORM:-}" ]`, yang tetap aman di bawah `set -u`. |
282* **Gunakan `--capacity 1` di runner yang dipijahkan**: pesanan kerja yang terikat sesi mendaftarkan tepat satu runner yang terikat ke sesi itu, jadi kapasitas lebih tinggi menambah slot yang tidak pernah menerima pekerjaan, dan runner mencatat peringatan saat startup.322* **Gunakan `--capacity 1` di runner yang dipijahkan**: pesanan kerja yang terikat sesi mendaftarkan tepat satu runner yang terikat ke sesi itu, jadi kapasitas lebih tinggi menambah slot yang tidak pernah menerima pekerjaan, dan runner mencatat peringatan saat startup.
283* **Pesanan kerja pre-warming mendaftarkan tidak terikat**: runner standby tidak terikat ke sesi dan mengklaim pekerjaan antri seperti runner fleet tetap.323* **Pesanan kerja pre-warming mendaftarkan tidak terikat**: runner standby tidak terikat ke sesi dan mengklaim pekerjaan antri seperti runner fleet tetap.
284 324
285Kontrak memiliki empat aturan yang agnostik provisioner:325Kontrak memiliki empat aturan, di platform mana pun hook Anda melakukan provisioning:
286 326
2871. **Jadilah idempoten pada `CLAUDE_RUNNER_ORDER_ID`.** Pengiriman ulang permintaan yang sama harus memijahkan paling banyak satu runner. Turunkan nama sumber daya deterministik dari order ID dan biarkan platform Anda menolak duplikat. Jangan kunci pada `CLAUDE_RUNNER_SESSION_ID` sebagai gantinya. Setiap permintaan ulang untuk sesi membawa ID sesi yang sama dengan order ID baru, jadi beban kerja yang dinamai atau dideduplikasi oleh ID sesi dibuat sekali dan tidak pernah lagi untuk sesi itu.3271. **Jadilah idempoten pada `CLAUDE_RUNNER_ORDER_ID`.** Pengiriman ulang permintaan yang sama harus memijahkan paling banyak satu runner. Turunkan nama sumber daya deterministik dari order ID dan biarkan platform Anda menolak duplikat. Jangan kunci pada `CLAUDE_RUNNER_SESSION_ID` sebagai gantinya. Setiap permintaan ulang untuk sesi membawa ID sesi yang sama dengan order ID baru, jadi beban kerja yang dinamai atau dideduplikasi oleh ID sesi dibuat sekali dan tidak pernah lagi untuk sesi itu.
2882. **Jangan coba ulang beban kerja.** Satu ID pesanan berarti paling banyak satu beban kerja yang dibuat. Jika runner tidak pernah mendaftar, Anthropic meminta ulang dengan ID pesanan segar setelah `--expected-spawn-seconds`.3282. **Jangan coba ulang beban kerja.** Satu ID pesanan berarti paling banyak satu beban kerja yang dibuat. Jika runner tidak pernah mendaftar, Anthropic meminta ulang dengan ID pesanan segar setelah `--expected-spawn-seconds`.
2893. **Gunakan kontrak kode keluar.** Keluar 0 berarti dikirimkan. Keluar 1 berarti kegagalan yang dapat dicoba ulang; sesi mundur dan ditawarkan kembali. Keluar 2 atau lebih tinggi berarti tidak dapat dicoba ulang; sesi diblokir dari pemijahan lagi sampai [Owner](/docs/id/cloud-environments#organization-shared-environments) memilih **Retry** di atasnya di tab **Activity** lingkungan. Pada keluar bukan nol, ekor stderr hook muncul di sana sebagai alasan kegagalan, jadi tulis kesalahan yang dapat ditindaklanjuti ke stderr dan jangan pernah rahasia. Untuk permintaan pre-warming tidak ada sesi untuk gagal: orchestrator mencatat keluar bukan nol secara lokal saja, dan server meminta ulang pemijahan setelah sewa.3293. **Gunakan kontrak exit code.** Keluar dengan status yang sesuai dengan hasilnya:
2904. **Atur `--expected-spawn-seconds` ke setidaknya waktu boot p99 Anda.** Ini adalah sewa server-side. Semua replika orchestrator harus menggunakan nilai yang sama.330
331 * **Keluar 0**: dikirimkan.
332 * **Keluar 1**: kegagalan yang dapat dicoba ulang. Sesi mundur dan ditawarkan kembali.
333 * **Keluar 2 atau lebih tinggi**: kegagalan yang tidak dapat dicoba ulang. Sesi diblokir dari pemijahan lagi sampai pengguna mengirimkan pesan baru ke sesi tersebut atau [Owner](/docs/id/cloud-environments#organization-shared-environments) memilih **Retry** di atasnya di tab **Activity** lingkungan.
334
335 Pada keluar bukan nol, ekor stderr hook muncul di tab **Activity** sebagai alasan kegagalan, jadi tulis kesalahan yang dapat ditindaklanjuti ke stderr dan jangan pernah menulis rahasia di sana. Dalam hook shell, [pertahankan kegagalan sementara agar dapat dicoba ulang](#keep-transient-failures-retryable-in-a-shell-hook).
336
337 Permintaan pre-warming tidak memiliki sesi untuk gagal: orchestrator mencatat keluar bukan nol secara lokal saja, dan server meminta ulang pemijahan setelah sewa `--expected-spawn-seconds` kedaluwarsa.
3384. **Atur `--expected-spawn-seconds` ke setidaknya waktu p99 Anda dari permintaan pemijahan hingga pendaftaran runner.** Ukur sejak orchestrator menerima permintaan pemijahan, dan sertakan waktu tunggu untuk kapasitas di platform Anda serta waktu boot. Nilai ini adalah sewa server-side, dan pesanan kerja kedaluwarsa bersamanya, sehingga runner yang beban kerjanya membutuhkan waktu lebih lama tidak dapat mendaftar. Semua replika orchestrator harus menggunakan nilai yang sama.
291 339
292Semua yang ditulis hook ke stdout atau stderr muncul dalam log orchestrator dengan kredensial secara otomatis diredaksi. Jika sesi tetap antri, periksa badan `/healthz` orchestrator untuk hitungan antrian, kemudian buka tab **Activity** lingkungan Anda di [halaman admin **Cloud environments**](https://claude.ai/admin-settings/cloud-environments): perluas sesi yang gagal di sana untuk kesalahan pemijahan, dan pilih **Retry** untuk memintanya ulang.340Semua yang ditulis hook ke stdout atau stderr muncul dalam log orchestrator dengan kredensial secara otomatis diredaksi. Jika sesi tetap antri, periksa badan `/healthz` orchestrator untuk hitungan antrian, kemudian buka tab **Activity** lingkungan Anda di [halaman admin **Cloud environments**](https://claude.ai/admin-settings/cloud-environments): perluas sesi yang gagal di sana untuk kesalahan pemijahan, dan pilih **Retry** untuk memintanya ulang.
293 341
294Sesi yang tetap antri tanpa kesalahan pemijahan di tab **Activity** dapat berarti hook dikunci pada ID sesi. Untuk mengonfirmasi, periksa apakah platform Anda memiliki beban kerja untuk permintaan pemijahan pertama sesi itu dan tidak ada untuk permintaan ulang. Jika demikian, kunci beban kerja pada `CLAUDE_RUNNER_ORDER_ID` sebagai gantinya.342Sesi yang tetap antri tanpa kesalahan pemijahan di tab **Activity** dapat berarti hook dikunci pada ID sesi. Untuk mengonfirmasi, periksa apakah platform Anda memiliki beban kerja untuk permintaan pemijahan pertama sesi itu dan tidak ada untuk permintaan ulang. Jika demikian, kunci beban kerja pada `CLAUDE_RUNNER_ORDER_ID` sebagai gantinya.
295 343
344<h4 id="keep-transient-failures-retryable-in-a-shell-hook">
345 Pertahankan kegagalan sementara agar dapat dicoba ulang dalam hook shell
346</h4>
347
348Dalam hook shell yang menggunakan `set -e`, kegagalan yang sebenarnya dapat teratasi dengan retry dapat memblokir sesi. Hook berhenti pada perintah yang gagal dan keluar dengan status milik perintah itu sendiri, dan orchestrator menerapkan kontrak exit code pada status tersebut. Banyak kegagalan mengembalikan status 2 atau lebih tinggi, seperti `127` ketika suatu perintah tidak terinstal dan `22` dari `curl --fail` pada kesalahan HTTP, sehingga kegagalan tersebut memblokir sesi pada kegagalan pertamanya.
349
350Sesi yang telah diblokir oleh hook tetap diblokir sampai pengguna mengirimkan pesan baru ke sesi tersebut atau [Owner](/docs/id/cloud-environments#organization-shared-environments) memilih **Retry** di atasnya di tab **Activity** lingkungan.
351
352Untuk mengubah kegagalan semacam itu menjadi keluar 1, letakkan baris-baris berikut tepat di bawah baris `#!` hook, di atas apa pun yang dapat gagal:
353
354```bash theme={null}
355set -e
356PERMANENT=; permanent() { printf '%s\n' "$*" >&2; PERMANENT=1; exit 2; }
357trap 'rc=$?; [ "$rc" -eq 0 ] || [ -n "${PERMANENT:-}" ] || exit 1' EXIT
358```
359
360Baris-baris ini mengubah perilaku bagian hook lainnya, jadi periksa hook untuk setiap pola berikut setelah Anda menambahkannya:
361
362* **`exit 2` atau lebih tinggi secara langsung**: dengan trap terpasang, ini menjadi keluar 1. Untuk kesalahan yang tidak dapat diperbaiki oleh retry apa pun, panggil `permanent` dengan alasannya sebagai gantinya, seperti `permanent "namespace claude-runners does not exist"`. Panggil di shell utama, bukan di dalam `$( )`, `( )`, atau pipe.
363* **`exec`**: jangan memulai perintah terakhir hook dengan `exec`, karena `exec` menggantikan shell dan trap tidak berjalan.
364* **Trap `EXIT` kedua**: `trap ... EXIT` kedua menggantikan yang pertama, jadi gabungkan keduanya menjadi satu trap. Letakkan perintah pembersihan Anda tepat setelah `rc=$?;` dan akhiri masing-masing dengan `|| true;`. Pembersihan kemudian berjalan saat gagal maupun saat berhasil, dan perintah pembersihan yang gagal tidak menetapkan status keluar hook. Trap gabungan ini menunjukkan bentuknya, dengan `your-cleanup-command` sebagai pengganti perintah Anda sendiri:
365
366 ```bash theme={null}
367 trap 'rc=$?; your-cleanup-command || true; [ "$rc" -eq 0 ] || [ -n "${PERMANENT:-}" ] || exit 1' EXIT
368 ```
369* **Perintah yang boleh gagal**: jika hook sebelumnya tidak menggunakan `set -e`, kini hook berhenti pada perintah pertama yang mengembalikan nilai bukan nol, seperti pencarian yang tidak menemukan apa pun atau pengiriman duplikat yang ditolak platform Anda. Jika hook bertindak berdasarkan hasilnya, jadikan perintah tersebut kondisi dari sebuah `if`. Jika hook mengabaikan hasilnya, tambahkan `|| true` setelah perintah tersebut.
370
371Untuk mengonfirmasi bahwa trap berfungsi, tambahkan baris tepat di bawah baris `trap` yang memanggil perintah yang tidak ada, seperti `no-such-command`. Jalankan file hook dari shell Anda dan periksa bahwa `echo $?` mencetak `1`, lalu hapus baris tersebut.
372
296<h2 id="send-model-requests-to-bedrock-or-agent-platform">373<h2 id="send-model-requests-to-bedrock-or-agent-platform">
297 Mengirim permintaan model ke Bedrock atau Agent Platform374 Mengirim permintaan model ke Bedrock atau Agent Platform
298</h2>375</h2>
381Sesi yang mengirim permintaan model ke Amazon Bedrock atau Google Cloud's Agent Platform berbeda dari sesi di Anthropic API dalam hal-hal berikut:458Sesi yang mengirim permintaan model ke Amazon Bedrock atau Google Cloud's Agent Platform berbeda dari sesi di Anthropic API dalam hal-hal berikut:
382 459
383* **Kebijakan dari claude.ai**: [pengaturan yang dikelola server](/docs/id/server-managed-settings) tidak sampai ke sesi ini. Begitu pula kebijakan organisasi yang ditetapkan Owner di pengaturan admin Claude Code, sehingga Claude Code tidak memberlakukannya di dalam sesi. Letakkan aturan yang Anda andalkan di [file pengaturan terkelola](/docs/id/managed-settings#delivery-mechanisms) pada image runner.460* **Kebijakan dari claude.ai**: [pengaturan yang dikelola server](/docs/id/server-managed-settings) tidak sampai ke sesi ini. Begitu pula kebijakan organisasi yang ditetapkan Owner di pengaturan admin Claude Code, sehingga Claude Code tidak memberlakukannya di dalam sesi. Letakkan aturan yang Anda andalkan di [file pengaturan terkelola](/docs/id/managed-settings#delivery-mechanisms) pada image runner.
461* **Skill akun**: sesi ini tidak mengunduh skill yang diaktifkan untuk akun claude.ai seseorang. Lihat [Bagaimana konfigurasi setiap sesi disusun](#how-each-session’s-config-is-assembled).
384* **File**: file yang dilampirkan orang ke sesi di claude.ai atau aplikasi seluler atau desktop tidak sampai ke sesi tersebut, dan Claude tidak dapat mengirim file kembali dengan [tool `SendUserFile`](/docs/id/tools-reference). Sebagai gantinya, letakkan file input di repositori atau di runner.462* **File**: file yang dilampirkan orang ke sesi di claude.ai atau aplikasi seluler atau desktop tidak sampai ke sesi tersebut, dan Claude tidak dapat mengirim file kembali dengan [tool `SendUserFile`](/docs/id/tools-reference). Sebagai gantinya, letakkan file input di repositori atau di runner.
385* **Pemilihan model**: control plane Anthropic mengirimkan model setiap sesi, dan ketika sesi dimulai tanpa model, Claude Code menggunakan model default untuk penyedia tersebut. Runner menghapus `ANTHROPIC_MODEL` dan `ANTHROPIC_DEFAULT_MODEL` dari environment yang diteruskannya ke sesi. Contoh di halaman penyedia menetapkan `ANTHROPIC_MODEL`, tetapi di environment runner tidak satu pun variabel tersebut berpengaruh. Variabel per keluarga model di Menyematkan versi model untuk [Amazon Bedrock](/docs/id/amazon-bedrock#4-pin-model-versions) dan [Agent Platform](/docs/id/google-vertex-ai#5-pin-model-versions) memang sampai ke sesi. Variabel tersebut menentukan ke mana alias seperti `opus` diarahkan, bukan ke mana ID model lengkap diarahkan.463* **Pemilihan model**: control plane Anthropic mengirimkan model setiap sesi, dan ketika sesi dimulai tanpa model, Claude Code menggunakan model default untuk penyedia tersebut. Anda tidak dapat memilih model dengan `ANTHROPIC_MODEL` atau `ANTHROPIC_DEFAULT_MODEL` di environment runner, tetapi Anda dapat menyematkan ke mana sebuah alias diarahkan:
464 * **`ANTHROPIC_MODEL` dan `ANTHROPIC_DEFAULT_MODEL`**: runner menghapus keduanya dari environment yang diteruskannya ke sesi, meskipun contoh di halaman penyedia menetapkan `ANTHROPIC_MODEL`.
465 * **Variabel penyematan per keluarga model**: variabel di Menyematkan versi model untuk [Amazon Bedrock](/docs/id/amazon-bedrock#4-pin-model-versions) dan [Agent Platform](/docs/id/google-vertex-ai#5-pin-model-versions) memang sampai ke sesi. Variabel tersebut menentukan ke mana alias seperti `opus` diarahkan, bukan ke mana ID model lengkap diarahkan.
386* **Model yang tidak dilayani akun Anda**: sebuah sesi dapat gagal pada suatu pesan dengan error yang menyebutkan nama model. Aktifkan model yang dapat dipilih developer Anda, model latar belakang yang dijelaskan dalam Menyematkan versi model, dan model pengklasifikasi yang digunakan [auto mode](/docs/id/permission-modes#enable-auto-mode-on-bedrock-agent-platform-or-foundry). Di Amazon Bedrock, izinkan masing-masing model tersebut dalam kebijakan Anda.466* **Model yang tidak dilayani akun Anda**: sebuah sesi dapat gagal pada suatu pesan dengan error yang menyebutkan nama model. Aktifkan model yang dapat dipilih developer Anda, model latar belakang yang dijelaskan dalam Menyematkan versi model, dan model pengklasifikasi yang digunakan [auto mode](/docs/id/permission-modes#enable-auto-mode-on-bedrock-agent-platform-or-foundry). Di Amazon Bedrock, izinkan masing-masing model tersebut dalam kebijakan Anda.
387* **Pencarian web dan fast mode**: [pencarian web](/docs/id/tools-reference#websearch-tool-behavior) tidak tersedia di Amazon Bedrock, dan [fast mode](/docs/id/fast-mode) tidak tersedia di kedua penyedia. Untuk kemampuan lain yang berbeda menurut penyedia, lihat [Kemampuan CLI yang bervariasi menurut penyedia](/docs/id/feature-availability#cli-capabilities-that-vary-by-provider).467* **Pencarian web dan fast mode**: [pencarian web](/docs/id/tools-reference#websearch-tool-behavior) tidak tersedia di Amazon Bedrock, dan [fast mode](/docs/id/fast-mode) tidak tersedia di kedua penyedia. Untuk kemampuan lain yang berbeda menurut penyedia, lihat [Kemampuan CLI yang bervariasi menurut penyedia](/docs/id/feature-availability#cli-capabilities-that-vary-by-provider).
388 468
411 491
412Sesi mewarisi environment runner, jadi atur [`ENABLE_TOOL_SEARCH`](/docs/id/mcp#scale-with-mcp-tool-search) di sana untuk mengontrol pencarian tool MCP bagi setiap sesi yang dijalankan runner; halaman MCP menjelaskan nilai-nilainya.492Sesi mewarisi environment runner, jadi atur [`ENABLE_TOOL_SEARCH`](/docs/id/mcp#scale-with-mcp-tool-search) di sana untuk mengontrol pencarian tool MCP bagi setiap sesi yang dijalankan runner; halaman MCP menjelaskan nilai-nilainya.
413 493
494<a id="connection-timing" />
495
496<h3 id="wait-for-mcp-servers-before-the-first-turn">
497 Menunggu server MCP sebelum giliran pertama
498</h3>
499
500Sesi self-hosted menunggu sebentar server MCP yang masih dalam proses terhubung, pada dua titik terpisah. Server yang terlewat dari suatu penantian akan kehilangan tool-nya saat giliran pertama dimulai, dan tool tersebut akan tersedia kemudian tanpa tindakan apa pun dari Anda. Kedua penantian tersebut adalah:
501
502* **Startup sesi**: sebelum daftar tool pertama kali diambil, sesi menunggu hingga 5 detik secara default untuk server HTTP atau SSE yang entrinya mengatur [`alwaysLoad: true`](/docs/id/mcp#exempt-a-server-from-deferral), atau untuk semua server ketika Anda mengatur [`MCP_CONNECTION_NONBLOCKING=0`](/docs/id/env-vars) di environment runner. Jika tidak, server HTTP dan SSE terhubung di latar belakang. Selama sesi menunggu di sini, inisialisasinya menjadi lebih lambat. [`MCP_CONNECT_TIMEOUT_MS`](/docs/id/env-vars) mengubah default 5 detik tersebut.
503* **Giliran pertama**: setelah pesan tiba, giliran pertama menunggu hingga 2 detik untuk server stdio yang masih dalam proses terhubung. Selama sesi menunggu di sini, balasan pertama menjadi lebih lambat. Untuk mengubah berapa lama penantian ini berlangsung, atur [`CLAUDE_CODE_MCP_STARTUP_WAIT_MS`](/docs/id/env-vars) di environment runner. Variabel ini tidak mengubah server mana yang dicakup oleh penantian tersebut. Memerlukan Claude Code v2.1.274 atau yang lebih baru.
504
505`claude mcp add` tidak memiliki flag `alwaysLoad`. Untuk mengatur kunci tersebut, tambahkan server dengan `claude mcp add-json` sebagai gantinya, yang menerima kunci itu dalam JSON server dan menuliskannya ke `.claude.json`. Di Dockerfile Anda:
506
507```dockerfile theme={null}
508RUN claude mcp add-json core '{"type":"http","url":"https://mcp.example.com/mcp","alwaysLoad":true}' --scope user
509```
510
511Jika tool sebuah server juga tidak muncul pada giliran berikutnya, periksa apakah server tersebut benar-benar mencapai sesi, seperti yang dijelaskan di [Server MCP](#mcp-servers).
512
414<h3 id="turn-off-built-in-session-tools">513<h3 id="turn-off-built-in-session-tools">
415 Matikan tool sesi bawaan514 Matikan tool sesi bawaan
416</h3>515</h3>
574 673
575Atur `SELF_HOSTED_RUNNER_HOST_CONFIG_DIR` untuk menabur dari jalur berbeda, atau arahkan ke direktori kosong untuk menonaktifkan penanaman.674Atur `SELF_HOSTED_RUNNER_HOST_CONFIG_DIR` untuk menabur dari jalur berbeda, atau arahkan ke direktori kosong untuk menonaktifkan penanaman.
576 675
577`.claude/settings.json` yang di-commit ke repositori diterapkan di atasnya sebagai pengaturan proyek. Dalam sesi dengan beberapa repositori, [paling banyak hanya file dari satu repositori yang berlaku](#repository-settings-in-sessions-with-several-repositories). Sesi juga membaca [`managed-settings.json`](/docs/id/settings#where-settings-live) dari jalur sistem standar di image runner Anda. Apakah kuncinya berlaku bersama [pengaturan terkelola server](/docs/id/server-managed-settings) mengikuti [bagaimana Claude Code menggabungkan sumber terkelola](/docs/id/managed-settings#how-claude-code-combines-managed-sources): secara default, ketika organisasi Anda mengirimkan kunci terkelola server apa pun, sesi mengabaikan file image runner kecuali [kunci yang dibaca Claude Code dari setiap sumber admin](/docs/id/managed-settings#keys-read-from-every-admin-source), seperti blok `env`, kunci sandbox, jalur biner sandbox, dan `forceRemoteSettingsRefresh`. Lihat [prioritas pengaturan](/docs/id/settings#settings-precedence).676Sesi juga membaca file pengaturan berikut:
677
678* **Pengaturan proyek**: `.claude/settings.json` yang di-commit ke repositori diterapkan di atas baseline tingkat pengguna. Dalam sesi dengan beberapa repositori, [paling banyak hanya file dari satu repositori yang berlaku](#repository-settings-in-sessions-with-several-repositories).
679* **Pengaturan terkelola**: sesi membaca [`managed-settings.json`](/docs/id/settings#where-settings-live) dari jalur sistem standar di image runner Anda. Untuk mengetahui apakah kuncinya berlaku bersama [pengaturan terkelola server](/docs/id/server-managed-settings), lihat [bagaimana Claude Code menggabungkan sumber terkelola](/docs/id/managed-settings#how-claude-code-combines-managed-sources).
680
681Untuk urutan penerapan sumber-sumber ini, lihat [prioritas pengaturan](/docs/id/settings#settings-precedence).
578 682
579Ketika bidang kontrol Anthropic memasok sesi dengan [Claude Code hooks](/docs/id/hooks), runner memasangnya bersama, bukan di atas, konfigurasi Anda sendiri. Memerlukan Claude Code v2.1.229 atau lebih baru.683Ketika bidang kontrol Anthropic memasok sesi dengan [Claude Code hooks](/docs/id/hooks), runner memasangnya bersama, bukan di atas, konfigurasi Anda sendiri. Memerlukan Claude Code v2.1.229 atau lebih baru.
580 684
582* **Siapa yang menulisnya**: bidang kontrol mengisinya dari konstanta tetap dalam deployment-nya sendiri, tidak pernah dari input per-sesi atau pihak ketiga.686* **Siapa yang menulisnya**: bidang kontrol mengisinya dari konstanta tetap dalam deployment-nya sendiri, tidak pernah dari input per-sesi atau pihak ketiga.
583* **Apa yang masih mengaturnya**: hook yang dikirimkan melalui `--settings` memasuki konfigurasi hook yang digabungkan biasa, bukan tingkat yang dikelola, jadi pengaturan yang dikelola Anda masih berlaku. `disableAllHooks` menonaktifkannya, dan mereka bukan di antara kategori yang [`allowManagedHooksOnly`](/docs/id/settings-reference#allowmanagedhooksonly) tetap dimuat.687* **Apa yang masih mengaturnya**: hook yang dikirimkan melalui `--settings` memasuki konfigurasi hook yang digabungkan biasa, bukan tingkat yang dikelola, jadi pengaturan yang dikelola Anda masih berlaku. `disableAllHooks` menonaktifkannya, dan mereka bukan di antara kategori yang [`allowManagedHooksOnly`](/docs/id/settings-reference#allowmanagedhooksonly) tetap dimuat.
584 688
689Ketika seseorang memulai sesinya sendiri, Claude Code juga mengunduh [skills yang diaktifkan untuk akun claude.ai mereka](/docs/id/skills#skills-in-cowork-and-cloud-sessions) ke direktori konfigurasi sesi tersebut. Eksekusi [routine](/docs/id/routines) tidak mendapatkan skills pemiliknya, dan sesi yang [mengirimkan permintaan model ke Bedrock atau Agent Platform](#send-model-requests-to-bedrock-or-agent-platform) tidak mengunduh skill apa pun. Untuk skill yang dibutuhkan sesi tersebut, commit skill tersebut ke `.claude/skills/` repositori atau tambahkan ke image runner Anda.
690
585Di luar sesi [Claude Tag](https://claude.com/docs/claude-tag/overview), sesi dalam lingkungan yang di-host sendiri berjalan dengan [auto memory](/docs/id/memory#auto-memory) nonaktif secara default. Untuk instruksi yang harus terbawa antar sesi, gunakan `CLAUDE.md` di image runner Anda atau di repositori.691Di luar sesi [Claude Tag](https://claude.com/docs/claude-tag/overview), sesi dalam lingkungan yang di-host sendiri berjalan dengan [auto memory](/docs/id/memory#auto-memory) nonaktif secara default. Untuk instruksi yang harus terbawa antar sesi, gunakan `CLAUDE.md` di image runner Anda atau di repositori.
586 692
587Snapshot runner atas `~/.claude/` host tidak menyertakan direktori `projects/`. Lokasi penyimpanan default auto memory berada di bawah direktori tersebut. Jika Anda meletakkan file memori di sana, runner tidak menanamkannya ke dalam sesi, dan file tersebut tidak mengaktifkan auto memory.693Snapshot runner atas `~/.claude/` host tidak menyertakan direktori `projects/`. Lokasi penyimpanan default auto memory berada di bawah direktori tersebut. Jika Anda meletakkan file memori di sana, runner tidak menanamkannya ke dalam sesi, dan file tersebut tidak mengaktifkan auto memory.