Files
FESADev/docs/shell-surface-pressure-load/implementation-plan.md
T
2026-09-01 02:34:04 +09:00

819 lines
67 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Shell Surface Pressure Load 구현 계획
## 1. Metadata
- `feature_id`: `shell-surface-pressure-load`
- `status`: `draft-awaiting-user-approval`
- `owner_agent`: `implementation-planning-agent`
- `date`: `2026-08-31`
- `source_requirement`: `docs/shell-surface-pressure-load/requirements.md`
- `source_research`: `docs/shell-surface-pressure-load/research.md`
- `source_formulation`: `docs/shell-surface-pressure-load/formulation.md`
- `source_numerical_review`: `docs/shell-surface-pressure-load/numerical-review.md`
- `source_io_definition`: `docs/shell-surface-pressure-load/io.md`
- `source_reference_models`: `docs/shell-surface-pressure-load/reference-model.md`
- `source_coordination_gate`: `docs/shell-surface-pressure-load/coordination.md`
- `proposed_phase_slug`: `shell-surface-pressure-load`
- `proposed_task_name`: `shell-surface-pressure-load`
- `authoritative_output`: input lexical sibling `<stem>_results.h5`
- `approval_hard_stop`: 이 문서는 승인용 Step 초안이다. 사용자 승인 전에는 `phases/index.json`, `phases/shell-surface-pressure-load/index.json`, `phases/shell-surface-pressure-load/stepN.md`를 생성하거나 수정하지 않는다.
- `execution_hard_stop`: Step 초안 또는 향후 phase 파일 승인은 Harness 실행 권한이 아니다. `scripts/execute.py`는 별도의 명시적 사용자 실행 요청이 있을 때만 Harness Executor가 실행한다.
- `executor_policy`: 승인 후에도 Step 선택, branch/commit, 상태·시각 기록, Stop 검증과 실행 report는 Harness Executor 소유다. 이 계획은 수동 `git commit`, 일반 sub-agent 실행 또는 대체 executor를 제안하지 않는다.
## 2. Goal, Architecture, Tech Stack, Spec
### Goal
승인된 Abaqus `.inp` subset의 assembly-level `*SURFACE, TYPE=ELEMENT`와 single-static-step `*DSLOAD P`를 Domain semantic model, MITC4 pressure evaluator, 선형/비선형 full-space assembly, 기존 HDF5 결과 경로와 read-only reference comparison까지 끊김 없이 연결한다. 구현은 각 Step에서 반드시 테스트를 먼저 작성하고 실제 실패를 관찰한 뒤 최소 구현과 집중/전체 검증을 수행한다.
### Architecture
- `AbaqusInputReader`는 byte-level lexical contract와 `KeywordBlock`/`DataLine` source location을 소유한다.
- `DomainMappingContext`, `TopologyMapper`, 새 candidate `SurfaceDefinitionMapper`, `StepDefinitionMapper`, `DomainBuilder`가 raw input을 완전한 semantic candidate로 만든 뒤 한 번만 `Domain::Create`에 commit한다.
- `Domain`은 immutable ordered surface/facet inventory를, `StepDefinition`은 additive pressure records를 소유한다. `AnalysisModel`은 이를 복사하지 않는 active-step view만 제공하고 Domain이 더 오래 살아야 한다.
- 새 pressure evaluator는 parser, analysis procedure, HDF5, MKL/TBB에 의존하지 않는 solver-core 함수다. element-local `24 x 1` force와 `24 x 24` external tangent candidate를 반환한다.
- 새 surface-pressure assembler는 immutable Domain identity, `DofManager`, trial generalized coordinates와 `ParallelFor`를 받아 element-local candidate를 stable source order로 reduction한다. worker는 global vector/CSR을 직접 갱신하지 않는다.
- 선형 procedure는 reference-configuration pressure를 기존 CLOAD와 합쳐 full-space external load에 한 번만 반영하고, nonlinear procedure는 current-configuration follower force와 generally nonsymmetric external tangent를 같은 trial에서 평가한다.
- `Hdf5ResultsWriter` schema `0`과 `NonlinearHdf5ResultsWriter` schema `1`은 변경하지 않는다. 새 pressure dataset, schema/version/CLI option을 추가하지 않는다.
- reference utility는 FESA가 생성한 schema-1 factor-one HDF5와 exact stored displacement CSV만 비교한다. Abaqus를 실행하지 않으며 stored input/CSV를 수정하지 않는다.
### Tech Stack
- C++17, MSVC x64 Debug, CMake, CTest, GoogleTest
- Intel oneAPI MKL PARDISO: linear SPD path는 기존 `MklPardisoSolver`, nonlinear full-CSR unsymmetric path는 기존 `MklPardisoTangentSolver`와 `mtype=11`
- Intel oneAPI TBB behind `ParallelFor`
- HDF5 behind existing writers/self-check/atomic-finalization boundaries
- Python Harness는 phase orchestration용이며 이 기능이 Harness/Python 코드를 변경하지 않으므로 Python test 추가는 없다.
### Binding Spec
- 입력·진단·internal model·HDF5·comparison mapping은 `io.md` §§2–10이 우선한다.
- force/tangent, sign, configuration, integration, geometry validity와 deterministic assembly는 `formulation.md` §§6, 9–11, 13–14가 우선한다.
- analytical, finite-difference, objectivity, equilibrium, reference acceptance threshold는 `numerical-review.md` §6과 `docs/TOLERANCE.md`가 우선한다.
- exact reference paths와 dispositions는 `reference-model.md` §§3–8이 우선한다.
- 다른 solver 내부 알고리즘과의 동등성을 주장하지 않는다. Abaqus 결과는 승인된 외부 수치 reference일 뿐이다.
## 3. Readiness Check
| input | upstream status / gate evidence | planning disposition |
| --- | --- | --- |
| `requirements.md` | 문서 자체는 `draft-for-coordinator-gate-review`; Coordinator가 Gate 1을 통과시켰고 normative must IDs `001`–`024`가 완결 | binding |
| `research.md` | 문서 자체는 `draft-for-coordinator-gate-review`; Coordinator gate 통과 | binding evidence |
| `formulation.md` | `ready-for-numerical-review` | binding math handoff |
| `numerical-review.md` | `pass-for-io-definition` | binding numerical/reference readiness |
| `reference-model.md` | `pass-for-io-definition` | binding artifact contract |
| `io.md` | `ready-for-implementation-planning` | binding parser/model/HDF5/comparator contract |
| `coordination.md` | Gate 5 `passed`; document `ready-for-implementation-planning` | planning authorized |
필수 comparison artifacts는 존재하며 경로·hash·cardinality가 upstream에서 고정되었다. 필수 파일은 `reference/shellNL-meshfine-pressure/shellNL-meshfine-pressure.inp`와 `reference/shellNL-meshfine-pressure/shellNL-meshfine-pressure displacements.csv` 두 개다. reaction CSV는 존재 여부와 값이 verdict를 바꾸지 않는 review-only inventory이고 stress CSV는 비교 대상에서 제외된다.
`C:\git\FESADev\.harness\config.json`은 현재 없고 `.harness/config.example.json`만 존재한다. 따라서 Harness Stop의 repository default는 `.harness/build`, CMake/MSVC/CTest다. 현재 `.harness/build/CMakeCache.txt`는 `Visual Studio 18 2026`, `x64`, GoogleTest `C:/git/googletest`, MKL `2026.1`, TBB `2023.1`, HDF5 `2.1.1`로 구성되어 있다. 계획 작성 중 configure/build/test는 실행하지 않았다.
결론: 구현 계획은 진행 가능하다. blocker는 없으며 유일한 현재 사용자 결정은 아래 7-Step 초안의 승인 또는 수정 요청이다.
## 4. Implementation Scope
### Included
- assembly-level element surface의 direct `instance.element-label` 및 explicit-instance assembly ELSET facet resolution. 하나의 surface가 여러 data line에서 서로 다른 explicit instance의 direct/ELSET member를 함께 포함할 수 있다.
- S4/S4R, SPOS/SNEG, one static step의 additive uniform `DSLOAD P`
- case/ASCII whitespace/numeric/cardinality/keyword continuation/source provenance contract
- exact duplicate normalization warning과 conflicting side를 포함한 deterministic fail-closed diagnostics
- bilinear `2 x 2` pressure force와 exact follower external tangent
- linear reference configuration, nonlinear current configuration, exact-once load-factor scaling
- full-space force/tangent assembly, reaction/free residual/global resultant/moment, deterministic serial/parallel reduction
- 기존 schema 0/1 HDF5 및 CLI/atomic finalization 회귀
- exact pressure reference input/CSV에 대한 schema-1 factor-one HDF5 comparison과 common tolerance report
### Excluded
- `*DLOAD`, `TRVEC`, `PNU`, nonuniform/distribution pressure, nodal surface, part-level surface
- implicit-instance ELSET, 하나의 ELSET 자체가 여러 instance를 섞는 mixed-instance set, part ELSET lookup fallback. 서로 다른 explicit instance에 결속된 여러 member/ELSET를 하나의 surface에 두는 것은 포함 범위다.
- edges, other face labels, solids/beams, shells other than S4/S4R
- multi-step, amplitude, transient, eigen, contact, material/geometric extensions unrelated to pressure
- pressure-specific HDF5 dataset, schema bump, CLI option, result filter, CSV product output
- Abaqus execution, Abaqus CSV creation/repair/rename, reference input/CSV mutation
- reaction or stress external acceptance expansion
### Non-goals
- Abaqus internal formulation, integration, stabilization, state or result-generation equivalence
- speculative load hierarchy refactor, generalized distributed-load framework, new vendor abstraction
- unrelated parser cleanup, element refactor, tolerance policy change, documentation portfolio expansion
## 5. Candidate Interface and Data Contracts
아래 이름과 파일은 implementation handoff를 위한 candidate다. public compatibility와 upstream 의미를 고정하지만 최종 API/저장 배치는 Implementation Agent가 기존 style과 compile evidence에 맞춰 최소 범위에서 확정한다.
### Semantic model candidate
`include/fesa/model/model_types.h`에 다음 의미를 갖는 value types를 추가한다.
```cpp
enum class ShellSurfaceSide { kSpos, kSneg };
enum class SurfaceMemberKind { kDirect, kElset };
struct ElementSurfaceFacetDefinition {
EntityIndex element_index;
std::size_t facet_ordinal;
std::string part_name_raw;
std::string part_name_canonical;
std::string instance_name_raw;
std::string instance_name_canonical;
std::int64_t source_element_label;
std::string source_element_label_raw;
std::string source_element_type;
ShellSurfaceSide side;
SourceLocation first_member_location;
std::size_t first_member_ordinal;
SurfaceMemberKind member_kind;
std::string elset_name_raw;
std::string elset_name_canonical;
};
struct ElementSurfaceDefinition {
std::string surface_name_raw;
std::string surface_name_canonical;
std::vector<ElementSurfaceFacetDefinition> facets;
SourceLocation declaration_location;
std::size_t declaration_ordinal;
};
struct SurfacePressureLoadDefinition {
std::string step_name_raw;
std::string step_name_canonical;
EntityIndex surface_index;
std::string surface_name_raw;
std::string surface_name_canonical;
std::string load_type;
double magnitude;
std::string magnitude_raw;
SourceLocation keyword_location;
SourceLocation data_location;
std::size_t data_ordinal;
std::size_t load_ordinal;
};
```
`ModelDefinition`은 `std::vector<ElementSurfaceDefinition> element_surfaces`를 소유하고 `StaticStepDefinition`은 `std::vector<SurfacePressureLoadDefinition> surface_pressure_loads`를 소유한다. `ElementSurfaceDefinition`의 scope 의미는 exact `assembly`다. Committed facet은 internal lookup/scatter용 `element_index`와 별도로 part/instance raw+canonical identity, source element numeric label+raw token, exact canonical `S4|S4R` source type, side, `facet_ordinal`, 최초 contributing surface member의 file/line/member ordinal, `direct|elset` kind와 ELSET raw+canonical provenance를 계속 소유한다. 따라서 stable source identity가 internal element/equation index로 대체되지 않는다.
Committed `SurfacePressureLoadDefinition`은 surface lookup용 `surface_index`만 남기는 record가 아니다. sole step과 referenced surface의 raw+canonical identity, exact canonical `load_type="P"`, unscaled signed finite `magnitude`와 `magnitude_raw`, keyword/data `SourceLocation`, DSLOAD block 안의 `data_ordinal`, 전체 step load data에서의 `load_ordinal`을 보존한다. 동일해 보이는 pressure rows도 distinct records이며 `(load_ordinal, facet_ordinal)` Cartesian product가 active contribution identity다.
`Domain`/`StepDefinition`/`AnalysisModel` candidate query는 다음 의미를 갖는다.
```cpp
const std::vector<ElementSurfaceDefinition>& Domain::ElementSurfaces() const noexcept;
const std::vector<SurfacePressureLoadDefinition>&
StepDefinition::SurfacePressureLoads() const noexcept;
bool StepDefinition::UsesNonlinearGeometry() const noexcept;
const std::vector<SurfacePressureLoadDefinition>&
AnalysisModel::ActiveSurfacePressureLoads() const noexcept;
```
모든 반환값은 non-owning immutable reference다. `AnalysisModel`은 surface/facet/load를 복사하지 않고 backing `Domain`이 더 오래 살아야 한다. pressure records는 기존 nodal `Load::ComputeContributions`에 억지로 넣지 않는다. 그 interface는 configuration-independent nodal contributions 전용이고 follower tangent를 표현하지 못하기 때문이다.
### Local evaluator candidate
새 `include/fesa/loads/shell_surface_pressure.h`와 `src/fesa/loads/shell_surface_pressure.cpp`는 다음 backend-neutral contract를 제공한다.
```cpp
enum class SurfacePressureConfiguration { kReference, kCurrent };
struct ShellSurfacePressureInput {
std::array<Vector3, 4> reference_coordinates;
std::array<Vector3, 4> translational_displacements;
ShellSurfaceSide side;
double pressure_magnitude;
double load_factor;
SurfacePressureConfiguration configuration;
SourceLocation location;
std::string entity_identity;
};
struct ShellSurfacePressureContribution {
std::array<double, 24> force;
std::array<double, 24 * 24> external_tangent;
};
Result<ShellSurfacePressureContribution> EvaluateShellSurfacePressure(
const ShellSurfacePressureInput& input);
```
함수는 fixed node/source order의 row-major tangent를 반환한다. force의 rotational entries와 tangent의 rotational rows/columns는 exact zero다. reference configuration은 `u`를 사용하지 않고 tangent가 exact zero이며, current configuration은 승인된 exact derivative를 반환한다. geometric validation은 pressure 또는 factor가 zero여도 생략하지 않는다.
### Full-space assembler candidate
새 `include/fesa/assembly/surface_pressure_assembler.h`와 `src/fesa/assembly/surface_pressure_assembler.cpp`는 다음 contract를 제공한다.
```cpp
struct SurfacePressureAssemblyCandidate {
Vector full_external_force;
SparseMatrix full_external_tangent;
std::vector<Diagnostic> diagnostics;
};
Result<SurfacePressureAssemblyCandidate> AssembleSurfacePressure(
const AnalysisModel& model,
const DofManager& dofs,
const Vector& full_generalized_coordinates,
double load_factor,
SurfacePressureConfiguration configuration,
const ParallelFor& parallel_for);
```
입력 vector는 stable full-DOF `[u1,u2,u3,phi1,phi2,phi3]` order다. assembler는 pressure record source order, 각 surface의 canonical facet order, fixed Gauss order로 local candidates를 만든 뒤 동일 순서로 serial reduction한다. 실패 시 output candidate를 반환하지 않으며 caller-owned `AnalysisState`/`NonlinearTrialState`는 갱신하지 않는다.
### Procedure composition candidate
- Linear: `LoadAssembler::AssembleFullNodalLoad(...)` 결과와 `AssembleSurfacePressure(..., 1.0, kReference, ...)`의 full force를 checked finite addition하여 `AnalysisState::ExternalForce()`에 한 번만 assign한다. existing stiffness factorization-before-load order와 `EffectiveFreeRhs(F, Kfc, dc, dofs)`를 보존한다.
- Nonlinear: 같은 trial에서 `AssembleInternal(...)`, existing `AssembleGlobalFixedLoadContribution(...)`, `AssembleSurfacePressure(..., increment.load_factor, kCurrent, ...)`를 평가한다. `f_ext=f_fixed+f_pressure`, `K_ext=K_fixed+K_pressure`, `r=f_int-f_ext`, `K=K_int-K_ext` 순서로 candidate를 완성한 뒤 factorization/solve/validation/commit한다. `MklPardisoTangentSolver`의 existing full-CSR unsymmetric path를 유지하며 tangent를 symmetrize하지 않는다.
## 6. Candidate Files and Ownership
### Existing files to modify
| path | responsibility |
| --- | --- |
| `include/fesa/io/abaqus/input_syntax.h` | continued keyword/source-line representation에 필요한 최소 lexical provenance |
| `src/fesa/io/abaqus/input_reader.cpp` | ASCII, 256-byte logical keyword, keyword-only continuation, comma/whitespace contract |
| `src/fesa/io/abaqus/domain_mapping_context.h` | raw surface/facet/DSLOAD records와 provenance |
| `src/fesa/io/abaqus/domain_mapping_context.cpp` | assembly `SURFACE`, assembly `ELSET INTERNAL`, step `DSLOAD` parsing 및 scope/cardinality diagnostics |
| `src/fesa/io/abaqus/domain_mapper.cpp` | surface resolution stage를 topology finalize와 step definition 사이에 호출 |
| `src/fesa/io/abaqus/step_definition_mapper.cpp` | DSLOAD target를 resolved surface index에 bind하고 procedure rules 검증 |
| `src/fesa/io/abaqus/domain_builder.cpp` | 완전 검증된 surface/load candidate를 ModelDefinition에 commit |
| `include/fesa/model/model_types.h` | immutable surface/facet와 Step pressure value definitions |
| `include/fesa/model/domain.h`, `src/fesa/model/domain.cpp` | Domain/Step ownership과 immutable views |
| `include/fesa/analysis/analysis_model.h`, `src/fesa/analysis/analysis_model.cpp` | active pressure non-owning view |
| `src/fesa/analysis/linear_static_procedure.cpp` | reference pressure full-space external force composition |
| `include/fesa/analysis/nonlinear_static_control.h`, `src/fesa/analysis/nonlinear_static_control.cpp` | pressure-independent fixed-load contract를 유지하면서 checked external contribution composition helper가 필요할 때만 최소 확장 |
| `src/fesa/analysis/nonlinear_static_procedure.cpp` | current follower force/tangent, residual/tangent sign, rollback/commit integration |
| `src/fesa/CMakeLists.txt` | 새 production `.cpp` 두 쌍 등록 |
| `tests/CMakeLists.txt` | 새 unit/integration/reference test sources를 기존 targets에 등록; raw `add_test` 추가 없음 |
| `tests/unit/io/abaqus/input_reader_test.cpp` | ASCII/continuation/length/comma lexical tests |
| `tests/unit/io/abaqus/domain_mapper_test.cpp` | 기존 `DLOAD` rejection 및 no-pressure regression 유지/구체화 |
| `tests/unit/io/abaqus/domain_mapping_components_test.cpp` | mapper stage atomicity와 surface resolution component tests |
| `tests/unit/io/hdf5/hdf5_results_writer_test.cpp` | schema 0 inventory/no-pressure-dataset/atomic final regression |
| `tests/unit/io/hdf5/nonlinear_hdf5_results_writer_test.cpp` | schema 1 force/residual/reaction/equilibrium projection/no-new-dataset regression |
| `tests/reference/nonlinear_static_reference_comparison.h`, `tests/reference/nonlinear_static_reference_comparison.cpp` | pressure case contract, optional review artifacts, factor-one projection/prechecks/report |
### New files to create during implementation
| path | responsibility / first owning Step |
| --- | --- |
| `src/fesa/io/abaqus/surface_definition_mapper.h` | raw-to-resolved assembly surface mapper internal interface / Step 1 |
| `src/fesa/io/abaqus/surface_definition_mapper.cpp` | direct/ELSET resolution, canonical sort/duplicate policy / Step 1 |
| `tests/unit/io/abaqus/shell_surface_pressure_domain_test.cpp` | feature-focused valid and fail-closed semantic mapping / Step 1 |
| `include/fesa/loads/shell_surface_pressure.h` | local evaluator input/result contract / Step 3 |
| `src/fesa/loads/shell_surface_pressure.cpp` | bilinear integration, geometry checks, force/external tangent / Step 3 |
| `tests/unit/loads/shell_surface_pressure_test.cpp` | analytical, objectivity, FD, geometry evaluator tests / Step 3 |
| `include/fesa/assembly/surface_pressure_assembler.h` | full-space deterministic assembly candidate / Step 4 |
| `src/fesa/assembly/surface_pressure_assembler.cpp` | local scatter and stable reduction / Step 4 |
| `tests/unit/assembly/surface_pressure_assembler_test.cpp` | source/facet/load order, additive/exact-once, serial/parallel tests / Step 4 |
| `tests/integration/analysis/shell_surface_pressure_linear_test.cpp` | linear procedure/reaction/residual/resultant/HDF5 schema 0 / Step 4 |
| `tests/integration/analysis/shell_surface_pressure_nonlinear_test.cpp` | follower Newton/tangent/rollback/balance/HDF5 schema 1 / Step 5 |
| `tests/integration/app/shell_surface_pressure_application_test.cpp` | CLI exact input syntax, existing output naming/schema/atomic/no-pressure regression / Step 4 then Step 5 additions |
| `tests/reference/shell_surface_pressure_reference_test.cpp` | exact artifact and end-to-end comparison gate / Step 6 |
| `docs/shell-surface-pressure-load/implementation-report.md` | implementation/task/test/change summary, future Step 7 |
| `docs/shell-surface-pressure-load/build-test.md` | command/exit/duration/tail/warning/runtime evidence, future Step 7 |
| `docs/shell-surface-pressure-load/reference-comparison.md` | artifact snapshots, comparison metrics/classification, future Step 7 |
`src/fesa/app/fesa_application.cpp`, HDF5 production writers, PARDISO adapters와 existing tolerance policy는 read-first verification targets이며 원칙적으로 수정하지 않는다. 새 tests가 승인된 contract 결함을 실제로 증명할 때만 해당 Step의 bounded scope 안에서 최소 수정하고 report에 이유를 남긴다.
## 7. Work Breakdown and Harness Step Draft
모든 Step은 이전 Step이 green인 상태에서 시작하고 단일 reviewer-rejectable responsibility를 완결한다. 각 Step은 `RED -> observed expected failure -> minimal GREEN -> focused VERIFY -> full/Stop VERIFY`를 같은 세션 안에서 끝낸다. 아래 phase 파일들은 제안일 뿐 아직 materialize하지 않는다.
### Step 1 — `map-pressure-input-contract`
**Bounded responsibility:** valid assembly `SURFACE`와 step `DSLOAD P`를 immutable Domain/Step/AnalysisModel contract로 map한다.
**Dependencies:** 없음.
**Prerequisites/read first:** `input_syntax.h`, `input_reader.cpp`, `domain_mapping_context.h/.cpp`, `topology_mapper.h/.cpp`, `step_definition_mapper.h/.cpp`, `domain_builder.h/.cpp`, `domain_mapper.cpp`, `model_types.h`, `domain.h/.cpp`, `analysis_model.h/.cpp`, upstream `requirements.md` §§6–8, `io.md` §§2–6, `formulation.md` §3.
**Exact files:** 위 Candidate Files의 parser/model existing files, 새 `surface_definition_mapper.h/.cpp`, 새 `shell_surface_pressure_domain_test.cpp`, `tests/CMakeLists.txt`, `src/fesa/CMakeLists.txt`.
**RED:** 먼저 다음 named tests를 작성한다.
- `InpSyntax.AcceptsAsciiKeywordContinuationAndPreservesPhysicalSourceLines`
- `ShellSurfacePressureInput.MapsDirectInstanceFacetsForS4AndS4rCaseInsensitively`
- `ShellSurfacePressureInput.MapsExplicitInstanceElsetAndResultNeutralInternalParameter`
- `ShellSurfacePressureInput.MapsMixedDirectAndElsetMembersAcrossTwoExplicitInstancesWithStableDataMemberAndElsetOrder`
- `ShellSurfacePressureInput.PreservesSposSnegMagnitudeTextLocationsAndSourceOrder`
- `ShellSurfacePressureDomain.OwnsCanonicalFacetsAndStepOwnedAdditivePressureRecords`
- `ShellSurfacePressureDomain.AnalysisModelBorrowsActivePressureWithoutCopyingDomain`
- `ShellSurfacePressureInput.AcceptsWhitespaceSignedZeroAndFiniteScientificNotation`
`MapsMixedDirectAndElsetMembersAcrossTwoExplicitInstancesWithStableDataMemberAndElsetOrder`의 RED fixture는 declaration order가 다른 `Instance-A`와 `Instance-B`, 서로 다른 casing으로 참조한 direct member와 각 instance에 explicit `INSTANCE=`로 결속된 flat assembly ELSET member를 하나의 surface data inventory에 교차 배치한다. Test는 case-insensitive resolution, raw data/member ordinal과 ELSET expansion provenance, canonical facet order, 두 instance에서 numeric label이 같아도 분리되는 part/instance/source label/source type/side identity, 각 unique facet의 first-member provenance를 exact 비교한다. Implicit-instance ELSET을 같은 test의 valid branch로 허용하지 않는다.
실행:
```powershell
cmake --build .harness/build --config Debug --target fesa_unit_tests
ctest --test-dir .harness/build -C Debug --output-on-failure -R "^(InpSyntax|ShellSurfacePressureInput|ShellSurfacePressureDomain)\."
```
**Observed expected failure:** 새 mapper/header 또는 semantic accessors가 없어 compile이 실패하거나, 현재 `SURFACE`/`DSLOAD`가 unsupported input diagnostic으로 거부되어 assertions가 실패해야 한다. Multi-instance RED fixture는 한 surface의 두 explicit instance와 mixed direct/ELSET를 resolve하지 못하거나 committed identity/provenance fields가 없어 exact assertions가 실패해야 한다. unrelated failure면 Step을 중지하고 `regression`으로 분류한다.
**Minimal GREEN:** 위 candidate semantic signatures를 최소 구현한다. reader는 keyword-only `**,` comment-aware continuation만 결합하며 logical keyword 256 bytes, ASCII, comma/cardinality와 physical source line을 보존한다. surface mapper는 topology finalize 뒤 direct `<instance>.<positive-label>` 또는 assembly ELSET의 explicit `INSTANCE`를 case-insensitive하게 resolve한다. 하나의 surface 안에서 direct와 ELSET member를 섞고 서로 다른 두 개 이상의 explicit instance를 참조할 수 있으며, raw data/member order와 flat ELSET expansion provenance를 보존한 뒤 unique facets를 canonical stable order로 만든다. implicit-instance syntax, 하나의 mixed-instance ELSET, part-scope fallback은 허용하지 않는다. step mapper는 parameterless `DSLOAD`, exactly three fields, `P`, finite C-locale scalar를 surface index에 bind하면서 §5 candidate provenance 전부를 보존한다. DomainBuilder는 모든 validation 이후에만 moved ModelDefinition을 commit한다. legacy `StaticStepDefinition` constructors는 empty pressure vector로 delegating하여 existing callers를 깨지 않는다.
**Focused VERIFY:** 위 RED 명령이 exit `0`이고 모든 named tests가 pass한다. 이어 parser/domain existing suites를 실행한다.
```powershell
ctest --test-dir .harness/build -C Debug --output-on-failure -R "^(InpDomainMapping|DomainMappingComponents|InpSyntax)\."
```
**Full/Stop VERIFY:** 공통 `V-BUILD`, `V-SHOW`, `V-FULL` 명령을 실행한다.
**Invariants:** 한 surface 안의 mixed direct/ELSET 및 여러 explicit instance는 지원한다. raw surface data/member ordinal과 각 flat ELSET expansion provenance를 stable하게 보존하되 committed unique facet sort는 `(instance declaration ordinal, numeric element label, SPOS before SNEG)`다. S4/S4R part/instance/source label/type/side와 최초 member provenance를 internal index와 함께 보존한다. DSLOAD rows는 raw+canonical step/surface identity, canonical `P`, signed magnitude/raw token, keyword/data location, data/load ordinal을 가진 distinct/additive records다. lookup은 case-insensitive이고 raw spelling은 보존하며 Domain lifetime > AnalysisModel이다.
**Failure/atomicity:** parse/map failure는 Domain을 반환하지 않으며 partial surface/load가 visible하지 않다. diagnostics는 backend-independent SourceLocation을 가진다.
**Forbidden scope:** physics evaluator/assembly, `DLOAD`, general surface framework, HDF5/schema, reference artifacts.
**Trace:** requirements `001`–`004`, `010`, `013`; `IO §§2–6`; `FORM §3`; numerical-review input readiness.
**Evidence/report:** exact commands, exit codes, expected RED diagnostic/compile reason, mapped facet/load dumps from tests, modified/new paths, warning count. Handoff은 immutable semantic queries와 stable ordering contract다.
### Step 2 — `reject-invalid-pressure-input`
**Bounded responsibility:** pressure input/mapping negative semantics와 deterministic diagnostics를 fail-closed/atomic하게 완결한다.
**Dependencies:** Step 1 green semantic output.
**Prerequisites/read first:** Step 1 changed files/tests, `core/ascii.h`, `core/diagnostic.h`, `source_target_resolver.h/.cpp`, `io.md` §§2.5–3.4, 5.2, 9, `requirements.md` `014`–`017` acceptance, `formulation.md` §11.
**Exact files:** `input_reader.cpp`, `domain_mapping_context.h/.cpp`, `surface_definition_mapper.h/.cpp`, `step_definition_mapper.cpp`, `domain_builder.cpp`, `shell_surface_pressure_domain_test.cpp`, existing `domain_mapper_test.cpp` and `domain_mapping_components_test.cpp`. 새 production type은 만들지 않는다.
**RED named tests:**
- `ShellSurfacePressureInput.RejectsNonAsciiOverlengthOrIllegalContinuationAtStableLocation`
- `ShellSurfacePressureInput.RejectsUnsupportedSurfaceParametersTypesSidesAndTargetKinds`
- `ShellSurfacePressureInput.RejectsDsloadParametersLabelsDistributionsAndCardinality`
- `ShellSurfacePressureInput.RejectsEmptyMissingAmbiguousAndCrossScopeSurfaceTargets`
- `ShellSurfacePressureInput.RejectsImplicitInstanceNestedCyclicAndMalformedElsets`
- `ShellSurfacePressureInput.NormalizesExactSameSideDuplicatesWithOneStableWarning`
- `ShellSurfacePressureInput.RejectsConflictingSidesForOneElement`
- `ShellSurfacePressureInput.RejectsNonfiniteDExponentAndLocaleDependentMagnitudes`
- `ShellSurfacePressureInput.PreservesAdditiveRepeatedPressureRowsWithoutDeduplication`
- `ShellSurfacePressureDomain.MappingFailureCommitsNoPartialSemanticCandidate`
- `ShellSurfacePressureInput.EmitsDiagnosticsInStableSourceOrderAcrossRepeatedRuns`
RED/focused command:
```powershell
cmake --build .harness/build --config Debug --target fesa_unit_tests
ctest --test-dir .harness/build -C Debug --output-on-failure -R "^(ShellSurfacePressureInput|ShellSurfacePressureDomain)\."
```
**Observed expected failure:** Step 1의 happy-path mapper가 unsupported fields를 허용하거나 첫 발견/container order로 진단을 내고, duplicate/conflicting normalization을 구분하지 못해 assertions가 실패해야 한다.
**Minimal GREEN:** allowed parameter/label/cardinality tables를 exact하게 적용한다. recursive/nested/cyclic ELSET expansion을 금지하고 part/implicit scope fallback을 하지 않는다. exact same-side duplicate는 한 facet으로 normalize하고 한 warning을 stable location/order로 emit하며 conflicting side는 error다. 모든 오류를 candidate validation 단계에서 모으고 `SortDiagnostics` contract로 정렬한 뒤 Domain commit 전에 반환한다. silent skip, guess, average, partial commit은 금지한다.
**Focused VERIFY:** named negative tests와 모든 `InpDomainMapping` tests exit `0`; golden diagnostic fields `(severity,code,file,line,keyword,entity_identity,message)`와 repeated-run order가 exact하다.
**Full/Stop VERIFY:** `V-BUILD`, `V-SHOW`, `V-FULL`.
**Invariants:** exact duplicate warning과 incompatible duplicate error 분리; missing/extra/ambiguous/cyclic/cross-scope/nonfinite 모두 tolerance 이전 차단; legacy input without pressure unchanged.
**Failure/atomicity:** failed candidate는 Domain/AnalysisState/HDF5로 이동하지 않는다. 실패한 input으로 기존 final output을 건드리지 않는 CLI proof는 Step 4/5에서 추가한다.
**Forbidden scope:** evaluator, tolerance 완화, artifact rewrite, parser-wide refactor.
**Trace:** requirements `002`–`004`, `013`–`017`; `IO §§2–6,9`; `FORM §11`; `NR §6` invalid-input rows.
**Evidence/report:** 각 test의 expected code/location/entity, warning normalization count, repeated diagnostic sequence, RED/GREEN exits. Handoff은 fail-closed semantic model이다.
### Step 3 — `evaluate-shell-pressure-kernel`
**Bounded responsibility:** one four-node shell facet의 reference/current pressure force와 exact external tangent를 승인된 geometry policy로 계산한다.
**Dependencies:** Step 1–2 semantic side/magnitude/source identity.
**Prerequisites/read first:** `mitc4_shell.h/.cpp`, `nonlinear_mitc4_shell.h/.cpp`, `shell_geometry.h/.cpp`, `vector3.h`, `matrix.h`, existing MITC4 unit/tangent tests, `formulation.md` §§6, 9–10, 13–14, `numerical-review.md` §§3–6.
**Exact files:** 새 `shell_surface_pressure.h/.cpp`, 새 `shell_surface_pressure_test.cpp`, `src/fesa/CMakeLists.txt`, `tests/CMakeLists.txt`.
**RED named tests:**
- `ShellSurfacePressureKernel.PartitionsUnityAndIntegratesPlanarResultantAndMoment`
- `ShellSurfacePressureKernel.ReversesExactlyForSposSnegAndNegativeMagnitude`
- `ShellSurfacePressureKernel.UsesReferenceGeometryWithExactZeroLinearTangent`
- `ShellSurfacePressureKernel.UsesCurrentAreaAndNormalForFollowerForce`
- `ShellSurfacePressureKernel.HasExactZeroRotationalForceRowsAndTangentBlocks`
- `ShellSurfacePressureKernel.IsTranslationAndRigidRotationObjective`
- `ShellSurfacePressureKernel.IsCovariantUnderCyclicNodeRelabeling`
- `ShellSurfacePressureKernel.MatchesCenteredFiniteDifferenceForForceAndResidualSigns`
- `ShellSurfacePressureKernel.PreservesGenerallyNonsymmetricFollowerTangent`
- `ShellSurfacePressureKernel.RejectsNonfiniteCollapsedFoldedAndInvertedGeometryAtEveryRequiredPoint`
- `ShellSurfacePressureKernel.ValidatesGeometryEvenForZeroPressureOrFactor`
RED/focused command:
```powershell
cmake --build .harness/build --config Debug --target fesa_unit_tests
ctest --test-dir .harness/build -C Debug --output-on-failure -R "^ShellSurfacePressureKernel\."
```
**Observed expected failure:** new evaluator declaration/definition이 없어 compile/link fail해야 한다. 기존 MITC4 internal-force code를 pressure처럼 재사용하여 GREEN으로 만들지 않는다.
**Minimal GREEN:** fixed Gauss order `(-1/sqrt(3),-1/sqrt(3))`, `(+,−)`, `(+,+)`, `(−,+)`의 common `2 x 2` rule, bilinear `N_i`, `s=+1/-1`, `f_i=-lambda*p*s*sum(w*N_i*a)`와 approved exact derivative를 직접 구현한다. current coordinates는 `X+u` translation만 사용한다. `tau_J=1e-12`와 mean/corner/Gauss chord-scaled checks, finite/fold/inversion rules를 그대로 적용한다. `max(1,...)`, absolute floor, clamp, connectivity reorder, normal flip, tangent symmetrization은 금지한다.
**Focused VERIFY acceptance:** shape sum error `<=1e-14`; normalized resultant/moment/sign/objectivity/covariance `<=1e-12`; centered FD `h=1e-5`, normalized tangent error `<=1e-8`; zero rotational blocks exact zero; antisymmetric tangent evidence nonzero; invalid cases exact failure.
**Full/Stop VERIFY:** focused test 뒤 existing `Mitc4Shell`, `NonlinearMitc4Shell`, `NonlinearMitc4ShellTangent` suites와 `V-BUILD`, `V-SHOW`, `V-FULL`.
**Invariants:** force/tangent same geometry/Gauss evaluation; sign consistency for both `f_ext` and residual derivative; no state mutation; deterministic fixed loops.
**Failure/atomicity:** function returns no contribution on any nonfinite/geometry failure; caller arrays/state remain unchanged.
**Forbidden scope:** element internal stiffness/constitutive changes, pressure stress recovery, integration configurability, vendor dependency.
**Trace:** requirements `005`–`009`, `016`, `020`–`021`; `FORM §§6,9–10,13–14`; `NR §6` kernel/objectivity/tangent/geometry rows.
**Evidence/report:** normalized metrics, FD numerator/denominator/h, antisymmetric entries, exact-zero checks, diagnostic identity/location and command exits. Handoff은 pure local evaluator contract다.
### Step 4 — `integrate-linear-shell-pressure`
**Bounded responsibility:** reference-configuration pressure를 deterministic full-space linear load path, reaction/free residual/global balance와 existing schema-0 CLI output에 연결한다.
**Dependencies:** Step 1–3 green.
**Prerequisites/read first:** Step 3 evaluator, `load_assembler.h/.cpp`, `sparse_assembler.h/.cpp`, `parallel_for.h/.cpp`, `dof_manager.h/.cpp`, `linear_static_procedure.cpp`, `analysis_state.h/.cpp`, `result_recovery.h/.cpp`, `global_equilibrium_recovery.h/.cpp`, HDF5 schema-0 writer/self-check/tests, `fesa_application.cpp`, `io.md` §§7.1, 7.3, 10, `formulation.md` §§9,11–13.
**Exact files:** 새 `surface_pressure_assembler.h/.cpp`, unit assembler test, new linear integration/app tests, `linear_static_procedure.cpp`, `src/fesa/CMakeLists.txt`, `tests/CMakeLists.txt`, schema-0 writer test only for contract assertions. HDF5 production writer는 expected no-change.
**RED named tests:**
- `SurfacePressureAssembly.AssemblesFullDofsInPressureFacetAndRecordOrder`
- `SurfacePressureAssembly.AddsRepeatedRecordsAndAppliesUnitFactorExactlyOnce`
- `SurfacePressureAssembly.IsBitwiseStableForSerialAndParallelLocalEvaluation`
- `LinearShellSurfacePressure.UsesReferenceNormalAndAreaAfterPrescribedDisplacement`
- `LinearShellSurfacePressure.AssemblesBeforeProjectionAndIncludesConstrainedReaction`
- `LinearShellSurfacePressure.SatisfiesFreeResidualGlobalResultantAndMoment`
- `LinearShellSurfacePressure.PreservesS4S4rMeshAndCyclicOrderInvariance`
- `LinearShellSurfacePressure.WritesSchemaZeroWithoutPressureDataset`
- `ShellSurfacePressureApplication.LinearFailurePreservesExistingFinalAndNoCandidate`
- `ShellSurfacePressureApplication.InputWithoutPressureRetainsExistingLinearBehavior`
RED/focused commands:
```powershell
cmake --build .harness/build --config Debug --target fesa_unit_tests fesa_integration_tests
ctest --test-dir .harness/build -C Debug --output-on-failure -R "^(SurfacePressureAssembly|LinearShellSurfacePressure|ShellSurfacePressureApplication)\."
```
**Observed expected failure:** assembler header/definition이 없거나 linear procedure가 nodal CLOAD만 assembly하여 pressure resultant/reaction가 zero이고 pressure CLI case가 acceptance를 충족하지 못해야 한다.
**Minimal GREEN:** local pressure candidates를 source/facet/Gauss stable order로 생성하고 worker-local buffers에서 full DOF/scatter COO를 만들며 fixed serial reduction한다. linear procedure는 stiffness partition/factorization 후 existing CLOAD와 reference pressure full force를 checked add하고, projection 전 `state.ExternalForce()`에 한 번만 commit한다. evaluator에는 load factor `1.0`을 정확히 한 번 전달한다. existing `Kff/Kfc`, 0x0 free system, `K*d-F` recovery와 output finalization order는 보존한다.
**Focused VERIFY acceptance:** analytical normalized force/moment/reaction/mesh/order errors `<=1e-12`; global force/moment balance `<=1e-8`; free residual uses approved existing scale gates; repeated serial/parallel output and diagnostics exact; schema version `0`, existing mandatory datasets만 존재하고 pressure-specific path는 없다; failed candidate가 prior final bytes를 보존한다.
**Full/Stop VERIFY:** existing `LoadAssembly`, `SparseAssembly`, `LinearStaticCli`, `Mitc4ShellCli`, `Hdf5ResultsWriter` suites와 `V-BUILD`, `V-SHOW`, `V-FULL`.
**Invariants:** factorization-before-load; full-space before free/constrained projection; linear tangent exact zero; pressure load factor exact once; worker global CSR write 금지; source/internal/equation IDs 분리.
**Failure/atomicity:** any local/nonfinite/assembly/recovery failure returns before state/result publication; HDF5 existing final preserved by current atomic writer.
**Forbidden scope:** nonlinear follower path, schema change, linear solver backend change, output dataset addition.
**Trace:** requirements `005`–`007`, `010`–`013`, `016`–`020`; `IO §§6–7,9–10`; `FORM §§9,11–14`; `NR §6` linear/resultant/balance rows.
**Evidence/report:** stable contribution order, external vector/reaction/residual/resultants, schema inventory, final-file snapshots, RED/GREEN exits. Handoff은 validated linear pressure path와 reusable full-space assembler다.
### Step 5 — `integrate-nonlinear-follower-pressure`
**Bounded responsibility:** current-configuration follower pressure force와 generally nonsymmetric external tangent를 nonlinear full-Newton trial/commit lifecycle 및 schema-1 output에 연결한다.
**Dependencies:** Step 1–4 green.
**Prerequisites/read first:** Step 3–4 evaluator/assembler, `nonlinear_static_control.h/.cpp`, `nonlinear_static_procedure.h/.cpp`, `nonlinear_analysis_state.h/.cpp`, `nonlinear_mitc4_shell.h/.cpp`, `tangent_solver.h`, `mkl_pardiso_tangent_solver.h/.cpp`, nonlinear HDF5 writer/self-check/tests, `prepared_analysis.h/.cpp`, `fesa_application.cpp`, `formulation.md` §§9.2–9.4, 11–13, `numerical-review.md` §6 nonlinear suite, `io.md` §§7.2, 7.4.
**Exact files:** `nonlinear_static_control.h/.cpp` only if checked contribution composition needs a helper, `nonlinear_static_procedure.cpp`, new nonlinear integration/app tests, nonlinear HDF5 writer test. Existing PARDISO/HDF5/app production files are no-change verification targets unless a test exposes a contract gap.
**RED named tests:**
- `NonlinearShellSurfacePressure.AssemblesFollowerForceFromCurrentTrialGeometry`
- `NonlinearShellSurfacePressure.FormsResidualAndTangentWithApprovedExternalSigns`
- `NonlinearShellSurfacePressure.AppliesIncrementFactorExactlyOnce`
- `NonlinearShellSurfacePressure.UsesFullUnsymmetricTangentSolverPath`
- `NonlinearShellSurfacePressure.ConvergesOpenPatchAndPreservesAntisymmetricEvidence`
- `NonlinearShellSurfacePressure.SatisfiesAcceptedFreeResidualAndFactorOneGlobalBalance`
- `NonlinearShellSurfacePressure.IsObjectiveUnderRigidMotionAndTracksCurrentArea`
- `NonlinearShellSurfacePressure.ReducesSerialAndParallelContributionsDeterministically`
- `NonlinearShellSurfacePressure.InvalidTrialRollsBackCommittedFrameAndFinalOutput`
- `NonlinearShellSurfacePressure.WritesSchemaOneExternalInternalResidualReactionAndEquilibrium`
- `ShellSurfacePressureApplication.InputWithoutPressureRetainsExistingNonlinearBehavior`
RED/focused commands:
```powershell
cmake --build .harness/build --config Debug --target fesa_unit_tests fesa_integration_tests
ctest --test-dir .harness/build -C Debug --output-on-failure -R "^(NonlinearShellSurfacePressure|ShellSurfacePressureApplication)\."
```
**Observed expected failure:** nonlinear procedure가 existing fixed-global CLOAD만 `f_ext`에 포함하고 pressure force/tangent를 누락하여 follower/objectivity/sign/balance assertions 또는 pressure nonlinear case가 실패해야 한다.
**Minimal GREEN:** each Newton trial에서 current pressure candidate를 평가하고 fixed/pressure external contributions를 stable checked add한다. internal과 external은 같은 trial이다. `r=f_int-f_ext`, `K=K_int-K_ext`를 full space에서 만든 후 constrained/free extraction한다. existing `FactorizeFresh` full-CSR `mtype=11` path를 사용하고 external tangent를 symmetrize하지 않는다. convergence가 검증된 candidate만 `CommitAcceptedFrame`에 전달하며 invalid geometry/nonfinite/factorization/solve failure는 committed frame/final HDF5를 보존한다.
**Focused VERIFY acceptance:** local FD `<=1e-8`; objectivity/current-area normalized `<=1e-12`; factor-one global force/moment balance `<=1e-8`; force/moment free residual은 existing nonzero scale relative `<=1e-2`, zero scale absolute `<=1e-3`; exact zero-scale rules 유지; schema version `1`의 unique factor-one accepted frame에 existing generalized external/internal/residual/reaction/equilibrium datasets가 일치한다; serial/parallel report order exact.
**Full/Stop VERIFY:** existing `NonlinearStaticProcedure`, `NonlinearStaticControl`, `TangentSolver`, `NonlinearHdf5ResultsWriter`, nonlinear reference regression suites와 `V-BUILD`, `V-SHOW`, `V-FULL`.
**Invariants:** translations only affect pressure kinematics; rotation force/tangent blocks zero; load factor exact once; generally nonsymmetric tangent retained; candidate-before-commit; stable reduction.
**Failure/atomicity:** failure does not append an accepted frame, does not replace existing final HDF5 and records last completed Newton stage/pressure source identity deterministically.
**Forbidden scope:** line search/arc length/new procedure, convergence threshold change, PARDISO adapter redesign, new HDF5 fields.
**Trace:** requirements `008`–`013`, `016`–`019`, `021`; `IO §§6–7,9–10`; `FORM §§9–14`; `NR §6` follower/tangent/objectivity/open-patch/balance rows.
**Evidence/report:** trial factor, force/tangent signs, nonsymmetry entries, solver spy events, iteration counts, free residual/balance metrics, HDF5 datasets, rollback snapshots, exits/durations/tails.
### Step 6 — `compare-pressure-reference`
**Bounded responsibility:** exact stored pressure artifacts와 FESA schema-1 factor-one HDF5의 deterministic displacement comparison을 기존 common tolerance policy에 연결한다.
**Dependencies:** Step 1–5 green; exact reference files read-only.
**Prerequisites/read first:** `reference-model.md` 전체, `io.md` §8, `numerical-review.md` §§6.2–6.3, `docs/TOLERANCE.md`, `reference_tolerance_policy.h/.cpp`, nonlinear reference comparison header/source/cases, `tests/CMakeLists.txt`, exact input/CSV. Artifact bytes는 inspection만 하고 수정하지 않는다.
**Exact files:** `nonlinear_static_reference_comparison.h/.cpp`, new `shell_surface_pressure_reference_test.cpp`, `tests/CMakeLists.txt`. tolerance policy source와 stored reference files는 no-change.
**RED named tests:**
- `ShellSurfacePressureReference.AuditsExactRequiredArtifactsAndIgnoresOptionalReviewArtifacts`
- `ShellSurfacePressureReference.SelectsUniqueSchemaOneFactorOneAcceptedFrame`
- `ShellSurfacePressureReference.Projects729WideRowsTo2187LogicalRowsPerFamily`
- `ShellSurfacePressureReference.MatchesByInstanceNodeLabelAndComponentNotRowOrder`
- `ShellSurfacePressureReference.RejectsSchemaIdentityCardinalityMissingExtraDuplicateAndNonfiniteBeforeTolerance`
- `ShellSurfacePressureReference.ClassifiesTranslationBlockingAndRotationWarningOnly`
- `ShellSurfacePressureReference.ExcludesReactionAndStressFamiliesFromVerdict`
- `ShellSurfacePressureReference.UsesUnchangedCommonScaleNearZeroRelativeAndRmsPolicy`
- `ShellSurfacePressureReference.WritesDeterministicComparisonReport`
RED/focused commands:
```powershell
cmake --build .harness/build --config Debug --target fesa_reference_tests
ctest --test-dir .harness/build -C Debug --output-on-failure -R "^ShellSurfacePressureReference\."
```
**Observed expected failure:** current nonlinear case registry requires coarse/fine legacy artifact portfolios and has no pressure case identity/disposition, so exact two-file pressure contract 또는 729/2187 cardinality가 지원되지 않아 test가 fail해야 한다.
**Minimal GREEN:** `NonlinearReferenceCase`에 pressure case의 required/optional/excluded artifact disposition을 explicit value fields로 표현한다. exact path/hash snapshot 뒤 input을 build-tree execution directory에 byte-for-byte copy하고 FESA application만 실행한다. HDF5에서 schema `1`, Step-1, unique accepted `load_factor==1`, `/model/nodes`, nodal displacement를 읽어 `(Part-1-1,node label,component)` key로 project한다. wide CSV 729 rows를 translation 2,187 + rotation 2,187 logical rows로 expand한다. all prechecks 후 기존 `EvaluateReferenceTolerance`만 호출한다. U family blocking, UR warning-only이며 reaction은 comparator family를 만들지 않고 review-only inventory, stress는 excluded다.
**Focused VERIFY acceptance:** input and displacement CSV exact hash/byte size unchanged; 729 unique node keys; each U/UR family 2,187 rows; missing/extra/duplicate/nonfinite/schema/frame/identity failures precede tolerance; common policy `S=max(abs(reference))`, near-zero band `0.01*S`, relative `0.05`, RMS/S `0.01`, zero-scale exact; report rows/warnings/metrics stable.
**Full/Stop VERIFY:** all `ShellSurfacePressureReference`, `NonlinearStaticReference`, `ReferenceTolerancePolicy`, `Mitc4Reference` suites와 `V-BUILD`, `V-SHOW`, `V-FULL`.
**Invariants:** stored input/CSV immutable; Abaqus never run; FESA CSV is not product output; reference row order ignored but source keys exact; tolerance unchanged.
**Failure/atomicity:** any artifact/precheck failure produces failed classification without tolerance result or artifact mutation. copied execution files and generated HDF5/log remain under build tree only.
**Forbidden scope:** reference CSV generation/edit, new tolerance, reaction/stress promotion, legacy artifact rename/metadata requirement.
**Trace:** requirements `017`–`019`, `021`–`024`; `IO §8`; reference-model §§3–8; numerical-review external acceptance.
**Evidence/report:** before/after snapshots, copied input hash, generated HDF5 path, selected frame identity, family cardinality/scale/row/RMS/worst row, warnings, classification, exits/durations/tails.
### Step 7 — `verify-and-report-pressure-feature`
**Bounded responsibility:** all implementation artifacts를 inspect하고 full MSVC/CTest 및 exact pressure reference gate를 실행해 implementation-owned reports를 완결한다. 코드 수정은 이 Step의 기본 scope가 아니다.
**Dependencies:** Step 1–6 green; clean or isolated executor worktree; no stored reference mutation.
**Prerequisites/read first:** all prior Step outputs, `AGENTS.md`, `docs/HARNESS.md`, `docs/HARNESS_WORKFLOW.md`, `.codex/hooks.json`, `.harness/config.json` if it exists at execution time, current CMake files, all upstream docs, exact reference bundle.
**Exact files:** future new `implementation-report.md`, `build-test.md`, `reference-comparison.md`. Test/production/CMake files are read-only in this Step unless a verification failure is classified `implementation` and Coordinator authorizes returning to the owning earlier Step; no silent repair here.
**RED:** report preflight must first prove the three implementation-owned reports are absent/incomplete and that no final passing classification has been recorded. This is the expected evidence-state failure, not permission to fabricate results. If any source/test/CMake change lacks a first-failing test record, classify `evidence-gap` and stop.
**Minimal GREEN sequence:** literally execute `ARTIFACT CHECK -> COMPARE -> CLASSIFY -> REPORT` after build/test gates:
1. **ARTIFACT CHECK:** record exact stored input/displacement CSV path, sha256, size, timestamp before run; reaction review-only and stress excluded disposition; verify source phase never invokes Abaqus.
2. **COMPARE:** run FESA on a copied exact `.inp`, locate generated schema-1 `<stem>_results.h5`, execute `ShellSurfacePressureReference` comparison, record 2,187 U and 2,187 UR rows and common tolerance metrics.
3. **CLASSIFY:** fail on U/precheck/internal equilibrium; preserve UR-only difference as warning-only; reaction/stress cannot change verdict. Distinguish `implementation`, `test`, `infrastructure`, `environment`, `artifact`, `regression`, `evidence-gap`.
4. **REPORT:** write commands, exit codes, durations, meaningful output tails, warning inventory, changed files, requirement coverage and artifact post-check to all three reports.
**Exact commands:** execute `V-CONFIG`, `V-BUILD`, `V-SHOW`, `V-FOCUSED`, `V-FULL`, `V-REFERENCE` from §12. No Harness Python command because no Harness/Python file changes are planned. If an executor later changes `scripts/` or Harness Python behavior under separate authority, it must additionally run `uv run --with pytest python -m pytest -v -rs` and record why.
**Observed expected failure:** any configure/build/test/reference nonzero exit, zero discovered tests, new `/W4 /WX` warning, runtime DLL staging failure, artifact mutation, cardinality mismatch or U blocking failure keeps reports non-passing and stops closure.
**Focused/Full/Stop VERIFY:** every command exit `0`, `ctest --show-only=json-v1` reports nonzero tests including all named feature tests, full CTest passes, no new warnings, runtime execution succeeds, artifacts unchanged, reports internally consistent.
**Invariants:** evidence before success claims; no release approval; no physics Gate 7 claim; no commit/task selection/manual status/timestamp ownership transfer from Harness Executor.
**Failure/atomicity:** a failed gate leaves status non-passing, retains outputs for diagnosis, does not alter upstream/tolerance/reference artifacts and returns to Coordinator with precise classification.
**Forbidden scope:** source fixes, reference generation, tolerance adjustment, phase execution expansion, release readiness.
**Trace:** all requirements `001`–`024`; all upstream contracts; Harness Stop contract.
**Evidence/report:** complete three-document handoff with task order, tests first, files, commands, comparison, assumptions, acceptance and open constraints.
## 8. TDD Test Plan
| order | test id | layer / named suite | RED cause | GREEN evidence |
| --- | --- | --- | --- | --- |
| 1 | `T-INPUT-VALID` | `InpSyntax`, `ShellSurfacePressureInput`, `ShellSurfacePressureDomain` valid tests | unsupported SURFACE/DSLOAD or missing semantic API | exact valid mapping/provenance/ownership |
| 2 | `T-INPUT-NEG` | pressure input negative tests | unsupported forms accepted or unstable/partial failure | fail-closed deterministic diagnostics and no Domain |
| 3 | `T-KERNEL-FORCE` | `ShellSurfacePressureKernel` analytical/sign/resultant/objectivity | evaluator absent | approved force integration and exact zero rotations |
| 4 | `T-KERNEL-TANGENT` | kernel FD/nonsymmetry/geometry | external derivative absent | `h=1e-5`, normalized `<=1e-8`, geometry gate exact |
| 5 | `T-ASSEMBLY` | `SurfacePressureAssembly` | full-space assembler absent | stable additive exact-once serial/parallel reduction |
| 6 | `T-LINEAR` | `LinearShellSurfacePressure` | linear procedure omits pressure | reference force/reaction/residual/resultant and schema 0 |
| 7 | `T-NONLINEAR` | `NonlinearShellSurfacePressure` | nonlinear external force/tangent omit pressure | current follower Newton convergence, rollback and schema 1 |
| 8 | `T-CLI-HDF5` | `ShellSurfacePressureApplication` plus writer tests | pressure route/output regression not covered | existing naming/schema/projection/atomic/no-pressure behavior |
| 9 | `T-REF-PRECHECK` | pressure reference precheck tests | registry/schema/cardinality unsupported | deterministic prechecks before tolerance |
| 10 | `T-REF-COMPARE` | pressure reference end-to-end tests | pressure disposition/comparison unsupported | exact U blocking/UR warning-only report |
| 11 | `E-FINAL` | full build/test/reference evidence | reports incomplete | verified commands and immutable artifact snapshots |
모든 production change는 같은 Step에서 먼저 생성/수정되는 관련 C++ test와 연결한다. `src/fesa/CMakeLists.txt` production 등록은 corresponding unit test RED와 함께 들어가며, `tests/CMakeLists.txt` 등록은 test source를 생성한 같은 Step에서 한다.
## 9. CMake/CTest Plan
- `src/fesa/CMakeLists.txt`: `surface_definition_mapper.cpp`, `shell_surface_pressure.cpp`, `surface_pressure_assembler.cpp`를 existing `fesa_solver` source inventory에 추가한다. public headers는 existing include tree를 통해 노출하고 별도 library/target을 만들지 않는다.
- `tests/CMakeLists.txt`: 새 unit sources는 `fesa_unit_tests`, integration/app sources는 `fesa_integration_tests`, reference source는 `fesa_reference_tests`에 추가한다.
- existing `gtest_discover_tests`가 개별 `Suite.Test` CTest entries를 만든다. 새 raw `add_test`는 필요하지 않다.
- feature-specific selection은 exact suite-name regex로 한다. existing target-wide legacy labels를 전면 재분류하지 않는다. 필요하면 각 `gtest_discover_tests(... PROPERTIES LABELS ...)`의 existing labels에 `shell-surface-pressure-load`를 append하되 기존 labels를 삭제하지 않는다.
- `.harness/config.json`이 execution 전에 생기면 그 설정이 아래 cache-derived command보다 우선한다. 현재는 없으므로 `.harness/build` default와 현재 MSVC x64 Debug cache를 사용한다.
- `ctest --show-only=json-v1`에서 discovered test count가 zero면 success로 인정하지 않는다.
- runtime staging은 existing `fesa_cli`, integration/reference target의 MKL/TBB/HDF5 DLL copy rules를 그대로 사용하며 새 manual PATH hack을 만들지 않는다.
## 10. Data Flow Contract
```text
exact/approved Abaqus .inp
-> AbaqusInputReader KeywordBlock/DataLine + physical SourceLocation
-> DomainMappingContext raw SURFACE/DSLOAD candidate
-> topology finalize -> SurfaceDefinitionMapper -> StepDefinitionMapper
-> Domain-owned ordered ElementSurfaceDefinition
+ Step-owned ordered SurfacePressureLoadDefinition
-> AnalysisModel non-owning active view (Domain outlives view)
-> ShellSurfacePressureEvaluator local force/tangent candidates
-> SurfacePressureAssembler stable full-space reduction
-> linear: Fext(ref), Kext=0
nonlinear: Fext(current), Kext(current)
-> residual/reaction/equilibrium recovery
-> existing atomic HDF5 writer
-> authoritative <stem>_results.h5
-> schema-1 factor-one HDF5 projection keyed by
(Step-1, factor=1, Part-1-1, source node label, component)
-> exact read-only displacement CSV projection
-> prechecks -> unchanged common tolerance -> deterministic report
```
Exact reference flow:
- Input: `reference/shellNL-meshfine-pressure/shellNL-meshfine-pressure.inp`
- Required CSV: `reference/shellNL-meshfine-pressure/shellNL-meshfine-pressure displacements.csv`
- FESA run: input copy under `.harness/build/reference/shell-surface-pressure-load/`; never Abaqus
- HDF5: schema `1`, `Step-1`, unique accepted factor-one frame, `/model/nodes`, existing nodal displacement/generalized force/residual/reaction/equilibrium paths
- CSV: 729 wide node rows; U1/U2/U3 = 2,187 blocking logical rows; UR1/UR2/UR3 = 2,187 warning-only logical rows
- Reaction CSV: optional review-only inventory, no comparison family/verdict effect
- Stress CSV: excluded, no comparison family
- Prechecks: missing/extra/duplicate/nonfinite/schema/frame/source-id/component/cardinality before tolerance
- Tolerance: family-specific Abaqus-only `S=max(abs(reference))`; `abs(ref)<=0.01*S`이면 absolute row error `<=0.01*S`, otherwise relative error `<=0.05`; `RMS(error)/S<=0.01`; zero-scale는 FESA exact zero only.
## 11. Acceptance Traceability Matrix
| requirement | Step | task/test evidence | acceptance criterion |
| --- | --- | --- | --- |
| `FESA-REQ-SHELL-PRESSURE-001` | 1, 7 | `T-INPUT-VALID`; valid direct/ELSET S4/S4R tests | approved SURFACE + DSLOAD sequence exact |
| `FESA-REQ-SHELL-PRESSURE-002` | 1, 2 | finite scalar/raw text, nonfinite/D-exponent tests | one uniform finite force/area scalar per row |
| `FESA-REQ-SHELL-PRESSURE-003` | 1, 2, 4 | canonical facet/order tests; assembler order | unique deterministic instance/label/side list |
| `FESA-REQ-SHELL-PRESSURE-004` | 1, 2 | S4/S4R/SPOS/SNEG valid and unsupported inventory | only approved shell types/sides; source type/label preserved |
| `FESA-REQ-SHELL-PRESSURE-005` | 3, 4 | sign reversal and linear analytical tests | positive opposite selected normal; negative reverses |
| `FESA-REQ-SHELL-PRESSURE-006` | 3, 4 | connectivity/SPOS/SNEG reversal | SPOS connectivity normal, SNEG inverse exact |
| `FESA-REQ-SHELL-PRESSURE-007` | 3, 4 | reference geometry and prescribed-displacement invariant | linear pressure fixed to reference geometry |
| `FESA-REQ-SHELL-PRESSURE-008` | 3, 5 | current area/normal/objectivity tests | nonlinear follower uses `X+u` |
| `FESA-REQ-SHELL-PRESSURE-009` | 3, 5 | centered FD and Newton tangent sign tests | exact external derivative included |
| `FESA-REQ-SHELL-PRESSURE-010` | 1, 4, 5 | additive records/unit factor/increment factor tests | pressure magnitude scaled exactly once |
| `FESA-REQ-SHELL-PRESSURE-011` | 4, 5 | full-DOF scatter before projection tests | all pressure assembled full-space first |
| `FESA-REQ-SHELL-PRESSURE-012` | 4, 5, 7 | reaction/free residual/global balance | `K*d-F` or `f_int-f_ext` includes pressure |
| `FESA-REQ-SHELL-PRESSURE-013` | 1, 2, 4, 5, 6 | repeated serial/parallel/order/report tests | deterministic facets, reductions, rows, diagnostics |
| `FESA-REQ-SHELL-PRESSURE-014` | 2 | unsupported params/labels/distribution/type/side tests | fail closed exact |
| `FESA-REQ-SHELL-PRESSURE-015` | 2 | missing/empty/ambiguous/cyclic/scope/duplicate tests | fail closed, no guessing/averaging |
| `FESA-REQ-SHELL-PRESSURE-016` | 2, 3, 4, 5 | invalid procedure/nonfinite/geometry/rollback | no clamp/fallback/partial result |
| `FESA-REQ-SHELL-PRESSURE-017` | 2, 4, 5, 6, 7 | stable diagnostics, no Domain, final snapshots | failed candidate never published |
| `FESA-REQ-SHELL-PRESSURE-018` | 4, 5, 7 | schema 0/1 inventory tests | existing HDF5 sole authority; no pressure dataset/version |
| `FESA-REQ-SHELL-PRESSURE-019` | 4, 5, 6 | displacement/reaction/residual/equilibrium projections | existing units/coordinates/source IDs finite and observable |
| `FESA-REQ-SHELL-PRESSURE-020` | 3, 4 | analytical sign/resultant/reaction/mesh/order suite | normalized analytical checks at approved thresholds |
| `FESA-REQ-SHELL-PRESSURE-021` | 3, 5, 7 | objectivity/current-area/FD/residual/balance/open-patch | FD `<=1e-8`, balance `<=1e-8`, other approved gates |
| `FESA-REQ-SHELL-PRESSURE-022` | 6, 7 | exact artifact audit and immutable snapshots | exact required input/displacement CSV only |
| `FESA-REQ-SHELL-PRESSURE-023` | 6, 7 | 729/2187 key mapping, U/UR disposition, tolerance report | U blocking; UR warning; deterministic factor-one comparison |
| `FESA-REQ-SHELL-PRESSURE-024` | 6, 7 | absent reaction/stress families and classification tests | reaction review-only, stress excluded; internal gates retained |
Coverage: normative IDs `24`, mapped IDs `24`, orphan IDs `0`. Every must requirement has at least one implementation/verification Step and one named test/evidence item.
## 12. Validation Commands
현재 execution context는 `.harness/config.json` 부재, existing `.harness/build` cache 존재다. 실행 시 config가 생겼으면 Harness가 그 값을 먼저 resolve하고 reports에 실제 command를 기록한다.
### `V-CONFIG` — clean/config-resolved MSVC x64 Debug configure
```powershell
cmake --fresh -S . -B .harness/build -G "Visual Studio 18 2026" -A x64 `
"-DFESA_GTEST_SOURCE_DIR=C:/git/googletest" `
"-DMKL_DIR=C:/Program Files (x86)/Intel/oneAPI/mkl/2026.1/lib/cmake/mkl" `
"-DTBB_DIR=C:/Program Files (x86)/Intel/oneAPI/tbb/2023.1/lib/cmake/tbb" `
"-DHDF5_DIR=C:/Program Files/HDF_Group/HDF5/2.1.1/cmake"
```
### `V-BUILD`
```powershell
cmake --build .harness/build --config Debug
```
Acceptance: exit `0`; new MSVC warning `0`; `/W4 /WX` 유지; `fesa_solver`, `fesa_cli`, `fesa_unit_tests`, `fesa_integration_tests`, `fesa_reference_tests` all build; runtime staging errors 없음.
### `V-SHOW`
```powershell
ctest --test-dir .harness/build -C Debug --show-only=json-v1
```
Acceptance: exit `0`, discovered count `>0`, 모든 새 named suite가 inventory에 존재.
### `V-FOCUSED`
```powershell
ctest --test-dir .harness/build -C Debug --output-on-failure -R "^(InpSyntax|ShellSurfacePressureInput|ShellSurfacePressureDomain|ShellSurfacePressureKernel|SurfacePressureAssembly|LinearShellSurfacePressure|NonlinearShellSurfacePressure|ShellSurfacePressureApplication|ShellSurfacePressureReference)\."
```
Acceptance: exit `0`, selected count `>0`, failed `0`.
### `V-FULL`
```powershell
ctest --test-dir .harness/build -C Debug --output-on-failure
```
Acceptance: exit `0`, failed `0`, existing no-pressure/beam/shell/nonlinear/reference regressions pass.
### `V-REFERENCE`
```powershell
ctest --test-dir .harness/build -C Debug --output-on-failure -R "^ShellSurfacePressureReference\."
```
Acceptance: exit `0`; exact artifact post-snapshots equal pre-snapshots; U blocking pass; any UR deviations warning-only; internal balance pass; 729 wide/2,187 logical rows per family exact; reaction/stress verdict exclusion exact.
Harness Python behavior/file은 범위 밖이므로 이 plan에는 Python test 실행을 넣지 않는다. 별도 승인된 Harness/Python 변경이 발생하는 경우에만 다음을 추가한다.
```powershell
uv run --with pytest python -m pytest -v -rs
```
## 13. Risks and Downstream Handoff
| risk | mitigation / stop condition |
| --- | --- |
| existing `Load` abstraction에 follower tangent를 강제로 넣어 ownership 왜곡 | 별도 evaluator/assembler candidate 유지; public nodal load contract를 변경하지 않음 |
| surface parser와 topology resolution order 혼동 | topology finalize 후 surface, surface 후 step binding 순서 고정 |
| duplicate normalization이 additive DSLOAD와 혼동 | facet exact duplicate만 normalize; DSLOAD records는 항상 distinct/additive |
| nonlinear sign 또는 factor double application | force and residual FD 두 부호 모두 test; factor at assembler boundary once |
| tangent symmetrization 또는 SPD solver 경로 | antisymmetric evidence test; existing `MklPardisoTangentSolver` `mtype=11` spy/adapter tests |
| invalid geometry가 zero load에서 bypass | evaluator zero pressure/factor geometry rejection test |
| parallel nondeterminism | worker-local candidates + fixed source/facet/Gauss serial reduction; repeated byte/metric order tests |
| HDF5 schema creep | no-new-path inventory and version `0`/`1` exact tests |
| reference utility가 legacy four-file portfolio를 강요 | per-case required/optional/excluded disposition을 explicit하게 추가; exact pressure two-file gate |
| reference comparison으로 implementation bug 은폐 | artifact/row prechecks first, tolerance unchanged, U blocking, internal balance retained |
| build environment drift | execution-time `.harness/config.json` precedence; actual commands/cache/toolchain recorded |
Coordinator를 통한 Implementation Agent 단일 handoff:
- task order: Step 1 → 7, 각 Step 안의 RED/GREEN/VERIFY 순서
- first tests: §7 named tests와 §8 test IDs
- candidate files/signatures: §§5–6
- validation commands: §12
- HDF5/reference mapping: §10
- tolerance/identity assumptions: common policy unchanged, factor-one, `(instance,node label,component)`, U blocking/UR warning-only
- acceptance criteria: §11 전 24 requirements + each Step metrics
- open constraints: phase files는 사용자 승인 이후 Planning Agent가 materialize; Executor는 별도 explicit request 이후만 실행; reference artifacts와 tolerance read-only
## 14. Open Issues
Implementation readiness를 막는 requirements/formulation/I/O/tolerance/reference/architecture gap은 없다. 다음은 blocker가 아닌 execution-time checks다.
- Step execution 직전 `.harness/config.json` 생성 여부를 다시 확인해 config precedence를 적용한다.
- current build cache paths가 execution host에서 유효한지 `V-CONFIG`/`V-BUILD` 결과로 증명한다.
- 새 feature suite가 `ctest --show-only=json-v1`에 실제 발견되는지 확인한다.
- exact reference artifact pre/post snapshot을 같은 run에서 기록한다.
현재 critical user decision은 이 7-Step draft의 `approve` 또는 구체적인 revision 요청이다. 승인만으로 phase 파일을 실행하거나 `scripts/execute.py`를 호출하지 않는다.
## 15. Plan Self-Review
- 실제 존재가 확인된 existing paths만 modify/read 대상으로 기재했다.
- 새 paths는 §6의 new-file table에서 first owning Step과 함께 명시했다.
- semantic/evaluator/assembler signatures와 linear/nonlinear caller contract를 Steps 사이에 동일하게 유지했다.
- requirements `001`–`024` 모두 Step과 named test/evidence에 연결했고 orphan이 없다.
- exact reference input/CSV, schema-1 factor-one, 729/2,187 cardinality, dispositions와 tolerance mapping을 포함했다.
- 모든 구현 Step에 test-first RED, expected failure, minimal GREEN, focused/full verification, invariants, atomicity, forbidden scope, trace, handoff evidence를 포함했다.
- final Step은 `ARTIFACT CHECK -> COMPARE -> CLASSIFY -> REPORT` 순서를 literal하게 보존하고 세 implementation-owned reports를 소유한다.
- manual commit, task selection, executor-owned timestamp/status 기록을 계획하지 않았다.
- `phases/`, source, tests, CMake, config/hooks, upstream docs, tolerance, reference artifacts는 이 planning turn에서 변경하지 않았다.
- `phases/index.json`와 phase task files는 사용자 승인 전 materialize하지 않았으며 Harness Executor 실행도 요청하지 않았다.