# 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 `_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 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 element_surfaces`를 소유하고 `StaticStepDefinition`은 `std::vector 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& Domain::ElementSurfaces() const noexcept; const std::vector& StepDefinition::SurfacePressureLoads() const noexcept; bool StepDefinition::UsesNonlinearGeometry() const noexcept; const std::vector& 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 reference_coordinates; std::array translational_displacements; ShellSurfaceSide side; double pressure_magnitude; double load_factor; SurfacePressureConfiguration configuration; SourceLocation location; std::string entity_identity; }; struct ShellSurfacePressureContribution { std::array force; std::array external_tangent; }; Result 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 diagnostics; }; Result 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 `.` 또는 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 `_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 _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 실행도 요청하지 않았다.