22 KiB
FESA Session Handoff
1. 문서 목적
이 문서는 equation-and-linear-solve 완료 후 새 세션에서
results-and-pipeline Phase를 바로 시작하기 위한 인수인계 기록이다.
요구사항과 설계의 기준은 이 문서가 아니라 다음 파일이다.
/AGENTS.md/docs/PRD.md/docs/ARCHITECTURE.md/docs/ADR.md/docs/HARNESS.md/docs/HDF5_SCHEMA.md— 다음 Phase Step 1에서 writer보다 먼저 생성할 문서/docs/superpowers/plans/2026-07-29-fesa-phase-1.md/phases/results-and-pipeline/index.json/phases/results-and-pipeline/step0.md부터step3.md
내용이 충돌하면 AGENTS.md, 제품·아키텍처 문서와 phases/의 현재 상태를
우선한다. 이 문서는 현재 구현과 실행환경에서 특히 놓치기 쉬운 계약을 보충한다.
2. 현재 저장소 상태
2026-07-31 확인 기준:
- 현재 브랜치:
dev - 현재
devHEAD:a02024929ca62c714335dd9811eea6eab816af38 origin/dev,origin/HEAD:d39340217421006c33bb7c61a0111d320cbaab2e- 로컬
dev는origin/dev보다 9 commit 앞서고 0 commit 뒤처져 있다. - 완료 Phase:
solver-bootstrapdomain-and-input-skeletonfem-and-beam-kernelequation-and-linear-solve
- 다음 Phase:
results-and-pipeline - 다음 Step:
0 - result-database results-and-pipeline의 Step 0~3은 모두pending이다.equation-and-linear-solve는dev에 fast-forward 병합되었고 로컬feat-equation-and-linear-solve브랜치는 삭제되었다.- 원격 push는 수행하지 않았다.
이 문서를 갱신하기 직전 작업 트리는 clean이었다. 현재
docs/HANDOFF.md 변경은 사용자가 별도로 요청하지 않는 한 커밋하지 않는다.
새 세션에서 Harness를 실행하기 전에 이 변경을 먼저 커밋하거나 별도로 정리해야
한다. 그렇지 않으면 executor의 feature branch와 Step commit에 인수인계 문서가
섞일 수 있다.
로컬 dev의 미push 9 commit을 보존한다. 원격에 맞추기 위한 reset, 강제 checkout,
rebase 또는 force push를 수행하지 않는다.
3. 완료된 equation-and-linear-solve
Phase metadata는 /phases/equation-and-linear-solve/index.json에 기록되어 있으며
Step 0~2가 모두 completed다.
주요 commit:
8342774— deterministic serial symmetric CSR assembly1bf277c— essential BC elimination과 reaction recoverye216660— MKL PARDISO linear solver adapter2dd17be— Phase 완료 metadata741fc9e— 독립 review 지적과 HANDOFF 계약 수정a020249— 완료된 Step 계약 문서 정합화
독립 재검토 결과 남은 Critical, Important, Minor 항목 없이 merge-ready 판정을 받았으며, 아래 계약이 테스트로 고정되어 있다.
3.1 Symmetric CSR과 serial assembly
관련 파일:
/include/fesa/assembly/symmetric_csr.hpp/include/fesa/assembly/equation_system.hpp/include/fesa/assembly/serial_assembler.hpp/src/fesa/assembly/serial_assembler.cpp/tests/unit/assembly/serial_assembler_test.cpp
핵심 계약:
SymmetricCsr는 0-based upper triangle만 저장한다.- 각 row의 column index는 strictly increasing이다.
- 연결되지 않은 절점의 자유도를 포함해 모든 row가 diagonal entry를 갖는다. contribution이 없으면 값은 0이다. 따라서 이후 solver가 구조 오류가 아니라 singular equation system으로 진단할 수 있다.
- sparsity pattern 생성과 numeric merge는 분리되어 있다.
- numeric contribution은
(row,column,element-origin,local-order)순서로 정렬·합산한다. - 비결합적인
1 + 1 + 1e16규모의 테스트가 element origin 순서를 bit pattern으로 고정한다. Domain storage order로 합산하도록 바꾸면 안 된다. - Beam kernel failure를 0 stiffness로 대체하지 않고 assembly 오류로 전달한다.
EquationSystem은 원래 fullstiffness와force를 소유하며 constraint 처리 전 상태로 보존한다.
이 serial assembler는 후속 deterministic-parallel-assembly Phase의 oracle이다.
이번 다음 Phase에서 TBB assembly를 선행 구현하지 않는다.
3.2 DofManager와 essential BC
관련 파일:
/include/fesa/fem/dof_manager.hpp/include/fesa/constraints/essential_bc.hpp/src/fesa/constraints/essential_bc.cpp/tests/unit/constraints/essential_bc_test.cpp
핵심 계약:
DofManager가 full DOF, free equation mapping과 prescribed value를 단독 소유한다.- full index 기반
equation(std::size_t)와prescribed_value(std::size_t)query가 추가되어 있다. eliminate_essential_bcs(const EquationSystem&, const DofManager&)에는 별도 prescribed 목록을 전달하지 않는다.ReducedSystem은 reducedstiffness와force만 소유한다. free/full mapping이나 prescribed full vector를 중복 저장하지 않는다.- full solution은
DofManager::reconstruct_full()로 복원한다. - 0과 비영 prescribed value의 RHS shift, all-constrained order 0 system, 원본 system 불변성이 검증되어 있다.
- 반력은 reduced system이 아니라 원래 full system의
r=Ku-f에서 계산한다. - 입력뿐 아니라 RHS shift와 reaction 산술 결과가 NaN/Inf가 되는 경우도 성공 결과로 반환하지 않는다.
Domain::step().prescribed_dofs를 다시 순회해 별도 constraint 상태를 만들지 않는다.
3.3 MKL PARDISO adapter
관련 파일:
/include/fesa/solvers/linear/linear_solver.hpp/include/fesa/solvers/linear/pardiso_linear_solver.hpp/src/fesa/solvers/linear/pardiso_linear_solver.cpp/tests/unit/solvers/linear/pardiso_linear_solver_test.cpp
핵심 계약:
- public
LinearSolver계약에는 MKL 타입이 노출되지 않는다. PardisoLinearSolver는 noncopyable이다.- MKL LP64
MKL_INT == std::int32_t,mtype=2,iparm[26]=1matrix checker,iparm[34]=10-based indexing을 사용한다. - analysis, factorization, solve와 release phase를 adapter 내부에서 관리한다.
- release는 destructor fallback 외에 명시적으로 호출되어 release error도
DiagnosticStage::solver의solver.release_failed로 변환된다. - matrix/RHS validation, singular diagnostic, repeated solve와 adapter 밖의 독립 상대잔차 계산이 검증되어 있다.
- order 0 reduced system은 constraint 계층에서는 유효하지만 PARDISO 입력으로는 거부된다. analysis orchestration이 all-constrained case를 별도로 처리해야 한다.
4. 검증된 baseline과 개발환경
새 PowerShell 세션에서 configure 또는 Harness 실행 전에 다음 환경 변수를 설정한다. 절대경로를 tracked CMake 파일이나 Preset에 넣지 않는다.
$env:MKL_DIR = "C:\Program Files (x86)\Intel\oneAPI\2026.1\lib\cmake\mkl"
$env:TBB_DIR = "C:\Program Files (x86)\Intel\oneAPI\2026.1\lib\cmake\tbb"
$env:HDF5_DIR = "C:\Program Files\HDF_Group\HDF5\2.1.1\cmake"
$env:GTest_DIR = "C:\Users\baram\AppData\Local\FESA\dependencies\googletest-1.17.0-v145-x64-crt\lib\cmake\GTest"
Test-Path "$env:MKL_DIR\MKLConfig.cmake"
Test-Path "$env:TBB_DIR\TBBConfig.cmake"
Test-Path "$env:HDF5_DIR\hdf5-config.cmake"
Test-Path "$env:GTest_DIR\GTestConfig.cmake"
2026-07-31 현재 네 package 경로가 모두 존재한다. 현재 dev HEAD에서 다음
baseline을 검증했다.
- MSBuild 18.8.2, MSVC v145 Debug build 성공
- build 출력에 새 warning 없음
- CTest 29개 중 29개 성공
- Harness pytest 20개 중 20개 성공
- pytest가 실제로 20개를 수집했으므로 0-test 성공이 아님
검증 명령:
cmake --build --preset windows-debug
ctest --preset windows-debug --output-on-failure
uv run --with pytest python -m pytest -v -rs
CMake cache가 없거나 package 경로가 바뀐 경우에만 같은 환경 변수 세션에서 먼저 다음을 실행한다.
cmake --fresh --preset windows-debug
HDF5 command-line tool은 현재 PATH에 없지만 다음 파일은 존재한다.
C:\Program Files\HDF_Group\HDF5\2.1.1\bin\h5ls.exe
h5ls.exe는 HDF5 DLL 외에 Intel libmmd.dll도 요구한다. HDF5 bin만 PATH에
추가하면 Windows exit 0xC0000135로 실패하므로 Step 1과 Step 3 Acceptance
Criteria에서는 HDF5와 oneAPI bin을 모두 현재 세션 PATH에 추가한다. 시스템
PATH를 영구 변경하지 않는다.
$env:PATH = @(
"C:\Program Files\HDF_Group\HDF5\2.1.1\bin",
"C:\Program Files (x86)\Intel\oneAPI\2026.1\bin",
$env:PATH
) -join ";"
h5ls --version
2026-07-31 현재 이 설정에서 h5ls: Version 2.1.1과 exit code 0을 확인했다.
5. 다음 Phase 목표와 Step 순서
results-and-pipeline의 독립 deliverable은 nodal result semantic model과 최소 HDF5
schema를 만들고, 이미 구현된 parser부터 linear solve까지 production 경로를
조율해 fesa solve ... --output ... 수직 슬라이스를 완성하는 것이다.
이 milestone은 입력-해석-출력 경로가 연결되었다는 뜻일 뿐 Beam의 수치 자격 완료나 Phase 1 내부 배포 완료를 의미하지 않는다. 요소 결과 회복, 완전한 자기완결 HDF5, Abaqus reference qualification은 뒤의 별도 Phase에 남아 있다.
Step 0 — result-database
/include/fesa/results/와/src/fesa/results/에 HDF5와 독립적인 최소 semantic result model을 만든다.- 현재 Step 계약의 실체는
ResultDatabase -> ResultStep -> ResultFrame -> NodalFrame이다. - 이 Phase에는 전역 좌표계 nodal displacement/rotation과 reaction/moment만 담는다.
- node ID와 6-component field의 size 일치, duplicate node, duplicate step/frame, nonfinite 값을 실패 테스트로 먼저 고정한다.
- aggregate를 그대로 공개하면서 invalid state를 나중에 검사할지, 검증된 factory를 둘지 구현 전에 하나로 정한다. 현재 Step의 “invalid result model을 거부” 조건을 실제 호출 가능한 API로 표현해야 한다.
- element result, field/history 범용 hierarchy, velocity, acceleration, temperature를 미리 만들지 않는다.
Step 1 — minimal-hdf5-schema
- writer code보다 먼저
/docs/HDF5_SCHEMA.md에 schema1.0.0의 정확한 계약을 작성한다. - 최소 writer/reader adapter는
/include/fesa/io/hdf5/와/src/fesa/io/hdf5/에 둔다. - schema/version, node origin
(part,instance,local label), dense ID map, 좌표, connectivity, 적용 전단강성과 input/default source, nodal displacement/reaction을 round trip한다. - public reader와
h5ls로 writer 산출물을 다시 연다. production writer 내부 상태나 test-only parser로 검증하지 않는다. - 모든
hid_t와 HDF5 resource는 move-only RAII wrapper 내부에 둔다. - 모든 HDF5 실패를
DiagnosticStage::results의 diagnostic 또는 adapter 경계에서 포착되는 오류로 변환한다. - reference CSV와 아직 존재하지 않는 결과를 위한 빈 group을 추가하지 않는다.
Step 2 — linear-static-analysis
/include/fesa/analysis/와/src/fesa/analysis/에 orchestration만 구현한다.- 이미 검증된
Domain을 입력받으며 parser, CLI, HDF5를 호출하지 않는다. - 실행 순서는
DofManager -> serial assembly -> essential BC -> PARDISO -> full reconstruction -> reaction -> nodal ResultDatabase다. - free equation 수가 0이면 PARDISO를 호출하지 않고 prescribed full vector와 원래 평형식으로 결과를 만든다.
- nodal result의 ID 순서와 full vector의 6-DOF block 순서가 반드시 일치해야 한다.
DofManagernumbering이 internalNodeId정렬 기반이므로 Domain storage order를 묵시적으로 사용하지 않는다. - hand-check 가능한 한 요소 Domain으로 displacement, reaction, solver residual과
Ku-f-r평형을 실패 테스트로 먼저 고정한다. - 수치 kernel, constraint 또는 solver 로직을 analysis에 복제하지 않는다.
Step 3 — cli-pipeline-integration
run_solver(const AnalysisRequest&)가 parser, semantic mapper, Domain, analysis와 HDF5 writer를 application 경계에서 조율한다.- 현재 parser API는
parse_deck(path), semantic mapping API는map_deck_to_domain(deck)이다. - CLI 계약은 다음 두 가지다.
fesa solve <model.inp> --output <results.h5>
fesa --version
/tests/fixtures/abaqus/minimal_cantilever.inp는 이미 존재한다.MinimalCantileverPipeline은run_solver또는 CLI와 public HDF5 reader만 사용한다.- 성공 시 node ID, finite displacement, reaction/equilibrium diagnostic과 schema path를 검증한다.
- parse, semantic, equation, solver 또는 results 실패는 원래 diagnostic stage와 source 정보를 보존하고 CLI nonzero exit로 전달한다.
- hierarchical fixture의 아직 미지원 keyword를 Step 3에서 우회 처리하지 않는다.
전체 Abaqus subset은 다음
abaqus-subset-completionPhase의 책임이다.
6. 구현 전에 명시적으로 정렬할 설계점
아래 항목은 범위를 늘리라는 의미가 아니다. 현재 Step 문서와 최종 PRD 사이의 모호함을 구현 전에 드러내고 가장 단순한 일관된 계약을 선택하기 위한 확인 목록이다.
-
Result model 유효성 API
- Step 0은 invalid model을 거부하라고 하지만 제시된 타입은 public aggregate다.
- raw aggregate + 별도 validation과 validated factory 중 하나를 선택하고 테스트가 production validation 경로를 통과하게 한다.
-
HDF5 reader의 model metadata 반환 범위
- Step 1의
Hdf5ReadResult초안은ResultDatabase만 반환하지만 round-trip 조건은 node origin, 좌표, connectivity, shear source까지 재검증하라고 한다. - 이 metadata를
ResultDatabase에 억지로 넣지 말고, reader inspection model을 최소로 추가하거나 read result 계약을 정렬한다.Domain을 HDF5 API 타입으로 오염시키지 않는다.
- Step 1의
-
schema
1.0.0의 최소/최종 범위- 이번 Phase는 nodal vertical slice만 구현하고
result-contract-completion이 element 결과와 완전한 자기완결 계약을 뒤에서 채운다. - 빈 미래 hierarchy는 만들지 않되,
/docs/HDF5_SCHEMA.md에 이번 최소 required dataset과 이후 additive compatibility 규칙을 분명히 구분한다.
- 이번 Phase는 nodal vertical slice만 구현하고
-
deterministic nodal ordering
DofManagerfull vector는 sorted internalNodeId순서다.NodalFrame::node_ids와 6-component displacement/reaction 배열을 같은 순서로 만드는 최소 query 또는 정렬 로직을 한 곳에서만 소유한다.
-
all-constrained analysis
- reduced order 0은 constraint 성공이고 PARDISO invalid input이다.
- Step 2가 solver 호출을 생략하는 명시적 branch를 갖고 prescribed displacement와 full reaction을 계산한다.
-
analysis와 application 경계
- Step 2
LinearStaticAnalysis는 Domain-to-ResultDatabase만 담당한다. - Step 3
run_solver가 parser와 HDF5를 담당한다. ARCHITECTURE의 포괄적 lifecycle 설명을 이유로 HDF5 API를 analysis에 직접 넣지 않는다.
- Step 2
7. 아키텍처와 범위 경계
results는 HDF5 API에 의존하지 않는 semantic model이다.io/hdf5만 HDF5 C API, schema version과 resource lifetime을 안다.analysis는 기존 production 모듈을 조율하지만 수치 kernel과 외부 API를 재구현하지 않는다.run_solver와 CLI는 application 경계다. CLI parsing을fesa_core의 analysis 객체에 넣지 않는다.core,model,fem,elements는 HDF5 API에 의존하지 않는다.- 외부 ID와 internal dense index mapping을 혼동하지 않는다.
- HDF5 파일에 단위 변환을 추가하지 않는다. FESA 입력과 결과는 일관 단위계를 전제로 한다.
- element section result, point stress, reference CSV, TBB parallel assembly, 다중 Step/Instance와 미지원 Abaqus keyword를 선행 구현하지 않는다.
- 성공 경로에 fake stiffness, fake result 또는 test-only solver를 사용하지 않는다.
8. Child sandbox의 MSBuild 실행 조건
이전 두 Harness Phase에서 child sandbox를 조사한 결과:
- 앱 설치 경로의
codex-cli 0.146.0은 matchingcodex-resources를 찾지 못했다. - 완전한 standalone 배포는 다음 위치에 있으며 현재
codex.exe와codex-resources가 모두 존재한다.C:\Users\baram\.codex\packages\standalone\releases\0.146.0-x86_64-pc-windows-msvc - WindowsApps 경유 PowerShell에서는 child command가 실패했고 Windows PowerShell 5.1에서는 정상 동작했다.
[windows] sandbox = "elevated"에서는 MSBuild FileTracker가 access denied로 실패했다.- standalone Codex, WindowsApps가 제거된 PATH와
[windows] sandbox = "unelevated"조합에서는 child MSBuild가 성공했다.
현재 C:\Users\baram\.codex\config.toml은 원래 값인
[windows] sandbox = "elevated"로 복원되어 있다. 다음 Harness 실행에서도 같은
문제가 재현되면 사용자가 이전에 승인한 임시 전환 방식에 따라 다음 순서를 사용한다.
- 다른 Codex 작업에 미칠 영향을 확인하고 global config 원래 값을 기록한다.
- Harness 실행 동안만
[windows] sandbox = "unelevated"로 바꾼다. - 현재 PowerShell 세션의 PATH 앞에 standalone
bin과 Windows PowerShell 5.1을 둔다. 모든WindowsAppsentry를 제거해야 하며 alias 디렉터리 하나만 제거하면 direct package 경로가 남을 수 있다.
$codexReleaseBin = "C:\Users\baram\.codex\packages\standalone\releases\0.146.0-x86_64-pc-windows-msvc\bin"
$windowsPowerShell = "$env:SystemRoot\System32\WindowsPowerShell\v1.0"
$filteredPath = $env:PATH -split ";" | Where-Object {
$_ -and
$_ -ne $codexReleaseBin -and
$_ -ne $windowsPowerShell -and
$_ -notmatch "WindowsApps" -and
$_ -notmatch "\\OpenAI\\Codex\\bin$"
}
$env:PATH = (@($codexReleaseBin, $windowsPowerShell) + $filteredPath) -join ";"
(Get-Command codex).Source
(Get-Command powershell).Source
- package 환경 변수와 baseline을 확인한 뒤 같은 세션에서 Harness를 실행한다.
- 성공·실패와 무관하게
finally에 해당하는 정리 단계에서 global config를 즉시[windows] sandbox = "elevated"로 복원하고 실제 값을 다시 읽어 확인한다.
사용자 profile 전체나 드라이브 루트를 --codex-add-dir로 허용하지 않는다. 설치
버전이나 경로가 달라졌다면 위 절대경로를 맹목적으로 사용하지 말고 실제 standalone
release와 codex-resources 존재를 먼저 확인한다.
이전 Harness는 모든 Step과 phase commit을 완료한 뒤 stderr reader의 CP949/UTF-8 decode 예외를 출력한 적이 있다. exit code, phase metadata와 Git commit이 정상이면 그 메시지만으로 제품 실패로 단정하지 않는다.
9. 새 세션 시작 절차
먼저 이 문서와 다음 Phase 파일을 모두 읽는다.
/phases/results-and-pipeline/index.json
/phases/results-and-pipeline/step0.md
/phases/results-and-pipeline/step1.md
/phases/results-and-pipeline/step2.md
/phases/results-and-pipeline/step3.md
그 다음 저장소 상태를 재검증한다.
git switch dev
git status --short --branch
git rev-parse HEAD
git rev-parse origin/dev
git rev-list --left-right --count origin/dev...dev
docs/HANDOFF.md 변경이 남아 있으면 먼저 사용자의 의도대로 커밋하거나 정리한다.
4절의 package 환경 변수를 설정하고 baseline을 실행한다. 필요하면 8절의 child
sandbox 조건을 적용한 뒤 다음을 실행한다.
python scripts/execute.py results-and-pipeline
executor는 feat-results-and-pipeline 브랜치를 생성하거나 checkout하고 Step 상태와
output metadata를 기록한다. 사용자가 명시적으로 요청하지 않은 한 --push를
사용하지 않는다.
각 Step은 다음 순서를 지킨다.
- Step 파일의 필수 문서와 선행 구현을 모두 읽는다.
- 성공 기준과 semantic/schema/lifecycle invariant를 명시한다.
- 모호한 계약은 6절을 기준으로 구현 전에 정렬한다.
- 실패 테스트를 먼저 작성하고 예상한 이유로 실패함을 확인한다.
- 테스트를 통과시키는 최소 production code만 구현한다.
- focused test, 전체 CTest와 Harness pytest를 실행한다.
- Step summary와 output metadata가 실제 결과와 일치하는지 확인한다.
- Phase 종료 전 전체 diff를 아키텍처, schema, diagnostic과 resource lifetime 기준으로 review한다.
10. 다음 Phase 완료 조건
/phases/results-and-pipeline/index.json의 Step 0~3이 모두completed/phases/index.json에서results-and-pipeline이completed- invalid nodal result model과 finite-data invariant 테스트 통과
/docs/HDF5_SCHEMA.md가 writer보다 먼저 작성되고 실제 산출물과 일치- public HDF5 reader round trip과
h5lsschema inspection 통과 - 모든 HDF5 handle이 adapter 내부 RAII wrapper에서 해제됨
- one-element linear static displacement, reaction, residual과 equilibrium 검증 통과
- all-constrained analysis가 PARDISO 없이 성공
fesa solve tests\fixtures\abaqus\minimal_cantilever.inp --output ...성공- CLI 실패 입력이 nonzero exit와 원래 stage/source diagnostic을 반환
- focused test와 전체 CTest 통과
- Harness pytest가 0개가 아닌 상태로 전체 통과
- 새 MSVC warning 없음
- HDF5 API가
io/hdf5밖의 public semantic contract로 노출되지 않음 - element result, full Abaqus subset, TBB assembly, reference 비교를 선행 구현하지 않음
- 이 결과를 Beam 수치 자격 완료나 Phase 1 내부 배포 완료로 표시하지 않음
- review의 Critical/Important 항목 해결
- 사용자 선택 전 원격 push나
dev병합을 수행하지 않음
새 세션의 권장 첫 요청:
docs/HANDOFF.md와phases/results-and-pipeline/step0.md부터step3.md를 읽고 현재 baseline, HDF5 도구 경로와 child sandbox의 MSBuild 실행 조건을 확인한 뒤results-and-pipelinePhase를 시작해주세요.