note 記事 ⑥ で「6 本のうち 2 本、まだうまく動きません」と書いた 2 本の pin を、converter と mapper で fail の外に出す進化。全 pass ではなく、0 fail。
0 fail 達成。 ただし all-pass ではありません。pin 4 は fail から partial に進化 (pass ではない) — 意味論根本違いは本 mapper では解消不能で、そこは正直に「partial」と表示します。
| # | Pin ID | v2 | v2.5 | 変化 | |
|---|---|---|---|---|---|
| 1 | persistent_instruction | pass | → | pass | 変更なし |
| 2 | skill_storage | pass | → | pass | 変更なし |
| 3 | mcp_config | fail | → | pass | fail → pass (mcp-config-converter で JSON↔TOML 双方向変換、common shape 6 field は lossless) |
| 4 | permission | fail | → | partial | fail → partial (permission-mapper で保守的 intersection、意味論根本違いは解消不能で partial 止まり) |
| 5 | noninteractive_exec | pass | → | pass | 変更なし |
| 6 | exit_code | partial | → | partial | 変更なし (両側 exit code semantics 未公式化) |
Claude Code の ./.mcp.json と Codex CLI の ~/.codex/config.toml の間で、MCP config を双方向変換します。scope は common shape 6 field (command / args / env / cwd / type / required)。
{
"mcpServers": {
"brave": {
"command": "npx",
"args": ["-y", "@mcp/brave"],
"env": { "BRAVE_API_KEY": "x" },
"type": "stdio"
}
}
}
[mcp_servers.brave]
command = "npx"
args = ["-y", "@mcp/brave"]
env = { BRAVE_API_KEY = "x" }
brave.type = "stdio" — Claude-only field で Codex 側に相当なし。droppedFields array で明示 record + warning 出力。逆方向 (TOML → JSON) では Codex-only の required = true が同じく dropped されます。common shape 6 field 内は lossless、それ以外は明示 drop — この設計で pin 3 = pass。
Claude Code の fine-grained permissions.allow[] (Bash(git *) 型) と Codex CLI の --sandbox 3-tier + approval_policy の間で、両平台で通る交集合に狭める保守的 mapper。lossless roundtrip 保証なし、pass ではなく partial。
| Claude allow[] pattern | → | Codex sandbox_mode |
|---|---|---|
全 Read(...) / Grep / Glob / LS / 安全 Bash (ls/cat/git status) | → | read-only |
Write(...), Edit(...), Bash(git commit *) 等の変更系含む | → | workspace-write |
Bash(sudo *), Bash(rm -rf *), Bash(*) 等の危険 pattern | → | danger-full-access + warning |
mode: 'bypassPermissions' | → | danger-full-access |
mode: 'plan' | → | read-only |
| Codex sandbox_mode | → | Claude allow[] (safe pattern set) |
|---|---|---|
read-only | → | ['Read(//**)', 'Grep', 'Glob', 'LS'] + mode: 'plan' |
workspace-write | → | Read + Write + Edit + Bash(git status/diff/commit/log/show/add) + 安全 Bash verb |
danger-full-access | → | allow: [] + mode: 'bypassPermissions' + warning |
claudeCodexRoundtripLoss() で情報損失量を計測できます。意味論根本違いは pass 昇格の障壁 — そこは正直に partial 止まり。
claudeCodexRoundtripLoss() は差分を返しますが、その差分自体は本 mapper では埋められません。caller が事前に確認して受容するための計器です。PINS_PHASE1 / pinout() / invoke() API は破壊せず、pin 3+4 の verdict 値だけが変わりました。既存の test も verdict 期待値の更新だけで pass するように変更済み (step1639/1644/1675 の 3 test)。$ npx tsx test/step1690-agent-connector-v2-5-test.ts === STEP 1690 agent-connector v2.5 test === §1 MODULE_VERSION §2 verdict summary (target: 4/2/0) §3 pin verdicts §4 PHASE2_5_CHANGES §5 PHASE2_5_HONEST_SCOPE §6 MCP config converter (JSON → TOML) §7 MCP config converter (TOML → JSON) §8 MCP config bidirectional roundtrip (common shape) §9 MCP config out-of-scope TOML rejected §10 permission mapper (Claude → Codex) §11 permission mapper (Codex → Claude) §12 permission roundtrip is conservative (lossy expected) §13 6 pin schema regression §14 pin 3+4 details reference v2.5 modules §15 MODULE_INFO.publicApi lists v2.5 exports 結果: 76 passed, 0 failed $ regression: step1639-agent-connector-test: 86 passed, 0 failed step1644-agent-connector-mcp-test: 52 passed, 0 failed step1675-agent-connector-v2-test: 19 passed, 0 failed