modify documents

This commit is contained in:
KOKO\Mimi
2026-09-06 00:52:59 +09:00
parent 97e4d7a971
commit ac84235b7a
17 changed files with 2912 additions and 1195 deletions
+213 -456
View File
@@ -1,506 +1,263 @@
# 아키텍처
# FESA 구조해석 솔버 아키텍처
## 목표
FESA의 아키텍처 목표는 Abaqus `.inp` subset을 내부 semantic model로 변환하고, 유한요소 equation system을 구성해 구조해석 결과를 HDF5로 저장하며, reference comparison과 physics sanity가 가능한 C++17/MSVC 솔버 구조를 제공하는 것이다.
## 목적과 적용 범위
FESA의 element formulation과 numerical path는 Abaqus와 독립적이다. Abaqus `.inp`는
승인된 입력 형식이고 Abaqus CSV는 기능별 blocking quantity의 외부 수치 reference다.
Abaqus 내부 적분, stabilization, state 또는 recovery 동작은 FESA architecture contract가
아니다.
FESA는 유한요소법 기반 구조해석 솔버를 단계적으로 구축한다. 이 문서는
[PRD](PRD.md)의 제품 목표를 공통 책임, 의존성, 데이터와 수명 경계로 연결한다.
특정 요소·재료·하중의 정식화, 해석 알고리즘, 코드 목록 또는 구현 완료 현황은 다루지 않는다.
핵심 품질 속성:
- FEM formulation traceability
- explicit I/O contracts
- sparse linear algebra backend isolation
- deterministic verification
- incremental feature addition
- Harness 기반 TDD
구체적인 API, 수식, 실행 순서와 결과 schema는 `docs/<feature-id>/`의 승인된
정식화·I/O·구현 계약에서 정의한다. 아래의 책임 모델은 아직 없는 클래스, 공통 base,
state field 또는 디렉토리를 미리 만들라는 지시가 아니다. 기존 구현의 승인된 의미를
일반적인 설명에 맞추어 변경하지 않는다.
현재 승인된 V0 end-to-end 기능은 `linear-static-3d-euler-beam`이다. 상세 계약의
source of truth는
`docs/superpowers/specs/2026-08-08-linear-static-3d-euler-beam-design.md`이며, 이 문서는
그 계약을 전체 solver architecture의 모듈과 데이터 흐름에 배치한다. 아래에 나타난
비선형, 동적, thermal 및 다른 element 계층은 장기 확장 경계이며 V0 지원 범위가 아니다.
설계 결정과 변경 근거는 [ADR](ADR.md), 코드 규약은 [CODINGSTYLE](CODINGSTYLE.md)을
따른다. 현재 프로젝트의 기술 선택은 [AGENTS.md](../AGENTS.md)와 실행 가능한
build/configuration에서 확인한다.
## 현재 구현된 디렉토리 구조
```text
include/fesa/ # backend-neutral public C++ API
src/
fesa/
analysis/ # Analysis lifecycle, V0 LinearStaticAnalysis
app/ # CLI application and main
assembly/ # deterministic stiffness/load assembly, ParallelFor adapter
constraints/ # essential-constraint elimination and reconstruction
core/ # source identity, status, diagnostics
elements/ # current B33/MITC4 kernels and recovery
fem/ # DOF/equation numbering and sparse pattern
io/
abaqus/ # .inp syntax reader and semantic Domain mapper
hdf5/ # private HDF5 writer and atomic finalization
math/ # owning Vector, row-major Matrix, 0-based CSR SparseMatrix
model/ # concrete V0 semantic records and immutable Domain
results/ # recovery records, full residual, ResultsWriter boundary
solvers/
linear/ # LinearSolver interface and MKL PARDISO adapter
tests/
unit/ # local contracts and failure paths
integration/ # analysis orchestration and CLI contracts
reference/ # HDF5-to-Abaqus projection and comparison
reference/
<case-dir>/ # declared read-only Abaqus input/required CSV pair
.agents/
skills/ # Harness and review skills
.codex/
hooks.json # PreToolUse/Stop hook registration
agents/ # FESA workflow custom agents
skills/ # FESA solver workflow skills
docs/ # Product, architecture, ADR, workflow artifacts
scripts/
execute.py # Phase step executor
hooks/ # PreToolUse/Stop hook implementations
msvc_harness/ # MSVC project discovery and validation adapters
phases/ # Optional generated phase plans
```
## 아키텍처 원칙
`materials/`, `properties/`, `loads/`와 checked `ElementFactory`는 승인된 C++ modular
refactoring의 target boundary이며 후속 implementation Step에서 추가한다. 이
documentation-only Step 시점에는 현재 구현 디렉토리로 표시하지 않는다. Density,
plasticity, anisotropy, nonlinear/dynamic analysis, MPC/penalty, history output과 production
validation module은 계속 장기 확장 경계이며 별도 승인 기능이 필요하다.
- 물리·수치 의미는 외부 파일 형식과 vendor API보다 독립적인 계약으로 유지한다.
- 모델 정의, 현재 실행 view, equation 구성, mutable state와 결과의 소유권을 구분한다.
- Local physics 계산과 global topology, assembly, constraint, solve 책임을 분리한다.
- Identity, units, coordinates, ordering과 failure 의미를 경계마다 명시한다.
- Candidate를 완성·검증한 뒤 계약된 state나 authoritative output에 반영한다.
- 병렬화와 최적화에서도 결정적인 ordering과 failure preservation을 유지한다.
- 실제 승인된 사용 사례에 필요한 최소 확장만 도입한다.
## Harness Execution Layer
Harness는 solver core와 분리된 세 계층의 개발 운영 인프라다.
- 계획 계층: `.agents/skills/harness`가 사용자 승인 전 Step 초안을 만들고, 승인 후 `phases/` 파일을 생성한다.
- 실행 계층: `scripts/execute.py`가 `feat-<phase-name>` 브랜치에서 Step마다 독립 Codex 세션을 실행하고 상태와 커밋을 관리한다.
- 검증 계층: `.codex/hooks.json`이 `scripts/hooks/pre_tool_use.py`와 `scripts/hooks/stop_validation.py`를 연결한다. Stop 검증은 `scripts/msvc_harness/`를 통해 MSVC build와 test를 실행한다.
Runner는 `git add -A`를 사용하므로 clean worktree 또는 별도 Git worktree가 실행 전제다. 전체 동작 계약은 `docs/HARNESS_WORKFLOW.md`, 설치와 `.harness/config.json` 설정은 `docs/HARNESS.md`를 source of truth로 삼는다.
## CMake target과 dependency graph
Root CMake project는 C++17, extension off, CMake 3.25 이상을 요구하고
`cmake/FesaDependencies.cmake`, `src/fesa`, `tests`를 차례로 구성한다.
## Solver runtime과 개발 운영 영역
```text
MKL CONFIG package ─> Fesa::MKL ─┐
TBB CONFIG package ─> Fesa::TBB ─┼─> fesa_solver (STATIC) ─> fesa_cli
HDF5 CONFIG package ─> Fesa::HDF5 ─┘ │
├─> fesa_unit_tests
approved local GoogleTest source ─> GTest targets ├─> fesa_integration_tests
└─> fesa_reference_tests
Solver runtime
입력 adapter → semantic model → analysis procedure → recovery/results → 출력 adapter
│
├─ DOF / equation / sparse pattern
├─ element / material / load contribution
├─ assembly / constraint policy
└─ numerical backend
개발 운영 영역
사용자 요구 → Coordinator → 담당 specialist → 산출물과 evidence → gate 판정
│
└─ 할당된 계획 / Harness / 코드·테스트·문서 변경
```
- `FESA_GTEST_SOURCE_DIR`는 네트워크 fetch 대신 승인된 local GoogleTest source checkout을 가리키는 필수 cache path다.
- MKL, TBB, HDF5는 CONFIG package로 탐지한다. Package search가 설치를 찾지 못하면 `MKL_DIR`, `TBB_DIR`, `HDF5_DIR`를 configure 때 지정한다.
- Package별 imported target 이름은 `Fesa::MKL`, `Fesa::TBB`, `Fesa::HDF5`로 정규화한다. Product module은 vendor target 이름을 직접 선택하지 않는다.
- HDF5 package가 shared와 static C target을 모두 제공하면 approved Windows environment에서는 shared target을 우선한다. Static archive의 숨은 compiler-runtime 요구가 link interface 밖으로 새는 것을 피하기 위한 결정이다.
- `fesa_solver`는 외부 dependency를 `PRIVATE`으로 link하고 `/W4 /WX`를 사용한다. 따라서 public header는 MKL/TBB/HDF5/Win32 type을 포함하지 않아야 한다.
- Test executable은 unit, integration, reference 경계를 분리하며 `fesa_tests` target은 세 executable을 build하는 aggregate target이다. Reference target에만 source/build root compile definition을 제공한다.
첫 흐름은 해석 데이터의 전달을, 두 번째는 개발 작업과 검증의 흐름을 나타낸다.
Agent, prompt, phase 파일과 Harness는 solver runtime API나 물리 모델의 일부가 아니다.
개발 운영 영역은 저장소의 변경과 검증을 통제하며 solver가 실행 중 이를 호출하지 않는다.
### Windows runtime closure
## 공통 책임과 의존성
Configure 성공은 executable이 GoogleTest discovery 또는 CLI 실행 시 필요한 DLL을 찾는다는
뜻이 아니다. `fesa_cli`와 세 test executable의 POST_BUILD 단계는 TBB, MKL thread/core/default
dispatch, OpenMP, `libmmd.dll`, HDF5를 포함한 imported-target runtime DLL을 executable 옆에
복사한다. 새 dynamic backend를 도입할 때는 link 성공뿐 아니라 clean environment에서의
post-build discovery/실행까지 runtime closure로 다뤄야 한다. 개인 설치 absolute path를
CMake source에 기록하지 말고 config package와 imported target metadata를 확장한다.
아래 명칭은 책임 경계이며 반드시 각각 하나의 클래스나 독립 library를 뜻하지 않는다.
실제 타입과 파일 배치는 승인된 Feature와 현재 코드 구조에서 결정한다.
## 모듈 경계
- `core`는 외부 라이브러리에 의존하지 않는다.
- `io/abaqus`는 syntax와 semantic mapping만 담당하고 해석 알고리즘을 알지 않는다.
- `model`은 Abaqus keyword 문자열이 아니라 solver semantic model을 가지며 `Domain`과
non-owning `AnalysisModel`의 수명 경계를 소유한다.
- `materials`와 `properties`는 Domain이 소유하는 semantic identity와 현재 승인된
isotropic elasticity 및 beam/shell property data만 제공한다.
- `elements`는 Domain-owned `ElementDefinition`, runtime numerical `Element`, checked
`ElementFactory`와 element-local stiffness/recovery contract를 제공한다.
- `fem`의 `DofManager`는 DOF, equation ordering, scatter와 sparse pattern을 소유한다.
- `assembly`는 runtime element contribution과 ordered load contribution을 stable full-DOF
space에 조립한다. Contribution producer는 global storage를 직접 갱신하지 않는다.
- `loads`는 semantic target과 magnitude를 소유하고 ordered `LoadContribution`을 생성한다.
- `constraints`는 `ConstraintDefinition` 생성과 V0 essential BC elimination 및 full/reduced
vector 변환을 분리한다. MPC와 penalty는 현재 범위가 아니다.
- `solvers`는 `LinearSolver` 뒤에 MKL PARDISO 세부 구현을 감춘다. TBB는 `assembly/ParallelFor`, HDF5는 `results/ResultsWriter` 경계 뒤에 각각 격리된다.
- `analysis`는 step/history data를 받아 procedure를 실행하고 solver backend와 result writer를 조율한다.
- `results`는 full residual과 B33/MITC4 rows를 복구하고 backend-neutral writer contract를
제공한다. HDF5 schema 구현은 `io/hdf5`가 담당한다.
- test helper는 production parser/solver 내부 상태를 우회하지 않는다.
| 경계 | 소유하는 책임 | 소유하지 않는 책임 |
| --- | --- | --- |
| Core identity/diagnostic | Source identity, 공통 상태와 진단의 의미 | 파일 문법, 물리 정식화, vendor resource |
| Input adapter | 외부 syntax와 지원 semantics의 검증·mapping | 해석 알고리즘과 acceptance 변경 |
| Model definition | Topology, 재료·property·하중·제약·step 정의와 stable identity | Equation 번호, 해석 중 mutable solution |
| Active model view | 현재 procedure/step에 필요한 모델의 non-owning 참조 | 원본 모델 복사나 수명 소유 |
| Element/material | 승인된 local ordering의 물리 응답과 recovery 계약 | Global equation numbering, 직접 sparse write, 파일 저장 |
| Load definition/evaluation | Target·magnitude·configuration 의미와 ordered contribution | Global vector의 공유 누적 |
| DOF/equation | 활성 DOF, full/free/constrained mapping, numbering, scatter와 sparse pattern | 요소 정식화, 수치 factorization |
| Assembly | Local contribution을 지정된 global structure에 결정적으로 누적 | Physics 재해석, equation 번호의 분산 생성 |
| Constraint policy | 승인된 제약의 equation 적용과 해 복구 의미 | Input syntax나 별도 물리 모델의 임의 도입 |
| Analysis procedure | 필요한 state·해법·반복/종료·commit·recovery lifecycle | Vendor handle이나 concrete storage API의 공개 |
| Numerical backend | 행렬·벡터 연산, 해법 resource와 backend failure translation | Source label의 물리 의미, 입력 모델 해석 |
| Results/recovery | 계산 결과의 물리량·위치·identity와 state 반영 | 저장 파일 layout이나 reference 데이터 보정 |
| Output adapter | 승인 schema로의 serialization, self-check와 finalization | 물리량 정의와 acceptance 판정 변경 |
## 승인된 리팩터링 dependency와 ownership
의존성은 consumer가 명시된 contract를 사용하는 방향으로 둔다. Input/output과 vendor
adapter가 core 계약에 의존하며, public core가 concrete adapter나 vendor/OS 타입에
의존하지 않는다. Interface와 implementation의 의존성 방향을 역전하지 않는다.
다음 graph는 C++ object-oriented modular refactoring의 구현 방향을 고정한다. `owns`는
단독 수명 소유권을, 나머지 화살표는 왼쪽 consumer가 오른쪽 contract를 사용한다는
뜻이다. 이 graph는 기존 B33/MITC4 물리 기능을 늘리지 않는다.
Numerical consumer가 요소 종류별 concrete storage를 직접 분기하지 않도록 승인된
evaluation/contribution contract를 사용한다. Definition과 runtime object의 호환성은
지정된 생성 경계에서 검사한다. 이를 위해 speculative registry, 공유 소유권 또는
사용하지 않는 polymorphic capability를 추가하지 않는다.
```text
Domain owns ElementDefinition / ElementProperty / Material / StepDefinition
AnalysisModel is a non-owning stable-index view into Domain
ElementFactory creates runtime Element candidates from compatible definitions
DofManager -> ElementDofLayout
SparseAssembler -> ElementStiffnessContribution
ResultRecovery -> ElementResultBundle
LoadAssembler -> ordered LoadContribution
EssentialConstraintPolicy -> ConstraintDefinition
Analysis <- LinearStaticAnalysis
```
## 데이터 계약
승인된 B33/MITC4 formulation, operation/reduction order, sign, units, coordinates와 row
identity는 이 ownership 리팩터링보다 우선한다. HDF5 schema, reference artifact와
ADR-014/ADR-020 tolerance도 변경하지 않는다.
### Identity
`Domain`은 `ElementDefinition`, `ElementProperty`, `Material`과 `StepDefinition` base
object를 `std::unique_ptr`로 단독 소유하고 const access를 제공한다. Collection position은
기존 stable `EntityIndex` 의미를 유지한다. `AnalysisModel`과 solver consumer는 ownership을
가져오지 않고 Domain 수명 안에서 stable index 또는 const reference만 사용한다.
`std::shared_ptr`, speculative `Clone()`과 global registry는 이 계약에 포함되지 않는다.
다음 개념을 같은 정수나 row 위치라는 이유로 서로 대체하지 않는다.
`ElementDefinition`은 source identity, source element type, connectivity와
property/material identity를 보존하는 semantic object다. Runtime `Element`는 active
`ElementDofLayout`, `ElementStiffnessContribution`과 `ElementResultBundle`을 제공하는
numerical kernel이다. `ElementFactory`만 compatible definition/property/material 조합을
검사해 runtime candidate를 만들며 unknown 또는 incompatible 조합을 기존
`Status`/`Result<T>` diagnostic으로 fail-closed 처리한다. `DofManager`,
`SparseAssembler`와 `ResultRecovery`는 B33/MITC4 concrete storage가 아니라 위 runtime
contract를 소비한다. Linear-static candidate는 runtime `Element`를
`std::vector<std::unique_ptr<Element>>`로 소유하고, consumer에는 그 owner 수명 안에서만
유효한 non-owning `ElementView`를 제공한다.
- Source identity: 외부 입력에서 의미가 있는 label과 instance/scope
- Internal identity/index: 검증된 모델 내부의 안정된 식별 또는 위치
- DOF identity: Entity의 물리 자유도와 component
- Equation index: 특정 procedure의 equation ordering
- Result identity: Entity, quantity, location, component, step/frame과 coordinate 의미
`Material` base는 identity, source location과 수명 의미만 공유한다. 현재 concrete
isotropic linear elasticity에 필요한 capability만 사용하며 density, anisotropy, plastic
state, temperature 또는 rate dependency를 optional field나 no-op method로 미리 추가하지
않는다. `ElementProperty`도 beam/shell이 실제 사용하는 data만 각 concrete type에 둔다.
Renumbering, filtering, 병렬 scheduling과 serialization 뒤에도 필요한 대응 관계를
보존한다. Reference matching은 row 순서가 아니라 계약된 source identity와 component를
사용한다. 특정 typed wrapper나 result-key 클래스를 이 문서만으로 새로 만들지 않는다.
`Load`는 semantic target과 magnitude를 소유하고 source order가 보존된
`LoadContribution`을 생성한다. Global vector의 deterministic accumulation은
`LoadAssembler`만 수행한다. `BoundaryCondition`은 `ConstraintDefinition`을 생성하고
`EssentialConstraintPolicy`가 prescribed displacement의 stable elimination과
reconstruction을 수행한다. Future distributed/body load와 MPC enforcement는 구현된
기능이 아니며 별도 승인 계약 없이 이 경계에 branch나 optional state를 추가하지 않는다.
### Units, coordinates와 result meaning
책임이 큰 facade는 외부 계약을 유지한 채 private implementation만 다음 owner로 나눈다.
입력 값의 단위계를 임의로 추론하거나 결과에 맞춰 변환하지 않는다. 필요한 dimension,
좌표계, component 순서, 변환과 부호는 정식화 및 I/O 계약으로 고정한다.
서로 다른 위치나 정의의 recovery quantity를 같은 결과로 취급하지 않는다.
Averaging, extrapolation 또는 station 변환은 별도 승인된 의미가 있을 때만 수행한다.
- Abaqus Domain mapping: topology, material/property, step/load/boundary mapping과 final
Domain assembly
- Result recovery: global equilibrium, beam recovery, shell recovery와 atomic state commit
- HDF5 writing: RAII/primitives, model datasets, result datasets, self-check와 atomic
finalization
### 모델, view와 state의 수명
이 분할은 parser diagnostic, `ResultsWriter` boundary, HDF5 schema 또는 final-file
atomicity를 변경하지 않는다.
## V0 입력 경계
V0 parser는 keyword와 parameter를 case-insensitive하게 해석하되 source label의 원문을
보존한다. 지원하는 model/procedure keyword는 다음과 같다.
- `*HEADING`
- `*PART`, `*END PART`
- `*NODE`
- `*ELEMENT, TYPE=B33`
- `*NSET`, `*ELSET`, including `GENERATE`
- `*MATERIAL`, `*ELASTIC`
- `*BEAM GENERAL SECTION, SECTION=GENERAL`
- `*SECTION POINTS`
- `*ASSEMBLY`, `*END ASSEMBLY`
- `*INSTANCE`, `*END INSTANCE`
- `*BOUNDARY`, `*CLOAD`
- `*STEP`, `*STATIC`, `*END STEP`
Part 내부 label은 `SourceEntityId { instance_name, source_label }`로 보존하고 Domain은
별도 stable internal index를 부여한다. 같은 part의 여러 identity instance는 허용하지만
translation/rotation data와 nested assembly는 구조화된 unsupported diagnostic으로
거부한다. 입력 파일당 하나의 static step만 허용하고 두 번째 step은 오류다.
`*PREPRINT`, `*RESTART`, `*TRANSVERSE SHEAR STIFFNESS`, `*OUTPUT, FIELD`,
`*OUTPUT, HISTORY`, `*NODE OUTPUT`, `*ELEMENT OUTPUT`, `*CONTACT OUTPUT` 및 그에 속한
미지원 output variable data는 warning 후 no-op 처리한다. 이 allowlist 밖의 미지원
model-affecting keyword는 오류다. FESA output은 Abaqus output request에 좌우되지 않는다.
## V0 beam과 section 계약
`EulerBeam3D`는 2절점과 절점당 `[UX, UY, UZ, URX, URY, URZ]` 6 DOF를 사용하며 축,
두 방향 Euler–Bernoulli 굽힘과 Saint-Venant 비틀림을 제공한다. Beam tangent를 local
`x`, Abaqus first section axis `n1`을 local `y`, `t x n1`을 local `z`로 둔다.
`*BEAM GENERAL SECTION`의 `A, I11, I12, I22, J`는 `Iy=I11`, `Iz=I22`로 매핑하고
V0는 `I12=0`만 허용한다. `E`, `G`, `A`, `Iy`, `Iz`, `J`는 양수여야 하며 zero-length
element와 tangent에 평행한 guide vector를 scale-aware tolerance로 거부한다.
요소 API는 stiffness, transformation, load와 recovery 책임을 분리한다.
```cpp
Matrix localStiffness() const;
Matrix globalStiffness() const;
Vector localEquivalentLoad(const ConstantLocalLineLoad& load) const;
BeamRecovery recover(const Vector& globalElementDisplacement) const;
```
`localEquivalentLoad`는 formulation의 constant local line-load kernel을 unit test하기
위한 계약이다. V0 parser는 `*DLOAD`나 distributed-load Domain object를 생성하지 않으므로
CLI pipeline에서는 이 kernel을 호출하지 않는다. Stiffness와 recovery는 formulation의
2점 Gauss rule과 부호 규약을 따른다.
## 핵심 객체 모델
```text
Domain
├── owns nodes, sets and source identity
├── owns unique_ptr<ElementDefinition / ElementProperty / Material>
├── owns StepDefinition with Load / BoundaryCondition definitions
└── owns source path/identity and mapping warnings
AnalysisModel
├── non-owning stable-index view into Domain
├── stable active element/BC/load definition indices
└── reachable material/property indices
ElementFactory
└── creates checked runtime Element candidates
Element
├── exposes ElementDofLayout
├── produces ElementStiffnessContribution
└── recovers ElementResultBundle
DofManager
├── owns node x [UX,UY,UZ,URX,URY,URZ] full-DOF numbering
├── owns stable free/constrained order and prescribed values
├── owns element scatter maps
└── owns full-space CSR structural pattern
AnalysisState
├── displacement U
├── external force Fext
├── internal force Fint
├── residual R and full-index reaction
├── StepFrameIdentity
└── endpoint, Gauss and S11 recovery rows
Analysis
└── LinearStaticAnalysis
Vector
Matrix
SparseMatrix
```
위 abstract boundary는 현재 B33/MITC4, isotropic linear elasticity, beam/shell property,
concentrated nodal load, prescribed displacement와 linear static procedure를 연결하는 데
필요한 최소 계약이다. MITC3, solid, dynamic, frequency, heat-transfer와 plastic behavior는
구현된 기능이 아니며 승인된 사용 사례 전에 future-only method나 state를 base에 추가하지
않는다.
## 상태 관리
- `Domain`은 입력 파일에서 만들어진 전체 모델 정의를 `std::unique_ptr`로 단독 소유한다.
파싱 이후에는 가능한 한 불변으로 취급하고 stable collection index를 바꾸지 않는다.
- `LinearStaticAnalysis`가 `Domain`을 소유하고, 그 뒤에 `AnalysisModel`, `DofManager`, `AnalysisState`, stiffness/RHS를 순서대로 만든다. 재사용 시에는 역순으로 해제하여 이전 Domain을 가리키는 view를 남기지 않는다.
- `AnalysisModel`은 현재 step에서 활성화되는 해석 객체들의 실행 view이다. `Domain`을 복사하지 않으므로 Domain이 반드시 더 오래 살아야 한다.
- `DofManager`는 자유도와 방정식 번호를 전담한다. `Node` 또는 `Element` 내부에 equation id를 분산 저장하지 않는다.
- `AnalysisState`는 V0 frame에 필요한 다섯 full-DOF vector와 recovery rows만 소유한다. Velocity, acceleration, temperature, iteration history, nonlinear element state는 해당 procedure가 승인될 때 별도 계약으로 추가한다.
- Result recovery는 모든 candidate vector/row를 검증한 뒤 state에 반영한다. 실패한 recovery가 앞선 유효 state를 부분적으로 덮어쓰지 않아야 한다.
## 데이터 흐름
```text
Abaqus input file
-> syntax parse and semantic mapping
-> immutable Domain 생성
-> 단일 step AnalysisModel view 생성
-> ElementFactory가 compatible definition에서 runtime Element candidate 생성
-> DofManager가 ElementDofLayout으로 DOF/scatter map/sparse pattern 생성
-> ElementStiffnessContribution의 deterministic COO-to-CSR 조립
-> ConstraintDefinition의 stable essential-constraint partition 생성
-> LinearSolver::factorize(Kff)
-> ordered LoadContribution의 full nodal load vector 조립
-> effective RHS = Ff - Kfc * dc
-> LinearSolver::solve(rhs, df) substitution
-> full displacement 복구
-> full residual/reaction = K*d - F 및 ElementResultBundle 복구
-> ResultsWriter로 derived `<stem>_results.h5` atomic finalization
```
### 승인된 Nonlinear Static 경로
`PrepareAnalysisInput()`은 input syntax와 semantic Domain을 정확히 한 번 만든다.
`ExecutePreparedAnalysis()`는 sole static step의 procedure identity로 linear static 또는
nonlinear static executor를 선택하며 두 procedure의 mutable state를 공유하지 않는다.
Nonlinear executor는 committed/trial `NonlinearAnalysisState`, full unsymmetric CSR tangent
solver와 closed-before-finalization Newton iteration log를 소유한다. Completion 뒤
`FinalizePreparedAnalysisResult()`가 selected backend-neutral writer로 only accepted frames를
atomic finalization한다.
Nonlinear schema v1의 factor-one `/global/equilibrium`은 raw full-residual sum이 아니라
global origin `[0,0,0]`에서 current `X+u` force arm과 independently spatialized applied and
masked constrained-reaction moments를 합한 applied-plus-reaction balance error다. Accepted
free residual은 generalized residual의 free mask projection이고 constrained-reaction resultant는
별도 review summary다. 어느 quantity도 다른 quantity의 substitute가 아니다.
강성행렬 factorization은 하중벡터 조립보다 먼저 수행한다. 반력은 element end action의
별도 합이 아니라 조립된 전체 residual에서 구한다. Constrained component는 physical
reaction이고 free component는 equilibrium residual evidence로 full-index vector에 남긴다.
- `Domain`은 전체 모델 정의를 소유하며 검증 이후 가능한 한 불변으로 취급한다.
- `AnalysisModel`은 Domain을 복사하지 않는 non-owning 실행 view다. Domain은 모든
view와 그에 의존하는 계산보다 오래 살아야 한다.
- `DofManager`는 DOF/equation mapping과 sparse pattern을 전담한다. Node나 Element에
equation 번호를 분산 저장하지 않는다.
- Analysis owner는 해당 procedure가 실제로 사용하는 mutable state와 workspace만 소유한다.
재사용·재시도·해제 시 dependent object를 남기지 않는다.
- Trial/committed 구분이 필요한 procedure는 update 실패와 commit 시점을 별도 계약으로
정의한다. 모든 procedure나 material에 이 state를 일괄 추가하지 않는다.
- Recovery와 output은 유효한 candidate를 검증한 뒤 반영한다. 기존 state와 최종 파일의
보존 범위는 성공 경로뿐 아니라 실패 경로에서도 검증한다.
## 해석 실행 흐름
`Analysis` base는 procedure-specific protected hook을 정의하지 않고 최소 실행 계약인
`Analysis::Run(const AnalysisRequest&)`만 제공한다. 다음 여덟 단계의 순서와 fail-fast
경계는 `LinearStaticAnalysis::Run()`의 private lifecycle이며 다른 procedure에 강제되지
않는다.
공통적으로 외부 입력의 의미를 검증하고 실행 모델을 구성한 뒤, 선택된 procedure가
equation과 state를 관리하여 결과를 복구·저장한다. 이것은 책임 수준의 설명이며 모든
procedure에 동일한 반복문이나 고정된 단계 목록을 강제하는 Template Method가 아니다.
| 순서 | Private stage | 주요 작업과 생성되는 소유 객체 | 순서/실패 불변식 |
| --- | --- | --- | --- |
| 1 | `Initialize(request)` | `.inp` syntax read, semantic map, owned immutable `Domain`, sorted warnings | 이전 run의 dependent object를 역순으로 제거하고 parse/map 실패를 input category로 반환한다. |
| 2 | `BuildAnalysisModel()` | non-owning `AnalysisModel` view | Domain을 복사하지 않으며 Domain lifetime 안에서만 사용한다. |
| 3 | `BuildDofMapAndSparsePattern()` | `DofManager`, zero-initialized `AnalysisState` | Stable full/free/constrained numbering과 structural pattern을 한 소유자에게 둔다. |
| 4 | `AssembleAndPartitionStiffness()` | full CSR K와 `Kff/Kfc/Kcf/Kcc` | Element-local buffer를 deterministic하게 reduce하고 structural zero와 stable order를 보존한다. |
| 5 | `Factorize()` | retained `Kff` factorization | 모든 load assembly보다 먼저 호출한다. Valid fully constrained model의 `0 x 0 Kff`는 trivial success다. |
| 6 | `AssembleLoadsAndEffectiveRhs()` | full F와 `Ff-Kfc*dc` | Semantic load source order와 finite sum을 보존하며 solver를 호출하지 않는다. |
| 7 | `SubstituteAndReconstruct()` | free solution과 full displacement | Factorization을 재수행하지 않고 substitution한 뒤 prescribed value를 stable order로 복구한다. |
| 8 | `RecoverAndWriteResults()` | full residual/reaction, B33/MITC4 rows, final HDF5 | Recovery candidate를 원자적으로 commit하고 writer 성공 뒤에만 최종 output을 교체한다. |
각 procedure 계약은 다음을 명시한다.
비선형 정적 및 동적 해석은 V0 범위가 아니며 별도 ADR과 formulation을 승인한 뒤 이
lifecycle과 state/equation 계약을 별도 procedure에 정의한다. LinearStaticAnalysis의
private stage 사이에 조용히 반복·증분·시간 적분 동작을 삽입하지 않는다.
1. 입력 준비와 procedure 선택의 경계, 원본 모델의 owner와 lifetime
2. 필요한 DOF, state, equation, workspace와 초기화 조건
3. Contribution, constraint, factorization/solve와 update의 순서
4. 해당하는 경우 increment, iteration, convergence와 종료 조건
5. 성공 candidate의 commit, recovery와 결과 frame의 의미
6. 실패 category, rollback·재사용 조건과 final output의 보존 범위
## 설계 패턴
- Strategy/Adapter Pattern: `Analysis::Run(const AnalysisRequest&)`, `LinearSolver`,
`ParallelFor`, `ResultsWriter`가 현재 승인된 public 실행/backend 경계다. Vendor API는
concrete adapter implementation 안에만 둔다.
- Procedure-owned lifecycle: `Analysis`는 protected Template Method hook을 공유하지 않고
`LinearStaticAnalysis`가 승인된 여덟 단계 lifecycle을 private하게 소유한다.
- Syntax/Semantic separation: `AbaqusInputReader`는 syntax record를 만들고 `AbaqusDomainMapper`가 승인된 keyword 의미를 concrete Domain record로 변환한다.
- Runtime Polymorphism: backend와 승인된 analysis/element/material/property/load/boundary
경계에만 사용한다. Factory compatibility는 중앙에서 fail-closed로 검사하며 global
registry 또는 future-only capability를 추가하지 않는다.
- RAII: MKL handle, HDF5 file/dataset, temporary solver workspace의 수명과 오류 처리를 wrapper에 묶는다.
정적·동적, 선형·비선형, eigen 또는 contact 계열은 실제 요구와 승인된 계약으로
정의한다. 이 구분을 명시하는 것은 해당 기능이 이미 지원된다는 뜻이 아니다.
기존 절차에 조건문으로 새 physics를 끼워 넣거나, 간결한 공통 그림을 근거로 승인된
연산 순서·reaction·residual·commit 의미를 바꾸지 않는다.
## Sparse Matrix Policy
- Assembly는 element마다 index-addressed contribution buffer를 만들고, join 뒤 COO tuple을 stable order로 정렬해 한 thread에서 순서대로 합산한 후 CSR로 finalize한다.
- `SparseMatrix`는 0-based CSR 데이터를 소유하는 별도 타입이며 dense `Matrix`를
상속하지 않는다. MKL PARDISO backend는 adapter 경계에서 필요한 descriptor와 indexing을
변환한다.
- CSR row offset, sorted-unique column, dimensions, finite values를 construction boundary에서 검증하며 structural zero를 삭제하지 않는다.
- Parallel worker는 global sparse matrix나 shared reduction accumulator를 직접 갱신하지 않는다. Worker별 failure slot과 contribution만 쓰고, deterministic reduction은 join 뒤에 수행한다.
- Matrix symmetry와 factorization/substitution failure는 solver adapter가 구조화된 solver diagnostic으로 번역한다. 승인되지 않은 regularization이나 fallback으로 singularity를 숨기지 않는다.
현재 개별 procedure의 구체적인 실행 계약은 해당 Feature의 formulation·I/O·구현 문서를
확인한다. 기존 프로젝트 문서의 실행 순서와 객체 배치는
[개정 전 아키텍처](archive/pre-generalization/ARCHITECTURE.md)에 이력으로 보존한다.
## Dense Math Policy
## Local 계산, assembly와 constraint
- `Vector`는 contiguous `double` 데이터와 크기를 소유하고 copy, dot, Euclidean norm,
scale, axpy를 MKL CBLAS adapter로 수행한다.
- `Matrix`는 row-major contiguous `double` 데이터와 dimensions를 소유하고
matrix-vector 및 matrix-matrix 연산에 `CBLAS_ROW_MAJOR`를 사용한다.
- 두 타입은 copy/move semantics와 bounds-checked access를 제공한다.
- MKL header와 MKL-specific type은 adapter implementation 밖으로 노출하지 않는다.
Local kernel은 승인된 geometry, material/property, DOF/state와 요청된 계산 범위를 받아
local ordering이 명시된 contribution 또는 recovery 값을 만든다. Global numbering,
공유 matrix 갱신, 파일 lookup, 전체 convergence 판정이나 최종 저장을 수행하지 않는다.
## Parallel Policy
- `ParallelFor`는 `[0,count)` index-addressed 독립 작업만 노출하며 `SerialParallelFor`와 `TbbParallelFor`가 같은 observable contract를 가진다.
- 첫 oneTBB 적용 지점은 element-local stiffness 계산이다. 각 callback은 자기 index의 output slot만 쓴다.
- 전역 sparse write와 부동소수 reduction은 parallel callback 밖의 deterministic 단계로 제한한다.
- MKL 내부 thread와 TBB element loop가 oversubscription을 만들지 않도록 thread count와 task arena 정책을 명시한다.
DOF owner가 지정한 pattern과 scatter를 assembly가 사용한다. Contribution 생성과
누적 순서를 명시하고 병렬 worker는 소유한 buffer에만 기록한다. Join 이후 reduction과
diagnostic 선택은 결정적으로 수행한다. Hash iteration이나 실행 scheduling을
authoritative ordering으로 사용하지 않는다.
## HDF5 Result Schema
```text
/metadata
/model/nodes
/model/elements
/steps/<step-name>/frames/0/nodal/displacement
/steps/<step-name>/frames/0/nodal/reaction
/steps/<step-name>/frames/0/element/end_force_local
/steps/<step-name>/frames/0/element/section_resultant
/steps/<step-name>/frames/0/element/generalized_strain
/steps/<step-name>/frames/0/element/stress_s11
/diagnostics
```
Constraint 방식, full/reduced space, prescribed value, residual과 reaction의 정의는
선택된 procedure의 수학 계약에 포함한다. 서로 다른 enforcement 방식의 결과 의미를
같다고 가정하지 않는다. 특수 차원·빈 시스템·singularity의 처리는 계약에 따라 검증하며
임의의 regularization, zero clamp 또는 fallback으로 실패를 숨기지 않는다.
Schema requirements:
- schema version, units, coordinate system, solver version, source input identity를 metadata에 기록한다.
- field output과 history output을 구분한다.
- reference comparison을 위한 row identity는 node id, element id, integration point id, step/frame id를 포함한다.
- FESA solver는 input lexical sibling `<stem>_results.h5`를 authoritative output으로 쓰며,
같은 directory의 `<stem>_log.txt`는 procedure log다.
- Abaqus reference results는 기능 문서가 선언한 기존 CSV 파일이다. Directory/file
naming, README, metadata 또는 provenance는 architecture readiness 조건이 아니다.
- Verification은 기능이 요구하는 source identity와 component를 결정적으로 대응시키고
승인 tolerance를 적용한다. Missing/extra/duplicate/nonfinite required row는 숫자 비교
전에 실패한다. 단일 step/final-frame 기능은 별도 CSV step/frame 열을 요구하지 않는다.
- FESA HDF5에서 추출한 deterministic CSV view는 optional debugging/review artifact이며 공식 solver output 또는 reference artifact가 아니다.
- Writer는 final과 같은 directory의 임시 HDF5에 전체 schema를 쓴 뒤 flush, checked close,
read-only reopen/self-check를 수행한다. Existing final은 `ReplaceFileW`, 새 final은
`MoveFileExW(..., MOVEFILE_WRITE_THROUGH)`로 완료하며 실패 시 temporary artifact를
정리하고 불완전한 파일을 정상 `<stem>_results.h5`로 노출하지 않는다.
## Numerical backend와 실행 환경
## V0 결과 복구와 reference normalization
Math storage, index convention, matrix capability, resource lifetime과 오류 변환은
backend-neutral 계약으로 노출한다. Vendor header, handle과 OS 타입은 private adapter에
격리한다. Dense와 sparse의 의미가 다르면 하나의 storage hierarchy로 억지로 합치지 않는다.
- Nodal displacement와 reaction은 global `[UX, UY, UZ, URX, URY, URZ]` 순서다.
- Equilibrium end action은 local `[FX,FY,FZ,MX,MY,MZ]`, endpoint section resultant는
`[N,T,My,Mz]`, generalized strain/resultant는 두 Gauss point에 기록한다.
- General beam section stress는 section point의 axial `S11`만 복구한다. Section point가
없으면 centroid `(0,0)`을 `source=fesa-default`로 기록한다.
- 승인된 `reference/cantilever beam/cantilever beam elemental forces.csv`는 각 B33
element의 두 endpoint에 `Element Label`, `Node Label`과 `SF1/SM1/SM2/SM3`을 제공한다.
`(instance, element label, endpoint node label, component)` identity로 HDF5
`[element,endpoint,N/T/My/Mz]`에 직접 대응하고 `SF1 -> N`, `SM1 -> My`, `SM2 -> Mz`,
`SM3 -> T`로 비교한다. External reference comparison은 node-station collapse나 평균을
사용하지 않는다.
- Reference tolerance는 같은 model/case, step/frame, logical quantity, unit dimension,
coordinate system과 blocking behavior의 component family에서 Abaqus-only scale
`S=max(abs(reference))`를 구한다. `abs(reference)<=0.01*S`인 행은 absolute error
`<=0.01*S`, 그 외 행은 relative error `<=0.05`로 판정하며 family scale-relative RMS
`RMS(error)/S<=0.01`도 통과해야 한다. 독립 absolute-error gate는 사용하지 않고
zero-scale family는 FESA도 exact zero일 때만 통과한다. 전체 판정 과정과 report/change
management contract는 `docs/TOLERANCE.md`를 따른다.
- Beam stress는 HDF5 schema와 unit/analytical test로 검증하지만 Abaqus reference
comparison은 N/A다.
Build dependency는 프로젝트가 소유한 target 경계에서 정규화하고, 새로운 dynamic
dependency는 link뿐 아니라 실제 실행에 필요한 runtime closure까지 확인한다.
개인 설치 절대 경로를 소스 계약으로 고정하지 않는다. Thread와 workspace 정책은
실제 workload와 재현성 evidence에 근거하여 관리한다.
## CLI와 diagnostics
현재 target graph와 dependency 선택은 [CMakeLists.txt](../CMakeLists.txt),
[dependency 설정](../cmake/FesaDependencies.cmake),
[solver target](../src/fesa/CMakeLists.txt), [test target](../tests/CMakeLists.txt)과
[CMakePresets.json](../CMakePresets.json)을 확인한다. 이 참조는 다른 toolchain이나
backend를 자동 승인하지 않으며 FESA의 현재 검증 baseline은 프로젝트 지침을 따른다.
```powershell
fesa.exe <model.inp>
```
## 입력, 결과와 진단
CLI는 input과 같은 lexical sibling directory에 `<stem>_results.h5`와
`<stem>_log.txt`를 유도하고 `--output`을 거부한다. Exit code는
`0=success`, `2=usage`, `3=input syntax/semantic mapping`, `4=model validation`,
`5=factorization/substitution`, `6=HDF5 output`으로 고정한다. Diagnostic은 `severity`,
`code`, `file`, `line`, `keyword`, `entity_identity`, `message`를 가지며 stderr에
deterministic한 순서로 출력한다.
Input adapter는 지원되는 외부 syntax, scope, default와 model/history 의미를
검증된 semantic model로 mapping한다. 의미상 무해하다고 계약된 항목만 warning/no-op으로
처리할 수 있으며 나머지 미지원 semantics는 fail-closed로 진단한다.
## 기능 확장 플레이북
Results/recovery가 물리량의 의미를, output adapter가 저장 layout을 소유한다.
Authoritative output과 diagnostic log, debug view, reference artifact를 구분한다.
공식 형식, 파일명, schema version, mandatory dataset과 backward compatibility는
현재 프로젝트·Feature I/O 계약을 따른다. 일반화 때문에 기존의 필수 결과를 optional로
바꾸거나 다른 파일 형식으로 대체하지 않는다.
다음 표는 코드 위치만이 아니라 함께 바뀌어야 하는 계약 경계를 나타낸다. 한 열만
구현하고 다른 열을 생략하면 internal utility 또는 실험 kernel일 수는 있어도 제품 기능은
아니다.
Output은 계약된 임시 candidate에 기록하고 검증·close를 완료한 뒤 최종 결과로 반영한다.
실패 frame이나 불완전한 파일을 정상 결과처럼 공개하지 않는다. 내부 state의 commit과
외부 파일의 finalization은 서로 다른 경계이므로 각각의 failure contract를 정의한다.
| 기능 유형 | 시작 전에 고정할 것 | 주요 구현 경계 | 함께 검증할 것 | 피해야 할 shortcut |
| --- | --- | --- | --- | --- |
| 새 element/material | DOF, interpolation, constitutive law, integration, local axes/sign, feature-approved validity boundary | Domain record와 mapper, element kernel, DofManager scatter/pattern, SparseAssembler, ResultRecovery | feature-required invariants/tests and blocking reference quantities | 서로 다른 물리를 같다고 주장, source ID와 internal index 혼용, 검증 전 범용 hierarchy 추가 |
| 새 load/constraint | Abaqus target grammar, application order, units, follower 여부, prescribed-value 의미 | Syntax/mapper, Domain target, full-space LoadAssembler 또는 constraint partition, diagnostics | set/direct target ambiguity, multi-instance identity, nonfinite sum, `Ff-Kfc*dc`, reaction | Element load kernel 존재를 parser 지원으로 간주, penalty를 elimination에 몰래 혼합 |
| 새 analysis procedure | governing equation, state variables, increment/time lifecycle, tangent/residual, convergence와 output frame | 별도 Analysis implementation, procedure-specific state/equation owner, solver interface extension | orchestration order, failure atomicity, restart/frame identity, numerical benchmark | V0 hook 사이에 조건문으로 반복/시간 적분 삽입, 사용하지 않는 future state 선할당 |
| 새 numerical backend | matrix/index contract, lifecycle, reusable state, failure taxonomy, thread/runtime policy | 기존 `LinearSolver` 또는 `ParallelFor` interface의 concrete adapter, CMake normalized target | empty/dimension/extreme-scale input, repeated call, failed-output preservation, clean runtime discovery | Vendor type을 public header에 노출, silent fallback/regularization, absolute install path 고정 |
| 새 output/reference quantity | 물리 정의, location, sign, units, coordinates, stable row identity, mandatory 여부, tolerance | Result record/recovery, AnalysisState, ResultsWriter/HDF5 schema, comparator projection | schema dtype/shape, ordering, nonfinite rejection, identity inventory, reference N/A 대체 evidence | 서로 다른 result identity 혼합, station mismatch 평균, output request로 mandatory result 제거 |
Diagnostic은 실패 단계, 안정된 code와 메시지, 가능한 source location/entity를 제공한다.
정확한 category, field와 CLI exit code는 I/O 계약을 따른다. Backend 오류를 그대로
누출하거나 내부 failure classification을 새 public exit code로 임의 승격하지 않는다.
모든 확장은 PRD의 제품 완료 정의와 요구조건→정식화→I/O→구현→reference→physics gate를
따른다. 기존 feature contract에 없는 범위를 편의상 “Abaqus compatible”이라고 넓히지 않는다.
## 검증과 reference 경계
## MITC4 확장 경계
검증 coverage와 비교량의 논리적 정의는 Numerical Review, 물리량의 저장·외부 대응은
I/O, 실행 evidence는 Implementation, 독립 물리 판단은 Physics Evaluation이 소유한다.
각 단계는 상위 계약을 결과에 맞춰 수정하지 않는다.
MITC4가 구현될 때 Abaqus `S4`와 `S4R` source type은 같은 FESA formulation을 선택한다.
Source type은 metadata/diagnostic identity로 보존하지만 FESA integration 또는 hourglass
경로를 선택하지 않는다. 6-DOF embedding의 비물리 drilling coordinate에는 physical
rotational stiffness block의 positive minimum diagonal에 `1e-3`을 곱한 고정 numerical
stabilization만 둔다. Drilling calibration, artificial-energy policy와 별도 drilling result
dataset은 이 기능 범위가 아니다.
- Source identity, location과 component 일치 여부를 수치 tolerance보다 먼저 확인한다.
- Missing, extra, duplicate와 nonfinite required value를 숨기지 않는다.
- 외부 reference 판정은 [TOLERANCE](TOLERANCE.md)의 공통 정책을 적용한다. 물리 평형,
정식화와 수렴의 검증 기준은 각자의 계약을 따른다.
- Reference artifact의 naming이나 보조 metadata를 맞추기 위해 파일을 변경하지 않는다.
- 공개 입력 의미나 관찰 가능한 결과 비교를 외부 solver의 내부 동작 동등성으로 해석하지 않는다.
Full-integration FESA-MITC4의 reference comparison은 `reference/shell/` S4의 기존 input 및
displacement CSV만 사용한다. Global `U1/U2/U3` translation family만 blocking이고
`UR1/UR2/UR3` rotation family는 warning-only evidence다. 두 family 모두 ADR-022의 공통
family-scale row/RMS 정책을 사용한다. S4R은
같은 kernel을 선택하는 source mapping과 metadata를 unit/integration tests로 검증하며
`reference/shellR/` artifact는 acceptance comparison에 포함하지 않는다.
구현 존재, 특정 revision의 검증 통과와 현재 release readiness는 별도로 확인한다.
Architecture 문서의 그림이나 모듈명이 기능의 완료 증거를 대신하지 않는다.
Approved nonlinear MITC4 verification은 `reference/shellNL-meshfine/` fine primary,
`reference/shellNL/` coarse companion과 `reference/shell/` linear control을 각각 독립
copied-input directory에서 실행한다. Factor-one global force/moment balance와 accepted free
residual은 blocking internal evidence다. External `U1/U2/U3`는 blocking, `UR1/UR2/UR3`는
warning-only이며 local nodal `RF1/RF2/RF3/RM1/RM2`는 deterministic review-only evidence다;
`RM3`와 stress는 nonlinear numerical comparison에서 제외한다.
## 개발 운영 인프라
공통 agent 상태 전이는 [SOLVER_AGENT_DESIGN](SOLVER_AGENT_DESIGN.md), skill의 역할은
[SOLVER_SKILL_DESIGN](SOLVER_SKILL_DESIGN.md)을 따른다. 실제 실행 절차는
[Harness skill](../.agents/skills/harness/SKILL.md)과 현재 agent/skill profile을 읽는다.
| Owner | 책임 |
| --- | --- |
| Coordinator | Feature 문서 목록·상태, dispatch, evidence gate, revision·retry budget과 closure |
| Specialist | 할당된 stage의 전문 판단, 기본·상세 산출물과 공통 handoff |
| Planning Agent | 할당된 implementation plan과 phase/index/step 계획 파일 |
| Executor | 현재 step 선택, branch, transport attempt, timestamp, path-scoped commit과 phase 진행 |
| Implementation Agent | 선택된 step의 코드·테스트·보고서와 result payload |
| Hook | 도구 호출 전 guardrail과 설정된 종료 검증; TDD 관찰이나 완전한 sandbox의 대체가 아님 |
Coordinator만 workflow를 전이한다. Specialist의 outcome은 전이 요청이고, Harness의
step 상태는 별개의 실행 상태다. Executor transport attempt는 최대 2회이며 동일
`retry_key`의 correction 1회와 뒤따르는 Implementation rerun은 Coordinator가 관리한다.
두 budget을 혼용하거나 실패 문구만 바꿔 반복하지 않는다.
승인된 scope와 할당된 작업 안의 일반 계획·문서·local 실행에는 반복 승인 gate를
추가하지 않는다. 계획 요청만으로 실행을 시작하지 않으며 외부 solver, 원격·파괴 작업과
sandbox 권한 확대에는 해당 명시적 권한이 필요하다.
Project config, preset과 실행 command는 검토해야 하는 실행 입력이다. Hook 통과나
구조화된 argument list만으로 그 side effect가 격리되었다고 간주하지 않는다.
Executor는 시작 전 선택된 phase 제어 파일 밖의 변경을 거부하며 모든 pending Step의
Planning 소유 `owned_paths`를 검증한다. 매 시도 후와 stage/commit 경계에서 신뢰된 목록과
변경·staged 경로를 대조하고 구현 변경과 phase metadata를 분리한다. 범위 밖 변경은
보존하고 재시도·커밋·다음 Step을 중단한다. 이 검사는 동시 writer의 원자적 격리나 여러
커밋의 단일 transaction을 보장하지 않는다. 실행 중 동시 편집을 피한다.
종료 코드와 Step 보고 상태를 함께 판정하며 명시적 실패를 transport 재시도로 덮어쓰지
않는다. 실제 wrapper timeout이고 결과 미보고일 때만 최초 포함 최대 두 번 시도한다.
환경·실패 진단과 원래 보고는 Executor 소유 `attempt_history`에 남기고 재개 때 보존한다.
등록된 Hook을 수동 실행하여 검증 evidence를 대신하지 않는다.
문서 전용 Stop 생략은 기록된 동일 session/turn의 허용된 편집 대상이 모두 저장소 내부
Markdown인 조건에 한정된다. 기록이 없거나 불완전한 읽기 전용 작업과 shell 쓰기까지
안전하게 분류한다고 가정하지 않는다. 생략은 build/test 통과가 아니다.
사용자가 실행을 제외한 문서 작업은 정적 검토와 미실행 항목을 보고한다.
## 문서와 아키텍처의 변경
프로젝트 공통 원칙의 변경은 공통 ADR로, 구현 항목별 선택은 해당 Feature ADR로
기록한다. Feature PRD는 범위와 acceptance 요약을, requirements·formulation·I/O는
전문 계약의 원본을 소유한다. 관리 문서와 기본·상세 산출물은
[FEATURE_DOCUMENTATION](FEATURE_DOCUMENTATION.md)의 소유권과 링크 규칙을 따른다.
Public dependency, identity, 수명, result meaning이나 lifecycle 변경은 영향받는
계약과 evidence를 함께 검토한다. 상위 계약 변경으로 영향받는 evidence는 stale 처리하며,
문서 정리만으로 기존 기능의 재검증이나 release 승인을 완료한 것으로 표시하지 않는다.
개정 전 구현 설명은 [보존본](archive/pre-generalization/ARCHITECTURE.md)에 남긴다.
해당 설명을 Feature 문서로 이관할 때 원래 범위와 승인 revision을 확인한다.
현재 문서는 과거 구현 상세를 삭제하여 계약을 없애거나 미래 API를 선결정하지 않는다.