docs: preserve classifier correction and bounded prep recovery

This commit is contained in:
KOKO\Mimi
2026-09-06 12:42:15 +09:00
parent 5dfbea7e54
commit 0a98b2c4fa
7 changed files with 386 additions and 7 deletions
@@ -275,3 +275,125 @@ checkpoint에 사용되는 guard가 변경되지 않았음을 확인했다. Phas
동일하며 상태 blocked/history1이다. 문서 EOF/trailing whitespace·local links와
`git diff --check`도 확인했다. Commit/status edit/DFA/CMake/CTest/pytest는 미실행이다.
최종 scope/link count·hash는 handoff에 기록한다.
## R6. 실제 Correction source2의 보존과 남은 실행 조건
R2는 실제 WIP commit `6e00dba1`과 blocked metadata commit
`5dfbea7e543b64fdefcea292de43237adb790a72`을 만든 **과거 명령**이다.
이후 classifier가 바뀌었으므로 그 timeout-only AST guard를 다시 쓰거나 완화하지 않는다.
[Correction 보고서](corrections.md)와 [검증 summary](../../.harness/build/mitc4-eigen-evidence/prep/classifier-correction/20260906025404Z-continuation3-verification-summary.json)는
실제 RED21fail/16pass 뒤 GREEN37pass, 전체 pytest152pass/1fail을 기록한다.
Manual configure0/build1의 FileTracker TEMP 접근 거부 뒤 manual CTest는 미실행이다.
[실제 native 결과](../../.harness/build/mitc4-eigen-evidence/prep/classifier-correction/native-continuation-3-result.json)는
native/wrapper0,1914.797초이며, [등록 process exits](../../.harness/build/mitc4-eigen-evidence/prep/classifier-correction/native-continuation-3-registered-exits.json)의
Stop2개/CTest exit0 및362pass는 별도 자동 검증이다. 이를 manual full 성공으로 합치지 않는다.
Classifier key의 Correction1회는 사용됐고 추가 source correction은 허용하지 않는다.
재개 Implementation은 확보된 RED/GREEN을 읽고 현재 source의 focused/full을 재검증한다.
GREEN source를 다시 망가뜨려 RED를 만들지 않는다. 과거 timeout RED와 마지막 enum fix의
당시 미검증 기록은 보존하며, enum fix가 이번 focused/full에서 통과했다는 새 evidence를 구분한다.
Protected Hook1800!=7500과 manual build 환경 문제는 아직 해소되지 않았다.
Root는 frozen management `FEATURED_AGENTS.md/ADR.md/coordination.md`, Planning의
`implementation-plan.md/implementation-environment.md/implementation-recovery.md`,
독립 Correction의 `corrections.md` **정확7문서만** 먼저 checkpoint한다.
Correction 보고서는 prep owned_paths 밖이므로 이 선행 문서 commit으로 clean하게 만든다.
Root ack 뒤에만 Coordinator가 아래 실제 unchanged Executor method 호출을 할당한다.
Dirty 경로는 source2만 허용하며 phase/top/raw/Hook/status/history와 report는 불변이다.
아래 AST normalization은 검사에만 사용하고 실행 module/method를 교체하지 않는다.
```powershell
$ErrorActionPreference = 'Stop'
$mfeCheckpointPython = Join-Path (Get-Location).Path '.harness/build/mitc4-eigen-evidence/prep/classifier-correction/pytest-venv/Scripts/python.exe'
if (-not (Test-Path -LiteralPath $mfeCheckpointPython -PathType Leaf)) { throw 'Named Python missing' }
@'
import ast, hashlib, json
from pathlib import Path
from scripts import execute
phase = "mitc4-shell-feast-eigen-execution-prep"
origin = "5dfbea7e543b64fdefcea292de43237adb790a72"
ex = execute.StepExecutor(phase)
root = Path(ex._root)
assert Path.cwd().resolve() == root
assert Path(ex._run_git_checked("rev-parse", "--show-toplevel").stdout.strip()).resolve() == root
assert ex._is_isolated_worktree() and ex._codex_sandbox_mode() == "workspace-write"
assert ex._implementation_agent_settings() == ("gpt-5.6-terra", "xhigh")
branch, before_head = ex._git_execution_identity()
assert branch == "refs/heads/feat-" + phase
ex._run_git_checked("merge-base", "--is-ancestor", origin, "HEAD")
docs = {"docs/mitc4-shell-feast-eigen/" + p for p in (
"FEATURED_AGENTS.md", "ADR.md", "coordination.md", "implementation-plan.md",
"implementation-environment.md", "implementation-recovery.md", "corrections.md")}
assert set(ex._run_git_checked("diff", "--name-only", "--no-renames",
origin, "HEAD").stdout.splitlines()) <= docs
assert not ex._run_git_checked("diff", "--cached", "--name-only").stdout.strip()
sources = {"scripts/execute.py": "64f5165fc544b3b17904c633ef3b222de79b52a0960e254c5b5c4eb99e79c2d0",
"tests/test_execute.py": "0eb0c1ca0f25199e00686b7e3ab57672b1390437d09da218a929added0346dd6"}
fixed = {".codex/hooks.json": "0ab23dad4643f45238f4a60402083e32d8801f5c41fd6ba12b68ef6a9fc5fc28",
"phases/index.json": "2e4dfef44cd76b7ae447d0e2186a8a949ec29627df9c573646162b92348f1edb",
"phases/" + phase + "/index.json": "e23269a5518a8dbffbbf2e4706431d7f8af67e43706dcc9086aa6c8991d24262",
"phases/" + phase + "/step0-output.json": "0d5c0fe0aeba5604c5289764e7aad1834902548ca02158f8feac03484b195941",
"docs/mitc4-shell-feast-eigen/corrections.md": "d4ea3fb18accc2b2316eb439f56f5106d8ae6640fe79452cef6cb341b1933ee4"}
def check_hashes():
for path, expected in {**sources, **fixed}.items():
assert hashlib.sha256((root / path).read_bytes()).hexdigest() == expected, path
check_hashes()
old_tree = ast.parse(ex._run_git_checked("show", origin + ":scripts/execute.py").stdout)
new_tree = ast.parse((root / "scripts/execute.py").read_text(encoding="utf-8"))
old_cls = next(n for n in old_tree.body if isinstance(n, ast.ClassDef) and n.name == "StepExecutor")
new_cls = next(n for n in new_tree.body if isinstance(n, ast.ClassDef) and n.name == "StepExecutor")
old_methods = {n.name: n for n in old_cls.body if isinstance(n, ast.FunctionDef)}
new_methods = {n.name: n for n in new_cls.body if isinstance(n, ast.FunctionDef)}
assert set(new_methods) - set(old_methods) == {"_stdout_has_helper_failure"}
assert not set(old_methods) - set(new_methods)
assert {n for n in old_methods if ast.dump(old_methods[n]) != ast.dump(new_methods[n])} == {"_codex_environment_failure"}
new_cls.body = [old_methods["_codex_environment_failure"] if isinstance(n, ast.FunctionDef)
and n.name == "_codex_environment_failure" else n for n in new_cls.body
if not (isinstance(n, ast.FunctionDef) and n.name == "_stdout_has_helper_failure")]
assert ast.dump(new_tree) == ast.dump(old_tree)
idx = ex._read_phase_index()
top = ex._read_top_index()
assert len(idx["steps"]) == 1 and idx["steps"][0]["status"] == "blocked"
assert len(idx["steps"][0]["attempt_history"]) == 1
assert next(p for p in top["phases"] if p["dir"] == phase)["status"] == "blocked"
owned = ex._step_owned_paths(idx["steps"][0])
assert set(sources) <= set(owned)
assert set(ex._assert_step_scope(owned)) == set(sources)
snapshot = {p: (root / p).read_bytes() for p in
list(owned) + list(fixed) + ["phases/" + phase + "/step0.md",
"phases/mitc4-shell-feast-eigen/index.json"]}
assert ex._commit_paths(list(sources),
"chore(mitc4-shell-feast-eigen-execution-prep): WIP classifier correction with full verification blocked",
owned_paths=owned)
after_branch, after_head = ex._git_execution_identity()
assert after_branch == branch and after_head != before_head
actual = ex._run_git_checked("diff-tree", "--no-commit-id", "--name-only",
"--no-renames", "-r", after_head).stdout.splitlines()
assert set(actual) == set(sources)
assert all((root / p).read_bytes() == value for p, value in snapshot.items())
check_hashes()
assert ex._read_phase_index() == idx and ex._read_top_index() == top
assert not ex._worktree_paths()
ex._preflight_repository()
print(json.dumps({"commit": after_head, "paths": sorted(actual), "clean": True,
"status": "blocked", "history_count": 1, "branch": branch}))
'@ | & $mfeCheckpointPython -B -X utf8 -
$mfeCorrectionCommitExit = $LASTEXITCODE
if ($null -eq $mfeCorrectionCommitExit) { throw 'Native exit unavailable' }
exit $mfeCorrectionCommitExit
```
이 명령은 아직 미실행이다. Native exit와 commit path/hash/clean 결과를 실제 관찰한 뒤
Coordinator가 감사한다. 실패하면 현재 bytes/index/HEAD를 보존하고 자동 재시도하지 않는다.
새 source commit은 WIP와 전체 검증의 제한을 명시하며 `_commit_step`/completed를 호출하지 않는다.
성공 뒤에도 R3의 별도 status-only 할당과 해당 실행 직전 exact DFA 사용자 승인이 필요하다.
DFA는 아직 승인되지 않았다. 후속 native process에는 [E6의 실제 환경 recipe](implementation-environment.md#e6-correction-후의-pythonpytest와-process-temp)를 적용하고,
그 환경에서 R4와 동일한 phase/finite14400/approval flag를 사용한다. 새 process는 corrected
classifier를 로드한다. Protected Hook 권한과 TEMP/TMP 운영 설정의 근거를 혼동하지 않는다.
Prep full gate·등록 Stop 실제 exit·Coordinator 사후 감사 전 main activation은 금지다.
정적 검증은 command AST/PowerShell syntax, source2/report hash, 변경 method2와 나머지
Executor AST 불변, local links/EOF/whitespace와 blocked archive 동일성을 대상으로 했다.
정확 결과와 갱신3문서 hash는 handoff에 기록한다. Source/tests/Hook/phase/status/Git과
Correction 본문은 이번 Planning 작업에서 수정하지 않았다.