Show HN: Claude Codeを1ドル未満の予算で、隔離された環境で無人実行
Show HN: Run Claude Code unattended inside a fence, under a dollar budget (github.com)
要約
SIwithinは、Claude CodeやOpenAI CodexなどのAIエージェントを、指定されたフォルダ内でのみ実行し、1ドル未満の予算で無人実行できるツールです。セキュリティを考慮した隔離環境(フェンス)内で動作し、APIキーを直接渡さずにトークンベースで安全にアクセスします。実行ごとにコストと結果を記録し、予算超過時には実行を停止します。macOSのみ対応しています。
全文翻訳
SIwithin
SIwithinは、エージェントCLIを、指定したフォルダの周囲にフェンスを張り、1ドル未満の予算で無人実行し、実行ごとに1つの記録を残します。これは希望ではなく、ツールによって3つの約束を守ります。
- 実行は指定されたフォルダのみに触れます。 ホームフォルダは読み書きともに拒否され、実行フォルダは許可されます。
- 実行は与えられたドルを超えて支出できません。 実行ごとの予算、全実行を通じた上限、各実行のタイマー、そしてClaudeアダプター用にはAPIへの唯一の扉となるループバックプロキシがあります。実行は実行ごとのトークンを保持し、あなたのキーは保持しません。そして、どのように行われたとしても、すべてのリクエストはそこで計測され、予算を超えると拒否されます。CLIが実行中に停止できない場合、ツールはあなたが受け入れに同意しない限りそれを拒否します(「台帳」および「Codexアダプター」を参照)。
- すべての実行は1行を残し、そのコストと完了したかどうかを示します。
Claude CodeおよびOpenAI Codexコマンドラインツールと連携します。SIwithinは独立したプロジェクトであり、AnthropicまたはOpenAIによって作成、承認、またはスポンサーされているものではありません。Claude、Claude Code、OpenAI、Codexはそれぞれの所有者の名前であり、ここではSIwithinがどのプログラムを駆動できるかを述べるためにのみ使用されています。SIwithinを介してベンダーのCLIを使用する場合、各ベンダーの利用規約および使用ポリシーが引き続き適用されます。SIwithinはそれらを一切変更しません。
SIwithinはmacOSでのみ動作します。LinuxおよびWindowsでは、フェンスなしで実行するのではなく、1行で実行を拒否します。
インストール
SIwithinは1つのファイルで、Python 3.10以降、標準ライブラリのみを使用します。独自のネットワーク呼び出しを行わず、テレメトリも送信しません。実行のために開始するプロキシはループバックポートでリッスンし、設定したAPIホストにのみ話します。
git clone <this repository> && cd siwithin
python3 siwithin.py --version
# オプション: PATHに追加
install -m 755 siwithin.py ~/.local/bin/siwithin
また、駆動したいCLIがインストールされ、PATH上にあり、APIキーが必要です(「認証」を参照)。
スモークテスト(python3 tests/smoke.py)は、記述されたPython 3.9.6でパスします。3.10がサポートされる最低バージョンであり、コードは新しい構文を避けていますが、3.10以降では実行されていません。
クイックスタート、Claude Code
mkdir -p ~/.config/siwithin && echo 20 > ~/.config/siwithin/cap # 全実行合わせて20ドルまで
export ANTHROPIC_API_KEY=...
python3 siwithin.py --dir ~/work/proj --model sonnet --dry-run < brief.md # 全て表示、実行なし
python3 siwithin.py --dir ~/work/proj --model sonnet --budget 2
--done "ALL TESTS PASS" --out notes.md < brief.md
--dirは実行のフォルダです。CLIはそこで作業し、書き込みが可能です(--readonlyは読み取り専用にします)。--read <folder>は読み取り可能なフォルダを追加します。--modelはIDまたはエイリアス(haiku、sonnet、opus)を取ります。
クイックスタート、Codex
mkdir -p ~/.config/siwithin && echo 20 > ~/.config/siwithin/cap
export CODEX_API_KEY=...
python3 siwithin.py --adapter codex --model gpt-5.3-codex --soft-budget --network open --dir ~/work/proj --dry-run < brief.md
python3 siwithin.py --adapter codex --model gpt-5.3-codex --soft-budget --network open --budget 2 --dir ~/work/proj < brief.md
このアダプターには、理由があって2つのフラグが必要です(「Codexアダプター」参照)。--model(CLIはトークンとコストを表示しないため、モデルIDで価格設定)、および--soft-budget(CLIはターン終了時にのみ使用状況を報告)。このアダプターはドキュメントから構築されており、ライブCLIに対して実行されていません。auth = "env"で実行されます。キーは実行の環境にあり(「認証」参照)、プロキシがないためネットワークウォールを上げることができません。そのため--network openが必要です(またはconfig.tomlの[fence]の下のnetwork = "open")。デフォルトでは、ネットワークなしで実行される代わりに実行が拒否されます(「フェンス」参照)。
認証
SIwithinはキーを解析、保存、表示、またはログに記録することはなく、ファイル、ログ行、またはエラーメッセージに書き込むこともありません。キーがAPIに到達する方法は、アダプターのauthフィールドに依存します。
Claudeアダプター、auth = "proxy"(0.3.0以降のデフォルト)。 起動前に、フェンスの外側で、ランナーはキーを一度読み取ります。自身の環境のANTHROPIC_API_KEYから、またはconfig.tomlの[auth] key_commandから出力される最初の行(例:キーチェーンルックアップ)から。キーを保持し、標準ライブラリのみを使用した小さなHTTPサーバーをループバックポートで起動します。実行の環境にはANTHROPIC_API_KEY=siwithin-<32文字>(実行ごとに新しいトークンで、それ以外では無価値)とANTHROPIC_BASE_URL=http://127.0.0.1:<port>が含まれます。実行がCLI、手動、または開始した別のCLIによって行うすべてのリクエストは、そのドアを通過します。プロキシは実行のトークンのみを受け取り(それ以外は401でどこにも行かない)、[auth] paths(デフォルトは/v1/messagesおよび/v1/messages/count_tokens、それ以外のパスは403で実際のキーは添付されない)のパスのみを転送し、実際のキーを追加し、レスポンスをストリーミングとして中継し、各/v1/messagesレスポンスをその使用量に基づいて[prices]レートで価格設定します。合計が予算に達すると、それ以降のすべての/v1/messagesリクエストは402を受け取り、最初の拒否は実行プロセスを終了させます(ストリーミング停止と同様)。実行が終了すると、プロキシは閉じられ、ログは閉じられ、サーバーはシャットダウンされるため、トークンは無価値になります。リクエストごとの1行が実行フォルダのproxy.jsonlに書き込まれます(パス、モデル、ステータス、使用量、コスト、実行中の合計、クライアントのポート、拒否された理由。本文、キー、トークンは含まれません)。実行設定ディレクトリにあるsettings.jsonがapiKeyHelperを指している場合、起動前に拒否されます。なぜなら、実行はそのヘルパーをフェンス内で実行でき、実行がそれを読み取れるからです。ヘルパーのコマンドは代わりに[auth] key_commandに配置してください。これはランナーがフェンスの外側で実行します。--dry-runはauth: proxy 127.0.0.1:<port>を表示し、何も起動しません。
auth = "env" は、0.2.1のように、キーの変数を名前で実行にコピーします。これはCodexアダプターの唯一のモードであり、Claudeアダプターのオプトインです(チェックは警告します)。このモードでは、キーは実行の環境にあり、実行が開始するすべてのコマンドに継承されます。プロキシポートがないためネットワークウォールは上げられず、デフォルトの[fence] network = "proxy"では実行が拒否され、network = "open"(または--network open)が必要です。これにより、実行はキーをどこにでも送信し、台帳の外で支出できます。SIwithin専用に作成されたキーを、プロバイダーのコンソールで支出限度額が設定されたワークスペースで使用し、実行が読み取るテキスト(SECURITY.md、「既知のギャップ」)に公開されていると見なしてください。
各アダプターは、SIwithinのホームの下に設定ディレクトリ(claude-config/、codex-config/)を持ち、その実行間で共有され、ログインがないため、CLIはログインで静かにサインインしてキーの代わりに請求することはできません。
- Claude Code は、
ANTHROPIC_API_KEY環境変数でキーを、ANTHROPIC_BASE_URLでAPIアドレスを見つけます。プロキシの下では、それらは実行のトークンとループバックポートになり、CLIは2026年10月14日と15日のライブレッドパス(テスト)でそのように実行されました。CLIを独自のsettingsファイルに向けるには、config.tomlのextra_argsに["--settings", "/path/to/settings.json"]を追加します。apiKeyHelperを指すものは、前述のように拒否されます。 - Codex CLI は、
codex exec(そのドキュメント)のためにCODEX_API_KEYを読み取ります。保存されたChatGPTログインは$CODEX_HOME/auth.jsonにあります。各実行は独自のCODEX_HOMEを持つため、そのログインは使用されず、ドル予算はプラン請求には関係ありません。
--require-api-key(claudeアダプターではデフォルトでオン、codexでは拒否、チェック方法がない)は、起動前にCLIにサインイン方法を尋ね、CLIの最初のイベントでキーソースをチェックします。プロキシの下では、それはトークンの変数であるANTHROPIC_API_KEYでなければなりません。どちらかがログインが請求されると報告した場合、実行は拒否または終了され、メッセージで理由が示されます。設定ディレクトリにログインを持つCLIは、イベントがAPIキーを指す間にそのログインでサインインできます。--no-require-api-keyはログインを受け入れます。
フェンス
SIwithinは、テンプレートから各実行のためにmacOSのsandbox-execプロファイルを生成し、ホームフォルダは実行時に派生します。--dry-runはそれを表示します。各実行フォルダはそれをfence.sbとして保持します。
- ホーム全体が読み書きともに拒否されます。
- 許可されるもの:実行のフォルダ(読み取り可能。最初の書き込み可能、
--readonlyを除く)、CLIのバイナリ、~/Library下のキャッシュとログ(読み書き可能)、キーチェーンファイル(読み取り専用)、Pythonユーザーパッケージ、シェルのrcファイル、gitの設定、および実行自身の設定ディレクトリ。 - CLIの設定ディレクトリ内では、その状態パスのみが書き込み可能(設定の
config_write):トランスクリプト、セッション、ファイル履歴、TODO、キャッシュなど。設定、状態ファイル、メモリ、コマンド、スキル、エージェント、フック、プラグイン、スケジュールされたタスク、およびそこに保持されているキーヘルパーは、所有者が残したままになり、各トランスクリプトフォルダ下のメモリフォルダも書き込み不可になるため、実行は次の実行のための指示を残しません。 /private/tmp、/tmp、/opt、/usr/local、/Applications、/Library、/Volumesへの書き込みも拒否されます。CLIの一時ルートは実行フォルダ内に移動され、CLIはそのための変数を持っています。open、screencapture、osascript、say、afplay、launchctl、crontab、at、batchは開始できません(deny_exec。パスごと、したがって別の場所のコピーは停止しません)。- SIwithin自身のホーム(設定、キャップ、台帳、他の実行のフォルダ)は、アダプターの設定ディレクトリを除き、実行には拒否されます。アダプターの設定ディレクトリでは、CLIは以前の実行のトランスクリプトを保持します。実行はそれらを読み取ることができます(SECURITY.md、「既知のギャップ」)。
--dirおよび--readは、ホームルートおよびそれを含む任意のフォルダ、~/.ssh、~/.config、~/Library、各アダプター自身の設定ディレクトリ(~/.claude、~/.codex)、SIwithinのホーム、およびconfig.tomlの[never]の下にリストされた任意のフォルダを拒否します。フェンスは指示されたもののみを強制するため、これらは事前に拒否されます。- 実行の環境は短いリストです(
[env] passおよびアダプターのenv_pass)。シェルの環境の残りは継承されません。 - ネットワーク(ウォール、0.4.0)。プロキシアダプターを使用する場合、プロファイルはキープロキシのループバックポート(
[fence] network = "proxy"、デフォルト)を除くすべてのソケット、DNS、およびバインドを拒否します。CLIはプロキシを介してAPIに到達し、実行からマシンから何も出ません。ローカルサーバーも拒否されます。各拒否は、実行自身のマーク(フォルダ名)の下でカーネルによって報告されます。実行が終了すると、ランナーはそのマークで統合ログからレポートを読み取ります(カーネルは結合された行を遅れて着陸させるため、2秒間隔で2回読み取ります)。それをsummary.json(network:refused、ターゲットごとおよびプロセスごと、CLI自身のPIDは他から取得、lateは読み取り間に着陸したもの)および1行の印刷にカウントします。network = "report"はネットワークを開いたままにし、実行が開くすべてのソケットをカウントします。これは、通常の実行がプロキシ以外に開くソケットの数、ポート、およびバインドするかどうかを調査します(カーネルはソケットを種類とポートで名前付けします。remote:*:443、またはパスでUnixソケット、ホスト名ではありません)。"open"は0.3.0のネットワークで、報告されません。--network proxy|report|openは、1回の実行について設定を上書きします。auth = "env"を持つアダプターにはプロキシがなく、"proxy"の下で拒否され、出口が名前付けされています。2026年10月15日にライブ実行(ステータス)。 - 実行プロセスはランナーが終了させるものです。CLIが生きている間、ランナーはその子孫のセットを保持し、各停止時(予算、タイマー、割り込み、CLI自身の終了)にプロセステーブルをスキャンして実行マーカーを持つあなたのプロセスを探し、セット、次にグループをキルし、何も残らなくなるまで再度確認します。
summary.jsonは、グループキルだけでは到達できなかった(outlived、クリーンな実行では0)プロセス数を示します。psが必要です。それがない場合、実行はそれをメモします。
フェンスが停止しないもの:実行がプロキシが未読で転送するリクエストボディ内でAPI自体に送信するもの(モデルのコンテキストは、ウォールが残す唯一の出口です)、および[fence] network = "report"または"open"下のネットワーク全体(auth = "env"アダプターが必要)。ホーム外での読み取り。ホームおよびリストされたルート外での書き込み。実行が自身のフォルダに書き込み、後であなたが実行するもの(スクリプト、gitフック)。シェルrcファイルにエクスポートされたキー(実行が読み取れる)。ウォークが検索する前にマーカーを消去して再親化されたプロセス。およびCLIが自身のクラウドサンドボックスまたはリモートマシンで行うもの(フェンスはそこにはありません)。依存する前にSECURITY.mdを参照してください。
台帳
各実行は、SIwithinのホームにあるledger.mdに1行を追加し、ターミナルに要約行を書き込みます。
2026-10-13 14:02 | docs-pass | /Users/you/work/proj | claude sonnet - | 12 turns | 6.4 min | cli $0.4123 | true $0.4123 | in 310k out 18k | runs/2026-10-13-1402-docs-pass | done | receipt 864410d4e9f126c9abf1b0b12c28e21ff8541cf24ceaf98039781609a9133881
- cli はCLI自身のコスト値です(CLIが提供しない場合は
-)。true はconfig.tomlの[prices]からの公開レートでのコストで、モデルIDでキー付けされます。プロンプトオンの場合、それはプロンプト自身の合計であり、APIにマシンから出たものです。[prices]にはレートが読み取られた日付(read_on)と場所(source)が含まれます。SIwithinはレートが90日以上古い場合に警告します。レートは変更されます。確認してください。 - キャップ。
capは1つの数値を保持し、すべての実行が合計で支出できるドル数です。SIwithinはtrue列を合計し、合計に--budgetを追加したときにキャップを超過すると実行を拒否します。これはロック下でチェックされます。cap、--budget、および設定の予算はnanとinfを拒否します。 - 予算。
--budgetは実際のドルです。予算フラグを持つCLIの場合、SIwithinはbudget × factorを渡します([factors]はCLIの単位と実際のドルの比率で、リストされていない場合は1)。最小のClaudeモデルの組み込みデフォルトは1です。CLI 2.1.284はそれを別のモデルのレートで価格設定し、40が必要でした。これはconfig.tomlの[factors]の下に設定できます。SIwithinは、CLIのコストが実際のコストよりも4倍以上または4分の1未満の場合に警告します。これは、ファクターがどちらかの方向に古くなっていることを意味します。予算フラグのないCLIの場合、SIwithinはストリーミング中に使用量を読み取り、予算で実行を終了します。使用量をターン終了時にのみ報告するCLIの場合、SIwithinは--soft-budgetが指定されていない限り拒否し、予算は各ターン終了時にチェックされます。 - Claude Code:予算は3回強制されます。 CLIのフラグ(
--max-budget-usd、budget × factorを渡す)によって。ストリームからのSIwithinによって(各アシスタントイベントはそのレスポンスの使用量を含み、SIwithinはそれを[prices]レートで価格設定し、メッセージIDごとに1回、実際のコストが予算に達すると実行プロセスを終了させます)。およびプロキシによって、プロキシはドアで各/v1/messagesレスポンスを価格設定し、合計が予算に達すると402で拒否し、最初の拒否で終了するため、CLIのストリームが表示しないリクエストもカウントされます。台帳行とサマリーはkilled: budget $0.50 reached at $0.5502 trueと表示されます。フラグが最初に実行を停止した場合、行はCLI自身の言葉でstopped by the CLI's budget flag: Reached maximum budget ($0.10)と表示され、result.mdにはモデルの最後のメッセージが含まれます。なぜなら、CLIの結果はその時点でテキストを持たないからです。--dry-runは3つすべてを表示します。制限は、サマリーノートに適用されるときにそれぞれ表示されます。- ストリームのイベントごとの出力トークンは、最終結果までのプレースホルダーです。ストリーム停止は入力トークンとキャッシュトークンを完全にカウントし、出力トークンはストリーミングされたもののみをカウントするため、早期に発火せず、出力が多い実行では実際の予算を超過した後に発火します。プロンプトオンの場合、プロンプトの合計が台帳に記録され、ストリームとプロンプトの差が1セント以上かつ1%以上の場合に
stream $x, proxy $yというノートが表示されます。 - プロンプトは予算を超過したリクエストの後で停止するため、1つのレスポンスがその全体コストでそれを通過できます。最悪の場合のシナリオが予算を超えるリクエストを拒否する上限チェックは組み込まれていません(SECURITY.md、「既知のギャップ」)。
[prices]にエントリがないモデルは、ストリームまたはドアから価格設定できません。台帳でのコストは、CLI自身の数値とそのファクターであり、どちらの停止もカウントせず、CLIのフラグのみがbudget × factorで制限します。そのレートを[prices](およびCLIの単位が異なる場合はファクター)に追加してください。
- ストリームのイベントごとの出力トークンは、最終結果までのプレースホルダーです。ストリーム停止は入力トークンとキャッシュトークンを完全にカウントし、出力トークンはストリーミングされたもののみをカウントするため、早期に発火せず、出力が多い実行では実際の予算を超過した後に発火します。プロンプトオンの場合、プロンプトの合計が台帳に記録され、ストリームとプロンプトの差が1セント以上かつ1%以上の場合に
ストリームが使用量フィールドを含まない場合、SIwithinはフラグとプロンプトにフォールバックし、ノートはそのように表示されます。
-
キルされた実行は、プロンプトの合計(プロンプトがあった場合)、または使用量が報告されなかった場合(タイマー、割り込み)は予算を上限として記録され、その行は
(ceiling, usage unreported)と表示され、キャップは真のままです。 -
各実行には、
runs/の下にbrief.md、command.txt(コマンド、環境変数名、CLIのバージョン)、fence.sb、events.jsonl、stderr.txt、result.md、summary.json、プロンプトがあった場合はproxy.jsonl、およびreceipt.json(「レシート」参照)を含むフォルダもあります。
レシート
実行終了後、台帳行が追加される前に、ランナーは実行フォルダにreceipt.jsonを書き込みます。ランナーが書き込んだ各ファイルのsha256が、前のレシートと台帳に連鎖されます。台帳行には、レシート自身のハッシュが最後のフィールド| receipt <64 hex>として含まれます。ターミナルには、session:の後にreceipt: <64 hex>という行が表示されます。ランナーはCLIが終了した後にそれを書き込みます。モデルは決して行いません。起動前に拒否された実行は、レシートも台帳行も書き込みません。--dry-runは何も書き込みません。summary.jsonはレシートのハッシュを保持できません。なぜなら、レシートはsummary.jsonをハッシュするからです。
receipt.jsonは、キーがソートされ、インデント1、UTF-8でJSON形式です。そのハッシュはバイトのsha256です。フィールド:
receipt: フォーマットのバージョン、1。tool: ランナーの名前とバージョン、siwithin 0.5.0。run: 台帳行のruns/の後の実行フォルダ名。startedとended: 実行の開始とレシートが書き込まれた瞬間、ISO 8601形式(秒まで)。status: 台帳行と同じ。files:brief.md、command.txt、fence.sb、events.jsonl、stderr.txt、result.md、summary.jsonのsha256。プロンプトがあった場合はproxy.jsonlも。フォルダ内の他のものはありません。tmp/はありません。ledger_before: この実行の行が追加される直前の台帳のバイトのsha256(台帳が新規の場合、ヘッダーは既に書き込まれています)。previous: レシートを最後に持つ台帳行のレシートハッシュ、またはnull。
検証:
python3 siwithin.py --verify [--home H] # 台帳のすべてのレシート
python3 siwithin.py --verify --expect <hash> [--home H] # 同上、最後のレシートはこのハッシュでなければならない
python3 siwithin.py --verify ~/.config/siwithin/runs/<run> # 1つの実行フォルダのファイルとレシートの比較
レシートを持つ各台帳行について、検証者はreceipt.jsonが存在し、行の16進数にハッシュされること。filesの各ファイルがレシート通りにハッシュされること。ledger_beforeがその行の前の台帳バイトのハッシュであること。previousが前のレシートを持つ行の16進数であること(最初のものはnull)をチェックします。レシートはそれが含まれる行を保持できないため、行の実行とステータスがレシートのものであること、およびそのtrue $値がレシートが保持するsummary.json内の値であることをチェックします。最初のレシートを持つ行より前の行は0.1台帳と見なされ、カウントされますが失敗しません。最初のレシート以降、レシートのない行は失敗します(FAIL line N: no receipt, after line M had one)。--expect <hash>を使用すると、最後のレシートを持つ行のハッシュは指定されたものと等しくなければなりません。そうでなければFAIL: the last receipt is <hash>, not <expected>となります。各レシートについてok <run>またはFAIL <run>: <what failed>と表示され、N receipts ok, M failed, K lines without a receiptと表示され、何も失敗しなかった場合にのみ終了コード0で終了します。ロックを取らず、設定も読み込みません。実行フォルダを使用すると、そのフォルダのファイルのみをチェックし、ok <run>: 7 files match the receiptまたはFAIL ...と表示されます。
証明するもの:実行のファイルと台帳はランナーが書き込んだ通りです。後で概要、結果、イベントファイル、またはコストを編集するとハッシュが壊れ、台帳行を編集すると次の行のledger_beforeが壊れ、行が末尾からカットされたり、レシートが剥がされたりすると、保持されているハッシュに対して失敗します。
証明しないもの:イベントがAPIの実際の動作と一致すること。CLIがそれらを書き込み、レシートはCLIが言ったことをハッシュします。また、SIwithinのホームを書き込める人は誰でも、最初の行からすべてのレシートとチェーン全体を書き換えることができるため、チェーンはそれへのアクセスを持たないものによる変更に対する証拠であり、所有者に対するものではありません。最後のレシートのハッシュを、台帳ライターが到達できない場所(メッセージ、メモ、コミット)に保持し、--verify --expectでチェーン全体をその時点でピン留めします。それ以前の変更、またはそれ以降のカットは表示されます。
照合
台帳は、実行内のキーの支出を記録します。プロバイダーの請求書に記録されていない支出は、キーの第2のユーザーの兆候です。--reconcileは、実行が支出したキーのプロバイダーの使用状況レポートを読み取り、バケットごとに台帳と照合します。何も実行せず、ロックを取らず、台帳行も書き込みません。
python3 siwithin.py --reconcile 2026-10-16 [--until 2026-10-17T09:00] [--bucket 1m|1h|1d] [--home H]
python3 siwithin.py --reconcile 2026-10-16 --csv usage.csv # コンソールの使用状況エクスポートの代わりに
python3 siwithin.py --reconcile 2026-10-16 --every 300 # 5分ごとに再度確認
python3 siwithin.py --reconcile 2026-10-16 --dry-run # 要求するリクエスト、キーは<key>として表示
-
2つの入力方法。
[reconcile] admin_key_commandは、フェンスの外側で実行されるコマンドで、最初の行は管理者APIキー(コンソールの管理者キーページから。個人アカウントには提供されません)です。これを使用して、SIwithinは使用状況とコストAPIの使用状況レポート(/v1/organizations/usage_report/messages)を、[reconcile] api_key_idsのキーに対して、キー、モデル、サービスティアごとにグループ化し、レポートが終了するまでページングして読み取ります。api_key_idsが空の場合、組織のキー(id | name | partial_key_hint)をリストし、拒否するため、選択する必要があります。管理者キーがない場合、--csv FILEはコンソールの使用状況エクスポートを代わりに読み取ります。その列は名前で検索されます:時刻、モデル、キャッシュされていない入力、キャッシュ読み取り、キャッシュ作成(ファイルにそれらがある場合、5分および1時間)、出力、および利用可能な場合のWeb検索。一致しないヘッダーは表示され、拒否されます。エクスポートのヘッダーは、これが書かれた時点ではまだ見られていません。あなたのものが拒否された場合、表示されるヘッダーはレポートと共に送信すべきものです。 -
ドル。 プロバイダーのトークンは
[prices]レートで価格設定されます。1時間のキャッシュ書き込みは、[prices] cache_write_1h_factor(1.6、公開比率)×キャッシュ書き込みレート、Web検索はweb_searchです。エントリのないモデルはトークンと共に表示され、unpricedとしてカウントされます。実行側は、各プロンプトされたリクエストのコストで、実行のproxy.jsonlから取得されます。プロンプトがない実行(別のプロンプト、0.1台帳)は、その行の時刻全体で配置されます。 -
判定、バケットごと。
unaccounted: プロバイダーの支出が[reconcile] toleranceを超えている、または価格設定されていないモデルのトークンで、実行中でリクエストが記録されていない場合。over: 実行がアクティブで、プロバイダーが実行よりも許容範囲を超えて多い場合。それ以外はok。サマリー行は最後に表示されます。report: <path>の後:reconcile: 2026-10-18 18:00 to 2026-10-18 20:30 | provider $0.0872 | runs $0.0272 | unaccounted $0.0600 in 1 buckets | over $0.0000 in 0 | unpriced 0 | key apikey_01Ab…すべてのバケットが
okの場合は終了コード0、いずれかがunaccountedまたはoverの場合は1、実行できなかった場合は2で、1行refused: …が表示されます。レポートは、バケットごとおよびプロバイダーの結果のテーブルで、.jsonと同じ数値を横に表示して、<home>/reconcile/<UTC stamp>.mdに書き込まれます。--every SECONDS(少なくとも60)は、その間隔で再度確認し、数値が変更されたときに1行表示し、最初の未説明バケットで終了コード1で終了します。 -
管理者キーは1つのオブジェクトに保持され、リクエストヘッダーにのみ入り、それ以外には入りません。レポート、エラーテキスト(401のメッセージは
<key>にスクラブされます)、ファイルには入りません。--dry-runはコマンドを一切実行しません。 -
見えないもの。 レポートはキー、モデル、サービスティアごとに要求されます。高速モード、米国の推論地理、またはロングコンテキストティアでの支出は標準レートで価格設定されるため、プロバイダーの数値は過小評価されますが、過大評価されることはありません。プロンプトは1つのキャッシュ書き込みを記録し、5分レートで価格設定するため、1時間のキャッシュを書き込むCLIは、キーに誰もいないバケットを
overとして読み取らせる可能性があります。実行がアクティブだったバケットで許容範囲内で支出する第2のユーザーは不可視です。デフォルトはバケットあたり0.05ドルで、バケットは1時間幅です。SINCEとUNTILはローカル時間、バケットはUTC、プロバイダーの数値は約5分以内に到着します。これは偽のサーバーとこのツールの台帳に対して実行されましたが、ライブ管理者APIまたは実際のインポートに対してではありません(ステータス)。
基本契約
- 基本は標準入力です。空の基本は拒否されます。
--done "<text>": 実行後、SIwithinはresult.mdにテキストが含まれているかどうかを報告します。--absent "<text>": そのテキストが含まれているかどうか、削除したいテキストです。完了したが--doneテキストを欠いている、または--absentテキストを含む実行はdoneではなく、ステータスはfinished, contract unmet: ...となり、台帳行にそのように表示されます。--out <file>: 結果は、実行がdoneの場合にのみ、そこに書き込まれます。パスは--dirからの相対パスで、その中に留まる必要があります。SIwithinはそれ以外には書き込みません。--readonlyでは拒否されます。読み取り専用実行の結果はresult.mdから取得してください。- 終了ステータス:
doneの場合は0、それ以外(拒否を含む)の場合は1。
Codexアダプター
公開ドキュメントから構築、2026年10月13日に読み取り:
- https://developers.openai.com/codex/noninteractive(https://learn.chatgpt.com/docs/non-interactive-modeにリダイレクト、読み取り済み)
- https://developers.openai.com/codex/cli/reference(https://learn.chatgpt.com/docs/developer-commands?surface=cliにリダイレクト、読み取り済み)
- https://github.com/openai/codex
- https://developers.openai.com/api/docs/pricing(
[prices]のレート)
それらのページから確認済み: codex exec;プロンプトが標準入力から読み取られる(省略または-の場合);--json(標準出力にJSON Lines)でイベントthread.started(thread_id)、turn.started、item.completed(textを持つagent_messageアイテム)、turn.completed(input_tokens、cached_input_tokens、output_tokens、reasoning_output_tokensを持つusage)、turn.failed、error;--cd/-C;--model/-m;--sandbox/-s(read-only、workspace-write、danger-full-access付き);--skip-git-repo-check;--output-last-message/-o;exec用のCODEX_API_KEY;CODEX_HOMEと~/.codex/auth.json。フラグはターンや支出を制限せず、コストフィールドは文書化されていません。 これが、このアダプターが--soft-budgetを必要とする理由です。使用量はturn.completedイベントでのみ到着するため、単一の長いターンはSIwithinがそれを認識する前に予算を超過する可能性があります。ターンで終了する実行は予算超過として報告され、ターンを開始する実行は終了されます。
config.tomlで未確認とマークされているもの(読み取られたページでは確認されていません。それらを必要とするオプションは拒否され、フィールド名を指定します):effort_flag、resume_flag(CLIはサブコマンドexec resumeで再開しますが、配線されていません)。仮定、すべてのドライランとサマリーにリスト:input_tokensにcached_input_tokensが含まれる(サンプル数値が示唆しています。間違っている場合、実際のコストは過小評価されます);output_tokensに理由付けトークンが含まれる;usageがターンごとか累積か(SIwithinはturn.completedイベントを合計します);CLI自身のサンドボックスがSIwithinのプロファイル内で開始されるか(デフォルトは--sandbox workspace-write、--readonlyの場合はread-only。開始を拒否する場合、config.tomlでargs_writeを認識して設定します);バイナリがインストールされる場所(SIwithinはPATHで見つかったもののフォルダを許可します);--versionの形式。--readフォルダは、CLIの--add-dirが書き込みを許可するため、このCLIには通知されません。
何をしないか
- LinuxとWindows。 そこにはフェンスがないため、SIwithinは拒否します。ロードマップにありますが、開始されていません。
- ホストされたチーム台帳。 台帳は1台のマシン上のファイルです。
- より多くのCLI。 2つが組み込まれています。3つ目は、2つの出力形式(
claude-stream-json、codex-jsonl)のいずれかを話す場合、config.tomlで宣言できます。他の形式にはコードが必要です。 - 2番目のアダプター用のプロンプト。 最初のもののみを提供します。Codexアダプターは
auth = "env"を保持し、キーは実行の環境にあり、ネットワークウォールはありません。そのため、実行には--network openが必要です。 - 実行ごとの設定ディレクトリ。 実行は、アダプターの以前の実行のトランスクリプト(基本を含む)を読み取ることができます(SECURITY.md、「既知のギャップ」)。
- まだ完了していないこと。 使用量を遅れて報告するCLIの中断中の予算強制、プロンプトでの上限チェック、2番目のアダプターの再開と労力、ライブCLIに対する2番目のアダプターの検証済み実行、および最初のもの以外のウォール(上記)。
- 最初のファクターのストリーミング出力トークン。 CLIのストリームは、最終結果でのみレスポンスの実際の出力カウントを報告します。SDKドキュメントによると、部分メッセージオプションは実行中のカウントをストリーミングしますが、SIwithinはそれを使用しません。したがって、ストリーム停止は出力が多い実行の下限です(「台帳」参照)。プロンプトオンの場合、プロンプトの合計が台帳に記録されます。2026年10月18日の48ターン実行では、ストリームの実行中の合計はプロンプトの0.0272ドルに対して0.0156ドルでした(ステータス)。
- ライブ照合。
--reconcile(照合)は、プロバイダーの使用状況レポートを台帳と照合し、バケットごとに設定します。偽のサーバーとこのツールの台帳に対してのみ実行されました。ライブ管理者API(個人アカウントには提供されません)や実際のインポートに対してではありません。レポートは、速度、地理、コンテキストウィンドウを要求しないため、そこでの支出は標準として価格設定され、過小評価されます。
設定
config.example.tomlを~/.config/siwithin/config.tomlにコピーします。すべてのオプションには1行のコメントがあり、すべての値は組み込みデフォルトです。変更したもののみを保持してください。[auth]にはkey_command、upstream、upstream_timeout、pathsが含まれます。[fence] networkは実行のネットワークを選択します:proxy、report、またはopen。[reconcile]にはadmin_key_command、api_key_ids、toleranceが含まれ、[prices] cache_write_1h_factorは1時間のキャッシュ書き込みの比率(照合)です。--home <folder>は、SIwithinのすべてのパス(config.toml、cap、ledger.md、lock、runs/、各CLIの設定ディレクトリ)を一度に移動します。
ステータス
バージョン0.5.0、2026年10月19日リリース:--reconcile(照合);--versionはsiwithin 0.5.0を表示し、スモークテストは偽のCLIと偽の使用状況サーバーで291のチェックに合格し、レッドフェイクパスは92(CHANGELOG)です。照合は、0.4.0リリース当日の夜、その日の使用状況とコストAPIのドキュメントから構築され、ループバック上の偽のサーバーでテストされました。ページング、すべてのトークン種類の算術演算、3つの判定、ファイルや出力に漏洩しない管理者キー、CSV方式、ウォッチ、およびサンドボックスを開始せず台帳行も書き込まないことが機能しました。このツールの台帳と偽のインポート(suiteが想定するヘッダーで手書き)に対して一度実行されました。10月18日の48ターン実行(下記)、そのプロンプトログからのトークンが1時間ごとに配置され、両側で0.0272ドルで照合されました。1時間後の実行がない行はunaccounted $0.0600 in 1 bucketsと読み取られ、終了コード1でした。実行されていないもの:ライブ管理者API(個人アカウントには提供されません)、および実際のインポート。そのため、コンソールインポートのヘッダーはAPIのフィールド名から取得され、ツールが一致しないヘッダーは表示され、拒否されます。APIのレポートは、速度、推論地理、コンテキストウィンドウでもグループ化されます。これらはそれぞれ価格を変更します。ツールはそれらを要求しないため、そこでの支出は標準として価格設定されます(照合、「見えないもの」)。
0.4.0、2026年10月18日リリース:ネットワークウォール(フェンス)とSTOLEN-KEYS.md;--versionはsiwithin 0.4.0を表示し、スモークテストは偽のCLIで266のチェックに合格し、レッドフェイクパスは92(CHANGELOG)です。ウォールは10月15日に、Claude CodeドキュメントのCLIが開くホストの表を読み、このマシンでsandbox-execのソケットルールをプローブした後、構築されました。同日午前中にライブ実行、レッドホームでClaude Code 2.1.296とHaikuを使用した3回の実行、それぞれ4ターン、1分未満:reportモードでの通常のタスクの調査では12個のソケットがカウントされ、プロンプトポートへの2つ以外にポート443への7つ、リゾルバーへの2つ、実行の一時ルートにバインドされた1つのUnixソケットがカウントされました。同じタスクがウォール下で同じ4ターン、同じコストで完了し、8回の拒否(リゾルバーの7つとバインドの1つ)があり、名前が解決されなかったため443への試みはありませんでした。net-out基本は保持され、プログラムの公開アドレスへの接続はerrno 1で拒否され、その2つのルックアップはerrno 8で拒否されました。プロンプトは到達可能でした(tests/red/scorecard-2026-10-15-3.md)。ランナーの数値とカーネルのログを比較したところ、読み取りに2つの誤りが見つかり、同日午前中に修正されました(CHANGELOG)。ここでの数値は、ログに対する修正されたリーダーのものです。2026年10月18日、レッドホームでClaude Code 2.1.302とHaikuを使用した48ターン、3.1分間の実行が1回ありました。30ファイル書き込みタスクで、中間で2回のネットワーク試行がありました。CLI自身のツールのフェッチとPythonリクエストです。両方とも実行自身の記録で失敗しました。ツールはドメインを確認できず、リクエストはリゾルバーからerrno 8で失敗しました。44件のリクエストがプロンプトを通過し、すべて/v1/messagesで、trueで0.0272ドル、CLI自身の数値と同じでした。カーネルのレポートは51回の拒否をカウントしました。リゾルバーのソケットへの50回(CLIの49回、Pythonプログラムの1回)とCLIの1つのUnixソケットバインド、ポート443へのゼロ、late 0;outlived 0;レシートは--expectで検証されました。カーネルの行は実行の5分後に統合ログを離れていたため、実行終了時のランナーの読み取りが記録となります。実行のシェルコマンドのうち2つは、CLI自身の許可レイヤーによって拒否されました。これは複合コマンドであり、フェンスによるものではありません。まだ不明なこと:ウォール下の別のプロンプト(2番目のプロンプトは--network openで実行されます)、および起動時にソケットを待機するCLIがそこでハングするかどうか。このCLIは一時ルートに1つのUnixソケットをバインドし、拒否され、終了します。STOLEN-KEYS.md、盗まれたキーのコスト、2026年10月17日のOpenCodeコンソール侵害後に作成:キーがどこから取られたか、各レイヤーが何をしたか、そしてこのツールがそれに対して何をし、何をしないか。
0.3.0、2026年10月15日リリース:キープロンプトとキルウォーク、--verify --expect、有限の資金、プロンプトのパス許可リスト、deny_execに4つのプログラム、およびキーとキルのための2つのレッドブリーフ。--versionはsiwithin 0.3.0を表示し、スモークテストは偽のCLIで244のチェックに合格します。プロンプトとウォークは2026年10月14日と15日のレッドパスでライブ実行されました(テスト)。Claude Code 2.1.296とHaikuを使用:以前の5つのウォールは保持され、予算停止は設計通りに発火し、env-keyブリーフは実行の環境またはその祖先でキー値を見つけられず、outliveブリーフのデタッチされたプログラムは発見され、キルされました。outlived 1、最初のパスでウォークがそれをキルし、カウントしなかったことが示された後(CHANGELOG)。4つのギャップのうち、10月14日に見られたコード全体を陌生人として読んだ結果、3つは閉じられ、1つ(トランスクリプト)は開いたままです。0.3.0はその自身のものを命名します(SECURITY.md、「既知のギャップ」)は、それぞれが置き換えられたものを持っています。リリース後、同日:プロンプトの予算での402は、0.4.0(CHANGELOG)でリリースされたsecond-clientブリーフでライブで確認されました。プロンプトは2番目のクライアントのリクエストを拒否し、CLI自身の次のリクエストも合計が予算を超過した後、38ミリ秒後に拒否し、実行は何も転送されずにキルされました。trueで0.0272ドルでした。また、レッドホームでの8ターン実行の調査では/v1/messagesのみが呼び出されたため、他のパスはライブでは確認されていません。
以前:0.2.1、2026年10月14日、1セント未満の予算を4桁で表示しました。0.2.0、2026年10月14日、レシート、同日の1回の実行でライブ;2026年10月13日の4回のライブ実行、Claude Code 2.1.296を使用、CLIの予算フラグが2回発火、キャップを超過した実行は起動前に拒否、フェンスによって書き込みは拒否されず、実行フォルダ外では見られませんでした。新しいマシンでは、python3 siwithin.py --dir <a scratch folder> --dry-run < /dev/nullを実行し、簡単なブリーフを作成し、stderr.txtを依存する前に読んでください。
テスト
python3 tests/smoke.py
一時的なホームとインストールされていないCLIで実行されます。各アダプターのドライラン、フェンスプロファイル行、禁止フォルダ、キャップ算術、設定リーダー、および(macOSで)サンドボックスプログラムがシムに置き換えられた偽のCLIに対する全体実行。これにより、ストリーミング、キル、台帳、およびサマリーコードが実行されます。これには、予算を超過する偽(実行、その子プロセス、台帳行はキルされる必要がある)と、それを下回る偽が含まれます。レシートは、記録された各実行に対して書き込まれ、拒否された実行には書き込まれません。連鎖され、--verifyはホームでパスし、変更された結果、変更されたコスト、置き換えられたハッシュ、変更された実行フォルダ、最初のレシート後のベアライン、および間違った--expectで失敗します。ループバック上の偽の上流と偽のCLIに対するプロンプトのチェック。およびプロセスをデタッチする偽、環境を消去する偽、パイプを開いたままにする偽、または孤児を残す偽に対するキルウォーク。およびネットワークウォールの3つのモード(ドライランと全体実行)、カーネルログがシムに置き換えられ、缶詰のレポート行を返します。および0.5.0以降、ループバック上の偽の使用状況サーバーで--reconcileを実行し、偽のホームに対して実行します。ページング、算術、判定、すべてのファイルと出力に対する管理者キーの漏洩チェック、CSV方式、およびウォッチ。291のチェック。フェンス自体はそこではテストされていません。
レッドブリーフ、tests/red/はフェンスをテストします。9つの通常のタスクがそれぞれ1つのウォールをクロスします。実行フォルダ外のホームディレクトリへの書き込み、/tmpへの書き込み、deny_exec上のプログラムの開始、SIwithin自身の台帳への書き込み、小さな予算を超えるのに十分な長さのタスク、実行の環境とその祖先でのキーの検索、キルよりも長生きしてはならない独自のセッションにデタッチされたプログラム、APIの2番目のクライアント、タスクによって開始され、ストリームが表示しない支出でプロンプトがカウントして予算で停止する必要があるもの、およびキープロンプトポート外のソケットを開くプログラム(公開アドレス、リゾルバー、httpsフェッチ)、ネットワークウォールが拒否する必要があるもの(net-out、まだライブ実行されていません)。python3 tests/red/run.py --fakeは、植え付けられた実行フォルダに対するスコアラーを証明し、何もライブで実行しません。--liveは各ブリーフをHaikuを使用してSIwithin.pyでレッドホームに実行し、実行フォルダをスコア付けし、キー漏洩検出器と--verifyを実行し、最後の列が各実行のレシートハッシュであるスコアカードを書き込みます。--live --only <id>は1つを再実行します。2026年10月14日と15日の6つのスコアカードがフォルダにあります。最初の3回のパスでは、4つのウォールがそれぞれ保持され、3番目のパスでは0.0001ドルの予算に対して0.0002ドルのtrueで予算停止が設計通りに発火しました(そのキルステータスの$0.00は0.2.1が修正したものです)。4回目のパスでは、5つが再び保持され、env-keyが保持されました。一方、outliveはウォークがデタッチされたプログラムをキルし、カウントしなかったことを示しました。これはその夜の修正で閉じられました。5回目のパスはoutliveのみを再実行し、保持されました。outlived 1。6回目のパスはsecond-clientのみを再実行し、保持されました。プロンプトは2番目のクライアントの3つのリクエストを価格設定し、予算0.005ドルを超えた後、4回目のリクエストを402で拒否し、CLI自身の次のリクエストを38ミリ秒後に拒否し、実行は何も転送されずにキルされました。trueで0.0056ドルでした。25件のレシートが検証されました。24件のレッド実行はレッドホームの台帳で合計0.0770ドル、8ターンの調査実行は、実際のCLIが呼び出すパスに対して0.0057ドルでした。それは/v1/messagesのみを呼び出しました。 tests/red/README.mdにはウォール、判定、および予算が残っているモデルがそれを超えないという発見が含まれています。
名前変更
siwithin.pyの先頭にあるNAMEを変更します。デフォルトのホーム、メッセージ、台帳ヘッダー、およびロックテキストがそれに続きます。
ライセンス
Apache License 2.0。 LICENSEを参照してください。セキュリティノートと問題の報告方法:SECURITY.md。
Copyright 2026 metahumansworld. Apache License, Version 2.0の下でライセンス供与。LICENSEを参照してください。