1074 lines
73 KiB
Markdown
1074 lines
73 KiB
Markdown
# 차단된 prep의 보존과 조건부 재개 계획
|
|
|
|
- Feature ID: `mitc4-shell-feast-eigen`
|
|
- Owner: `implementation-planning-agent`
|
|
- Input contract revision: `r2`
|
|
- 기본 보고서: [implementation-plan](implementation-plan.md)
|
|
- 범위: 문서와 정적 검토만 완료한다. 아래 Git mutation/status edit/재실행은 아직 실행하지 않는다.
|
|
|
|
## R1. 실제 상태와 변경 없는 경계
|
|
|
|
필수 입력은 Feature 폴더와 [FEATURED_AGENTS](FEATURED_AGENTS.md), [PRD](PRD.md),
|
|
[ADR](ADR.md), [현재 Coordinator 감사](coordination.md#execution-prep-attempt-1-실제-결과),
|
|
기존 [환경](implementation-environment.md), [interfaces](implementation-interfaces.md),
|
|
[verification](implementation-verification.md) 및 그 upstream r2 links다.
|
|
[AGENTS](../../AGENTS.md), [agent 계약](../SOLVER_AGENT_DESIGN.md),
|
|
[문서 관리](../FEATURE_DOCUMENTATION.md), [harness](../../.agents/skills/harness/SKILL.md),
|
|
[fem-implementation-tdd](../../.codex/skills/fem-implementation-tdd/SKILL.md)를 적용한다.
|
|
|
|
Prep attempt1은 종료되었고 Step0/top은 blocked, history1이다.
|
|
[원 보고서](implementation-prep-evidence.md)의 미검증 test 수정/실패 횟수 서술은 후속
|
|
Implementation owner가 실제 raw 순서에 맞춰 갱신한다. Planning은 본문을 수정하지 않는다.
|
|
[보존된 raw](../../.harness/build/mitc4-eigen-evidence/prep/attempt1/step0-output.json)와
|
|
[observation](../../.harness/build/mitc4-eigen-evidence/prep/attempt1/observation.json)을 사용한다.
|
|
Raw SHA-256은 `0d5c0fe0aeba5604c5289764e7aad1834902548ca02158f8feac03484b195941`이다.
|
|
마지막 focused run은2pass/2fail, 이후 test-only 수정은 미실행이다. Registered CTest의
|
|
362pass 기록은 manual full VERIFY/별도 process exit를 대신하지 않는다.
|
|
|
|
[현재 Executor](../../scripts/execute.py)의 constructor는 경로/schema를 읽고 field를 설정한다.
|
|
`_stop_step`은 blocked/history/top을 저장한 뒤 종료하며 커밋하지 않는다.
|
|
`_commit_paths`는 자체 `_assert_step_scope`, trusted path 검증, exact staged 경로 검사와
|
|
commit 직전 재검사를 수행한다. 내부 index reset은 검사된 dirty 경로의 staging만 정리하며
|
|
worktree bytes는 보존한다. 아래 명령은 이 method를 변경 없이 호출한다.
|
|
`run/_commit_step/_finalize/_stop_step`, status reset, Hook writes 또는 guard overrides는 없다.
|
|
일반 실행용 clean preflight는 dirty WIP 보존 전에 성립하지 않으므로 이 전용 checkpoint는
|
|
constructor/identity/scope/commit 경로를 사용하고 마지막 clean 상태에서 정상 preflight를 확인한다.
|
|
이는 새로운 recovery CLI가 아니다.
|
|
|
|
## R2. Root checkpoint 이후의 정확한 WIP 보존 명령
|
|
|
|
1. 모든 실행이 종료된 상태에서 Coordinator가 이 계획을 감사한다. Root는 management4문서와
|
|
이 변경3문서, classifier delta를 반영한 prep step0.md의 정확한8경로만 먼저 checkpoint한다.
|
|
Partial runtime/tests/report와 phase index/top의
|
|
controls는 stage하거나 커밋하지 않는다. Root checkpoint 후 staging은 비어 있어야 한다.
|
|
2. Branch `feat-mitc4-shell-feast-eigen-execution-prep`, linked root, origin
|
|
`d533b615410751fe023dc73ac2be994f05d37d30`의 descendant, origin 이후 commit path가
|
|
해당8계획/관리 파일 이내임을 아래 명령이 검증한다. 현재 partial implementation8경로와 control2경로가
|
|
정확히 남아야 한다. `.codex/hooks.json`은 이 WIP commit의 변경 대상이 아니다.
|
|
3. Coordinator가 실행을 할당하면 **실제 Executor method**가 두 개의 local commit을 만든다.
|
|
Root/Coordinator는 실행 동안 추가 편집·커밋을 멈춘다. 성공 명칭이나 completed를 쓰지 않는다.
|
|
첫 commit 후 두 번째가 실패할 수 있으며 두 commit은 하나의 transaction이 아니다.
|
|
실패 시 현재 HEAD/index/worktree/log를 그대로 감사하고 자동 재시도나 rollback을 하지 않는다.
|
|
|
|
Workspace root의 별도 managed PowerShell process에서 아래 전체 block을 실행하도록 계획한다.
|
|
Python native exit를 즉시 저장하여 동일 shell exit로 전파한다. CommandNotFound는 terminating
|
|
error이며 나중 명령의 exit0으로 덮이지 않는다. 이 block은 **현재 planning turn에서 미실행**이다.
|
|
|
|
```powershell
|
|
$ErrorActionPreference = 'Stop'
|
|
Get-Command python -ErrorAction Stop | Out-Null
|
|
@'
|
|
import ast, hashlib, json, os
|
|
from pathlib import Path
|
|
from scripts import execute
|
|
phase = "mitc4-shell-feast-eigen-execution-prep"
|
|
origin = "d533b615410751fe023dc73ac2be994f05d37d30"
|
|
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()
|
|
assert 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")
|
|
doc_names = ("FEATURED_AGENTS.md", "PRD.md", "ADR.md", "coordination.md",
|
|
"implementation-plan.md", "implementation-environment.md", "implementation-recovery.md")
|
|
doc_paths = {"docs/mitc4-shell-feast-eigen/" + n for n in doc_names}
|
|
doc_paths.add("phases/" + phase + "/step0.md")
|
|
committed = ex._run_git_checked("diff", "--name-only", "--no-renames", origin, "HEAD").stdout.splitlines()
|
|
assert set(committed) <= doc_paths
|
|
assert not ex._run_git_checked("diff", "--cached", "--name-only").stdout.strip()
|
|
current_source = (root / "scripts/execute.py").read_text(encoding="utf-8")
|
|
original_source = ex._run_git_checked("show", origin + ":scripts/execute.py").stdout
|
|
assert ast.dump(ast.parse(current_source.replace("CODEX_TIMEOUT_SECONDS = 14400",
|
|
"CODEX_TIMEOUT_SECONDS = 1800"))) == ast.dump(ast.parse(original_source))
|
|
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])
|
|
expected_owned = ("scripts/execute.py", ".codex/hooks.json",
|
|
"scripts/hooks/stop_validation.py", "scripts/msvc_harness/models.py",
|
|
"scripts/msvc_harness/process.py", "tests/test_execute.py",
|
|
"tests/test_harness_timeouts.py", "docs/HARNESS_WORKFLOW.md",
|
|
"docs/mitc4-shell-feast-eigen/implementation-prep-evidence.md")
|
|
assert owned == expected_owned
|
|
control = ["phases/index.json", "phases/" + phase + "/index.json"]
|
|
code = [p for p in owned if p != ".codex/hooks.json"]
|
|
assert set(ex._assert_step_scope(owned)) == set(code + control)
|
|
raw_path = "phases/" + phase + "/step0-output.json"
|
|
raw = (root / raw_path).read_bytes()
|
|
assert hashlib.sha256(raw).hexdigest() == "0d5c0fe0aeba5604c5289764e7aad1834902548ca02158f8feac03484b195941"
|
|
frozen_paths = list(owned) + control + ["phases/" + phase + "/step0.md", raw_path]
|
|
frozen = {p: (root / p).read_bytes() for p in frozen_paths}
|
|
def verify_frozen():
|
|
assert all((root / p).read_bytes() == data for p, data in frozen.items())
|
|
assert ex._read_phase_index() == idx and ex._read_top_index() == top
|
|
assert ex._git_execution_identity()[0] == branch
|
|
verify_frozen()
|
|
previous = before_head
|
|
for paths, message in (
|
|
(code, "chore(mitc4-shell-feast-eigen-execution-prep): WIP blocked partial deadline preparation"),
|
|
(control, "chore(mitc4-shell-feast-eigen-execution-prep): preserve blocked attempt 1 metadata"),
|
|
):
|
|
verify_frozen()
|
|
assert ex._commit_paths(paths, message, owned_paths=owned)
|
|
current = ex._git_execution_identity()[1]
|
|
assert current != previous
|
|
actual = ex._run_git_checked("diff-tree", "--no-commit-id", "--name-only",
|
|
"--no-renames", "-r", current).stdout.splitlines()
|
|
assert set(actual) == set(paths), (current, actual)
|
|
verify_frozen()
|
|
print(json.dumps({"commit": current, "paths": sorted(actual), "status": "blocked"}))
|
|
previous = current
|
|
assert not ex._worktree_paths()
|
|
ex._preflight_repository()
|
|
verify_frozen()
|
|
print(json.dumps({"clean": True, "branch": branch, "head": previous,
|
|
"raw_sha256": hashlib.sha256(raw).hexdigest(),
|
|
"phase_status": "blocked", "history_count": 1}))
|
|
'@ | python -B -
|
|
$mfeCheckpointExit = $LASTEXITCODE
|
|
if ($mfeCheckpointExit -ne 0) { exit $mfeCheckpointExit }
|
|
exit $mfeCheckpointExit
|
|
```
|
|
|
|
상태/history/timestamps/다른 step/top/step markdown/raw/owned file bytes는 전후 동일해야 한다.
|
|
출력 commit SHA와 actual path set, clean/branch/root 및 실제 process exit를 Coordinator가
|
|
관리문서에 감사한다. 이 두 commit은 blocked WIP 보존이며 구현/검증 통과가 아니다.
|
|
Raw archive는 ignored 상태로 유지하고 Git에 추가하지 않는다.
|
|
|
|
## R3. 승인 후에만 가능한 status-only checkpoint
|
|
|
|
현재 exact DFA run의 명시적 사용자 승인은 없다. WIP checkpoint에는 별도 사용자 질문이
|
|
필요하지 않지만 DFA는 [harness elevated rule](../../.agents/skills/harness/SKILL.md#elevated-and-remote-execution)에 따라
|
|
동일 native 명령 실패 evidence, clean linked worktree, **해당 실행 직전 명시적 사용자 승인**,
|
|
approval flag가 모두 필요하다. 과거 일반 구현 승인이나 이 문서 작성은 그 승인이 아니다.
|
|
|
|
그 승인이 실제로 도착한 경우에만 다음 순서를 같은 bounded 복구 준비로 진행한다.
|
|
|
|
1. Coordinator가 승인된 exact command와 recovery dispatch를 management에 기록하고 Root가
|
|
그 문서만 checkpoint하여 clean을 유지한다. 원시 attempt1 archive는 그대로 보존한다.
|
|
2. Coordinator의 별도 명시 할당을 받은 Planning만
|
|
`phases/mitc4-shell-feast-eigen-execution-prep/index.json`의 **현재 Step0 status 한 값**
|
|
`blocked -> pending`을 바꾼다. `blocked_reason/blocked_at/started_at/created_at/
|
|
attempt_history`, owned paths, 다른 Step/top은 그대로 둔다. 현재 dispatch는 이 편집을 허용하지 않는다.
|
|
3. Coordinator가 할당한 실제 Executor method는 아래 control-only checkpoint를 수행한다.
|
|
Staged HEAD의 blocked JSON과 working pending JSON의 차이가 status 한 값뿐인지 검증한다.
|
|
Top은 계속 blocked다. 기존 `_check_blockers`는 phase의 첫 미완료 Step을 판별하므로
|
|
pending을 실행할 수 있으며 top을 미리 성공/초기화할 필요가 없다.
|
|
4. Clean checkpoint 확인 뒤 별도 변경 없이 R4의 승인된 invocation을 시작한다.
|
|
필요한 준비 사이에 실행 범위나 환경이 달라지면 재개하지 않고 Coordinator에 반환한다.
|
|
|
|
```powershell
|
|
$ErrorActionPreference = 'Stop'
|
|
Get-Command python -ErrorAction Stop | Out-Null
|
|
@'
|
|
import json
|
|
from pathlib import Path
|
|
from scripts import execute
|
|
phase = "mitc4-shell-feast-eigen-execution-prep"
|
|
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"
|
|
branch, before_head = ex._git_execution_identity()
|
|
assert branch == "refs/heads/feat-" + phase
|
|
path = "phases/" + phase + "/index.json"
|
|
before = json.loads(ex._run_git_checked("show", "HEAD:" + path).stdout)
|
|
after = ex._read_phase_index()
|
|
expected = json.loads(json.dumps(before))
|
|
assert len(expected["steps"]) == 1 and expected["steps"][0]["status"] == "blocked"
|
|
expected["steps"][0]["status"] = "pending"
|
|
assert after == expected
|
|
assert set(ex._assert_step_scope(())) == {path}
|
|
assert not ex._run_git_checked("diff", "--cached", "--name-only").stdout.strip()
|
|
top_before = ex._read_control_bytes(ex._top_index_file)
|
|
raw_path = root / "phases" / phase / "step0-output.json"
|
|
raw_before = raw_path.read_bytes()
|
|
phase_before = ex._read_control_bytes(ex._index_file)
|
|
assert ex._commit_paths([path],
|
|
"chore(mitc4-shell-feast-eigen-execution-prep): queue approved recovery preserving attempt history")
|
|
current = ex._git_execution_identity()
|
|
assert current[0] == branch and current[1] != before_head
|
|
assert ex._run_git_checked("diff-tree", "--no-commit-id", "--name-only", "-r",
|
|
current[1]).stdout.splitlines() == [path]
|
|
assert ex._read_control_bytes(ex._index_file) == phase_before
|
|
assert ex._read_control_bytes(ex._top_index_file) == top_before
|
|
assert raw_path.read_bytes() == raw_before
|
|
assert ex._read_phase_index() == after and not ex._worktree_paths()
|
|
ex._preflight_repository()
|
|
print(json.dumps({"commit": current[1], "clean": True,
|
|
"step_status": "pending", "history_preserved": True}))
|
|
'@ | python -B -
|
|
$mfeStatusExit = $LASTEXITCODE
|
|
if ($mfeStatusExit -ne 0) { exit $mfeStatusExit }
|
|
exit $mfeStatusExit
|
|
```
|
|
|
|
이 단계도 `_commit_step`이나 완료 처리를 부르지 않는다. 이후 실행에서 추가 attempt 기록과
|
|
terminal outcome/timestamp 정리는 Executor 소유다. Planning/Root가 과거 failure를 지우지 않는다.
|
|
|
|
## R4. 조건부 exact DFA invocation과 후속 검증
|
|
|
|
Prep에 실제 classifier 결함의 TDD delta가 추가되었다. 상세 RED/GREEN/신규 test3개 및 전체
|
|
VERIFY는 [prep Step0](../../phases/mitc4-shell-feast-eigen-execution-prep/step0.md)에 있다.
|
|
[순수함수 재현](../../.harness/build/mitc4-eigen-evidence/prep/attempt1/classifier-observation.json)은
|
|
성공한 source read stdout의 marker7회가 오판 원인이었음을 보여 준다. 실제 protected Hook
|
|
쓰기 거부/명시 blocked는 별개의 실제 failure로 보존한다. Root/Coordinator가 확정한 순서는
|
|
이번 계획 종료 → 정확 문서 checkpoint → R2의 unchanged Executor WIP 두 commit → 별도
|
|
Correction Agent dispatch다. Correction 소유는 scripts/execute.py, tests/test_execute.py와
|
|
`docs/mitc4-shell-feast-eigen/corrections.md`이며 Hook/index/status/Git은 변경하지 않는다.
|
|
Correction은 Step0에 정의한 최소 RED/GREEN·focused/full acceptance를 수행한다.
|
|
Checkpoint/recovery bootstrap이 classifier를 monkeypatch하거나 진단을 지우지 않는다.
|
|
|
|
이미 시작된 Executor는 source 수정 뒤에도 예전 classifier를 유지하므로 Correction은 다음
|
|
실제 prep invocation보다 먼저 완료되어야 한다. 실제 Correction 결과가 반환된 뒤 Coordinator는
|
|
Planning을 별도 재개하여 source/report의 정확 checkpoint 계획을 감사한다. 현재 문서는 미래
|
|
Correction 성공/hash/commit이나 그 checkpoint를 미리 승인하지 않는다. 해당 검증·checkpoint와
|
|
새 process가 수정 classifier를 읽는 activation 확인이 끝나기 전 R3/R4 재개를 실행하지 않는다.
|
|
현재 timeout-only AST guard는 최초 WIP 보존에 그대로 유지한다. 수정된 classifier를 현재
|
|
Executor에 reload/override하거나 old classifier의 terminal을 성공으로 바꾸지 않는다.
|
|
|
|
R3과 사용자 승인까지 실제 완료된 경우에만, workspace root의 새 managed PowerShell
|
|
process에서 아래 실행을 허용한다. E3의 실제 `main()`과 단일 유한14400 timeout assignment를
|
|
유지하며 flag와 process-local sandbox 값만 승인 범위에 맞춘다. 이전 환경 값은 `finally`에서
|
|
복원하고 native exit를 즉시 저장한다. transport/ownership/Hook/verification guard는 변경하지 않는다.
|
|
|
|
```powershell
|
|
$ErrorActionPreference = 'Stop'
|
|
Get-Command python -ErrorAction Stop | Out-Null
|
|
$mfePriorSandbox = [Environment]::GetEnvironmentVariable('FEM_HARNESS_CODEX_SANDBOX', 'Process')
|
|
if ($null -ne $mfePriorSandbox -and $mfePriorSandbox -ne 'workspace-write') {
|
|
throw 'Unexpected pre-existing sandbox environment'
|
|
}
|
|
$mfeNativeExit = $null
|
|
try {
|
|
$env:FEM_HARNESS_CODEX_SANDBOX = 'danger-full-access'
|
|
python -B -c "from scripts import execute; execute.StepExecutor.CODEX_TIMEOUT_SECONDS = 14400; execute.main()" mitc4-shell-feast-eigen-execution-prep --approve-danger-full-access
|
|
$mfeNativeExit = $LASTEXITCODE
|
|
if ($null -eq $mfeNativeExit) { throw 'Native Executor exit was not captured' }
|
|
}
|
|
finally {
|
|
[Environment]::SetEnvironmentVariable('FEM_HARNESS_CODEX_SANDBOX', $mfePriorSandbox, 'Process')
|
|
}
|
|
exit $mfeNativeExit
|
|
```
|
|
|
|
Implementation은 선행 Correction의 실제 RED/GREEN evidence를 읽고 같은 classifier regression,
|
|
남은 Hook 변경, 미검증 test 수정의 focused 재검증, 전체 pytest와
|
|
MSVC/x64/Debug CMake/CTest, actual registered Stop을 모두 수행한다. 기존 보고서의 실제
|
|
2개 실패와 미검증 수정도 owner가 바로잡는다. 실패 이력을 새 RED 성공이나 correction으로
|
|
바꾸지 않는다. Native Exit/Stop 사후 감사까지 prep gate가 완료되기 전 main activation은 금지다.
|
|
Push/tag/publish/release 또는 다른 sandbox/guard 변경 권한은 없다.
|
|
|
|
## R5. 계획 정적 검증
|
|
|
|
Command AST/PowerShell syntax와 현 상태의 read-only 검사를 수행했다. Python `ast.parse`로
|
|
WIP/status checkpoint code2개를 검증했고 PowerShell `Parser::ParseInput`으로 실행 block3개의
|
|
syntax errors0을 확인했다(각 exit0). 현재 execute.py는 origin 대비 timeout 상수 외 AST가 같아
|
|
checkpoint에 사용되는 guard가 변경되지 않았음을 확인했다. Phase/top/raw는 보존 archive와
|
|
동일하며 상태 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 작업에서 수정하지 않았다.
|
|
|
|
## R7. Attempt2 실패 보존과 정상 workspace-write 재개
|
|
|
|
R2/R6/R3와 E6은 과거 실행·승인 이력으로 보존한다. 이번 actual attempt2는 종료됐으며
|
|
[terminal archive](../../.harness/build/mitc4-eigen-evidence/prep/attempt2/terminal-archive.json)에
|
|
native PowerShell1/Codex0, Step error/history2와 이전 history1이 남아 있다.
|
|
Hook RED3pass/1fail→GREEN4pass, focused136pass(기존 classifier37 포함),
|
|
configure/build/discovery0 뒤 manual CTest와 registered CTest는 각각 exit8,
|
|
361/362pass였다. Stop wrapper/Python0은 검증 성공이 아니다. Full pytest는 미실행이다.
|
|
|
|
[동일 binary의 경로 길이 비교](../../.harness/build/mitc4-eigen-evidence/prep/attempt2/path-length-probe-e15c1747/observation.json)는
|
|
TEMP152/result251/lock261에서 해당 test exit1, TEMP70/관찰 lock179에서 exit0을 기록한다.
|
|
Binary SHA-256 `d52ed2538be8f66e076f25ae44f073aea8486c5f543fbc7c179b7a5610dc3209`는 같고
|
|
source/shared CTest log/reference 변경은 없다. 이 결과는 정상 환경 설정의 근거이며
|
|
solver defect 또는 직접 관찰하지 않은 GetLastError를 주장하지 않는다.
|
|
|
|
### 실패 상태의 WIP checkpoint
|
|
|
|
Root는 frozen management4문서와 Planning3문서의 실제 변경 경로만 먼저 checkpoint한다.
|
|
Hook/report/phase controls는 그 문서 commit에 섞지 않는다. Root ack 뒤 Coordinator가 아래
|
|
unchanged Executor 호출을 할당한다. Origin은 `d64cd1403ac41fb1397dfb088361ce18ad1d59bd`,
|
|
dirty는 Hook+report2 및 controls2뿐이어야 한다. 두 commit은 WIP/실패 기록이며 성공 전환이 아니다.
|
|
모든 bytes/history/raw/error는 유지한다. 중간 실패 시 원래 HEAD/index/worktree를 보존하며
|
|
자동 재시도나 rollback을 하지 않는다. `_commit_step`/runtime override는 사용하지 않는다.
|
|
|
|
```powershell
|
|
$ErrorActionPreference = 'Stop'
|
|
$mfePython = Join-Path (Get-Location).Path '.harness/build/mitc4-eigen-evidence/prep/classifier-correction/pytest-venv/Scripts/python.exe'
|
|
if (-not (Test-Path -LiteralPath $mfePython -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="d64cd1403ac41fb1397dfb088361ce18ad1d59bd"
|
|
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,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/"+n for n in ("FEATURED_AGENTS.md","PRD.md","ADR.md",
|
|
"coordination.md","implementation-plan.md","implementation-environment.md","implementation-recovery.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()
|
|
expected={".codex/hooks.json":"e7e5d3c0c4fcd1e33b60680122ea7c42298d5cbde78a7f87d9e0007bf60a0fa4",
|
|
"docs/mitc4-shell-feast-eigen/implementation-prep-evidence.md":"90d104423af2971837a38eb632c8a4aa54b8acf6f6cd96b5a193dbd4ba4e083f",
|
|
"phases/index.json":"c2d98e5bcb96bb781f687e696083076a3f5bea2d095f4c7264bb4a6415b6cc38",
|
|
"phases/"+phase+"/index.json":"7990530b4d259850f614ae68036c551b3c11539c90673512c6515d3f87ad1ebe",
|
|
"phases/"+phase+"/step0-output.json":"8852e0ddae9ef94d885e8b4ae4b8a3b2e3a9d9161a3801bc7e56ea157e9411f4",
|
|
"scripts/execute.py":"64f5165fc544b3b17904c633ef3b222de79b52a0960e254c5b5c4eb99e79c2d0",
|
|
"tests/test_execute.py":"0eb0c1ca0f25199e00686b7e3ab57672b1390437d09da218a929added0346dd6"}
|
|
for p,h in expected.items():assert hashlib.sha256((root/p).read_bytes()).hexdigest()==h,p
|
|
assert ast.dump(ast.parse((root/"scripts/execute.py").read_text(encoding="utf-8")))==ast.dump(ast.parse(ex._run_git_checked("show",origin+":scripts/execute.py").stdout))
|
|
old_hook=json.loads(ex._run_git_checked("show",origin+":.codex/hooks.json").stdout)
|
|
old_hook["hooks"]["Stop"][0]["hooks"][0]["timeout"]=7500
|
|
assert json.loads((root/".codex/hooks.json").read_bytes())==old_hook
|
|
idx=ex._read_phase_index();top=ex._read_top_index()
|
|
assert idx["steps"][0]["status"]=="error" and len(idx["steps"][0]["attempt_history"])==2
|
|
assert next(p for p in top["phases"] if p["dir"]==phase)["status"]=="error"
|
|
owned=ex._step_owned_paths(idx["steps"][0])
|
|
code=[".codex/hooks.json","docs/mitc4-shell-feast-eigen/implementation-prep-evidence.md"]
|
|
control=["phases/index.json","phases/"+phase+"/index.json"]
|
|
assert set(ex._assert_step_scope(owned))==set(code+control)
|
|
frozen={p:(root/p).read_bytes() for p in list(owned)+list(expected)+["phases/"+phase+"/step0.md","phases/mitc4-shell-feast-eigen/index.json"]}
|
|
for paths,message in (
|
|
(code,"chore(mitc4-shell-feast-eigen-execution-prep): WIP Hook update with verification failure"),
|
|
(control,"chore(mitc4-shell-feast-eigen-execution-prep): preserve attempt 2 error metadata")):
|
|
assert all((root/p).read_bytes()==v for p,v in frozen.items())
|
|
assert ex._git_execution_identity()==(branch,head)
|
|
assert ex._commit_paths(paths,message,owned_paths=owned)
|
|
new_branch,new_head=ex._git_execution_identity()
|
|
assert new_branch==branch and new_head!=head
|
|
actual=ex._run_git_checked("diff-tree","--no-commit-id","--name-only","--no-renames","-r",new_head).stdout.splitlines()
|
|
assert set(actual)==set(paths)
|
|
assert all((root/p).read_bytes()==v for p,v in frozen.items())
|
|
assert ex._read_phase_index()==idx and ex._read_top_index()==top
|
|
print(json.dumps({"commit":new_head,"paths":actual,"status":"error","history_count":2}))
|
|
head=new_head
|
|
assert not ex._worktree_paths()
|
|
ex._preflight_repository()
|
|
print(json.dumps({"head":head,"branch":branch,"clean":True}))
|
|
'@ | & $mfePython -B -X utf8 -
|
|
$mfeWipExit = $LASTEXITCODE
|
|
if ($null -eq $mfeWipExit) { throw 'Native exit unavailable' }
|
|
exit $mfeWipExit
|
|
```
|
|
|
|
### 별도 할당 뒤 status-only checkpoint
|
|
|
|
위 terminal WIP 보존이 실제 완료되기 전에는 status를 바꾸지 않는다.
|
|
그 후 Coordinator의 별도 할당을 받은 Planning만 prep index의 현재 Step0.status를
|
|
`error -> pending` 한 값으로 바꾼다. error_message/failed_at/started_at/created_at/
|
|
attempt_history2/owned_paths와 다른 fields/top/raw는 그대로 둔다. 현재 Planning dispatch는
|
|
이 status edit를 허용하지 않는다. 반환 감사 뒤 Coordinator가 다음 Executor control
|
|
checkpoint를 할당하고 clean을 확인한다. 일반 환경 복구이므로 새 사용자 승인은 필요하지 않다.
|
|
|
|
```powershell
|
|
$ErrorActionPreference = 'Stop'
|
|
$mfePython = Join-Path (Get-Location).Path '.harness/build/mitc4-eigen-evidence/prep/classifier-correction/pytest-venv/Scripts/python.exe'
|
|
if (-not (Test-Path -LiteralPath $mfePython -PathType Leaf)) { throw 'Named Python missing' }
|
|
@'
|
|
import json
|
|
from pathlib import Path
|
|
from scripts import execute
|
|
phase="mitc4-shell-feast-eigen-execution-prep"
|
|
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"
|
|
branch,head=ex._git_execution_identity();assert branch=="refs/heads/feat-"+phase
|
|
path="phases/"+phase+"/index.json"
|
|
before=json.loads(ex._run_git_checked("show","HEAD:"+path).stdout)
|
|
assert before["steps"][0]["status"]=="error" and len(before["steps"][0]["attempt_history"])==2
|
|
expected=json.loads(json.dumps(before));expected["steps"][0]["status"]="pending"
|
|
assert ex._read_phase_index()==expected
|
|
assert set(ex._assert_step_scope(()))=={path}
|
|
assert not ex._run_git_checked("diff","--cached","--name-only").stdout.strip()
|
|
frozen={p:(root/p).read_bytes() for p in (path,"phases/index.json","phases/"+phase+"/step0-output.json")}
|
|
assert ex._commit_paths([path],"chore(mitc4-shell-feast-eigen-execution-prep): queue short-temp environment recovery")
|
|
new_branch,new_head=ex._git_execution_identity()
|
|
assert new_branch==branch and new_head!=head
|
|
assert ex._run_git_checked("diff-tree","--no-commit-id","--name-only","-r",new_head).stdout.splitlines()==[path]
|
|
assert all((root/p).read_bytes()==v for p,v in frozen.items())
|
|
assert ex._read_phase_index()==expected and not ex._worktree_paths()
|
|
ex._preflight_repository()
|
|
print(json.dumps({"commit":new_head,"status":"pending","history_count":2,"clean":True}))
|
|
'@ | & $mfePython -B -X utf8 -
|
|
$mfeStatusExit = $LASTEXITCODE
|
|
if ($null -eq $mfeStatusExit) { throw 'Native exit unavailable' }
|
|
exit $mfeStatusExit
|
|
```
|
|
|
|
이어 [E7의 짧은 TEMP와 정상 sandbox](implementation-environment.md#e7-짧은-temp를-사용하는-정상-재개)로
|
|
prep를 재개한다. 이전 E6의 one-time DFA 승인은 사용 완료됐고 Hook7500은 안전하게
|
|
보존되므로 이번에는 DFA flag나 danger-full-access 환경을 사용하지 않는다.
|
|
Main도 full prep gate/Coordinator 사후 감사 뒤 같은 짧은 환경과 workspace-write로 실행한다.
|
|
Source classifier의 harness r2 Correction allowance는 이미 사용됐으며 두 번째 source
|
|
Correction은 허용하지 않는다. 같은 테스트·전체 VERIFY·Hook·retry/ownership guard를 유지한다.
|
|
|
|
재개 Implementation은 기존 RED/GREEN을 읽고 focused/full을 실제 재검증한다. Full CTest는
|
|
기존 정적 reference를 읽고 비교하므로 보고서의 'reference를 읽거나 비교하지 않았다' 문장은
|
|
owner가 바로잡아야 한다. 원본 reference의 직접 수정 없음, 새 eigen reference 비교 없음과
|
|
기존 static regression 비교 수행을 구분하고 당시 실패·미실행 기록도 보존한다.
|
|
Planning은 implementation-prep-evidence.md를 수정하지 않는다.
|
|
|
|
이 R7의 commit/status edit/재실행은 아직 미실행이다. 정적 검사 결과와 갱신3문서 hash는
|
|
handoff에 기록하며 실제 실행 exit·commit path/bytes·clean 확인은 Coordinator가 감사한다.
|
|
|
|
## R8. Attempt3의 blocked 기록 보존
|
|
|
|
현재 경계는 [attempt3 archive](../../.harness/build/mitc4-eigen-evidence/prep/attempt3/terminal-archive.json)와
|
|
[Root 환경 관찰](../../.harness/build/mitc4-eigen-evidence/prep/attempt3/root-manual-build-environment-observation.json)이다.
|
|
E7 native는 짧은 TEMP/TMP를 같은 build shell에 실제 지정했지만 FileTracker 접근 거부로
|
|
manual build가 실패했다. Classifier37/focused136은 통과했으며 manual CTest/full pytest는
|
|
미실행이다. Registered Stop의 build/CTest 성공은 이 manual 실패를 대체하지 않는다.
|
|
현재 Step0은 blocked/history3이며 이전 두 history와 원시 기록을 보존한다.
|
|
|
|
이번 할당은 보존 명령의 문서화와 정적 확인뿐이다. Root가 동결된 관리2문서
|
|
`FEATURED_AGENTS.md`, `coordination.md`와 Planning3문서를 exact-path checkpoint한 뒤,
|
|
Coordinator가 아래 unchanged Executor method invocation을 실행한다. 첫 commit은
|
|
Implementation 보고서1개의 WIP, 둘째는 phase/top controls2개의 blocked metadata이다.
|
|
완료 판정·`_commit_step`·status reset·Hook/source 변경·guard override는 없다.
|
|
현재 origin 이후 수정 가능한 선행 commit 경로도 이5문서로 제한한다. Source2와 Hook은
|
|
현재 hash/내용 그대로이며, staging은 비어 있어야 한다. Linked root/branch, 실제
|
|
`_assert_step_scope`, staged-path guard와 실행 전후 bytes/전체 JSON 비교를 유지한다.
|
|
|
|
```powershell
|
|
$ErrorActionPreference = 'Stop'
|
|
$mfePython = Join-Path (Get-Location).Path '.harness/build/mitc4-eigen-evidence/prep/classifier-correction/pytest-venv/Scripts/python.exe'
|
|
if (-not (Test-Path -LiteralPath $mfePython -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="dc6b9b1cf70b0ca1685eb1ac5476aa6f8cd3dab6"
|
|
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,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/"+n for n in ("FEATURED_AGENTS.md","coordination.md","implementation-plan.md","implementation-environment.md","implementation-recovery.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()
|
|
expected={".codex/hooks.json":"e7e5d3c0c4fcd1e33b60680122ea7c42298d5cbde78a7f87d9e0007bf60a0fa4",
|
|
"docs/mitc4-shell-feast-eigen/implementation-prep-evidence.md":"1e4d61997817b84b1df3933c6aa6518f030ca413edcda74393e0a0cf805e6732",
|
|
"phases/index.json":"42c9581868cc3f552ea3b42764a291098f648352f31021c7bdd7b4bebcdcf91e",
|
|
"phases/"+phase+"/index.json":"f863def2d19869ccb0cdc058b32c240b786a6d94a4a761cc98f9eeae62cd4c36",
|
|
"phases/"+phase+"/step0-output.json":"d106f7ade2d678b6e0b383439b1b9b8d25f5ec32e883aed50c6fb4949a8983f1",
|
|
"scripts/execute.py":"64f5165fc544b3b17904c633ef3b222de79b52a0960e254c5b5c4eb99e79c2d0",
|
|
"tests/test_execute.py":"0eb0c1ca0f25199e00686b7e3ab57672b1390437d09da218a929added0346dd6"}
|
|
for p,h in expected.items():assert hashlib.sha256((root/p).read_bytes()).hexdigest()==h,p
|
|
assert ast.dump(ast.parse((root/"scripts/execute.py").read_text(encoding="utf-8")))==ast.dump(ast.parse(ex._run_git_checked("show",origin+":scripts/execute.py").stdout))
|
|
old_hook=json.loads(ex._run_git_checked("show",origin+":.codex/hooks.json").stdout)
|
|
assert json.loads((root/".codex/hooks.json").read_bytes())==old_hook
|
|
idx=ex._read_phase_index();top=ex._read_top_index()
|
|
assert idx["steps"][0]["status"]=="blocked" and len(idx["steps"][0]["attempt_history"])==3
|
|
assert next(p for p in top["phases"] if p["dir"]==phase)["status"]=="blocked"
|
|
owned=ex._step_owned_paths(idx["steps"][0])
|
|
code=["docs/mitc4-shell-feast-eigen/implementation-prep-evidence.md"]
|
|
control=["phases/index.json","phases/"+phase+"/index.json"]
|
|
assert set(ex._assert_step_scope(owned))==set(code+control)
|
|
frozen={p:(root/p).read_bytes() for p in list(owned)+list(expected)+["phases/"+phase+"/step0.md","phases/mitc4-shell-feast-eigen/index.json"]}
|
|
for paths,message in (
|
|
(code,"chore(mitc4-shell-feast-eigen-execution-prep): WIP prep report with native build blocked"),
|
|
(control,"chore(mitc4-shell-feast-eigen-execution-prep): preserve attempt 3 blocked metadata")):
|
|
assert all((root/p).read_bytes()==v for p,v in frozen.items())
|
|
assert ex._git_execution_identity()==(branch,head)
|
|
assert ex._commit_paths(paths,message,owned_paths=owned)
|
|
new_branch,new_head=ex._git_execution_identity()
|
|
assert new_branch==branch and new_head!=head
|
|
actual=ex._run_git_checked("diff-tree","--no-commit-id","--name-only","--no-renames","-r",new_head).stdout.splitlines()
|
|
assert set(actual)==set(paths)
|
|
assert all((root/p).read_bytes()==v for p,v in frozen.items())
|
|
assert ex._read_phase_index()==idx and ex._read_top_index()==top
|
|
print(json.dumps({"commit":new_head,"paths":actual,"status":"blocked","history_count":3}))
|
|
head=new_head
|
|
assert not ex._worktree_paths()
|
|
ex._preflight_repository()
|
|
print(json.dumps({"head":head,"branch":branch,"clean":True}))
|
|
'@ | & $mfePython -B -X utf8 -
|
|
$mfeWipExit = $LASTEXITCODE
|
|
if ($null -eq $mfeWipExit) { throw 'Native exit unavailable' }
|
|
exit $mfeWipExit
|
|
```
|
|
|
|
각 실제 commit 직후 경로와 전체 snapshot을 확인하고, 마지막 clean preflight와 native
|
|
exit를 즉시 보존·전파한다. 중간 실패 시 이미 생성된 commit과 남은 dirty 내용을 보존해
|
|
Coordinator로 반환하며 명령을 무조건 반복하지 않는다. 원시 archive와 report의 당시 실패를
|
|
삭제하거나 WIP commit을 full VERIFY 통과로 해석하지 않는다.
|
|
|
|
이 보존과 Coordinator 감사가 실제 완료된 뒤에만 별도 Planning dispatch로
|
|
`steps[0].status`의 `blocked -> pending` 한 값 변경을 할당할 수 있다. 당시 history3,
|
|
blocked_reason/blocked_at/started_at/created_at 및 모든 다른 값, top/raw를 보존한다.
|
|
그 status-only edit의 actual Executor checkpoint와 재실행 명령은 다음 bounded delta에서
|
|
확정한다. 이번에는 reset하거나 실행하지 않는다. 현재 정상 backend 대안과 미완료
|
|
활성화 경계는 [E8](implementation-environment.md#e8-attempt3-후의-정상-backend-대안)에 있다.
|
|
|
|
다음 Implementation은 기존 RED/GREEN과 실패 기록을 읽고 전체 검증을 다시 수행해야 한다.
|
|
기존 full CTest는 static reference를 읽고 비교한다. 보고서 owner는 원본의 직접 수정 없음,
|
|
새 eigen comparison 미실행, 기존 static regression 비교를 구분하도록 현재 광범위한
|
|
reference 미사용 문장을 바로잡는다. Planning은 해당 보고서를 수정하지 않는다.
|
|
Harness r2 source Correction1회는 사용 완료됐으며 두 번째 source correction은 허용하지 않는다.
|
|
|
|
## R9. E8 활성화 전의 status-only checkpoint
|
|
|
|
R8의 실제 두 commit과 clean/blocked/history3 보존은
|
|
[실제 결과](../../.harness/build/mitc4-eigen-evidence/prep/attempt3/r8-wip-checkpoint-result.json)에
|
|
있다. R8 본문은 당시 명령과 경계로 남긴다. 현재 activation은
|
|
[E8](implementation-environment.md#e8-attempt3-후의-정상-backend-대안)의 Root setup →
|
|
Coordinator 감사 → 별도 Planning status-only 할당 → 아래 actual Executor checkpoint →
|
|
clean → 새 workspace-write native 순서다. 이번 Planning 문서 작업에서는 status를 바꾸지 않는다.
|
|
|
|
별도 할당을 받은 Planning은 `phases/mitc4-shell-feast-eigen-execution-prep/index.json`의
|
|
`steps[0].status` 한 값만 `blocked -> pending`으로 바꾼다. 기존 history3, 모든
|
|
timestamp/block 필드, owned_paths와 다른 JSON값/형식, top/raw는 그대로 둔다.
|
|
Gate는 HEAD 불변·한 값 외 deep-equal·exact dirty1·보호 hash·diff check다.
|
|
이 결과를 감사한 Coordinator만 아래 unchanged `_commit_paths` 명령을 수행한다.
|
|
|
|
```powershell
|
|
$ErrorActionPreference = 'Stop'
|
|
$mfePython = Join-Path (Get-Location).Path '.harness/build/mitc4-eigen-evidence/prep/classifier-correction/pytest-venv/Scripts/python.exe'
|
|
if (-not (Test-Path -LiteralPath $mfePython -PathType Leaf)) { throw 'Named Python missing' }
|
|
@'
|
|
import hashlib,json
|
|
from pathlib import Path
|
|
from scripts import execute
|
|
phase="mitc4-shell-feast-eigen-execution-prep"
|
|
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"
|
|
branch,head=ex._git_execution_identity();assert branch=="refs/heads/feat-"+phase
|
|
origin="96efbffa425ff5ce9cd1b7cebe673555273122b9"
|
|
ex._run_git_checked("merge-base","--is-ancestor",origin,"HEAD")
|
|
docs={"docs/mitc4-shell-feast-eigen/"+n for n in ("FEATURED_AGENTS.md","coordination.md",
|
|
"implementation-plan.md","implementation-environment.md","implementation-recovery.md")}
|
|
assert set(ex._run_git_checked("diff","--name-only","--no-renames",origin,"HEAD").stdout.splitlines())<=docs
|
|
protected={".codex/hooks.json":"e7e5d3c0c4fcd1e33b60680122ea7c42298d5cbde78a7f87d9e0007bf60a0fa4",
|
|
"scripts/execute.py":"64f5165fc544b3b17904c633ef3b222de79b52a0960e254c5b5c4eb99e79c2d0",
|
|
"tests/test_execute.py":"0eb0c1ca0f25199e00686b7e3ab57672b1390437d09da218a929added0346dd6",
|
|
"docs/mitc4-shell-feast-eigen/implementation-prep-evidence.md":"1e4d61997817b84b1df3933c6aa6518f030ca413edcda74393e0a0cf805e6732",
|
|
"phases/index.json":"42c9581868cc3f552ea3b42764a291098f648352f31021c7bdd7b4bebcdcf91e",
|
|
"phases/"+phase+"/step0-output.json":"d106f7ade2d678b6e0b383439b1b9b8d25f5ec32e883aed50c6fb4949a8983f1"}
|
|
for p,h in protected.items(): assert hashlib.sha256((root/p).read_bytes()).hexdigest()==h,p
|
|
path="phases/"+phase+"/index.json"
|
|
before=json.loads(ex._run_git_checked("show","HEAD:"+path).stdout)
|
|
assert before["steps"][0]["status"]=="blocked" and len(before["steps"][0]["attempt_history"])==3
|
|
expected=json.loads(json.dumps(before));expected["steps"][0]["status"]="pending"
|
|
assert ex._read_phase_index()==expected
|
|
assert set(ex._assert_step_scope(()))=={path}
|
|
assert not ex._run_git_checked("diff","--cached","--name-only").stdout.strip()
|
|
frozen={p:(root/p).read_bytes() for p in [path,*protected]}
|
|
assert ex._commit_paths([path],"chore(mitc4-shell-feast-eigen-execution-prep): queue MSVC Ninja environment recovery")
|
|
new_branch,new_head=ex._git_execution_identity()
|
|
assert new_branch==branch and new_head!=head
|
|
assert ex._run_git_checked("diff-tree","--no-commit-id","--name-only","-r",new_head).stdout.splitlines()==[path]
|
|
assert all((root/p).read_bytes()==v for p,v in frozen.items())
|
|
assert ex._read_phase_index()==expected and not ex._worktree_paths()
|
|
ex._preflight_repository()
|
|
print(json.dumps({"commit":new_head,"status":"pending","history_count":3,"clean":True}))
|
|
'@ | & $mfePython -B -X utf8 -
|
|
$mfeStatusExit = $LASTEXITCODE
|
|
if ($null -eq $mfeStatusExit) { throw 'Native exit unavailable' }
|
|
exit $mfeStatusExit
|
|
```
|
|
|
|
명령은 origin 이후 Root의 관리2/Planning3 선행 문서 checkpoint만 허용하고 source/Hook/
|
|
report/top/raw의 현재 hash를 확인한다. Phase control 한 경로만 commit하며
|
|
`_commit_step`, 완료/status 자동변경, guard override나 직접 Git commit은 사용하지 않는다.
|
|
Native exit를 즉시 전파하고 commit 전후 snapshot 및 clean preflight를 감사한다.
|
|
실패하면 bytes/원시 로그/이미 생성된 commit을 보존하고 다음 invocation을 시작하지 않는다.
|
|
E8 setup 또는 native 성공을 이 status checkpoint 성공에서 추론하지 않는다.
|
|
|
|
## R10. Attempt4의 error/history4 보존
|
|
|
|
[Executor 결과](../../.harness/build/mitc4-eigen-evidence/prep/attempt4/executor-result.json)와
|
|
[terminal archive](../../.harness/build/mitc4-eigen-evidence/prep/attempt4/terminal-archive.json)는
|
|
native PowerShell1, Codex0, transportFailure null과 report1/controls2만의 변경을 기록한다.
|
|
현재 Step0/top은 error/history4다. Classifier37/focused136은 통과했지만 required manual
|
|
build는 GoogleTest JSON parsing에서 실패했고 manual CTest/full pytest는 미실행이다.
|
|
후속 단독 discovery와 등록 CTest 성공으로 최초 실패를 대체하지 않는다.
|
|
|
|
[프로세스 관찰](../../.harness/build/mitc4-eigen-evidence/prep/attempt4/root-process-observations.json)의
|
|
registered Ninja build/CTest0·362pass 및 Python 두 개0과 외부 pwsh1은 별개의 실제 결과다.
|
|
Whole Stop0으로 합치지 않는다. [원시 선택 이벤트](../../.harness/build/mitc4-eigen-evidence/prep/attempt4/raw-audit-selected-events.json)의
|
|
item67 direct discovery0은 뒤의 빈 log 조회 때문에 전체 shell1이고 item68은 memo/hash0이다.
|
|
176-byte log는 후속 관찰 메모이며 해당 direct 실행 stdout 원본으로 치환하지 않는다.
|
|
|
|
Root가 frozen 관리/Planning 문서만 exact checkpoint한 뒤 Coordinator가 아래 unchanged
|
|
Executor method invocation으로 report1 WIP와 controls2 error 보존을 분리 commit한다.
|
|
사용자 요청 [Root 설명문서](msvc-build-access-error.md)의 기존 commit도 origin 이후
|
|
허용 문서에 포함하며 현재 bytes/hash를 보존한다. Source/Hook/config/cache 변경,
|
|
`_commit_step`, 상태 성공·reset, guard override와 직접 Git commit은 없다.
|
|
|
|
```powershell
|
|
$ErrorActionPreference = 'Stop'
|
|
$mfePython = Join-Path (Get-Location).Path '.harness/build/mitc4-eigen-evidence/prep/classifier-correction/pytest-venv/Scripts/python.exe'
|
|
if (-not (Test-Path -LiteralPath $mfePython -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="23c4ebe526260d584247804d8cbe2f7aa8cc60ac"
|
|
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,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/"+n for n in ("FEATURED_AGENTS.md","PRD.md","ADR.md","coordination.md","msvc-build-access-error.md","implementation-plan.md","implementation-environment.md","implementation-recovery.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()
|
|
expected={".codex/hooks.json":"e7e5d3c0c4fcd1e33b60680122ea7c42298d5cbde78a7f87d9e0007bf60a0fa4",
|
|
"docs/mitc4-shell-feast-eigen/implementation-prep-evidence.md":"fc88f1c943f7f25d7eeece87dbbd967a6007b14b0adce342ced9aa78f4cd20b2",
|
|
"phases/index.json":"33d911587305cc96148a3e60f9ca32f9ec114ce75e49118391bcc1ef3a6692c3",
|
|
"phases/"+phase+"/index.json":"3f4ce6178172819f3e1ab4310db61bc318348aeea822b806d4dcca676b53a60f",
|
|
"phases/"+phase+"/step0-output.json":"c74f18d0b681f6ab7480b825de4458188fb6b204147ab84b08582820039cab61",
|
|
"scripts/execute.py":"64f5165fc544b3b17904c633ef3b222de79b52a0960e254c5b5c4eb99e79c2d0",
|
|
"tests/test_execute.py":"0eb0c1ca0f25199e00686b7e3ab57672b1390437d09da218a929added0346dd6"}
|
|
expected.update({
|
|
"docs/mitc4-shell-feast-eigen/msvc-build-access-error.md":"0722dff075e706977d55eb1ac2514d4318b1341adab30a51fc82c744315f1c9f",
|
|
".harness/config.json":"3ebdfa80124f1eb96909b2738d6f2a96fecd55cce61150a9cd7ef27d7c5fd892",
|
|
".harness/build-ninja-msvc-debug/CMakeCache.txt":"bf024961a7469672d1fd4f9e8b6606fc1ccaac3fa40dea25709ec4c00ddd5d0e",
|
|
".harness/build/CMakeCache.txt":"d880104fdc3f1411119ce787c0ddb9a63db23de3f571ba2fedce1c56cb91085b"})
|
|
for p,h in expected.items():assert hashlib.sha256((root/p).read_bytes()).hexdigest()==h,p
|
|
assert ast.dump(ast.parse((root/"scripts/execute.py").read_text(encoding="utf-8")))==ast.dump(ast.parse(ex._run_git_checked("show",origin+":scripts/execute.py").stdout))
|
|
old_hook=json.loads(ex._run_git_checked("show",origin+":.codex/hooks.json").stdout)
|
|
assert json.loads((root/".codex/hooks.json").read_bytes())==old_hook
|
|
idx=ex._read_phase_index();top=ex._read_top_index()
|
|
assert idx["steps"][0]["status"]=="error" and len(idx["steps"][0]["attempt_history"])==4
|
|
assert next(p for p in top["phases"] if p["dir"]==phase)["status"]=="error"
|
|
owned=ex._step_owned_paths(idx["steps"][0]);assert len(owned)==9
|
|
code=["docs/mitc4-shell-feast-eigen/implementation-prep-evidence.md"]
|
|
control=["phases/index.json","phases/"+phase+"/index.json"]
|
|
assert set(ex._assert_step_scope(owned))==set(code+control)
|
|
frozen={p:(root/p).read_bytes() for p in list(owned)+list(expected)+["phases/"+phase+"/step0.md","phases/mitc4-shell-feast-eigen/index.json"]}
|
|
for paths,message in (
|
|
(code,"chore(mitc4-shell-feast-eigen-execution-prep): WIP prep report with discovery build failure"),
|
|
(control,"chore(mitc4-shell-feast-eigen-execution-prep): preserve attempt 4 error metadata")):
|
|
assert all((root/p).read_bytes()==v for p,v in frozen.items())
|
|
assert ex._git_execution_identity()==(branch,head)
|
|
assert ex._commit_paths(paths,message,owned_paths=owned)
|
|
new_branch,new_head=ex._git_execution_identity()
|
|
assert new_branch==branch and new_head!=head
|
|
actual=ex._run_git_checked("diff-tree","--no-commit-id","--name-only","--no-renames","-r",new_head).stdout.splitlines()
|
|
assert set(actual)==set(paths)
|
|
assert all((root/p).read_bytes()==v for p,v in frozen.items())
|
|
assert ex._read_phase_index()==idx and ex._read_top_index()==top
|
|
print(json.dumps({"commit":new_head,"paths":actual,"status":"error","history_count":4}))
|
|
head=new_head
|
|
assert not ex._worktree_paths()
|
|
ex._preflight_repository()
|
|
print(json.dumps({"head":head,"branch":branch,"clean":True}))
|
|
'@ | & $mfePython -B -X utf8 -
|
|
$mfeWipExit = $LASTEXITCODE
|
|
if ($null -eq $mfeWipExit) { throw 'Native exit unavailable' }
|
|
exit $mfeWipExit
|
|
```
|
|
|
|
검사 실패 시 이미 생성된 commit, 남은 dirty 파일과 원시 기록을 보존하고 반환한다.
|
|
이 명령 성공은 실패의 안전한 보존일 뿐 prep gate 통과가 아니다.
|
|
R11 status edit와 E9 실행은 별도 할당 전 미실행이다. 현재 resolver의 canonical Stop1800
|
|
해석은 확인됐지만 정상 override 지원·적용 방법이 미확정이므로 현재는 보존만 진행한다.
|
|
기존 exact owned9와 r2 source Correction1회 소진을 유지한다.
|
|
|
|
## R11. R10 뒤의 별도 status-only 복구
|
|
|
|
R10 실제 두 commit/clean 감사와 [E9 환경 진입 조건](implementation-environment.md#e9-attempt4-후의-직렬-ninja-검증)이
|
|
해소된 뒤 Coordinator가 별도 할당할 때만 Planning이 Step0의 `status` 한 값을
|
|
`error -> pending`으로 바꾼다. 나머지 모든 JSON/bytes, error_message/failed_at/started_at,
|
|
created_at, history4, owned_paths, top/raw는 보존한다. 이번 문서 작업에서는 바꾸지 않는다.
|
|
그 한 값 diff/HEAD/staging/hash 감사를 받은 Coordinator만 아래 control checkpoint를 실행한다.
|
|
|
|
```powershell
|
|
$ErrorActionPreference = 'Stop'
|
|
$mfePython = Join-Path (Get-Location).Path '.harness/build/mitc4-eigen-evidence/prep/classifier-correction/pytest-venv/Scripts/python.exe'
|
|
if (-not (Test-Path -LiteralPath $mfePython -PathType Leaf)) { throw 'Named Python missing' }
|
|
@'
|
|
import hashlib,json
|
|
from pathlib import Path
|
|
from scripts import execute
|
|
phase="mitc4-shell-feast-eigen-execution-prep"
|
|
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"
|
|
branch,head=ex._git_execution_identity();assert branch=="refs/heads/feat-"+phase
|
|
origin="23c4ebe526260d584247804d8cbe2f7aa8cc60ac"
|
|
ex._run_git_checked("merge-base","--is-ancestor",origin,"HEAD")
|
|
report="docs/mitc4-shell-feast-eigen/implementation-prep-evidence.md"
|
|
controls={"phases/index.json","phases/"+phase+"/index.json"}
|
|
docs={"docs/mitc4-shell-feast-eigen/"+n for n in ("FEATURED_AGENTS.md","PRD.md","ADR.md",
|
|
"coordination.md","msvc-build-access-error.md","implementation-plan.md","implementation-environment.md","implementation-recovery.md")}
|
|
assert set(ex._run_git_checked("diff","--name-only","--no-renames",origin,"HEAD").stdout.splitlines())<=docs|controls|{report,".gitignore"}
|
|
ignore_commit="3cfbefb000dfbe8afc7a743213146ab7253cbbc0"
|
|
ex._run_git_checked("merge-base","--is-ancestor",ignore_commit,"HEAD")
|
|
assert ex._run_git_checked("log","-1","--format=%H","--",".gitignore").stdout.strip()==ignore_commit
|
|
assert ex._run_git_checked("diff-tree","--no-commit-id","--name-only","-r",ignore_commit).stdout.splitlines()==[".gitignore"]
|
|
for paths,probe in ((controls,"phases/"+phase+"/index.json"),({report},report)):
|
|
commit=ex._run_git_checked("log","-1","--format=%H","--",probe).stdout.strip()
|
|
actual=set(ex._run_git_checked("diff-tree","--no-commit-id","--name-only","--no-renames","-r",commit).stdout.splitlines())
|
|
assert actual==paths
|
|
protected={".codex/hooks.json":"e7e5d3c0c4fcd1e33b60680122ea7c42298d5cbde78a7f87d9e0007bf60a0fa4",
|
|
"scripts/execute.py":"64f5165fc544b3b17904c633ef3b222de79b52a0960e254c5b5c4eb99e79c2d0",
|
|
"tests/test_execute.py":"0eb0c1ca0f25199e00686b7e3ab57672b1390437d09da218a929added0346dd6",
|
|
report:"fc88f1c943f7f25d7eeece87dbbd967a6007b14b0adce342ced9aa78f4cd20b2",
|
|
"phases/index.json":"33d911587305cc96148a3e60f9ca32f9ec114ce75e49118391bcc1ef3a6692c3",
|
|
"phases/"+phase+"/step0-output.json":"c74f18d0b681f6ab7480b825de4458188fb6b204147ab84b08582820039cab61",
|
|
".gitignore":"e9a67c202173c7b049429bb3eddc6dd921a4a76e7a5d248604fa8bdfb2ecdd68",
|
|
"CMakeUserPresets.json":"c4665b004be903c4beb913967143c0b0ac4da7e7d857a8c2f09e48754e865e9c",
|
|
".harness/config.json":"47ea5f1da7f6c0312429ead5a3d6d1c71fa884c49e511c1608e7fcccd90d796d",
|
|
".harness/build-ninja-msvc-debug/CMakeCache.txt":"4c2ad564d2f84deb1b8f5e055941ff18f8ba1826b4cd7f197f0bdfbdafe074b5",
|
|
".harness/build/CMakeCache.txt":"d880104fdc3f1411119ce787c0ddb9a63db23de3f571ba2fedce1c56cb91085b"}
|
|
for p,h in protected.items():assert hashlib.sha256((root/p).read_bytes()).hexdigest()==h,p
|
|
path="phases/"+phase+"/index.json"
|
|
before=json.loads(ex._run_git_checked("show","HEAD:"+path).stdout)
|
|
assert before["steps"][0]["status"]=="error" and len(before["steps"][0]["attempt_history"])==4
|
|
expected=json.loads(json.dumps(before));expected["steps"][0]["status"]="pending"
|
|
assert ex._read_phase_index()==expected
|
|
assert set(ex._assert_step_scope(()))=={path}
|
|
assert not ex._run_git_checked("diff","--cached","--name-only").stdout.strip()
|
|
frozen={p:(root/p).read_bytes() for p in [path,*protected]}
|
|
assert ex._commit_paths([path],"chore(mitc4-shell-feast-eigen-execution-prep): queue serial Ninja environment recovery")
|
|
new_branch,new_head=ex._git_execution_identity()
|
|
assert new_branch==branch and new_head!=head
|
|
assert ex._run_git_checked("diff-tree","--no-commit-id","--name-only","-r",new_head).stdout.splitlines()==[path]
|
|
assert all((root/p).read_bytes()==v for p,v in frozen.items())
|
|
assert ex._read_phase_index()==expected and not ex._worktree_paths()
|
|
ex._preflight_repository()
|
|
print(json.dumps({"commit":new_head,"status":"pending","history_count":4,"clean":True}))
|
|
'@ | & $mfePython -B -X utf8 -
|
|
$mfeStatusExit = $LASTEXITCODE
|
|
if ($null -eq $mfeStatusExit) { throw 'Native exit unavailable' }
|
|
exit $mfeStatusExit
|
|
```
|
|
|
|
R10 report1/controls2 commit 경로와 HEAD의 error/history4를 검사하므로 미보존 상태에서
|
|
pending 재실행을 시작하지 않는다. 실제 source/Hook/config 및 기존 cache는 그대로다.
|
|
각 native exit와 clean을 확인하고, 다음 E9 invocation은 Coordinator가 새 process로
|
|
별도 할당한다. 실패를 재분류해 새 Correction budget을 만들거나 자동 재시도하지 않는다.
|
|
|
|
## R12. User preset setup 이후의 stale hash 경계
|
|
|
|
R10은 실제 report `fc032212f75b9008f0a46e0f2d9f3736f184b05f`/controls
|
|
`aa03fc3d049b82f519db1962b5da592524a1c496`로 완료됐다. 과거 R10 명령을 다시 실행하지 않는다.
|
|
[E10](implementation-environment.md#e10-부모-환경과-독립적인-workspace-user-preset)의 최초 setup1과
|
|
[같은 preset configure 후속0](../../.harness/build/mitc4-eigen-evidence/prep/attempt4/root-e10-setup/configure-followup/result.json)을
|
|
구분한다. 이번 read-only 확인에서 실제 UserPresets/config/cache/ignore hash는 Root 관찰과 같았다.
|
|
그 값과 exact ignore1줄 commit만 R11에 반영했다. Source/Hook/control/history4/raw 및
|
|
unchanged `_commit_paths` guard를 유지하며 R10 보존 명령을 재실행하지 않는다.
|
|
|
|
사용자의 후속 응답은 Root가 MFE-OQ-004의 제시된 한 값 변경·정상 재신뢰 승인으로 해석했다.
|
|
Root의 **actual canonical7500/enabled/trusted** evidence가 확인되기 전에는 R11 status 변경과
|
|
새 native를 할당하지 않는다. 새 DFA/remote 권한은 없다. 현재 정상 invocation은
|
|
[E11](implementation-environment.md#e11-실제-local-설정에-대한-정상-invocation)을 따른다.
|
|
이번 task는 Planning3문서뿐이며 phase/status/Git/설정/실행 권한이 아니다.
|
|
|
|
## R13. Attempt5 명령 정합과 실패 보존
|
|
|
|
[실제 결과](../../.harness/build/mitc4-eigen-evidence/prep/attempt5/e11-result.json)와
|
|
[terminal audit](../../.harness/build/mitc4-eigen-evidence/prep/attempt5/coordinator-terminal-audit.json)는
|
|
native2/Codex0·blocked/history5를 보존한다. Manual37/4와 focused136 세 실행은 통과했지만
|
|
과거 VS configure/build를 실행해 build1이었다. Manual CTest/full pytest는 미실행이다.
|
|
Registered local Ninja의 full362/CTest·Stop Python·wrapper0은 별도 자동 결과이며
|
|
registered build exit의 관찰 공백도 남긴다. 이는 새 local Ninja 실패나 source Correction이 아니다.
|
|
[명령 원시 관찰](../../.harness/build/mitc4-eigen-evidence/prep/attempt5/manual-command-events-observation.json)을
|
|
유지하고 r.output-only 표시 때문에 결과가 보이지 않았던 실행을 미실행으로 바꾸지 않는다.
|
|
|
|
현재 prep/main9 Step 본문의 active CMake/CTest를 local preset으로 직접 고쳤다.
|
|
Root가 frozen 관리/Planning/9 Step definitions/사용자 설명문서를 먼저 exact checkpoint한 뒤,
|
|
Coordinator가 아래 unchanged Executor로 report1 WIP와 controls2 blocked metadata를 분리 commit한다.
|
|
Source/config/reference/Hook, current history5/첫4 history 및 raw는 보존하고
|
|
`_commit_step`, 완료 판정·reset·guard override는 하지 않는다.
|
|
|
|
```powershell
|
|
$ErrorActionPreference = 'Stop'
|
|
$mfePython = Join-Path (Get-Location).Path '.harness/build/mitc4-eigen-evidence/prep/classifier-correction/pytest-venv/Scripts/python.exe'
|
|
if (-not (Test-Path -LiteralPath $mfePython -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="c051adc9c3feb4ff85758eeaf06ae08be277b097"
|
|
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,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/"+n for n in ("FEATURED_AGENTS.md","PRD.md","ADR.md","coordination.md","msvc-build-access-error.md","implementation-plan.md","implementation-environment.md","implementation-recovery.md")}
|
|
definitions={"phases/"+phase+"/step0.md"}|{"phases/mitc4-shell-feast-eigen/step"+str(i)+".md" for i in range(8)}
|
|
assert set(ex._run_git_checked("diff","--name-only","--no-renames",origin,"HEAD").stdout.splitlines())<=docs|definitions
|
|
assert not ex._run_git_checked("diff","--cached","--name-only").stdout.strip()
|
|
expected={".codex/hooks.json":"e7e5d3c0c4fcd1e33b60680122ea7c42298d5cbde78a7f87d9e0007bf60a0fa4",
|
|
"docs/mitc4-shell-feast-eigen/implementation-prep-evidence.md":"7789386f17c416fb21cd82514e71f1504e6ee8998bc9e886931d55bb76eeec62",
|
|
"phases/index.json":"b291eebdf5782763bcad37d7c22de91c813c44922c76b8cbdd0b019f71b3b612",
|
|
"phases/"+phase+"/index.json":"6d4ba8f2960bf55169b1ffac740151014bf5d8a47673ecdec5c557c65629cf0e",
|
|
"phases/"+phase+"/step0-output.json":"915c56af488d477cbff46b24d1744e46305d50cac71d77466a8fcf49508302c9",
|
|
"scripts/execute.py":"64f5165fc544b3b17904c633ef3b222de79b52a0960e254c5b5c4eb99e79c2d0",
|
|
"tests/test_execute.py":"0eb0c1ca0f25199e00686b7e3ab57672b1390437d09da218a929added0346dd6"}
|
|
expected.update({
|
|
".gitignore":"e9a67c202173c7b049429bb3eddc6dd921a4a76e7a5d248604fa8bdfb2ecdd68",
|
|
"CMakeUserPresets.json":"c4665b004be903c4beb913967143c0b0ac4da7e7d857a8c2f09e48754e865e9c",
|
|
".harness/config.json":"47ea5f1da7f6c0312429ead5a3d6d1c71fa884c49e511c1608e7fcccd90d796d",
|
|
".harness/build-ninja-msvc-debug/CMakeCache.txt":"f58c337fc09fccd29c088b2a65859f6c925322dfc8eb7bea9d1509518a2b3d87",
|
|
".harness/build/CMakeCache.txt":"d880104fdc3f1411119ce787c0ddb9a63db23de3f571ba2fedce1c56cb91085b"})
|
|
for p,h in expected.items():assert hashlib.sha256((root/p).read_bytes()).hexdigest()==h,p
|
|
assert ast.dump(ast.parse((root/"scripts/execute.py").read_text(encoding="utf-8")))==ast.dump(ast.parse(ex._run_git_checked("show",origin+":scripts/execute.py").stdout))
|
|
old_hook=json.loads(ex._run_git_checked("show",origin+":.codex/hooks.json").stdout)
|
|
assert json.loads((root/".codex/hooks.json").read_bytes())==old_hook
|
|
canonical=Path("C:/git/FESADev/.codex/hooks.json")
|
|
canonical_bytes=canonical.read_bytes()
|
|
assert hashlib.sha256(canonical_bytes).hexdigest()=="c8065e7b60882da5db3f90d57b265da25b3c25980bf669d0b1da863e621871ca"
|
|
idx=ex._read_phase_index();top=ex._read_top_index()
|
|
assert idx["steps"][0]["status"]=="blocked" and len(idx["steps"][0]["attempt_history"])==5
|
|
assert next(p for p in top["phases"] if p["dir"]==phase)["status"]=="blocked"
|
|
owned=ex._step_owned_paths(idx["steps"][0]);assert len(owned)==9
|
|
code=["docs/mitc4-shell-feast-eigen/implementation-prep-evidence.md"]
|
|
control=["phases/index.json","phases/"+phase+"/index.json"]
|
|
assert set(ex._assert_step_scope(owned))==set(code+control)
|
|
frozen={p:(root/p).read_bytes() for p in list(owned)+list(expected)+list(definitions)+["phases/mitc4-shell-feast-eigen/index.json","docs/mitc4-shell-feast-eigen/msvc-build-access-error.md"]}
|
|
for paths,message in (
|
|
(code,"chore(mitc4-shell-feast-eigen-execution-prep): WIP prep report with manual backend mismatch"),
|
|
(control,"chore(mitc4-shell-feast-eigen-execution-prep): preserve attempt 5 blocked metadata")):
|
|
assert all((root/p).read_bytes()==v for p,v in frozen.items())
|
|
assert ex._git_execution_identity()==(branch,head)
|
|
assert ex._commit_paths(paths,message,owned_paths=owned)
|
|
new_branch,new_head=ex._git_execution_identity()
|
|
assert new_branch==branch and new_head!=head
|
|
actual=ex._run_git_checked("diff-tree","--no-commit-id","--name-only","--no-renames","-r",new_head).stdout.splitlines()
|
|
assert set(actual)==set(paths)
|
|
assert all((root/p).read_bytes()==v for p,v in frozen.items())
|
|
assert ex._read_phase_index()==idx and ex._read_top_index()==top
|
|
assert canonical.read_bytes()==canonical_bytes
|
|
print(json.dumps({"commit":new_head,"paths":actual,"status":"blocked","history_count":5}))
|
|
head=new_head
|
|
assert not ex._worktree_paths()
|
|
ex._preflight_repository()
|
|
print(json.dumps({"head":head,"branch":branch,"clean":True}))
|
|
'@ | & $mfePython -B -X utf8 -
|
|
$mfeWipExit = $LASTEXITCODE
|
|
if ($null -eq $mfeWipExit) { throw 'Native exit unavailable' }
|
|
exit $mfeWipExit
|
|
```
|
|
|
|
실제 두 commit/clean 감사 뒤 **별도 Planning 할당**에서 Step0.status의
|
|
`blocked -> pending` 한 값만 바꾼다. 다른 bytes/JSON·timestamp·blocked fields·owned_paths·
|
|
history5·top/raw를 보존한다. 그 한 값 diff를 감사한 Coordinator만 아래 control checkpoint를 실행한다.
|
|
이번 Planning은 status를 바꾸거나 어느 명령도 실행하지 않았다.
|
|
|
|
```powershell
|
|
$ErrorActionPreference = 'Stop'
|
|
$mfePython = Join-Path (Get-Location).Path '.harness/build/mitc4-eigen-evidence/prep/classifier-correction/pytest-venv/Scripts/python.exe'
|
|
if (-not (Test-Path -LiteralPath $mfePython -PathType Leaf)) { throw 'Named Python missing' }
|
|
@'
|
|
import hashlib,json
|
|
from pathlib import Path
|
|
from scripts import execute
|
|
phase="mitc4-shell-feast-eigen-execution-prep"
|
|
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"
|
|
branch,head=ex._git_execution_identity();assert branch=="refs/heads/feat-"+phase
|
|
origin="c051adc9c3feb4ff85758eeaf06ae08be277b097"
|
|
ex._run_git_checked("merge-base","--is-ancestor",origin,"HEAD")
|
|
report="docs/mitc4-shell-feast-eigen/implementation-prep-evidence.md"
|
|
controls={"phases/index.json","phases/"+phase+"/index.json"}
|
|
docs={"docs/mitc4-shell-feast-eigen/"+n for n in ("FEATURED_AGENTS.md","PRD.md","ADR.md",
|
|
"coordination.md","msvc-build-access-error.md","implementation-plan.md","implementation-environment.md","implementation-recovery.md")}
|
|
definitions={"phases/"+phase+"/step0.md"}|{"phases/mitc4-shell-feast-eigen/step"+str(i)+".md" for i in range(8)}
|
|
assert set(ex._run_git_checked("diff","--name-only","--no-renames",origin,"HEAD").stdout.splitlines())<=docs|definitions|controls|{report}
|
|
for paths,probe in ((controls,"phases/"+phase+"/index.json"),({report},report)):
|
|
commit=ex._run_git_checked("log","-1","--format=%H","--",probe).stdout.strip()
|
|
actual=set(ex._run_git_checked("diff-tree","--no-commit-id","--name-only","--no-renames","-r",commit).stdout.splitlines())
|
|
assert actual==paths
|
|
protected={".codex/hooks.json":"e7e5d3c0c4fcd1e33b60680122ea7c42298d5cbde78a7f87d9e0007bf60a0fa4",
|
|
"scripts/execute.py":"64f5165fc544b3b17904c633ef3b222de79b52a0960e254c5b5c4eb99e79c2d0",
|
|
"tests/test_execute.py":"0eb0c1ca0f25199e00686b7e3ab57672b1390437d09da218a929added0346dd6",
|
|
report:"7789386f17c416fb21cd82514e71f1504e6ee8998bc9e886931d55bb76eeec62",
|
|
"phases/index.json":"b291eebdf5782763bcad37d7c22de91c813c44922c76b8cbdd0b019f71b3b612",
|
|
"phases/"+phase+"/step0-output.json":"915c56af488d477cbff46b24d1744e46305d50cac71d77466a8fcf49508302c9",
|
|
".gitignore":"e9a67c202173c7b049429bb3eddc6dd921a4a76e7a5d248604fa8bdfb2ecdd68",
|
|
"CMakeUserPresets.json":"c4665b004be903c4beb913967143c0b0ac4da7e7d857a8c2f09e48754e865e9c",
|
|
".harness/config.json":"47ea5f1da7f6c0312429ead5a3d6d1c71fa884c49e511c1608e7fcccd90d796d",
|
|
".harness/build-ninja-msvc-debug/CMakeCache.txt":"f58c337fc09fccd29c088b2a65859f6c925322dfc8eb7bea9d1509518a2b3d87",
|
|
".harness/build/CMakeCache.txt":"d880104fdc3f1411119ce787c0ddb9a63db23de3f571ba2fedce1c56cb91085b"}
|
|
for p,h in protected.items():assert hashlib.sha256((root/p).read_bytes()).hexdigest()==h,p
|
|
canonical=Path("C:/git/FESADev/.codex/hooks.json")
|
|
canonical_bytes=canonical.read_bytes()
|
|
assert hashlib.sha256(canonical_bytes).hexdigest()=="c8065e7b60882da5db3f90d57b265da25b3c25980bf669d0b1da863e621871ca"
|
|
path="phases/"+phase+"/index.json"
|
|
before=json.loads(ex._run_git_checked("show","HEAD:"+path).stdout)
|
|
assert before["steps"][0]["status"]=="blocked" and len(before["steps"][0]["attempt_history"])==5
|
|
expected=json.loads(json.dumps(before));expected["steps"][0]["status"]="pending"
|
|
assert ex._read_phase_index()==expected
|
|
assert set(ex._assert_step_scope(()))=={path}
|
|
assert not ex._run_git_checked("diff","--cached","--name-only").stdout.strip()
|
|
frozen={p:(root/p).read_bytes() for p in [path,*protected,*definitions]}
|
|
assert ex._commit_paths([path],"chore(mitc4-shell-feast-eigen-execution-prep): queue aligned local preset verification")
|
|
new_branch,new_head=ex._git_execution_identity()
|
|
assert new_branch==branch and new_head!=head
|
|
assert ex._run_git_checked("diff-tree","--no-commit-id","--name-only","-r",new_head).stdout.splitlines()==[path]
|
|
assert all((root/p).read_bytes()==v for p,v in frozen.items())
|
|
assert ex._read_phase_index()==expected and not ex._worktree_paths()
|
|
assert canonical.read_bytes()==canonical_bytes
|
|
ex._preflight_repository()
|
|
print(json.dumps({"commit":new_head,"status":"pending","history_count":5,"clean":True}))
|
|
'@ | & $mfePython -B -X utf8 -
|
|
$mfeStatusExit = $LASTEXITCODE
|
|
if ($null -eq $mfeStatusExit) { throw 'Native exit unavailable' }
|
|
exit $mfeStatusExit
|
|
```
|
|
|
|
Root/Coordinator는 actual invocation 동안 non-owned 편집·commit을 멈춘다.
|
|
WIP나 checkpoint 실패 시 이미 만든 commit과 dirty bytes/원시 evidence를 보존하고 반환한다.
|
|
이후 같은 [E11](implementation-environment.md#e11-실제-local-설정에-대한-정상-invocation)의
|
|
workspace-write/terra/xhigh/유한14400 새 process를 별도 할당한다. Step에 직접 적힌
|
|
local preset·직렬 clean-first·세 discovery·모든 Python/full CTest·fresh manual/reference·
|
|
registered actual evidence를 완료해야 하며 자동 결과로 manual 실패를 대체하지 않는다.
|
|
새 source key/DFA/policy/runner 변경이나 자동 재시도는 없다.
|