Skip to content

fix(BOXP-428): judge K0 on what a tool reads or runs, not on carried prose - #14596

Open
boxp wants to merge 9 commits into
mainfrom
codex-task-board/BOXP-428-td12-precision
Open

boxp wants to merge 9 commits into
mainfrom
codex-task-board/BOXP-428-td12-precision

Conversation

@boxp

@boxp boxp commented Nov 7, 2026 •

Copy link
Copy Markdown
Owner

概要 (BOXP-428 TD-12)

Owner 指摘「Langfuse の trace が [withheld: the session saw a known source or a known format] だらけ」への対応。Task Board exporter の K0(既知機密源)判定を、tool が実際に読む/実行する位置だけで行うように直し、文書中のプレースホルダで系譜保留しないようにします。既知機密源の保護(K0 表・既知形式マスク・最終ガード)は維持します。

原因(実run、秘密値なしで集計)

07:04Z 以降の Task Board 実run 25件を現行 exporter で再計算し、各runの最初の withheld trigger を特定:

最初の trigger 例 実際
拡張子なし token ファイル規則が散文の単語 token に一致 委譲 prompt heredoc「MCP の token をログに出さない」、--note "ID token の検証…"、grep -c -i token 言及のみ
kubectl + secret がコマンド全体のどこかにある kubectl logs … | grep -viE 'authorization|token|secret'(BOXP-440 のtrigger) 秘密を除外するフィルタ
environ / process.env / env 単語 os.environ.get('LAYOUT')、process.env.H、/usr/bin/env python3 単一の普通の変数
set 単語 Python の {'op':'set'}、rg '"op": "set"' コード中の文字列
Edit/Write の書込内容、Agent の prompt、description も K0 判定対象 Edit 本文に .env 書込/依頼文
K1 lineage の bearer/header WebFetch した文書の Authorization: Bearer <token> プレースホルダ

1回 trigger すると session の以後の全観測と親子へ伝播するため、BOXP-441 は1runで 335/374 観測が withheld でした。

変更

  • K0 はツール入力の path 系引数と command 系引数だけで判定(Edit/Write 内容・description・prompt は対象外)。
  • shell は「実行される部分」を抽出してから判定: 非インタプリタへの heredoc 本文、空白を含むオプション値(--note "…", -m "…")、echo/printf の文字列、grep/rg のパターンは除外。ただしその中の $(...)/backtick と bash -lc '…' の中身、インタプリタが読む heredoc(python3 - <<EOF, ssh host bash <<EOF)は判定する。
  • 環境変数: 全量ダンプ(env/printenv 単独、set/export/declare 単独や -p、os.environ、process.env、getenv()、/proc/*/environ、.items() 等)と、秘密名の単一変数を同じ行で print する場合だけ K0。
  • kubectl/oc は同じ pipeline segment に secret(s) 語がある場合だけ K0。
  • 拡張子なし token ファイルは読取位置(path 引数・非言及プログラムの被演算子・<・NAME=file)だけ。
  • K1 lineage: bearer/header/URL資格情報は値がプレースホルダ形(<token>、$TOKEN、YOUR_API_TOKEN のような数字なし大文字名、12文字以下の小文字語、xxx、password、token 等)の場合だけ以後を保留しない(どちらもその場マスクは従来どおり)。
  • 256 KiB 超のコマンドは解析せず保留(fail-closed)。

脅威モデル(diff 内 LANGFUSE_EXPORTER_THREAT_MODEL.md を更新)

  • 保証(維持): K0 表の既知機密源(.env/鍵/kubeconfig/クラウド CLI 認証コマンド/env ダンプ/kubectl secret …)を読む tool の本文と以後の系譜は保留。既知形式はその場マスク、最終ガード、spool/queue へはマスク後のみ。
  • 許容残差に追加: 変数経由で組み立てたパス(f=.e; cat ${f}nv)、空白入りパスをオプション値で渡す形、秘密名の環境変数を別変数/別行で print、プレースホルダ形の資格情報値による以後保留(値自体はその場マスク)。
  • 陽性可視性: 言及だけの tool 使用の後も、依頼・tool 入出力・次ターン・応答本文が読める。

検証

  • unit: 新規テスト3件(言及18種は K0 にならない/既知機密源24種は K0 のまま/文書プレースホルダは以後を保留しないが実値形は保留/言及の後の継続会話の本文陽性と cat .env 後の陰性)。
    • Red: 新テストを main の exporter に当てると 23 failures(陰性側の既知機密源は main でも全て保留 = 保護の弱化なし)。
    • Green: 71 tests / 1813 assertions / 0 failures(既存 68 tests 含む)。
  • 実run 25件の再計算(件数のみ): 可視(sent+masked)観測 590/2454 → 1881/2454。残る保留は実際の env ダンプ(env | grep)、gh auth token、名前付き短値(契約どおり)。
  • 性能: 26 万文字の病的入力で最大 2.7 秒(非同期 sidecar)。

🤖 Generated with Claude Code

…prose

In production most Task Board runs were withheld after a mention: a delegation prompt
saying 'ID token', grep -viE 'token|secret' after kubectl logs, os.environ.get('LAYOUT'),
'op':'set' in Python, or 'Authorization: Bearer <token>' in fetched docs. Over 25 real
runs since 07:04Z visible bodies go from 590/2454 to 1897/2454 with the same exporter
otherwise; real sources (env dump, gh auth token, cat .env ...) are still withheld.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
boxp and others added 8 commits November 7, 2026 17:52
…ge evidence

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s executed text

bash -c 'printenv' / sh -lc env were not parsed recursively because the
script had no whitespace, so the environment dump was not a K0 source.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… environment dump

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… as no command

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
An unquoted delimiter (cat <<EOF) still runs $(...) and backticks inside
the body, so $(cat .env) or $(printenv) there is judged as the commands it
runs. Quoted (<<'EOF') bodies stay literal data.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ators

Port of the Hermes observer fix: a quoted or commented <<EOF no longer hides
the lines after it from the K0 command judgement.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… command

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant