diff --git a/docs/doeff-2026-07-14-agent-first-investment-architecture-plan.md b/docs/doeff-2026-07-14-agent-first-investment-architecture-plan.md index 7104cb41..7ccdb550 100644 --- a/docs/doeff-2026-07-14-agent-first-investment-architecture-plan.md +++ b/docs/doeff-2026-07-14-agent-first-investment-architecture-plan.md @@ -34,12 +34,12 @@ | # | 事実 / Gap | 根拠 | |---|---|---| | F-1 | ~~statement 位置素通し~~ **解消(T-A1、2026-07-14)**: 4 emit サイトに guard 実装、HY-001 green、1094 テスト無回帰 | macros.hy(_wrap-statement-guard) | -| F-2 | pyproject testpaths に docs/adr 不在 → defadr 15 本は既定 pytest で不可視。**flip は E1 まで保留**(DOMAIN-001 の意図的 red のため) | pyproject.toml:80-86 | +| F-2 | ~~pyproject testpaths に docs/adr 不在~~ **解消(T-B1、2026-07-14 PR #521)**: root testpaths に docs/adr を追加(flip 実施)。defadr 収集自己検査と strict 検査が既定 pytest で稼働し、DOMAIN-001 は xfail(strict) 相当で E1 待ちを表明 | pyproject.toml / tests/test_adr_wiring_gate.py | | F-3 | ~~oracle 起動経路ゼロ~~ **解消(T-B3、2026-07-14)**: dev ビルド常時有効 + hard-fail pytest 常駐(実測 True) | Makefile / tests/test_vm_invariant_checks_enabled.py | -| F-4 | ~~semgrep 手動のみ~~ **ゲート稼働(T-B2、2026-07-14)**: 既定 pytest で fail-closed 実行 + baseline 46 等値 ratchet。残: 違反解消・fixture 化・dev 依存化 | tests/test_semgrep_gate.py / docs/adr/semgrep-baseline.json | +| F-4 | ~~semgrep 手動のみ~~ **ゲート稼働 + 違反解消済み(T-B2、2026-07-14 PR #523)**: violations 0、baseline 0。残: 個別ルールの defsemgrep fixture 化・semgrep の dev 依存化 | tests/test_semgrep_gate.py / docs/adr/semgrep-baseline.json | | F-5 | deftest は最大 Python 消費者(mediagen)で使用 0 / 260。**:env 経路は doeff 側では機能する**と実証済み(HY-002 roundtrip green)— 残ギャップは消費側配線と語彙拡張(D2) | mediagen conftest / docs/adr/conftest.py | | Gap-1 | ~~docs/adr に conftest.py が無い~~ **解消済み(Stage 0)**: `docs/adr/conftest.py` を新設(:env を reader で反映・エラー再送出。ADR-DOE-HY-002 R3 の参照実装) | 2026-07-14 実装 | -| Gap-2 | 新規 enforcement の実測(2026-07-14): **red 4**(HY-001 guard = DID NOT RAISE / ENFORCE-001 testpaths / ENFORCE-001 oracle / DOMAIN-001 defdomain)+ **green 6**(adr_contract ×5 + **HY-002 :env roundtrip green** — deftest→fixture→Ask の受け渡しは doeff 側で機能しており、mediagen の NotImplementedError は消費側配線の問題と確定)。収集は docs/adr 全 15 ファイル 39 テスト・エラーゼロ。テストパス配線(T-B1)までは `uv run pytest docs/adr` の明示実行でのみ見える | `uv run pytest docs/adr -q` 2026-07-14 | +| Gap-2 | T-A1/B3 は green、root testpaths の flip 済みで ADR 検査と wiring 自己検査が既定ゲートに常駐。残る designed-red は DOMAIN-001 の xfail(strict) 相当 1 件のみ(E1 未実装中は xfail、defdomain 実装で緑化したら fail して記帳を強制) | `uv run pytest -q` 2026-07-14 / tests/test_adr_wiring_gate.py | | Gap-3 | ~~CORE-002 enforcement blocked~~ **解消(T-C1、2026-07-14)**: 現行 main に per-effect 捕捉は存在しないと確定。回帰ガード deftest green。下流 TRD-002 は旧版への計測 — pin 更新後の再検証を下流へ差し戻し(issue に追記済み) | C1 spike / CORE-002 enforcement | | Gap-4 | `doeff-main-with-handler-stack`(489MB 姉妹 checkout)は 2026-07-11 に main へ完全マージ済みの残骸と判明 — 計画対象外、削除は maintainer 判断 | git merge-base 検証 2026-07-14 | @@ -55,7 +55,7 @@ ▼ ▼ ▼ ▼ [A: bind guard] [C: trace(再スコープ)] [D: deftest 契約] [E: defdomain/SEDA/適合] A1 ✅ 実装済み C1 ✅ 税は不存在 D1 ✅ 大半完了 E1 defdomain(設計=frontier) - A2 下流洗い出し C2 lookup_line 一行 D2 シム語彙吸収 E2 SEDA CLI/MCP + A2 下流洗い出し C2 ✅ 行解決遅延化 D2 シム語彙吸収 E2 SEDA CLI/MCP (A3 裁定済み) C3 裁定(優先度低) D3 mediagen 移行 E3 適合検査 (下流) (B 完了が前提: R4) │ @@ -67,7 +67,7 @@ 1. `uv run pytest`(既定 testpaths)が docs/adr の全 defadr enforcement を収集・実行する(ENFORCE-001 law)。 2. 本計画で追加した red enforcement 4 本が green(HY-001 guard / ENFORCE-001 testpaths+oracle / DOMAIN-001 defdomain)。 -3. ~~ADR-DOE-CORE-002 に実測に基づく enforcement を追加~~ **達成(2026-07-14)**: 回帰ガード green。残: T-C2 の一行修正と下流 TRD-002 の再検証。 +3. ~~ADR-DOE-CORE-002 に実測に基づく enforcement を追加~~ **達成(2026-07-14)**: 回帰ガード green、T-C2 は PR #520 で完了。残: 下流 TRD-002 の再検証。 4. ADR-DOE-HY-002 の :env roundtrip が green、かつ mediagen の run_test.py が deftest 語彙で置換可能なことを下流で実証。 5. 全 5 ADR の :status が "accepted" に昇格(enforcement green が条件)。 6. semgrep 229 ルール+VM oracle が「バイナリ/feature 不在 = hard fail」で既定ゲートに常駐。 @@ -76,15 +76,15 @@ | ID | 出典 ADR | 作業 | red 反例(現状) | green 機構 | 状態 | |---|---|---|---|---|---| -| T-B1 | ENFORCE-001 R2 | testpaths に docs/adr 追加 + defadr 収集自己検査を doeff-adr に実装 | test-…-docs-adr-in-default-testpaths が red | 同 deftest green + 自己検査テスト | 自己検査=codex 委譲待ち。**flip は E1 まで保留**(DOMAIN-001 の意図的 red が既定ゲートに入るため。代替: xfail(strict) マーキングの裁定) | -| T-B2 | ENFORCE-001 R3 | .semgrep.yaml を既定 pytest ゲートで実行 | 手動 make のみ・skip 可能 | **ゲート稼働(2026-07-14)**: tests/test_semgrep_gate.py が 229 ルールを fail-closed で実行。初回実行で**既存違反 46 件検出** → baseline 等値 ratchet(docs/adr/semgrep-baseline.json に内訳)。残: 46 件解消バッチ(codex — no-future-annotations 24 は前方参照リスクあり)、defsemgrep fixture 化、semgrep の dev 依存化 | ゲート稼働・残作業 codex | +| T-B1 | ENFORCE-001 R2 | testpaths に docs/adr 追加 + defadr 収集自己検査を doeff-adr に実装 | test-…-docs-adr-in-default-testpaths が red | root testpaths の flip 実施。`pytest_collection_finish` で全 defadr 候補と session.items を照合する自己検査(既定 warn / strict で非ゼロ終了)と `doeff-adr verify-wiring` CLI を実装し、ADR-DOE-ADR-001 に記録。DOMAIN-001 は xfail(strict) 相当で既定ゲートを green 維持 | **完了(2026-07-14 PR #521)** | +| T-B2 | ENFORCE-001 R3 | .semgrep.yaml を既定 pytest ゲートで実行 | 手動 make のみ・skip 可能 | tests/test_semgrep_gate.py が 229 ルールを fail-closed で実行。PR #523 で違反 46→0、docs/adr/semgrep-baseline.json を baseline 0 に更新 | ゲート稼働 + 違反解消済み(PR #523、baseline 0)。残: 個別ルールの defsemgrep fixture 化、semgrep の dev 依存化 | | T-B3 | ENFORCE-001 R4 | dev ビルド invariant-checks 常時有効 + oracle の pytest 起動 | test-…-vm-oracle-wired が red | **完了(2026-07-14)**: doeff-vm に feature 転送、make sync に --features、PyO3 で invariant_checks_enabled() 公開(doeff_vm/__init__.py 再輸出込み)、tests/test_vm_invariant_checks_enabled.py が hard-fail 常駐(実測 True)。oracle は全 VM 実行で常時演習される。make test-vm-invariants 追加 | **完了** | | T-B4 | ENFORCE-001 R5 | enforcement 台帳 ratchet メタテスト | 台帳の黙減が検出されない | **完了(2026-07-14)**: docs/adr/enforcement-ledger.json(defadr 15 / semgrep 229 / deftest 8 / defsemgrep 19 / law 49)+ tests/test_enforcement_ledger.py 等値 ratchet green | **完了** | | T-A1 | HY-001 R1-R4 | statement 位置 runtime guard 実装(修正プロンプト形式メッセージ) | test-…-bare-statement-program-raises が red | **完了(2026-07-14)**: macros.hy に _guard-statement-value / _wrap-statement-guard を実装、defk(_build-fn-with-contracts)/do!/defp(_build-defp)/deftest の4 emit サイトに適用。HY-001 green、既定スイート 1094 passed 無回帰 | **完了** | | T-A2 | HY-001 R5 | 下流(ema/ACP/mediagen/reactor 系)で guard 有効化 → 休眠 discard 全数洗い出し・修正 | 休眠 bare form 数 未知 | 各リポジトリのスイート green + 洗い出し報告。**⚠️ Hy バイトコード罠**: マクロ変更はソース mtime に映らないため、掃引は必ず `PYTHONPYCACHEPREFIX=` か touch で全再コンパイルして走らせること(doeff 自身の検証でこの罠を実踏) | 未着手(codex、リポジトリ毎) | | T-A4 | HY-001 付随 | CPS の鋭い縁(ネスト try 内 `<-`、closure 内 bind)の解消 or 明示エラー化 | ACP ADR0056 facts の回避イディオム | マクロ改善 or 展開時エラー + テスト | 未着手 | | T-C1 | CORE-002 R3 | profiling spike: 現行 main の捕捉サイト・コスト内訳の確定、ADR facts 更新 | Gap-3(サイト未特定) | **完了(2026-07-14)**: 現行 main に per-effect 捕捉は存在しない(opt-in effect + エラー経路のみ、linecache は描画時限定。100k Ask 実測で linecache/stack-walk/整形 = 0 呼び出し)。ADR facts 更新済み + 回帰ガード deftest green。**下流 3.7x は旧版への計測 — pin 更新後の再検証を下流 issue に**。副産物: @do の generator 再構築グルーが Python 側時間の ~39%(別 issue 種、本 ADR 対象外) | **完了** | -| T-C2 | CORE-002 R2(再スコープ) | run.py の _merge_python_frames に lookup_line=False(例外経路の字義ギャップ解消、一行) | 例外1回につき linecache 先読み | 一行修正 + 既存テスト green | 未着手(codex、小) | +| T-C2 | CORE-002 R2(再スコープ) | run.py の traceback 行テキスト解決を `StackSummary.extract(walk_tb(tb), lookup_lines=False)` で遅延化 | 例外1回につき linecache 先読み | `extract_tb` に存在しない lookup_line 引数を使わず等価代替で実装 + 既存テスト green | **完了(2026-07-14 PR #520)** | | T-C3 | CORE-002 R3(再スコープ) | GetTraceback/GetExecutionContext の VM 組み込み vs observability handler 化 — perf 根拠は消滅、可観測性設計論のみで裁定 | — | frontier+人間の裁定 | 裁定待ち(優先度低下) | | T-D1 | HY-002 R2/R3 | deftest params 忠実受け渡し + docs/adr conftest fixture(:env 反映の参照実装) | — | :env roundtrip **green 済み(Stage 0 実測)**。残作業 = fixture 契約の文書化 + 未対応 params の hard fail | 大半完了 | | T-D2 | HY-002 R1 | mediagen run_test.py の要求(部分スタック+差し替え)を deftest 語彙へ吸収 | シムの存在自体 | 語彙追加 + 等価性デモテスト | T-D1 後 | @@ -96,9 +96,9 @@ ## 段階計画 - **Stage 0(完了 / 本セッション)**: 価値評価・理論文書(22 番)・本計画・5 defadr(red enforcement 4 本 + blocked 1 件)作成。A3/B3 裁定記録。 -- **Stage 1(即時並行、codex 委譲可)**: T-B1 → T-B2 → T-B4、T-C1、T-D1。B1 完了時点で red 4 本が既定ゲートに入るため、**B1 の着地は T-A1/T-B3 の green 化と同一変更セットにするか、直前に順序付ける**(既定ゲートを恒常 red にしない)。 -- **Stage 2**: T-A1(frontier 設計 → codex 実装)→ T-A2(下流展開、リポジトリ毎に codex)。 -- **Stage 3**: T-D2 → T-D3(下流 PR)。T-C2(C1 の結果を受けて)。 +- **Stage 1(着地済み)**: T-B1/T-B4/T-C1 完了、T-D1 大半完了、T-B2 はゲート稼働 + 違反解消済み。残: T-B2 の defsemgrep fixture 化・semgrep の dev 依存化。 +- **Stage 2**: T-A1 完了。残: T-A2(下流展開、リポジトリ毎に codex)。 +- **Stage 3**: T-C2 完了。残: T-D2 → T-D3(下流 PR)。 - **Stage 4(設計セッション)**: T-E1 defdomain 設計 + T-C3 裁定を同一 frontier セッションで実施 → T-E2/T-E3 実装。 - **Stage 5(本計画外・次期計画)**: class 2 新プリミティブ(rate-limit token-bucket scheduler → batching/dedup/hedging)。前提 = 本計画の Gate 1-6。 @@ -151,12 +151,31 @@ src/lib.rs・doeff_vm/__init__.py(oracle flag)、Makefile(sync features / test-v tests/test_vm_invariant_checks_enabled.py、tests/test_enforcement_ledger.py、tests/test_semgrep_gate.py、 docs/adr/enforcement-ledger.json、docs/adr/semgrep-baseline.json、docs/adr/conftest.py、defadr 5本、本計画。 +### 追記(同日後半: Stage 0-2 全着地) + +- **PR #520 merged / T-C2 完了**: run.py の traceback 行テキスト解決を + `StackSummary.extract(walk_tb(tb), lookup_lines=False)` で遅延化(`extract_tb` に lookup_line 引数は + 存在しないため等価代替で実装)。 +- **PR #522 merged / Stage 0-2 着地**: T-A1 statement bind guard、T-B3+T-B4 の VM + invariant-checks dev 常時有効 + oracle、enforcement 台帳 ratchet、semgrep ゲート、実行可能 ADR 5本、 + docs/adr/conftest.py、docs/22-capability-classes.md が着地。 +- **PR #521 merged / T-B1 完了**: root testpaths を docs/adr へ flip。defadr 収集自己検査(既定 warn / + strict で非ゼロ終了)と `doeff-adr verify-wiring` CLI が稼働し、ADR-DOE-ADR-001 に記録済み。 + DOMAIN-001 は xfail(strict) 相当 1 件として既定ゲートを green に維持。GitHub CI には配線せず、 + tests/test_adr_wiring_gate.py が pytest 正典ゲート内で strict 検査を常時実行。 +- **PR #523 merged / T-B2 違反解消**: semgrep 違反 46→0、baseline 0。datetime.now 4件を GetTime + 効果へ、sleep 2件を決定的同期へ置換し、no-future-annotations 24件、公開 API の Any 10件、 + traceback の silent except を解消。 +- **現 main の既定 suite**: `uv run pytest -q` は 1149 passed / 86 skipped / 1 xfailed / + failed 0。xfail は E1 待ちを表明する DOMAIN-001 のみ。 +- **最終記帳値**: enforcement 台帳は defadr_files 16 / adr_defsemgrep_enforcements 20 / + adr_laws 51、semgrep baseline は 0。 + ## Immediate next action(/goal 実行者へ) -1. Stage 1 の G1 バッチ(T-B1/T-B2/T-B4/T-C1/T-D1)を並行着手。ただし **T-B1 の着地順序に注意**: - docs/adr を testpaths に入れると red 4 本が既定ゲートに入るため、T-A1/T-B3 の green 化を同一 - 変更セットに含めるか、自己検査のみ先行させ testpaths 反映を最後に置く。 -2. 各変更は doeff の TDD+Semgrep 3 フェーズ手順(CLAUDE.md)に従い、着地は orch issue/run 経由。 -3. T-C1 の結果で ADR-DOE-CORE-002 の facts と enforcement を必ず更新する(blocked 解消)。 -4. 検証: `uv run pytest docs/adr -q` と `uv run pytest --collect-only -q docs/adr` を各ステップで実行し、 - red→green の遷移を PR 本文の Verification 表(issue 項目 1:1 対応)に記録する。 +1. frontier+人間の設計セッションで T-E1 defdomain 設計、T-C3 裁定、T-A4、T-D2 を扱う。 +2. T-A2 の下流 sweep を ema / ACP / mediagen / reactor 系で実施する(リポジトリ毎に codex)。 +3. 下流の doeff pin を更新し、ema ISSUE-TRD-002 を再計測する。 +4. T-B2 の残作業として、個別ルールの defsemgrep fixture 化と semgrep の dev 依存化を行う。 +5. T-D2 の設計後に T-D3(mediagen のパイロット deftest 移行)を実施する。 +6. T-E1 の設計後に T-E2(SEDA CLI/MCP)と T-E3(適合検査 3 種)を実装する。