Continue preserved P08 implementation with Opus direction and local checker evidence

This commit is contained in:
Takeshi
2026-10-14 03:01:25 +09:00
parent 4c00c72ec3
commit 75670dffe1
5 changed files with 154 additions and 4 deletions
@@ -0,0 +1,7 @@
{
"action": "request-repair",
"task_id": "P08-03",
"reason": "判断: 既存worktreeでrequest-repairを1回だけ継続し、このCodex実行に限り観測時間を1800秒にする。新実装・作業の破棄・Godot実行・全体回帰は行わない。\n\n【1800秒が必要な理由】前回のa8660e56は、成果を出しかけた段階で900秒のexit124により打ち切られた。読取り確認の結果、残作業はドキュメントと起動経路だけではない(下記2)。900秒のまま繰り返すと、同じ打ち切りがまた起きる可能性が高い。1800秒はこの継続1回だけに使う。他の役割、他task、検証timeout、権限、課金、config、dB固定契約は変えない。Rootは既存の署名契約を壊さないexact-task timeout adapterを使う。\n\n【確認した具体的な不具合(読取り確認済み)】\n1. tools/run_p08_normal_placement.py:84 は input_mode=native_os でも r.execute_phase(tools/run_all_tests.py:143)を呼んでいる。この関数は import(157行)と script(181行)の両方で argv に --headless を固定で付ける。そのため実windowが作られず、通常のOS入力が届かない。\n2. tests/fixtures/p08-03/placement.gd:22-37 の os_request は `<role>-request-NNNN.json` を書き、Rootが `-ack.json`(target_pid, input_receipt, screen_before, screen_after)を返すまで60秒待つ。ところがdriverにはこのrequestを受けて実OS入力を行い、ackを書くRoot側の応答処理が無い。execute_phaseは呼び出し中ブロックするので、応答処理は並行で動かす必要がある。\n3. tools/strict_test_markers.py:81 と tools/regression/review_protocol.py:38 は --headless を含むcommand形状を期待している。\n\n【worker指示】\n- 再実装禁止。残っている12ファイル(/private/tmp/p08-03-preserved-partial-r01-manifest.json に記載)とtracked差分をそのまま土台にし、差分は最小にする。\n- Godot、ネイティブ、全体回帰は実行しない。純Pythonの構文確認と意味のある checker/driver 試験だけを行う。\n- 編集してよいのは allowed_paths の中だけ。tools/run_all_tests.py、Runtime、strict_test_markers.py、review_protocol.py は編集しない。\n(a) native_os 経路の起動: --headless を除いた正確な raw argv、PID、lifecycle を保存する。既存の profile guard、owned_outer cleanup、audio/diagnostic/owner gate、schema、source/default-player保護は一つも弱めない。handler経路は既存の execute_phase のまま残す。\n - 既存guardを再利用できない部分がある場合は、迂回や判定緩和はしない。失敗した根拠と、範囲外への最小提案を返す。\n - 既存guardの例: marker command形状、review_protocol。\n(b) Root OS応答処理を driver 内に追加する。\n - request を監視し、実OSのクリック/wheelと前後のスクリーンショットを行い、ack を書く。ack には target_pid と input_receipt を含める。\n - viewport座標から画面座標への変換根拠を raw で残す。対象は window位置と HiDPI 倍率。\n - 応答処理の単体試験は mock だけで行う。\n(c) 上記と同じ変更の中で、UI fixture が非headless起動で動くか確認する。問題があれば tests/fixtures/p08-03 の中だけで直す。\n(d) 次を作成または更新する。\n - docs/plans/original-completion-2026-10-02/execution/p08-03 配下の CONDITION_MATRIX.md と implementation.json\n - 最終的に実行したローカル source/input の正確なSHA\n - 実際に実行した試験だけ。以前の版のPASSは流用しない。\n(e) 最後に checker を含む全ローカル試験と git diff --check を再実行する。\n - 5条件それぞれを正直な状態で記載する。\n - Root側の native/OS/full回帰/独立Opusレビュー/統合が保留であることを明記する。\n - Windowsは global 未達のまま。\n - 原30/88と5条件は変えない。\n - その上で genuine submitted として提出する。",
"codex_model": "gpt-6-astra",
"codex_model_reason": "gpt-6-astraを選ぶ。既定のgpt-6.1-solではなくこちらにする理由は、残りが単純なドキュメント作業ではないため。\n1. execute_phase には --headless が固定で入っており、編集できない。その上で、既存の guard/cleanup/audio/marker 契約を弱めずに、非headless の起動と raw argv の証明を両立させる必要がある。\n2. ブロックする execute_phase と並行して OS 応答処理を動かし、PID 照合と HiDPI 座標変換を行う必要がある。これを Godot を使わず mock だけで正しく検証しなければならない。\n3. strict marker と review_protocol が headless 形状を前提にしているため、範囲外の不具合かどうかを正しく判断する必要がある。\n\n前回のastra実行の失敗原因は品質ではなく900秒の打ち切りだった。今回は1800秒を1回だけ使い、範囲を最小にすることで時間超過のリスクを抑える。"
}
@@ -0,0 +1,7 @@
{
"action": "run",
"task_id": "P08-03",
"reason": "現在repair_ready、修正1回目のrequest-repairは送付済み、同じworktreeに12ファイルすべて残っているので、続けて run を実行します。これは前回の「1800秒で継続」判断と同じ指示を確定するものです。timeout 1800 はオーナーが承認済みです。対象は exact-task timeout adapter が当てる P08-03 / codex / implementer の1プロセスだけです。固定config、契約、DB、権限、予算、修正上限(null)、受入分母(30/88)、5条件は一切変えません。ここで最小限の継続だけ行い、それ以上のrunや範囲拡大は含みません。\n\nworkerへの具体的な指示:\n(0) 最初に、同じworktreeにある既存の12ファイル(main.gd、world_preview.gd、test_p08_normal_placement_ops.gd/.uid、tests/fixtures/p08-03/**、run/check/test の3つのtool、suite-policy.json、completion_marker_contracts.json、docs/.../p08-03/**)を読みます。消さずに続きから実装し、作り直しはしません。\n\n(1) 再利用元 docs/plans/original-completion-2026-10-02/execution/p08-02-os-r01/collect_native_os.py と passive_os_migration_recorder.gd は allowed_paths の外なので、読むだけにして編集しません。その中の次のパターンを、tools/run_p08_normal_placement.py または docs/.../p08-03/ 配下に置く P08-03 用の独立collectorで再利用します。\n- run_all_tests.py の module/require/source_refs/inventory/default_player/profile_path/private_project/fresh_environment を読み込む\n- 開始時に owned_outer の live_engines を確認し、外部エンジンが無いことを前提にする\n- 対象HEADが固定済みで、worktreeがクリーンであることを確認する\n- uuidで新しいprivate profileを作り、正式保存fixtureはSHAを照合しながらコピーする\n- disk admission を確認する\n- project.godot は一時的に private 用へ差し替え、finally で必ず元に戻す\n- 実際の Godot argv(非headless、--path stage --script recorder)をそのまま記録し、actual_pid、process-started、engine log、exit0、ERROR走査を残す\n- 子プロセスは owned_outer.finish_captured で片付ける\n- 終了後にソース・stage・default player が変わっていないことを確認し、started/ended.json に controller と recorder の SHA を記録する\nP08-02 固有のハードコード(R/A/OUT のパス、candidate SHA、migration 用の内容)は P08-03 の値に置き換え、引数で受け取る形にします。全く新しいOS基盤は作りません。\n\n(2) handler経路の既存strict headless command契約はそのまま残します。OS経路にheadless専用gateを当てて偽装することは禁止です。\n\n(3) RootによるOS入力は既存CUAツールで行います。collectorは request.json(対象ウィンドウ、操作手順、期待する世界セル、変換後の画面座標)を書き出し、Rootの操作を待つ状態を明示します。Rootが返す receipt/ack.json は読むだけで受け取るブリッジにします。passive recorder は観測するだけで、product handler を呼びません。Accessibility設定の変更や別権限による迂回は追加しません。\n\n(4) 次のすべてを1つのまとまりとして完成させます。\n- 通常パレットからの撤去モード(選択・確認・取消・結果表示)。実行は SimulationRuntime.submit_command demolish_facility を使う\n- 支持・接続、不正位置の理由一致、撤去後の再建築、移動モード+Ctrlなしwheelと通常wheelズームでの世界セル同一性、別PIDでの再開\n- 上記の strict marker、fixture/UID、checker の --verify-only、checker の正例と意味的破損の負例\n- CONDITION_MATRIX.md と implementation.json(最終の実SHA、各条件の正直な現状)\n\n(5) worker は実Godot、OS操作、ネイティブ実行、full regression を行いません。mockだけを使い、Python構文チェックと checker テストだけを実行して、実行したものだけ記録します。\n\n(6) 判定に必要な範囲外修正があれば、失敗の証拠を付けた最小提案として返します。成果・docs・局所試験は捨てず、Root収集・ネイティブ・OS・full regression・Opusレビュー・統合が未完了であることを明記した上で、本当の submitted を返します。",
"codex_model": "gpt-6-astra",
"codex_model_reason": "gpt-6-astra を選びます。理由は4つです。\n- 範囲が広い。UIの撤去モード追加、5条件の fixture、checker の意味的な負例、OS collector の移植を、1つのまとまりとして整合させる必要がある\n- 移植元の P08-02 collector は1ファイルに詰め込んだ密なコードで、ガードや後処理を順序も含めて同等に保つ必要がある。省略や偽装が起きやすい\n- headless契約とOS経路を分けたまま、read-only の request/ack ブリッジを設計する必要がある\n- 修正1回目で、1800秒の継続は1回きり\n\n失敗してやり直すと時間と使用量がかえって増えるので、上位モデルの品質のほうが割に合うと判断しました。"
}
@@ -23,7 +23,7 @@
"scope_relationship": "RP24 bounded-shell acceptance is independent; not a dependency of Codex functional implementation"
},
"Claude_auth": "existing native subscription client automatically renewed; actual authenticated request success, no user login wait or API fallback",
"P08_03_next": "Actual Opus run recorded and dispatch launched in the-tree-p08-03-code; Codex model gpt-6-astra chosen by Opus for integrated UI/proof design complexity",
"P08_03_next": "Same preserved worktree continuation dispatched with actual Opus run and Astra model; exact-task provider timeout1800, no new implementation or rights",
"current_game_sources_changed": false,
"permission_request": "still pending and not applied; independent source work does not require marker command",
"UI_worker_method": "Codex functional implementation selected by actual Opus; Antigravity read-only visual review",
@@ -41,12 +41,25 @@
"replacement_model": "gpt-6-astra",
"actual_code_run": {
"id": "a8660e56f3b14bf483d8325412290679",
"state": "implementing",
"pid": 27695,
"state": "terminal_failed",
"pid": null,
"session": 90553,
"service": "codex",
"model": "gpt-6-astra",
"worker_count": 1,
"independent_review_pending": true
"independent_review_pending": true,
"exit_code": 124
},
"actual_code_continuation": {
"state": "implementing",
"model": "gpt-6-astra",
"repairs": 1,
"individual_cap": null,
"provider_timeout_seconds": 1800,
"adapter_sha256": "2d2d562983229e336ec083ffa77df7452c58f18ffd65a62c97a3a2dd0ef1358a",
"native_OS_response": "Root CUA request/ack bridge using completedP08-02 collector patterns, no headless gate spoofing",
"run": "c7e96c0a54b649c8b78711c603071cdd",
"pid": 35355,
"session": 77882
}
}
@@ -0,0 +1,85 @@
{
"original_unit": "P08-03",
"project": "the-tree-p08-03-code",
"run": "a8660e56f3b14bf483d8325412290679",
"terminal_exit": 124,
"cause": "existing900second process timeout",
"worker_process_ended": true,
"submitted": false,
"worktree_preserved": true,
"preserved_files": {
"scenes/main/main.gd": {
"bytes": 139617,
"sha256": "ef416e073ca0995c7700ccb8d14239baafd561bed444e8206a9c4bca7d9a73ff"
},
"scenes/main/world_preview.gd": {
"bytes": 69708,
"sha256": "2f0e417ae2ff1745062bdbdcec74b3b058cfcffbbd9001ca3e6a62cd23efb47d"
},
"tools/regression/suite-policy.json": {
"bytes": 16704,
"sha256": "0e5ddf9226cef0a515f76ab6f9b03040f7066117146bcc144236ad999645b904"
},
"docs/plans/original-completion-2026-10-02/execution/completion_marker_contracts.json": {
"bytes": 186634,
"sha256": "f59f01f65c795057117fda753706a6200928d4954af901fc965cf1a7c09232b5"
},
"tests/fixtures/p08-03/placement.gd": {
"bytes": 13985,
"sha256": "350d216716211114ff7bd6d142fd3d66c9b4400f292a1f7df0e78ed175748a6d"
},
"tests/fixtures/p08-03/checker_fixture.py": {
"bytes": 13183,
"sha256": "23fa9294c24a053d339371de86610673b575dfcb913e9c703090fe29f7fee284"
},
"tests/fixtures/p08-03/placement.gd.uid": {
"bytes": 20,
"sha256": "5caca08c1e627e0ca07e2ab7b13bd82b24a22f77513fe87e30b79023568e1987"
},
"tools/run_p08_normal_placement.py": {
"bytes": 7375,
"sha256": "16490abea2548aebbc7735cb56f8c1d9984c02b3b159edb82da306c9518cc89d"
},
"tools/test_p08_normal_placement_evidence.py": {
"bytes": 4852,
"sha256": "28652a34d276dc55aab36d1bc888aa41138ac1ae06b6f742b1cdcad281a02892"
},
"tools/check_p08_normal_placement_evidence.py": {
"bytes": 20494,
"sha256": "ae62bc0839384ab22237e3c73201ed966120ad0f069d0075cfc31aebf3385cc6"
},
"tests/ui/test_p08_normal_placement_ops.gd": {
"bytes": 621,
"sha256": "734f4f85d0b0fc45dc31fc23502425b911635667dabc0341ba0d88b0107f4405"
},
"tests/ui/test_p08_normal_placement_ops.gd.uid": {
"bytes": 20,
"sha256": "7d168ac50ca82ae1979da31c467f9a5020ca5ec7616b5bf99294413d85b3b299"
}
},
"local_checker": {
"command": "python3 -B tools/test_p08_normal_placement_evidence.py -v",
"actual_exec_session": 26937,
"exit_code": 0,
"tests": 16,
"elapsed_seconds": 5.044,
"result": "OK",
"scope": "synthetic whole checker positive and semantic corruption cases, no native/OS/gameplay acceptance"
},
"git_diff_check": "pass",
"required_correction": "native_os currently calls unchanged headless execute_phase; genuine nonheadless collection and raw input provenance required, do not weaken existing guards",
"pending": [
"completion docs",
"exact final inputs/source hashes",
"driver nonheadless path",
"final local check",
"genuine submitted",
"native",
"normal OS",
"full regression",
"independent review",
"integration"
],
"acceptance_credit": 0,
"updated_utc": "2026-10-13T17:57:23.625336+00:00"
}
@@ -0,0 +1,38 @@
"""Exact P08-03 continuation timeout; fixed contracts and other roles unchanged."""
import json
import os
from pathlib import Path
import runpy
import sys
control = Path(os.environ['OWNER_RUNNER_CONTROL']).resolve()
sys.path.insert(0, str(control))
from runner.core import Runner, require
original_process = Runner.process
def continuation_process(self, task_id, role, service, argv, cwd,
input_text=None, writable=(), timeout=None, execution=None,
validation_id=None, verification_kind=None, verification_sha=None):
if (self.config['project'] == 'the-tree-p08-03-code' and task_id == 'P08-03'
and role == 'implementer' and service == 'codex'):
contract = json.loads(self.task(task_id)['contract'])
require(contract['base_commit'] == '12430ba89970bda349781e51157e72e48a4ac06f'
and contract['spec_sha256'] == '7941da4edbd3c43a636a4a3d834d57c095b56da988fa3a056e55b22d3a5d50e9'
and contract['acceptance_ids'] == ['P08-03']
and contract['worker'] == 'codex', 'exact P08 continuation contract required')
decision = json.loads(Path(os.environ['P08_CONTINUATION_APPROVAL']).read_text())
require(decision['task_id'] == 'P08-03' and decision['action'] == 'run'
and '1800' in decision['reason'], 'actual Opus timeout decision required')
row = self.db.execute("SELECT data FROM events WHERE task_id=? AND event='commander_proposal' ORDER BY id DESC LIMIT 1", (task_id,)).fetchone()
require(row and json.loads(row[0])['decision'] == decision,
'timeout decision must equal the recorded commander run')
require(timeout is None and execution is None and validation_id is None,
'only ordinary provider continuation timeout may change')
timeout = 1800
return original_process(self, task_id, role, service, argv, cwd, input_text,
writable, timeout, execution, validation_id,
verification_kind, verification_sha)
Runner.process = continuation_process
runpy.run_path('/private/tmp/the-tree-owner-model-cli.py', run_name='__main__')