docs: prepare MSVC Ninja environment recovery

This commit is contained in:
KOKO\Mimi
2026-09-06 16:28:38 +09:00
parent 96efbffa42
commit 7d714c2713
5 changed files with 344 additions and 32 deletions
@@ -53,8 +53,8 @@ Reference artifact와 공통 정책은 수정하지 않는다. 외부 solver 실
| [io-schema.md](io-schema.md) | io-definition-agent | r2 | 기존 static 보존·eigen discriminant·N vectors/all-c evidence·self-check | | [io-schema.md](io-schema.md) | io-definition-agent | r2 | 기존 static 보존·eigen discriminant·N vectors/all-c evidence·self-check |
| [io-mapping.md](io-mapping.md) | io-definition-agent | r2 | 책임·candidate 보존·TXT Value-only·27개 요구/11개 I/O 검증 obligation | | [io-mapping.md](io-mapping.md) | io-definition-agent | r2 | 책임·candidate 보존·TXT Value-only·27개 요구/11개 I/O 검증 obligation |
| [implementation-plan.md](implementation-plan.md) | implementation-planning-agent | r2 | Prep 1/main 8개 step 및 실행 계획 gate pass | | [implementation-plan.md](implementation-plan.md) | implementation-planning-agent | r2 | Prep 1/main 8개 step 및 실행 계획 gate pass |
| [implementation-environment.md](implementation-environment.md) | implementation-planning-agent | r2 | 실제 backend·유한 deadline·bootstrap/activation·Git/사후 evidence 경계 | | [implementation-environment.md](implementation-environment.md) | implementation-planning-agent | r2 | E8 기존 Ninja preset의 exact Root setup/native·registered same graph 명령 감사 완료; actual native 성공은 미검증 |
| [implementation-recovery.md](implementation-recovery.md) | implementation-planning-agent | r2 | R8 attempt3 실패 보존 명령 감사 완료; E8 정상 backend 요약은 미실행이며 상세 활성화 미확정 | | [implementation-recovery.md](implementation-recovery.md) | implementation-planning-agent | r2 | R8 실패 보존 실제 완료; R9 별도 status-only/Executor checkpoint 계획 감사 완료, 실행 상태는 coordination |
| [implementation-interfaces.md](implementation-interfaces.md) | implementation-planning-agent | r2 | 기존 확장점·API/source-test·vendor/state/transaction 책임 | | [implementation-interfaces.md](implementation-interfaces.md) | implementation-planning-agent | r2 | 기존 확장점·API/source-test·vendor/state/transaction 책임 |
| [implementation-verification.md](implementation-verification.md) | implementation-planning-agent | r2 | 요구27/NR27/I/O11·신규 test40·독립 oracle·fresh evidence·실제 validator | | [implementation-verification.md](implementation-verification.md) | implementation-planning-agent | r2 | 요구27/NR27/I/O11·신규 test40·독립 oracle·fresh evidence·실제 validator |
| [implementation-prep-evidence.md](implementation-prep-evidence.md) | implementation-agent | r2 | attempt1/2 역사와 attempt3 classifier37/focused136 pass·manual build 환경 차단; 별도 registered362 pass와 terminal 판정은 coordination 참조 | | [implementation-prep-evidence.md](implementation-prep-evidence.md) | implementation-agent | r2 | attempt1/2 역사와 attempt3 classifier37/focused136 pass·manual build 환경 차단; 별도 registered362 pass와 terminal 판정은 coordination 참조 |
+9 -1
View File
@@ -5,7 +5,7 @@
- Contract revision: `r2` (사용자 승인 stabilization 개선·영향받는 정적/eigen 재검증 범위) - Contract revision: `r2` (사용자 승인 stabilization 개선·영향받는 정적/eigen 재검증 범위)
- Stage: `implementation` (E7 attempt3 종료; native build 환경 복구 검토) - Stage: `implementation` (E7 attempt3 종료; native build 환경 복구 검토)
- Outcome: `blocked-environment` - Outcome: `blocked-environment`
- Next owner: `Executor` (R8 exact report1/blocked controls2 보존; 이후 Planning의 E8 상세 delta) - Next owner: `Root` (E8.1 exact ignored 환경 setup; 이후 Planning의 R9 status-only 할당)
- Attempt: `3` (실제 blocked/history3; 기존 history2 보존) - Attempt: `3` (실제 blocked/history3; 기존 history2 보존)
- Completion: 미완료 - Completion: 미완료
- Failure classification: `environment` - Failure classification: `environment`
@@ -45,6 +45,14 @@ Root의 intake 시작 Git 조사에서는 worktree clean을 확인했다. 당시
## 현재 bounded dispatch ## 현재 bounded dispatch
Owner의 [E8](implementation-environment.md#e8-attempt3-후의-정상-backend-대안)·[R9](implementation-recovery.md#r9-e8-활성화-전의-status-only-checkpoint) 상세를 owner/r2/현재 hash와 대조해 계획 gate `pass`로 수락했다. 실제 adapter의 preset 명령4/7200 cap·기존 guard, PowerShell18 blocks/errors0, Python AST7, local links91/missing0, 고정 hash7·Executor AST·blocked/history3 보존과 diffcheck가 exit `0`이다. Root는 설치 DevShell의 실제 인수, config.example/preset의 `.harness/build-ninja-msvc-debug`, load_config 필드 및 process 환경 전체 finally 복원을 read-only 확인했다. Native Ninja 성공은 아직 미검증이다.
동결된 management2/Planning3 정확5문서의 Root checkpoint 이후 **E8.1 첫 PowerShell block 그대로**를 Root 환경 지원에 할당한다. Owned 범위는 기존 예시와 같은 ignored `.harness/config.json`, 새 `.harness/build-ninja-msvc-debug` cache 및 새 짧은 ignored TEMP뿐이다. Source/Hook/reference/기존 VS cache/phase/status/Git은 setup에서 변경하지 않는다. Actual configure 및 config-selected graph/exit·전후 tracked bytes/clean 확인이 setup gate다. 이 prepare configure를 native build/full 검증으로 대체하지 않는다. 실패하면 실제 결과와 남은 ignored 설정을 보존하고 재실행하지 않는다. 성공 후 Coordinator가 audit하고 별도 Planning의 R9 status 한 값 복구와 actual Executor checkpoint를 할당한다. E8.2 native invocation은 그 이후 clean 상태에서 별도로 시작한다.
Root exact5문서 commit `c0f3dc7c11eca7959a10ca9f8aecb5343b831d13` 뒤 [R8 실제 보존 실행](../../.harness/build/mitc4-eigen-evidence/prep/attempt3/r8-wip-checkpoint-result.json)은 native/managed exit `0`, `2.094`초로 완료했다. Actual unchanged Executor가 report1을 `9601b1f53e8a11d3e08d49cf9528fa6f028108cf`, blocked controls2를 `96efbffa425ff5ce9cd1b7cebe673555273122b9`로 구분 commit했다. [실제 stdout](../../.harness/build/mitc4-eigen-evidence/prep/attempt3/r8-wip-checkpoint-stdout.log)은 exact paths, 전후 bytes/전체 JSON/history3/raw/branch 보존과 clean을 확인한다. `_commit_step` 또는 성공 전환은 없었다.
후속 Planning의 소유는 기존 plan/environment/recovery 3문서다. 이미 확인한 정상 Ninja preset과 표준 archive output 설정의 exact Root local setup, 별도 build directory, Step0/main8·registered Stop의 같은 graph 명령 mapping 및 실제 library 존재/hash/mtime 확인을 구체화한다. Source/기존 VS cache/reference 및 검사 guard를 보존하고, default workspace-write·명시 DevShell/dependency/Python/짧은 TEMP 환경과 기존 finite14400/7500/7200 한도를 유지한다. 이후 별도 할당의 status 한 값 복구/actual Executor checkpoint와 native 검증 순서도 문서화한다. 현재 config/status/재실행은 미할당이며 이 상세 delta의 syntax·owner·경로/명령 감사 전에는 실행하지 않는다. Root는 정확히 동결된 local 환경 설정만 수행하고 Coordinator는 실제 Executor invocation/전이·audit를 맡는다.
Owner의 [R8 실패 보존 명령](implementation-recovery.md#r8-attempt3의-blocked-기록-보존)을 현재 hash/role/guard와 대조해 계획 gate `pass`로 수락했다. 정적 결과는 local links82/missing0·Python AST6·R8 PowerShell errors0·고정 hash7/Executor AST/blocked history3 불변, exit `0`이다. Coordinator 관리2문서는 local links175/missing0·diffcheck exit `0`을 확인했다. Root가 동결된 management2/Planning3 정확5문서를 checkpoint한 뒤 R8 actual unchanged Executor가 report1과 controls2를 별도 WIP commit한다. 이는 실제 prep 검증 통과가 아니다. [E8 정상 Ninja 대안](implementation-environment.md#e8-attempt3-후의-정상-backend-대안)은 현재 미실행 요약이며 WIP 보존/clean 이후 별도 Planning이 exact local config/bootstrap·같은 graph의 명령 mapping·status-only/activation을 확정한다. 지금 config/status를 변경하거나 재실행하지 않는다. Owner의 [R8 실패 보존 명령](implementation-recovery.md#r8-attempt3의-blocked-기록-보존)을 현재 hash/role/guard와 대조해 계획 gate `pass`로 수락했다. 정적 결과는 local links82/missing0·Python AST6·R8 PowerShell errors0·고정 hash7/Executor AST/blocked history3 불변, exit `0`이다. Coordinator 관리2문서는 local links175/missing0·diffcheck exit `0`을 확인했다. Root가 동결된 management2/Planning3 정확5문서를 checkpoint한 뒤 R8 actual unchanged Executor가 report1과 controls2를 별도 WIP commit한다. 이는 실제 prep 검증 통과가 아니다. [E8 정상 Ninja 대안](implementation-environment.md#e8-attempt3-후의-정상-backend-대안)은 현재 미실행 요약이며 WIP 보존/clean 이후 별도 Planning이 exact local config/bootstrap·같은 graph의 명령 mapping·status-only/activation을 확정한다. 지금 config/status를 변경하거나 재실행하지 않는다.
E7 attempt3는 [실제 wrapper result](../../.harness/build/mitc4-eigen-evidence/prep/attempt3/executor-result.json)의 native PowerShell/managed exit `2`, `1372.328`초로 종료했다. HEAD `dc6b9b1cf70b0ca1685eb1ac5476aa6f8cd3dab6`와 branch, 모든 비소유 bytes는 불변이다. Dirty는 Implementation report1/control2뿐이며 source/tests/Hook은 변하지 않았다. [Terminal archive](../../.harness/build/mitc4-eigen-evidence/prep/attempt3/terminal-archive.json)는 raw SHA-256 `d106f7ade2d678b6e0b383439b1b9b8d25f5ec32e883aed50c6fb4949a8983f1`, blocked/history3와 이전 history2 equality를 보존한다(exit `0`). Actual Codex exit `0`, 명시 reported-blocked 및 transportFailure null을 별도로 기록하며 transport retry로 재분류하지 않는다. Owner의 attempt1 표기는 전이 요청 이력으로 보존하고 Coordinator 원본은 실제 history3다. E7 attempt3는 [실제 wrapper result](../../.harness/build/mitc4-eigen-evidence/prep/attempt3/executor-result.json)의 native PowerShell/managed exit `2`, `1372.328`초로 종료했다. HEAD `dc6b9b1cf70b0ca1685eb1ac5476aa6f8cd3dab6`와 branch, 모든 비소유 bytes는 불변이다. Dirty는 Implementation report1/control2뿐이며 source/tests/Hook은 변하지 않았다. [Terminal archive](../../.harness/build/mitc4-eigen-evidence/prep/attempt3/terminal-archive.json)는 raw SHA-256 `d106f7ade2d678b6e0b383439b1b9b8d25f5ec32e883aed50c6fb4949a8983f1`, blocked/history3와 이전 history2 equality를 보존한다(exit `0`). Actual Codex exit `0`, 명시 reported-blocked 및 transportFailure null을 별도로 기록하며 transport retry로 재분류하지 않는다. Owner의 attempt1 표기는 전이 요청 이력으로 보존하고 Coordinator 원본은 실제 history3다.
@@ -253,36 +253,7 @@ foreach ($mfeRun in $mfePytestRuns) {
} }
``` ```
## E8. Attempt3 후의 정상 backend 대안
E7의 짧은 TEMP/TMP는 actual native build shell에 적용됐지만 FileTracker 접근 거부가
재발했다. 환경 누락으로 해석하지 않는다. 현재 우선 작업은
[R8](implementation-recovery.md#r8-attempt3의-blocked-기록-보존)의 실패 보존이며,
아래는 다음 bounded delta에서 구체화할 정상 backend 대안이다. 설정·configure·build·
Executor 재실행은 이번 Planning에서 수행하지 않았다.
저장소의 [MSVC Ninja preset](../../CMakePresets.json)과
[local config 예시](../../.harness/config.example.json)는 동일 Ninja graph를 manual 검증과
registered Stop이 선택할 수 있는 기존 경로다. MSVC/x64/Debug, 테스트·Hook·유한
7200/7500/14400초 한도와 workspace-write는 유지한다. 기존 config/adapter에 없는
Ninja Multi-Config 선택 기능이나 새 public preset은 만들지 않는다.
Single-config의 실제 archive 출력에는 기존 reference helper가 확인하는
`src/fesa/Debug/fesa_solver.lib`가 필요하다. 표준 CMake cache 변수
`CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG`로 새 ignored build의 해당 디렉터리를 지정하는
대안을 검토했다. Local CMake help는 archive target 속성 초기화 의미를 확인했지만,
이 선택의 actual native configure/build/full VERIFY 성공은 아직 미검증이다.
실제 library 위치/hash/mtime와 기존 cache freshness를 확인해야 하며 파일 복사나 mtime
조작으로 cache guard를 만족시키지 않는다. 기존 VS cache와 attempt evidence는 보존한다.
다음 delta에서 Root 소유의 exact ignored config/환경 setup과 Coordinator 소유의
unchanged Executor invocation을 분리해 확정한다. Prep/main의 기존 고정 build 경로를
새 preset graph에 대응시키는 명령과 registered Stop의 같은 graph 선택까지 명시한 뒤
활성화한다. 현재 E8 요약만으로 이전 명령을 임의 대체하거나 재실행하지 않는다.
기존 named Python/UV offline, 짧은 새 TEMP와 pytest basetemp, process 환경 복원은 유지한다.
이 정상 대안에는 새 DFA 승인을 요청하지 않는다. 이전 one-time DFA 승인은 소진됐으며,
정상 대안이 실제 실패하면 그 evidence로 exact-run의 새 결정을 별도로 다룬다.
Main은 prep 전체 gate와 Coordinator의 사후 감사 전 활성화하지 않는다.
CMake/MSVC/x64/Debug configure/build와 전체 CTest discovery/run은 기존 Step0의 정확한 CMake/MSVC/x64/Debug configure/build와 전체 CTest discovery/run은 기존 Step0의 정확한
명령을 같은 inherited TEMP/TMP에서 별도로 실행한다. 실패 시 actual command/exit와 남은 명령을 같은 inherited TEMP/TMP에서 별도로 실행한다. 실패 시 actual command/exit와 남은
@@ -396,3 +367,260 @@ foreach ($mfeRun in $mfePytestRuns) {
if ($null -eq $mfePytestExit -or $mfePytestExit -ne 0) { throw 'pytest verification failed' } if ($null -eq $mfePytestExit -or $mfePytestExit -ne 0) { throw 'pytest verification failed' }
} }
``` ```
## E8. Attempt3 후의 정상 backend 대안
이 절은 R8 보존 뒤의 **현재 backend 명령 계약**이다. E1~E7의 당시 실행·실패 기록은 유지한다.
[R8 실제 checkpoint 결과](../../.harness/build/mitc4-eigen-evidence/prep/attempt3/r8-wip-checkpoint-result.json)에서
report1 commit `9601b1f53e8a11d3e08d49cf9528fa6f028108cf`, controls2 commit
`96efbffa425ff5ce9cd1b7cebe673555273122b9`와 native exit0을 확인했다.
이후 status 변경·Ninja 설정·native 검증은 아직 미실행이다.
[기존 preset](../../CMakePresets.json)과 [local config 예시](../../.harness/config.example.json)를
사용한다. 새 binaryDir는 `.harness/build-ninja-msvc-debug`이며 source, 기존 VS
`.harness/build` cache와 모든 attempt evidence를 보존한다.
[CMake adapter](../../scripts/msvc_harness/adapters/cmake.py)가 지원하는 이 세 preset을 함께
선택하면 manual CMake/CTest와 registered Stop이 같은 graph를 사용한다. 기존 config에
없는 Multi-Config 선택이나 public preset/API를 추가하지 않는다.
Single-config에서도 기존 reference helper가 확인하는 실제 library 경로가
`<new binaryDir>/src/fesa/Debug/fesa_solver.lib`가 되도록 표준
`CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG`를 지정한다. Local CMake help가 설명한
per-configuration archive target 속성 초기화를 사용하며 fake cache 파일·복사·mtime 조작은
허용하지 않는다. 이 정상 MSVC/x64/Debug 대안의 **actual native 성공은 미검증**이다.
### E8.1. Root의 ignored 환경 준비
순서는 Root frozen 관리2/Planning3문서 checkpoint와 clean 확인 → 아래 Root setup의
actual configure/config 검증 → Coordinator의 setup 감사 → 별도 Planning status-only
할당과 [R9 control checkpoint](implementation-recovery.md#r9-e8-활성화-전의-status-only-checkpoint)
→ clean 확인 → E8.2 새 native invocation이다. 현재 문서 할당은 아래 setup 실행을 포함하지 않는다.
Root는 별도 할당을 받은 뒤 repository root의 PowerShell에서 아래 block만 수행한다.
Local config는 예시와 정확히 같은 기존 지원 설정만 생성하며 예상 밖 기존 config를 덮어쓰지
않는다. New CMake cache에 archive 경로를 고정하고 native/Stop의 후속 preset configure가
같은 값을 유지하게 한다. Root configure는 준비 evidence이며 native manual VERIFY의 대체가 아니다.
```powershell
$ErrorActionPreference = 'Stop'
$mfeRoot = (Get-Location).Path
$mfeVs = 'C:/Program Files/Microsoft Visual Studio/18/Community'
$mfeNinja = Join-Path $mfeVs 'Common7/IDE/CommonExtensions/Microsoft/CMake/Ninja'
$mfeEvidence = Join-Path $mfeRoot '.harness/build/mitc4-eigen-evidence/prep/classifier-correction'
$mfePython = Join-Path $mfeEvidence 'pytest-venv/Scripts/python.exe'
$mfeBasePython = Join-Path $mfeEvidence 'python-runtime/cpython-3.11.15-windows-x86_64-none/python.exe'
foreach ($mfeFile in @($mfePython, $mfeBasePython)) {
if (-not (Test-Path -LiteralPath $mfeFile -PathType Leaf)) { throw 'Named Python missing' }
}
Get-Command uv -ErrorAction Stop | Out-Null
$mfeNewBuild = Join-Path $mfeRoot '.harness/build-ninja-msvc-debug'
$mfeArchive = (Join-Path $mfeNewBuild 'src/fesa/Debug').Replace('\','/')
$mfeTempParent = Join-Path $mfeRoot '.harness/build'
$mfeTemp = Join-Path $mfeTempParent ('t-' + [guid]::NewGuid().ToString('N').Substring(0,8))
if ($mfeTemp.Length -gt 80 -or (Test-Path -LiteralPath $mfeTemp)) { throw 'TEMP must be short and new' }
$null = New-Item -ItemType Directory -Path $mfeTemp
$mfeEnvBefore = [Environment]::GetEnvironmentVariables('Process')
$mfeExit = $null
try {
& $mfePython -B -X utf8 -c "from scripts import execute; e=execute.StepExecutor('mitc4-shell-feast-eigen-execution-prep'); assert not e._worktree_paths(); assert e._is_isolated_worktree(); e._preflight_repository(); print('Clean linked worktree verified')"
$mfePreflightExit = $LASTEXITCODE
if ($mfePreflightExit -ne 0) { exit $mfePreflightExit }
$mfeConfig = Join-Path $mfeRoot '.harness/config.json'
$mfeExample = Join-Path $mfeRoot '.harness/config.example.json'
if (Test-Path -LiteralPath $mfeConfig) {
if ((Get-Content -LiteralPath $mfeConfig -Raw | ConvertFrom-Json | ConvertTo-Json -Depth 10 -Compress) -ne (Get-Content -LiteralPath $mfeExample -Raw | ConvertFrom-Json | ConvertTo-Json -Depth 10 -Compress)) { throw 'Preserve unexpected existing local config' }
} else { Copy-Item -LiteralPath $mfeExample -Destination $mfeConfig }
if ($null -ne $env:FEM_HARNESS_CODEX_SANDBOX -and $env:FEM_HARNESS_CODEX_SANDBOX -ne 'workspace-write') {
throw 'Unexpected sandbox environment'
}
& (Join-Path $mfeVs 'Common7/Tools/Launch-VsDevShell.ps1') -VsInstallationPath $mfeVs -Arch amd64 -HostArch amd64 -SkipAutomaticLocation -NoLogo
$env:PATH = (Split-Path $mfePython) + ';' + (Split-Path $mfeBasePython) + ';' + $mfeNinja + ';' + $env:PATH
$env:FESA_GTEST_SOURCE_DIR = 'C:/git/googletest'
$env:MKL_DIR = 'C:/Program Files (x86)/Intel/oneAPI/mkl/2026.1/lib/cmake/mkl'
$env:TBB_DIR = 'C:/Program Files (x86)/Intel/oneAPI/tbb/2023.1/lib/cmake/tbb'
$env:HDF5_DIR = 'C:/Program Files/HDF_Group/HDF5/2.1.1/cmake'
$env:UV_PYTHON = $mfePython
$env:UV_CACHE_DIR = Join-Path $mfeEvidence 'workspace-python-cache'
$env:UV_OFFLINE = 'true'
$env:TEMP = $mfeTemp
$env:TMP = $mfeTemp
$env:FEM_HARNESS_CODEX_SANDBOX = 'workspace-write'
Get-Command cl.exe, ninja.exe, cmake.exe, ctest.exe -ErrorAction Stop | Select-Object Name, Source
if ($env:VSCMD_ARG_TGT_ARCH -notin @('x64','amd64')) { throw 'MSVC target must be x64' }
git check-ignore --quiet .harness/config.json
if ($LASTEXITCODE -ne 0) { throw 'Local config must remain ignored' }
git check-ignore --quiet .harness/build-ninja-msvc-debug/
if ($LASTEXITCODE -ne 0) { throw 'New build must remain ignored' }
cmake --preset windows-msvc-ninja-debug "-DCMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG=$mfeArchive"
$mfePrepareExit = $LASTEXITCODE
if ($mfePrepareExit -ne 0) { exit $mfePrepareExit }
& $mfePython -B -X utf8 -c "from pathlib import Path; from scripts.msvc_harness.config import load_config; c=load_config(Path.cwd()); assert c.cmake.configure_preset=='windows-msvc-ninja-debug'; assert c.cmake.build_preset==c.cmake.test_preset==c.cmake.configure_preset; assert c.cmake.binary_dir==Path.cwd()/'.harness/build-ninja-msvc-debug'; print('Ninja local config validated')"
$mfeConfigExit = $LASTEXITCODE
if ($mfeConfigExit -ne 0) { exit $mfeConfigExit }
$mfeExit = $mfeConfigExit
if ($null -eq $mfeExit) { throw 'Root setup exit unavailable' }
}
finally {
foreach ($mfeName in @([Environment]::GetEnvironmentVariables('Process').Keys)) {
if (-not $mfeEnvBefore.Contains($mfeName)) { [Environment]::SetEnvironmentVariable($mfeName, $null, 'Process') }
}
foreach ($mfeName in $mfeEnvBefore.Keys) {
[Environment]::SetEnvironmentVariable($mfeName, $mfeEnvBefore[$mfeName], 'Process')
}
}
exit $mfeExit
```
Installed VS x64 DevShell이 설정하는 INCLUDE/LIB/PATH 등을 포함해 process 환경 전체를
snapshot/finally 복원한다. Config와 새 cache는 ignored 상태로 feature 동안 유지한다.
Root setup process의 종료가 다른 parent/tool shell의 환경을 갱신하지는 않는다.
Native의 **각 tool shell**도 E8.2의 동일 VS/dependency/Python/TEMP 설정을 실제 적용한
상태에서 명령을 실행해야 한다. 이전 attempt3의 명시적 짧은 TEMP 적용 실패를 환경 누락으로
재분류하지 않는다. Setup 실패 시 실제 exit와 남은 ignored 파일을 보존하고 재실행을 멈춘다.
### E8.2. Coordinator의 새 정상 invocation과 native shell 환경
Root setup과 R9의 실제 완료를 감사한 Coordinator만 다음 invocation을 할당한다.
`StepExecutor/main`과 모든 guard는 그대로이며 승인된 유한14400 module invocation을
사용한다. Registered Stop7500/shared·command7200, terminal 보존, transport budget,
terra/xhigh 및 workspace-write를 유지한다. 기존 one-time DFA 승인은 소진됐으며 flag가 없다.
```powershell
$ErrorActionPreference = 'Stop'
$mfeRoot = (Get-Location).Path
$mfePhase = 'mitc4-shell-feast-eigen-execution-prep'
$mfeVs = 'C:/Program Files/Microsoft Visual Studio/18/Community'
$mfeNinja = Join-Path $mfeVs 'Common7/IDE/CommonExtensions/Microsoft/CMake/Ninja'
$mfeEvidence = Join-Path $mfeRoot '.harness/build/mitc4-eigen-evidence/prep/classifier-correction'
$mfePython = Join-Path $mfeEvidence 'pytest-venv/Scripts/python.exe'
$mfeBasePython = Join-Path $mfeEvidence 'python-runtime/cpython-3.11.15-windows-x86_64-none/python.exe'
foreach ($mfeFile in @($mfePython, $mfeBasePython)) {
if (-not (Test-Path -LiteralPath $mfeFile -PathType Leaf)) { throw 'Named Python missing' }
}
Get-Command uv -ErrorAction Stop | Out-Null
$mfeNewBuild = Join-Path $mfeRoot '.harness/build-ninja-msvc-debug'
$mfeArchive = (Join-Path $mfeNewBuild 'src/fesa/Debug').Replace('\','/')
$mfeTempParent = Join-Path $mfeRoot '.harness/build'
$mfeTemp = Join-Path $mfeTempParent ('t-' + [guid]::NewGuid().ToString('N').Substring(0,8))
if ($mfeTemp.Length -gt 80 -or (Test-Path -LiteralPath $mfeTemp)) { throw 'TEMP must be short and new' }
$null = New-Item -ItemType Directory -Path $mfeTemp
$mfeEnvBefore = [Environment]::GetEnvironmentVariables('Process')
$mfeExit = $null
try {
if ($null -ne $env:FEM_HARNESS_CODEX_SANDBOX -and $env:FEM_HARNESS_CODEX_SANDBOX -ne 'workspace-write') {
throw 'Unexpected sandbox environment'
}
& (Join-Path $mfeVs 'Common7/Tools/Launch-VsDevShell.ps1') -VsInstallationPath $mfeVs -Arch amd64 -HostArch amd64 -SkipAutomaticLocation -NoLogo
$env:PATH = (Split-Path $mfePython) + ';' + (Split-Path $mfeBasePython) + ';' + $mfeNinja + ';' + $env:PATH
$env:FESA_GTEST_SOURCE_DIR = 'C:/git/googletest'
$env:MKL_DIR = 'C:/Program Files (x86)/Intel/oneAPI/mkl/2026.1/lib/cmake/mkl'
$env:TBB_DIR = 'C:/Program Files (x86)/Intel/oneAPI/tbb/2023.1/lib/cmake/tbb'
$env:HDF5_DIR = 'C:/Program Files/HDF_Group/HDF5/2.1.1/cmake'
$env:UV_PYTHON = $mfePython
$env:UV_CACHE_DIR = Join-Path $mfeEvidence 'workspace-python-cache'
$env:UV_OFFLINE = 'true'
$env:TEMP = $mfeTemp
$env:TMP = $mfeTemp
$env:FEM_HARNESS_CODEX_SANDBOX = 'workspace-write'
Get-Command cl.exe, ninja.exe, cmake.exe, ctest.exe -ErrorAction Stop | Select-Object Name, Source
if ($env:VSCMD_ARG_TGT_ARCH -notin @('x64','amd64')) { throw 'MSVC target must be x64' }
if (-not (Test-Path -LiteralPath (Join-Path $mfeNewBuild 'CMakeCache.txt'))) { throw 'Root cache preparation missing' }
& $mfePython -B -X utf8 -c "from pathlib import Path; from scripts.msvc_harness.config import load_config; c=load_config(Path.cwd()); assert c.cmake.configure_preset=='windows-msvc-ninja-debug'; assert c.cmake.build_preset==c.cmake.test_preset==c.cmake.configure_preset; assert c.cmake.binary_dir==Path.cwd()/'.harness/build-ninja-msvc-debug'; print('Ninja local config validated')"
$mfeConfigExit = $LASTEXITCODE
if ($mfeConfigExit -ne 0) { exit $mfeConfigExit }
& $mfePython -B -X utf8 -c "from scripts import execute; execute.StepExecutor.CODEX_TIMEOUT_SECONDS = 14400; execute.main()" $mfePhase
$mfeExit = $LASTEXITCODE
if ($null -eq $mfeExit) { throw 'Native Executor exit unavailable' }
}
finally {
foreach ($mfeName in @([Environment]::GetEnvironmentVariables('Process').Keys)) {
if (-not $mfeEnvBefore.Contains($mfeName)) { [Environment]::SetEnvironmentVariable($mfeName, $null, 'Process') }
}
foreach ($mfeName in $mfeEnvBefore.Keys) {
[Environment]::SetEnvironmentVariable($mfeName, $mfeEnvBefore[$mfeName], 'Process')
}
}
exit $mfeExit
```
이 block의 환경 설정은 Executor child와 그 registered Stop에 상속된다. Implementation
tool shell이 이를 상속하지 않았거나 별도 shell을 시작했다면 동일 block의 환경 설정과
finally를 그 shell에서 적용한다. **Manual 검증용 정확한 composition**은 위 block에서
`& $mfePython -B -X utf8 -c "from scripts import execute; execute.StepExecutor.CODEX_TIMEOUT_SECONDS = 14400; execute.main()" $mfePhase`
한 줄을 E8.3의 해당 검증 명령들로 교체하는 것이다. 나머지 config 검사/DevShell/환경
복원은 그대로 두며 manual shell에서 Executor를 중첩 호출하지 않는다. 각 명령 직후
`$LASTEXITCODE`를 캡처하고 0이 아니면 해당 native exit로 종료하여 finally를 실행한다.
Active Executor 동안 Root/Coordinator는 non-owned 편집과 commit을 멈춘다. 구현 owner는
Step0 보고서와 result payload만 할당 범위에서 작성하며 phase/timestamps/history/Git을
변경하지 않는다. 실제 manual evidence와 아직 발생하지 않은 final registered Stop을
구분하고 Coordinator가 native 종료 뒤 raw/Hook/CTest actual exit를 사후 감사한다.
Prep 전체 gate를 통과한 뒤 별도 main invocation은 위 block의 `$mfePhase`만
`mitc4-shell-feast-eigen`으로 바꾼다. Main도 workspace-write와 같은 환경/graph를 사용한다.
### E8.3. Prep와 main8의 정확한 명령 대응 및 evidence
Prep [Step0](../../phases/mitc4-shell-feast-eigen-execution-prep/step0.md)와
[main8](../../phases/mitc4-shell-feast-eigen/index.json)의 모든 Step은 현재 environment를
필수 입력으로 읽는다. 해당 문서의 과거 config absent/VS 고정 명령은 이번 Coordinator
E8 dispatch에서 아래 대응으로 **명시 대체**한다. 이는 선택 backend 변경이며 승인된
owned_paths, TDD 순서, target/test regex/mandatory names, full VERIFY 범위는 그대로다.
Phase 파일을 임의 수정하거나 예전 VS 명령과 새 graph를 섞지 않는다.
| 기존 Step 명령 | E8에서 실행할 명령 |
| --- | --- |
| `cmake -S . -B .harness/build -A x64` | `cmake --preset windows-msvc-ninja-debug "-DCMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG=$mfeArchive"` |
| `cmake --build .harness/build --config Debug --target fesa_tests` | `cmake --build --preset windows-msvc-ninja-debug --target fesa_tests` |
| `cmake --build .harness/build --config Debug` | `cmake --build --preset windows-msvc-ninja-debug` |
| `ctest --test-dir .harness/build -C Debug -R '<Step 원문 regex>' --show-only=json-v1` | `ctest --preset windows-msvc-ninja-debug -R '<같은 원문 regex>' --show-only=json-v1` |
| `ctest --test-dir .harness/build -C Debug -R '<Step 원문 regex>' --output-on-failure` | `ctest --preset windows-msvc-ninja-debug -R '<같은 원문 regex>' --output-on-failure` |
| `ctest --test-dir .harness/build -C Debug --show-only=json-v1` | `ctest --preset windows-msvc-ninja-debug --show-only=json-v1` |
| `ctest --test-dir .harness/build -C Debug --output-on-failure` | `ctest --preset windows-msvc-ninja-debug --output-on-failure` |
Table의 regex 표시는 새 선택값이 아니다. 현재 Step 명령의 `-R` 인수 문자열 전체를
byte 의미 그대로 유지한다. Combined selection이 0보다 크다는 것만 확인하지 않고
[V1~V6](implementation-verification.md)의 새 mandatory test 이름도 discovery에서 확인한다.
`fesa_tests`는 기존 unit/integration/reference 세 executable을 포함하는 aggregate target이다.
Manual full C++ 검증에 넣을 정확한 명령 bundle은 다음과 같다. E8.2의 `$mfeArchive`는
새 binaryDir의 absolute forward-slash 경로다. Ninja preset은 Debug를 명시하므로 VS 전용
`-A x64`나 이전 `--test-dir`를 추가하지 않는다.
```powershell
cmake --preset windows-msvc-ninja-debug "-DCMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG=$mfeArchive"
$mfeVerifyExit = $LASTEXITCODE
if ($null -eq $mfeVerifyExit -or $mfeVerifyExit -ne 0) { exit $mfeVerifyExit }
cmake --build --preset windows-msvc-ninja-debug
$mfeVerifyExit = $LASTEXITCODE
if ($null -eq $mfeVerifyExit -or $mfeVerifyExit -ne 0) { exit $mfeVerifyExit }
ctest --preset windows-msvc-ninja-debug --show-only=json-v1
$mfeVerifyExit = $LASTEXITCODE
if ($null -eq $mfeVerifyExit -or $mfeVerifyExit -ne 0) { exit $mfeVerifyExit }
ctest --preset windows-msvc-ninja-debug --output-on-failure
$mfeVerifyExit = $LASTEXITCODE
if ($null -eq $mfeVerifyExit -or $mfeVerifyExit -ne 0) { exit $mfeVerifyExit }
```
Python은 E7 말미의 정확한 classifier/focused/full 세 호출을 같은 환경 wrapper 안에서
수행한다. Named venv, UV offline/cache, 기존 대상/assertions, 새
`.harness/build/p-<8hex>` basetemp80자 이하와 TEMP80자 이하를 유지한다.
Already GREEN인 timeout/classifier source를 RED로 되돌리지 않는다. 실제 보존된 RED/GREEN을
읽고 classifier37/focused136 및 남은 full pytest를 현재 code로 재검증한다. r2 harness
Correction1회는 사용 완료됐으며 두 번째 source correction을 시작하지 않는다.
Native configure/build evidence에는 actual MSVC compiler/x64/Debug와 Ninja cache,
CMake/CTest 명령·binaryDir, 새 warning0, 실제
`src/fesa/Debug/fesa_solver.lib`의 존재·SHA256·mtime를 기록한다.
Library가 계획 위치에 없으면 환경 gate 실패로 반환한다. 기존 helper의 실제 mtime 판단을
유지하고 새 binary에 대한 fresh solve 및 정확 입력복사/hash를 확인한다. 기존 VS 결과를
새 graph의 fresh evidence로 옮기지 않는다. 새 graph의 최초 전체 suite 시간도 실제 측정하며,
이전 약27.9분 추정이나 finite cap을 성공/소요 보장으로 해석하지 않는다.
각 Step의 focused/full 및 registered Stop에 같은 graph가 사용됐는지 실제 raw를 대조한다.
기존 static reference 비교와 새 eigen Value10 비교의 승인 기준은 그대로다. 다음
Implementation은 보고서의 광범위한 reference 미사용 문장을 정정해 static full CTest가
원본 reference를 읽고 비교한다는 사실, 원본 직접 수정 없음, 새 eigen 비교 미실행을
구분한다. 과거 manual build 실패/미실행과 automatic pass도 보존한다.
Source·수식·schema·tolerance·reference를 이 환경 준비에서 변경하지 않는다.
정상 native 대안이 실제 실패하면 결과를 보존해 Coordinator에 반환하며, 새 exact-run DFA
결정이 필요한지는 그 evidence로 판단한다. 지금 main까지 권한을 확대하지 않는다.
@@ -29,6 +29,12 @@ error/history2 WIP 보존 뒤 [E7](implementation-environment.md#e7-짧은-temp
report1/controls2 blocked/history3 WIP 보존이다. [E8](implementation-environment.md#e8-attempt3-후의-정상-backend-대안)의 report1/controls2 blocked/history3 WIP 보존이다. [E8](implementation-environment.md#e8-attempt3-후의-정상-backend-대안)의
정상 Ninja 대안은 후속 bounded delta에서 명령을 확정하며 이번에는 설정·status reset·재실행하지 않는다. 정상 Ninja 대안은 후속 bounded delta에서 명령을 확정하며 이번에는 설정·status reset·재실행하지 않는다.
R8 report/controls 보존은 실제 두 commit과 clean 확인까지 완료됐다. 현재
[E8](implementation-environment.md#e8-attempt3-후의-정상-backend-대안)은 Root의 ignored 설정 준비와
Coordinator의 별도 정상 Ninja invocation, 기존 Step 명령 대응을 확정한다.
[R9](implementation-recovery.md#r9-e8-활성화-전의-status-only-checkpoint)의 status-only 변경·checkpoint는
후속 할당으로 남는다. 이번 delta는 문서/정적 확인이며 native Ninja 성공은 아직 미검증이다.
[FEATURED_AGENTS](FEATURED_AGENTS.md), [PRD](PRD.md), [ADR](ADR.md)와 [FEATURED_AGENTS](FEATURED_AGENTS.md), [PRD](PRD.md), [ADR](ADR.md)와
[coordination](coordination.md), 승인된 [requirements](requirements.md), [research](research.md), [coordination](coordination.md), 승인된 [requirements](requirements.md), [research](research.md),
[formulation](formulation.md), [NR](numerical-review.md), [I/O](io.md) 및 각 상세 r2를 적용한다. [formulation](formulation.md), [NR](numerical-review.md), [I/O](io.md) 및 각 상세 r2를 적용한다.
@@ -646,3 +646,73 @@ blocked_reason/blocked_at/started_at/created_at 및 모든 다른 값, top/raw
새 eigen comparison 미실행, 기존 static regression 비교를 구분하도록 현재 광범위한 새 eigen comparison 미실행, 기존 static regression 비교를 구분하도록 현재 광범위한
reference 미사용 문장을 바로잡는다. Planning은 해당 보고서를 수정하지 않는다. reference 미사용 문장을 바로잡는다. Planning은 해당 보고서를 수정하지 않는다.
Harness r2 source Correction1회는 사용 완료됐으며 두 번째 source correction은 허용하지 않는다. 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 성공에서 추론하지 않는다.