STEP 1639 — Agent connector Phase 2 3 tool 実装 test 88/88 verify defer

2026-09-01 · STEP 1634 Phase 1 pinout 実測 (4/6 pass + 2/6 fail) 受けて Phase 2 実装 · src/agent-connector/ 6 file (~500 line) · test test/step1639-agent-connector-test.ts 88/88 PASS · npm test:step1639

Overview — Phase 2 の 位置と 産物

Phase 1 (STEP 1634) recommendation: 「detect / pinout / invoke = 実装可、 verify tool は defer 妥当 (spec 化できない、 Phase 2.5 で 別 arc 起動 提案)、 pin 3+4 は caller 責任 で config 事前準備 (connector が config 変換責任 を 負わない decoupling)」

Phase 2 done: 上記 recommendation そのまま 3 tool 実装、 verify defer。 副作用は invoke({ mode: 'execute' }) のみ (subprocess spawn)、 mode は required で default なし = 呼出側が 毎回 明示的に 選択 する 強制 (STEP 1345 SafetyGate + STEP 1625 陰性対照 と 同族の safety discipline)。

1. Module 構成

File役割Side effect
src/agent-connector/types.tsAgentName / Pin / PinoutResult / DetectResult / InvokeOptions / InvokeResult 型定義 (全 readonly)なし
src/agent-connector/pins-data.tsPhase 1 (STEP 1634) の 6 pin data を PINS_PHASE1 const で encode + PHASE1_HONEST_SCOPEなし (static data)
src/agent-connector/detect.tsdetect(agent) + detectAll()execFile('claude', ['--version']) で CLI 検出、 semver-ish regex で version 抽出、 where/which で CLI path 抽出subprocess spawn (read-only: --version + which 呼出のみ)
src/agent-connector/pinout.tspinout() + pinById(id) + pinsByVerdict(v) + pinsWithInformationLoss() — pins-data.ts を programmatic API 化なし (pure function)
src/agent-connector/invoke.tsinvoke(agent, opts) — dryRun mode で command argv 返却、 execute mode で subprocess spawn + timeout + stdout/stderr/exitCode 返却subprocess spawn (execute mode のみ、 dryRun mode は なし)
src/agent-connector/index.tsPublic re-exportなし

2. API examples

2.1 detect

import { detect, detectAll } from './agent-connector/index.js';

const d = await detect('claude');
// {
//   agent: 'claude',
//   isAvailable: true,
//   cliPath: 'C:\\Users\\user\\.local\\bin\\claude.exe',
//   version: '2.1.251',
//   rawVersionOutput: '2.1.251 (Claude Code)',
//   detectedAt: '2026-09-01T00:47:...Z'
// }

const all = await detectAll();
// { claude: {...isAvailable:true}, codex: {...isAvailable:false, error:'...'} }

2.2 pinout

import { pinout, pinById, pinsByVerdict } from './agent-connector/index.js';

const p = pinout();
// {
//   pins: [ ...6 pin ],
//   summary: { total: 6, pass: 3, partial: 1, fail: 2, falsificationRate: 0.333 },
//   generatedAt: '...',
//   phase1Ref: 'https://rei-aios.pages.dev/tools/step-1634-agent-pinout-phase1/',
//   honestScope: [ ...6 items ]
// }

const mcpPin = pinById('mcp_config');
// { id: 'mcp_config', verdict: 'fail', informationLoss: { direction: 'bidirectional', ... } }

const failPins = pinsByVerdict('fail'); // [mcp_config, permission]

2.3 invoke (dryRun / execute)

import { invoke } from './agent-connector/index.js';

// dryRun mode = argv を 返すのみ、 spawn しない
const dry = await invoke('claude', {
  mode: 'dryRun',
  prompt: 'summarize this',
  outputFormat: 'stream-json',
  extraArgs: ['--verbose'],
});
// {
//   agent: 'claude', mode: 'dryRun',
//   command: ['claude', '-p', '--output-format', 'stream-json', '--verbose', 'summarize this']
// }

// execute mode = 実 CLI spawn (billable + side-effect)
const exec = await invoke('claude', {
  mode: 'execute',       // ★ REQUIRED、 default なし
  prompt: 'ping',
  timeoutMs: 30_000,
});
// { agent, mode: 'execute', command, stdout, stderr, exitCode, elapsedMs, timedOut }

3. Safety discipline

4. Test 結果 88/88 PASS

Sectiontest 内容件数
1. detectclaude available + codex not-installed + detectAll 挙動10 assert
2. pinout6 pin 返却 + summary (pass 3 / partial 1 / fail 2 / falsification rate 2/6)14 assert
3. pinout helperspinById / pinsByVerdict / pinsWithInformationLoss / unknown 挙動10 assert
4. invoke dryRunargv 構築正確、 claude -p / codex exec / --output-format / extraArgs passthrough13 assert
5. invoke executeopt-in mode の skip 動作 (STEP1639_RUN_EXECUTE=1 で 実行)0 assert (skip 状態確認のみ)
6. error handlingcodex execute → ENOENT (graceful error return、 throw しない)3 assert
7. pin data invariants6 pin 全て refutation ≥3 + source valid + fail pin 全て informationLoss あり38 assert

Total: 88 assert PASS / 0 fail。 実行: npm run test:step1639

5. 実測 detect 出力 (本 PC)

=== Section 1: detect ===
  claude: v2.1.251 at C:\Users\user\.local\bin\claude.exe
  codex: not installed on this PC (expected on Windows dev box)

Phase 1 環境非対称性 (Codex CLI 未 install) を connector が 正しく handle: detect('codex') は isAvailable=false + error message + throw なし、 invoke('codex', {mode:'execute'}) は ENOENT を error field に 収める。

6. Phase 1 pin data の Phase 2 反映

Phase 2 では Phase 1 の pin 4 field を そのまま encode:

pinsWithInformationLoss() で 上記 2 pin を 一覧取得可能。 caller は これを 見て 「直接 pass-through しない、 provider 別 config を 事前準備」 の 判断が できる。

7. Verify tool (Phase 2.5) defer 理由

Phase 1 で verify tool の spec 化不能 と 判明:

Phase 2.5 別 arc で defer、 前提条件: (a) 両 CLI の exit code semantics 実測 (b) sandbox / permission 意味論 の cross-provider 共通 subset 定義 (c) 「verify pass」 の 定義自体を rei stack の どの verdict vocabulary (TRUE / NEITHER / N/A) に 落とすかの 判断。

8. Honest scope (Phase 2 で 意図的に やっていないこと)

9. 次 STEP candidate

  1. Phase 2.5 GO 判断 (藤本さん): verify tool spec 化 の 前提条件 (exit code semantics 実測 + cross-provider verdict vocabulary 定義) を 別 arc で 詰めるか。
  2. rei-aios MCP register: src/mcp/agent-connector-mcp.ts で detect / pinout tool を expose (invoke は SafetyGate 越し ラッピング 必要、 or defer)。
  3. Codex CLI install (藤本さん judgment): 本 PC に codex install で Phase 2 execute mode の 双方向 実測可、 Phase 1 反証条件 tightening も 進む。
  4. Phase 3 Archify IR emit spike: agent-connector と 独立進行可、 rei-aios connector-inventory / comparator JSON から Archify IR 直接生成 の PoC (Phase 2 完了 の 後 前提なし)。