docs: add modular refactoring implementation plan

This commit is contained in:
KOKO\Mimi
2026-08-16 02:49:35 +09:00
parent 1e5758f3e4
commit 2ab2e0c641
28 changed files with 2876 additions and 1 deletions
@@ -0,0 +1,410 @@
# C++ Object-Oriented Modular Refactoring Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use
> `superpowers:subagent-driven-development` (recommended) or
> `superpowers:executing-plans` to implement this plan task-by-task. Steps use
> checkbox (`- [ ]`) syntax for tracking.
>
> In FESA, those task-by-task semantics are mediated by the project Harness. Do not
> invoke an implementation skill or select a Step directly; a separate user request
> must start `scripts/execute.py`, which selects exactly one pending Step.
**Goal:** Preserve the current B33, MITC4, and linear-static numerical and external
contracts while converting the FESA C++ production code to explicit object-oriented
boundaries, focused modules, shared utilities, Google C++ style, and production-only
Doxygen documentation.
**Architecture:** Domain owns immutable polymorphic semantic definitions through
`std::unique_ptr` and stable `EntityIndex` positions. `ElementDefinition` remains
separate from runtime numerical `Element`, and load, boundary-condition, analysis,
material, and property abstractions each have independent hierarchies. Existing
deterministic assembly, result identity, HDF5 schema, and reference comparison
contracts remain unchanged.
**Tech Stack:** C++17, MSVC x64 Debug, CMake, CTest, GoogleTest, Intel oneMKL,
Intel oneTBB, HDF5, clang-format, clang-tidy, and optional Doxygen configuration.
## Global Constraints
- Follow `/docs/CODINGSTYLE.md` and the official Google C++ Style Guide baseline.
- Use PascalCase for every C++ function and accessor; use `.h` production headers
with full-path include guards; retain `.cpp` as the FESA source-file exception.
- Add Doxygen comments only to production code. Do not add Doxygen coverage to tests.
- Keep C++17 and MSVC x64 Debug compatibility and add no compiler warnings under
`/W4 /WX`.
- Preserve the approved B33 and MITC4 formulations, signs, units, coordinate systems,
reduction order, result row identity, HDF5 schema, tolerances, and reference files.
- Do not implement MITC3, solid elements, dynamics, eigenvalue analysis, response
spectrum, random vibration, density, plasticity, anisotropy, distributed load, body
force, or MPC behavior.
- Do not expose MKL, TBB, HDF5, Win32, or vendor integer types from public solver-core
headers.
- Every C++ production change requires a related C++ test and an in-Step
`RED -> observed failure -> minimal GREEN -> focused/full VERIFY` cycle.
- Do not run `scripts/execute.py` until the user gives a separate explicit execution
request.
- Doxygen comments and `Doxyfile` configuration are in scope; generated Doxygen
output is deferred and is not a blocking command for this phase.
---
## 1. Metadata
| Field | Value |
| --- | --- |
| `feature_id` | `cpp-object-oriented-modular-refactoring` |
| `source_requirement` | `/docs/superpowers/specs/2026-08-16-cpp-object-oriented-modular-refactoring-design.md` |
| `source_research` | Existing repository duplication and ownership audit captured by the approved design; no new FEM research is required |
| `source_formulation` | `/docs/linear-static-3d-euler-beam/formulation.md`; `/docs/linear-static-mitc4-shell/formulation.md` |
| `source_numerical_review` | `/docs/linear-static-3d-euler-beam/numerical-review.md`; `/docs/linear-static-mitc4-shell/numerical-review.md` |
| `source_io_definition` | `/docs/linear-static-3d-euler-beam/io.md`; `/docs/linear-static-mitc4-shell/io.md` |
| `source_reference_models` | `/docs/linear-static-3d-euler-beam/reference-model.md`; `/docs/linear-static-mitc4-shell/reference-model.md` |
| `status` | `ready-for-implementation` |
| `owner_agent` | `implementation-planning-agent` |
| `date` | `2026-08-16` |
## 2. Readiness Check
- The written refactoring design and the 25-Step draft were explicitly approved on
2026-08-16.
- B33 and MITC4 requirements, formulations, numerical reviews, I/O projections, and
reference contracts already exist and remain upstream read-only inputs.
- Required reference inputs and CSVs are present under
`/reference/cantilever beam/` and `/reference/shell/`.
- `clang-format.exe` and `clang-tidy.exe` are present at
`C:/Program Files/LLVM/bin/`; the current long-lived process PATH need not contain
that directory because the plan uses the absolute paths.
- Doxygen generation is intentionally deferred by user decision. The implementation
still adds production comments and a warning-strict `Doxyfile` for later use.
- No missing formulation, tolerance, HDF5 projection, or artifact decision prevents
implementation planning.
## 3. Implementation Scope
### Included
- Repository policy/tooling and Implementation Agent enforcement.
- Mechanical `.hpp` to `.h`, header guard, PascalCase, formatting, and production
Doxygen conversion in reviewable module slices.
- Shared `Vector3`, dense-BLAS internal adapter, ASCII utilities,
`SourceTargetResolver`, and owner-based DOF invariant validation.
- Independent abstract boundaries for material, element property, semantic element
definition, runtime element, load, boundary condition, and analysis.
- Current concrete B33, MITC4, isotropic linear elasticity, beam/shell property,
concentrated nodal load, prescribed displacement, and linear-static behavior.
- Responsibility-based splits of domain mapping, result recovery, and HDF5 writing.
- Full MSVC/CTest and existing B33/MITC4 external reference verification.
### Excluded and non-goals
- New physics, input keywords, output datasets, tolerances, reference artifacts, or
runtime performance optimization.
- A common root base shared by unrelated element, load, material, and analysis types.
- A giant material interface containing density, plasticity, and anisotropy options.
- Registry/plugin frameworks, global static registration, speculative `Clone()`, or
unnecessary shared ownership.
## 4. Refactoring Requirements
| ID | Requirement |
| --- | --- |
| `R-PRESERVE-001` | Current B33/MITC4/linear-static numerical and external results shall remain unchanged within their approved contracts. |
| `R-STYLE-001` | Production and test C++ shall use approved Google-style naming and formatting; production headers shall use `.h` and header guards. |
| `R-DOC-001` | Production functions and classes shall carry useful Doxygen contracts; tests shall not require Doxygen comments. |
| `R-DUP-001` | Repeated fixed-size 3D vector operations shall be implemented once by `Vector3`. |
| `R-DUP-002` | Repeated dense-BLAS conversion/copy, ASCII/source resolution, and DOF invariant logic shall have one owner. |
| `R-MODEL-001` | Material, element-property, and element-definition semantic objects shall have independent abstractions and Domain-owned stable lifetime. |
| `R-ELEMENT-001` | Semantic `ElementDefinition` and runtime numerical `Element` shall remain separate and be connected by a fail-closed factory. |
| `R-PIPELINE-001` | DofManager, SparseAssembler, and ResultRecovery shall consume runtime `Element` interfaces without scattered B33/MITC4 type branches. |
| `R-LOAD-001` | A `Load` shall emit ordered contributions and only `LoadAssembler` shall accumulate the global vector. |
| `R-BC-001` | A `BoundaryCondition` shall emit definitions and an essential-constraint policy shall enforce prescribed displacement. |
| `R-ANALYSIS-001` | `Analysis` shall expose only `Run()` and `LinearStaticAnalysis` shall own its approved lifecycle. |
| `R-MODULE-001` | Domain mapping, recovery, and HDF5 writing shall be split by their approved responsibilities. |
| `R-AGENT-001` | Implementation Agent shall read `/docs/CODINGSTYLE.md` as a mandatory global input. |
| `R-SCOPE-001` | No excluded future feature or runtime-performance change shall be introduced. |
## 5. Work Breakdown
| Task | Name | Depends on | Deliverable |
| --- | --- | --- | --- |
| `T00` | coding-style-agent-contract | none | Agent profile and Python contract enforce `CODINGSTYLE.md`. |
| `T01` | cpp-style-tooling | `T00` | clang-format/tidy configuration and deferred Doxygen configuration. |
| `T02` | architecture-boundaries | `T00` | Architecture and ADR record the approved responsibility graph. |
| `T03` | foundation-google-style | `T01` | Core/math/linear-solver APIs use the approved style. |
| `T04` | model-element-google-style | `T03` | Model and current element APIs use the approved style. |
| `T05` | solver-workflow-google-style | `T04` | FEM/assembly/constraint/analysis/result APIs use the approved style. |
| `T06` | io-application-google-style | `T05` | I/O, application, and test helper APIs use the approved style. |
| `T07` | vector3-value-type | `T03` | Tested fixed-size vector value type. |
| `T08` | element-geometry-vector3 | `T04`, `T07` | Element/model geometry duplicate helpers removed. |
| `T09` | result-io-vector3 | `T06`, `T08` | Result/I/O vector duplicate helpers removed. |
| `T10` | dense-blas-adapter | `T03` | Matrix/Vector share private MKL conversion and copy helpers. |
| `T11` | source-target-resolver | `T06` | Shared ASCII and source-target resolution module. |
| `T12` | material-property-hierarchy | `T04` | Independent semantic material and property abstractions. |
| `T13` | element-definition-domain | `T11`, `T12` | Domain-owned polymorphic semantic element definitions. |
| `T14` | runtime-element-factory | `T08`, `T13` | Runtime element abstraction and fail-closed factory. |
| `T15` | generic-dof-manager | `T14` | DofManager consumes element DOF layouts and owns invariant checks. |
| `T16` | generic-sparse-assembler | `T15` | SparseAssembler consumes element stiffness contributions. |
| `T17` | generic-result-recovery | `T16` | ResultRecovery consumes element result bundles. |
| `T18` | load-hierarchy | `T11`, `T15` | Ordered load contribution hierarchy. |
| `T19` | boundary-condition-policy | `T15` | Constraint definition hierarchy and essential policy. |
| `T20` | analysis-hierarchy | `T17`, `T18`, `T19` | Minimal Analysis base and unchanged linear-static lifecycle. |
| `T21` | domain-mapper-modules | `T11`, `T13`, `T18`, `T19` | Mapper split by semantic responsibility. |
| `T22` | result-recovery-modules | `T17` | Recovery split into global, beam, shell, and commit responsibilities. |
| `T23` | hdf5-writer-modules | `T17`, `T22` | HDF5 writer split without schema changes. |
| `T24` | final-quality-reference-gate | all prior tasks | Full style, build/test, HDF5, determinism, and reference evidence. |
Each task maps one-to-one to `/phases/cpp-object-oriented-modular-refactoring/stepN.md`.
## 6. TDD Test Plan
| Test ID | First failing evidence | GREEN evidence |
| --- | --- | --- |
| `P-AGENT-001` | Python contract reports missing mandatory `CODINGSTYLE.md` input. | Agent workflow contract passes. |
| `P-STYLE-001` | Policy test reports missing or incorrect clang/Doxygen configuration. | Policy and full Harness Python tests pass. |
| `C-STYLE-001..004` | Test includes/calls use `.h` and PascalCase before production conversion, causing a compile failure. | Focused module suites and full CTest pass. |
| `C-VEC3-001` | `vector3_test.cpp` cannot compile because `Vector3` is absent. | Arithmetic, finite, and normalization-boundary tests pass. |
| `C-DUP-001..004` | Tests reference the new shared seam before it exists. | Shared seam passes and old duplicate helper definitions are absent by `rg` checks. |
| `C-MODEL-001..002` | Polymorphic ownership and const stable-index tests fail before semantic bases exist. | Material/property/definition tests and Domain mapping tests pass. |
| `C-ELEMENT-001` | Base-interface creation and incompatibility tests fail before `ElementFactory`. | B33/MITC4 creation, rejection, stiffness, and recovery tests pass. |
| `C-DOF-001` | Fake runtime element layout is not accepted by DofManager. | Stable scatter/pattern and invariant tests pass. |
| `C-ASSEMBLY-001` | Fake runtime contribution is not assembled. | Serial/TBB/repeated CSR outputs remain byte-identical. |
| `C-RECOVERY-001` | Fake result bundle cannot flow through recovery. | Beam/shell identities, signs, energy, and atomic rollback pass. |
| `C-LOAD-001` | A fake Load cannot emit ordered full-DOF contributions. | Source-order accumulation and current load validation pass. |
| `C-BC-001` | A fake BoundaryCondition cannot resolve constraint definitions. | Nonzero prescribed displacement and reconstruction pass. |
| `C-ANALYSIS-001` | LinearStaticAnalysis cannot be invoked through `Analysis`. | Approved factorization/load/solve/recovery lifecycle passes. |
| `C-MODULE-001..003` | Tests reference extracted mapper/recovery/HDF5 responsibilities before their seams exist. | Existing public behavior and atomicity suites pass after extraction. |
| `C-REF-B33-001` | No new intentional failure; final gate reuses the approved external comparison. | B33 comparison passes under its existing component-scale tolerance. |
| `C-REF-MITC4-001` | No new intentional failure; final gate reuses the approved external comparison. | MITC4 translations pass at fixed `1.0e-5`; rotations remain warning-only. |
RED and GREEN evidence, command, exit code, duration, output tail, and failed test names
must be recorded during execution in the Implementation-owned reports. A final reference
gate does not manufacture an artificial RED because it verifies an unchanged approved
external contract after all refactoring tasks.
## 7. CMake/CTest Plan
- Keep the existing `fesa_solver`, `fesa_cli`, `fesa_unit_tests`,
`fesa_integration_tests`, `fesa_reference_tests`, and `fesa_tests` targets.
- Register new production/test files in `/src/fesa/CMakeLists.txt` and
`/tests/CMakeLists.txt` in their owning task.
- Do not create a new test executable or change existing test labels.
- `.harness/config.json` is absent, so use `.harness/build`, MSVC x64, Debug, and the
explicit local dependency paths recorded in each Step.
- Every C++ task runs a focused CTest regular expression and the full CTest discovery
and execution sequence.
- Step `T24` performs a fresh configure and the final B33/MITC4 reference tests.
## 8. Candidate Files and Ownership
| Responsibility | Candidate files |
| --- | --- |
| Policy/tooling | `.codex/agents/implementation-agent.toml`, `.clang-format`, `.clang-tidy`, `Doxyfile`, `tests/test_agent_skill_workflow_contract.py`, `tests/test_cpp_policy_contract.py` |
| Fixed/dynamic math | `include/fesa/math/vector3.h`, `include/fesa/math/vector.h`, `include/fesa/math/matrix.h`, `src/fesa/math/dense_blas_internal.h`, matching `.cpp` and unit tests |
| Semantic material/property | `include/fesa/materials/*.h`, `include/fesa/properties/*.h`, `src/fesa/materials/*.cpp`, `src/fesa/properties/*.cpp`, matching unit tests |
| Semantic element definitions | `include/fesa/elements/element_definition.h`, concrete definition headers, `include/fesa/model/domain.h`, `src/fesa/model/domain.cpp` |
| Runtime elements | `include/fesa/elements/element.h`, `element_factory.h`, existing B33/MITC4 kernels and new factory implementation/tests |
| Source resolution | `include/fesa/model/source_target_resolver.h`, `src/fesa/model/source_target_resolver.cpp`, focused tests |
| Solver consumers | DofManager, SparseAssembler, ResultRecovery headers/sources/tests |
| Loads | `include/fesa/loads/load.h`, `concentrated_nodal_load.h`, sources, LoadAssembler and tests |
| Constraints | `boundary_condition.h`, `prescribed_displacement.h`, `essential_constraint_policy.h`, sources and tests |
| Analysis | `analysis.h`, `linear_static_analysis.h`, sources and integration tests |
| Mapper split | focused private mapper modules under `src/fesa/io/abaqus/` with one public `domain_mapper.h` facade |
| Recovery split | focused modules under `src/fesa/results/` with one public `result_recovery.h` facade |
| HDF5 split | private modules under `src/fesa/io/hdf5/` with one public `hdf5_results_writer.h` facade |
These are implementation candidates, not permission to introduce extra public API. Each Step
must choose the minimum files consistent with the approved boundaries.
## 9. Candidate Interface Contracts
The implementation may refine parameter carrier names while preserving these semantic contracts:
```cpp
struct AnalysisRequest {
std::filesystem::path input_path;
std::filesystem::path output_path;
};
class Analysis {
public:
virtual ~Analysis() = default;
virtual Status Run(const AnalysisRequest& request) = 0;
};
class ElementDefinition {
public:
virtual ~ElementDefinition() = default;
virtual ElementDefinitionKind Kind() const noexcept = 0;
virtual const SourceEntityId& SourceId() const noexcept = 0;
virtual const std::vector<EntityIndex>& NodeIndices() const noexcept = 0;
virtual EntityIndex PropertyIndex() const noexcept = 0;
};
class Element {
public:
virtual ~Element() = default;
virtual const ElementDofLayout& DofLayout() const noexcept = 0;
virtual Result<ElementStiffnessContribution> ComputeStiffness() const = 0;
virtual Result<ElementResultBundle> Recover(
const Vector& full_displacement) const = 0;
};
class Load {
public:
virtual ~Load() = default;
virtual Result<std::vector<LoadContribution>> ComputeContributions(
const LoadContext& context) const = 0;
};
class BoundaryCondition {
public:
virtual ~BoundaryCondition() = default;
virtual Result<std::vector<ConstraintDefinition>> ResolveConstraints(
const BoundaryConditionContext& context) const = 0;
};
```
Do not add future-only methods to these bases. Factory compatibility may use a centralized,
explicit kind discriminator followed by a checked concrete access; consumers must not scatter
`dynamic_cast` or B33/MITC4 switches.
## 10. Data Flow Contract
```text
existing Abaqus .inp
-> syntax reader
-> responsibility-split semantic mappers
-> immutable Domain-owned definitions
-> AnalysisModel non-owning active view
-> ElementFactory runtime elements
-> DofManager / deterministic assembly / constraints
-> LinearStaticAnalysis
-> result recovery candidate and validation
-> authoritative results.h5 atomic commit
-> test-only deterministic projection
-> existing Abaqus CSV comparison by source identity and component
```
- B33 input and CSVs remain under `/reference/cantilever beam/` with their current
names and component-scale tolerance.
- Blocking MITC4 S4 input/displacement CSV remains under `/reference/shell/` with
fixed absolute tolerance `1.0e-5` for U1/U2/U3 and warning-only UR1/UR2/UR3.
- `/reference/shellR/` is not promoted into a blocking comparison.
- No reference artifact is renamed, rewritten, regenerated, or normalized.
## 11. Acceptance Traceability Matrix
| Requirement | Tasks | Tests/evidence | Acceptance |
| --- | --- | --- | --- |
| `R-PRESERVE-001` | `T03..T24` | all current suites, `C-REF-B33-001`, `C-REF-MITC4-001` | Full CTest and blocking references pass. |
| `R-STYLE-001` | `T01`, `T03..T06`, `T24` | `P-STYLE-001`, clang-format, clang-tidy config, legacy-header scan | Style commands and full build pass. |
| `R-DOC-001` | `T03..T24` | policy scan and configured warning-strict Doxyfile | Production comments exist; tests are excluded. |
| `R-DUP-001` | `T07..T09` | `C-VEC3-001`, element/result/I/O suites, duplicate scan | One Vector3 implementation remains. |
| `R-DUP-002` | `T10`, `T11`, `T15` | `C-DUP-001..004` | Shared owners pass focused tests. |
| `R-MODEL-001` | `T12`, `T13` | `C-MODEL-001..002` | Polymorphic stable ownership passes. |
| `R-ELEMENT-001` | `T13`, `T14` | `C-ELEMENT-001` | Factory creates current kinds and rejects incompatible combinations. |
| `R-PIPELINE-001` | `T15..T17` | `C-DOF-001`, `C-ASSEMBLY-001`, `C-RECOVERY-001` | Generic consumer and deterministic tests pass. |
| `R-LOAD-001` | `T18` | `C-LOAD-001` | Ordered accumulation and current validations pass. |
| `R-BC-001` | `T19` | `C-BC-001` | Prescribed displacement partition/reconstruction passes. |
| `R-ANALYSIS-001` | `T20` | `C-ANALYSIS-001` | Lifecycle and factorization count pass. |
| `R-MODULE-001` | `T21..T23` | `C-MODULE-001..003` | Facade behavior and atomicity suites pass. |
| `R-AGENT-001` | `T00` | `P-AGENT-001` | Python workflow contract passes. |
| `R-SCOPE-001` | every task | diff review and final reference/artifact checks | No excluded behavior or artifact change appears. |
## 12. Validation Commands
Harness Python and policy validation:
```powershell
uv run --with pytest python -m pytest -v -rs
& "C:/Program Files/LLVM/bin/clang-format.exe" --version
& "C:/Program Files/LLVM/bin/clang-tidy.exe" --version
& "C:/Program Files/LLVM/bin/clang-tidy.exe" --verify-config
```
MSVC clean configure and full verification:
```powershell
$requiredBuildPaths = @(
"C:/git/googletest",
"C:/Program Files (x86)/Intel/oneAPI/mkl/2026.1/lib/cmake/mkl",
"C:/Program Files (x86)/Intel/oneAPI/tbb/2023.1/lib/cmake/tbb",
"C:/Program Files/HDF_Group/HDF5/2.1.1/cmake"
)
foreach ($requiredBuildPath in $requiredBuildPaths) {
if (-not (Test-Path -LiteralPath $requiredBuildPath)) {
throw "Missing $requiredBuildPath"
}
}
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"
cmake --build .harness/build --config Debug --target fesa_tests
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure
ctest --test-dir .harness/build -C Debug `
-R "B33ReferenceComparison|Mitc4S4Reference" --output-on-failure
```
Repository style and artifact checks:
```powershell
$cppFiles = @(rg --files include src tests -g "*.h" -g "*.cpp")
& "C:/Program Files/LLVM/bin/clang-format.exe" --dry-run --Werror $cppFiles
$publicHeaders = @(rg --files include/fesa -g "*.h")
foreach ($publicHeader in $publicHeaders) {
& "C:/Program Files/LLVM/bin/clang-tidy.exe" --config-file=.clang-tidy `
$publicHeader -- -x c++ -std=c++17 -Iinclude
if ($LASTEXITCODE -ne 0) {
throw "clang-tidy failed for $publicHeader"
}
}
$legacyHeaders = @(rg --files include tests -g "*.hpp")
if ($legacyHeaders.Count -ne 0) {
$legacyHeaders
throw "Legacy .hpp headers remain"
}
git diff --exit-code 1e5758f -- reference
```
Doxygen generation is deliberately absent from the blocking commands. When the user
requests documentation generation later, execute `doxygen Doxyfile` and treat warnings
as failures without committing generated HTML.
## 13. Risks and Downstream Handoff
- Global API/header renaming has a wide compile blast radius. Mechanical style Steps
are isolated from semantic restructuring to keep failures attributable.
- Domain polymorphism can accidentally destabilize vector indices or lifetimes. Tests
must prove insertion order, const access, and AnalysisModel non-owning lifetime.
- Virtual element recovery can tempt a giant result record. Preserve distinct beam and
shell rows in a backend-neutral bundle rather than adding meaningless common fields.
- Moving vector helpers can change floating-point operation order. Preserve each
formulation expression order and use exact regression where no approved tolerance
applies.
- File splits can leak vendor dependencies through public headers. Keep all HDF5/MKL/TBB
types in private implementation modules.
Downstream handoff is one bounded handoff to `implementation-agent` through the
Coordinator: execute only the Executor-selected `stepN.md`, read `/docs/CODINGSTYLE.md`
before C++ work, record RED/GREEN/VERIFY evidence, and do not advance another Step.
## 14. Harness Step Draft
- Task name: `cpp-object-oriented-modular-refactoring`
- Steps: `step0.md` through `step24.md` in dependency order shown in Work Breakdown.
- Every Step contains its own prerequisite files, test-first failure, candidate
interfaces, exact focused/full commands, and prohibitions.
- Stop conditions are an upstream contract conflict, a missing declared artifact at
final comparison, an unresolved environment dependency, or repeated build/test
failure. In each case only the current Step status payload is changed.
- Planning approval materializes these files but does not authorize
`python scripts/execute.py cpp-object-oriented-modular-refactoring`.
## 15. Open Issues
- No blocking architecture, formulation, I/O, reference, or tolerance issue remains.
- Doxygen executable use and generated documentation are deferred by explicit user
decision; this does not waive production Doxygen comments or `Doxyfile` configuration.
@@ -0,0 +1,31 @@
{
"project": "FESA Structural Solver",
"phase": "cpp-object-oriented-modular-refactoring",
"steps": [
{ "step": 0, "name": "coding-style-agent-contract", "status": "pending" },
{ "step": 1, "name": "cpp-style-tooling", "status": "pending" },
{ "step": 2, "name": "architecture-boundaries", "status": "pending" },
{ "step": 3, "name": "foundation-google-style", "status": "pending" },
{ "step": 4, "name": "model-element-google-style", "status": "pending" },
{ "step": 5, "name": "solver-workflow-google-style", "status": "pending" },
{ "step": 6, "name": "io-application-google-style", "status": "pending" },
{ "step": 7, "name": "vector3-value-type", "status": "pending" },
{ "step": 8, "name": "element-geometry-vector3", "status": "pending" },
{ "step": 9, "name": "result-io-vector3", "status": "pending" },
{ "step": 10, "name": "dense-blas-adapter", "status": "pending" },
{ "step": 11, "name": "source-target-resolver", "status": "pending" },
{ "step": 12, "name": "material-property-hierarchy", "status": "pending" },
{ "step": 13, "name": "element-definition-domain", "status": "pending" },
{ "step": 14, "name": "runtime-element-factory", "status": "pending" },
{ "step": 15, "name": "generic-dof-manager", "status": "pending" },
{ "step": 16, "name": "generic-sparse-assembler", "status": "pending" },
{ "step": 17, "name": "generic-result-recovery", "status": "pending" },
{ "step": 18, "name": "load-hierarchy", "status": "pending" },
{ "step": 19, "name": "boundary-condition-policy", "status": "pending" },
{ "step": 20, "name": "analysis-hierarchy", "status": "pending" },
{ "step": 21, "name": "domain-mapper-modules", "status": "pending" },
{ "step": 22, "name": "result-recovery-modules", "status": "pending" },
{ "step": 23, "name": "hdf5-writer-modules", "status": "pending" },
{ "step": 24, "name": "final-quality-reference-gate", "status": "pending" }
]
}
@@ -0,0 +1,81 @@
# Step 0: Coding Style Agent Contract
## 담당 역할과 필수 스킬
- 담당 역할: `implementation-agent`
- 필수 스킬: `harness`, `fesa-cpp-msvc-tdd`
- 이 Step만 `RED -> observed failure -> minimal GREEN -> focused/full VERIFY`로 수행한다.
## 읽어야 할 파일
- `/.agents/skills/harness/SKILL.md`
- `/.codex/skills/fesa-cpp-msvc-tdd/SKILL.md`
- `/AGENTS.md`
- `/docs/CODINGSTYLE.md`
- `/docs/SOLVER_AGENT_DESIGN.md`
- `/docs/HARNESS.md`
- `/docs/HARNESS_WORKFLOW.md`
- `/.codex/hooks.json`
- `/.codex/agents/implementation-agent.toml`
- `/tests/test_agent_skill_workflow_contract.py`
- `/docs/cpp-object-oriented-modular-refactoring/implementation-plan.md`
- `/phases/cpp-object-oriented-modular-refactoring/index.json`
- `/phases/cpp-object-oriented-modular-refactoring/step0.md`
필수 파일이 없거나 승인 설계와 충돌하면 현재 Step을 `blocked`로 기록하고 중단한다.
## 작업
Requirement `R-AGENT-001`만 구현한다.
1. `tests/test_agent_skill_workflow_contract.py``P-AGENT-001`을 먼저 추가한다.
2. Test는 `implementation-agent.toml`의 mandatory global input 구간이 literal path
`docs/CODINGSTYLE.md`를 직접 포함하고, C++ Step 시작 전에 읽도록 지시하는지 검증한다.
3. RED에서 현재 profile이 이 contract를 만족하지 않아 assertion failure가 발생함을 기록한다.
4. `/.codex/agents/implementation-agent.toml`에 다음 의미의 지시를 최소 추가한다.
```text
Before every C++ implementation Step, read docs/CODINGSTYLE.md as a mandatory global
input and apply it to production and test code. Doxygen coverage applies only to
production code.
```
5. 다른 agent profile, solver 문서, production C++, CMake는 수정하지 않는다.
## Acceptance Criteria
RED와 GREEN을 다음 명령으로 구분해 기록한다.
```powershell
uv run --with pytest python -m pytest -v -rs `
tests/test_agent_skill_workflow_contract.py
uv run --with pytest python -m pytest -v -rs
```
Repository Stop 검증과 동일한 C++ 회귀 확인:
```powershell
cmake -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"
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure
```
## 검증 및 상태 갱신
- RED assertion, GREEN targeted/full pytest, C++ regression 결과를 summary에 남긴다.
- 성공 시 현재 Step만 `completed`와 한 줄 `summary`로 갱신한다.
- 실패면 `error`/`error_message`, 사용자 개입이 필요하면
`blocked`/`blocked_reason`을 기록한다.
- timestamp, retry, commit, 다음 Step 선택은 Executor 소유다.
## 금지사항
- C++ 또는 CMake를 수정하지 마라. 이유: 이 Step은 agent contract만 소유한다.
- 다른 agent profile에 동일 문구를 일괄 추가하지 마라. 이유: 승인 범위를 넓힌다.
- 직접 commit하거나 hook script를 수동 실행하지 마라. 이유: Executor와 hook의 소유권이다.
- `scripts/execute.py`를 호출하지 마라. 이유: 현재 독립 Step을 재귀 실행하면 안 된다.
@@ -0,0 +1,76 @@
# Step 1: C++ Style Tooling
## 담당 역할과 필수 스킬
- 담당 역할: `implementation-agent`
- 필수 스킬: `harness`, `fesa-cpp-msvc-tdd`
- 이 Step만 `RED -> observed failure -> minimal GREEN -> focused/full VERIFY`로 수행한다.
## 읽어야 할 파일
- `/.agents/skills/harness/SKILL.md`
- `/.codex/skills/fesa-cpp-msvc-tdd/SKILL.md`
- `/AGENTS.md`
- `/docs/CODINGSTYLE.md`
- `/docs/superpowers/specs/2026-08-16-cpp-object-oriented-modular-refactoring-design.md`
- `/docs/cpp-object-oriented-modular-refactoring/implementation-plan.md`
- `/CMakeLists.txt`
- `/.gitignore`
- `/tests/test_agent_skill_workflow_contract.py`
- `/phases/cpp-object-oriented-modular-refactoring/index.json`
- `/phases/cpp-object-oriented-modular-refactoring/step1.md`
- Step 0이 수정한 `/.codex/agents/implementation-agent.toml`
## 작업
Requirements `R-STYLE-001``R-DOC-001`의 repository tooling만 구현한다.
1. `/tests/test_cpp_policy_contract.py``P-STYLE-001`을 먼저 작성한다. 다음 literal
contract를 검사한다.
- `.clang-format`: `BasedOnStyle: Google`, `IndentWidth: 2`, `ColumnLimit: 80`.
- `.clang-tidy`: C++17-compatible checks와 FESA PascalCase/snake_case identifier rules.
- `Doxyfile`: `INPUT = include src`, tests 제외, `WARN_AS_ERROR = YES`, generated HTML은
source control 밖의 build 경로.
- Root CMake의 optional `fesa_docs` target은 Doxygen가 발견될 때만 등록되고 default
configure에는 Doxygen를 요구하지 않는다.
2. RED에서 설정 파일 부재로 test failure를 확인한다.
3. `/.clang-format`, `/.clang-tidy`, `/Doxyfile`을 추가한다.
4. `/CMakeLists.txt``find_package(Doxygen QUIET)`와 발견 시에만 등록되는
`fesa_docs` custom target을 추가한다. Default build dependency에 넣지 않는다.
5. Generated Doxygen HTML 경로가 ignore되지 않았다면 `/.gitignore`에 정확한 output
directory만 추가한다.
6. Doxygen executable은 실행하지 않는다. 사용자가 문서 생성을 추후 수행하기로 했다.
## Acceptance Criteria
```powershell
uv run --with pytest python -m pytest -v -rs tests/test_cpp_policy_contract.py
uv run --with pytest python -m pytest -v -rs
& "C:/Program Files/LLVM/bin/clang-format.exe" --version
& "C:/Program Files/LLVM/bin/clang-tidy.exe" --version
& "C:/Program Files/LLVM/bin/clang-tidy.exe" --verify-config
cmake -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"
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure
```
Expected GREEN에는 Doxygen 실행이나 generated HTML이 포함되지 않는다.
## 검증 및 상태 갱신
- RED policy failure와 GREEN pytest/tool version/config/full CTest를 summary에 남긴다.
- 성공 시 현재 Step만 `completed`로 갱신하고 생성한 설정 파일을 summary에 기록한다.
- 환경에 두 LLVM executable이 없으면 `blocked`와 정확한 경로를 기록한다.
- timestamp, retry, commit, advancement는 Executor 소유다.
## 금지사항
- 기존 C++를 format하지 마라. 이유: 기계적 migration은 Step 36 소유다.
- Doxygen를 실행하거나 generated HTML을 commit하지 마라. 이유: 사용자 결정으로 생성은 연기됐다.
- Doxygen를 default build 필수 dependency로 만들지 마라. 이유: 현재 blocking gate가 아니다.
- 직접 commit하거나 hook script를 수동 실행하지 마라.
@@ -0,0 +1,82 @@
# Step 10: Dense BLAS Adapter
## 담당 역할과 필수 스킬
- 담당 역할: `implementation-agent`
- 필수 스킬: `harness`, `fesa-cpp-msvc-tdd`
- 이 Step만 `RED -> observed failure -> minimal GREEN -> focused/full VERIFY`로 수행한다.
## 읽어야 할 파일
- `/AGENTS.md`
- `/docs/CODINGSTYLE.md`
- `/docs/ARCHITECTURE.md`
- `/docs/cpp-object-oriented-modular-refactoring/implementation-plan.md`
- `/include/fesa/math/vector.h`, `/src/fesa/math/vector.cpp`
- `/include/fesa/math/matrix.h`, `/src/fesa/math/matrix.cpp`
- `/tests/unit/math/vector_test.cpp`, `/tests/unit/math/matrix_test.cpp`
- `/src/fesa/CMakeLists.txt`, `/tests/CMakeLists.txt`
- `/phases/cpp-object-oriented-modular-refactoring/index.json`
- `/phases/cpp-object-oriented-modular-refactoring/step10.md`
## 작업
Requirement `R-DUP-002`의 dense-BLAS duplication만 제거한다.
1. `/tests/unit/math/dense_blas_internal_test.cpp`를 먼저 추가하고 `C-DUP-003`을 작성한다.
Test는 zero/normal/overflow length conversion과 zero/nonzero contiguous copy behavior를
검증한다.
2. Missing internal adapter include/symbol로 RED compile failure를 기록한다.
3. Private candidate module은 `/src/fesa/math/dense_blas_internal.h`
`/src/fesa/math/dense_blas_internal.cpp`다.
Tests에 private include directory가 필요하면 `fesa_unit_tests`에만
`${PROJECT_SOURCE_DIR}/src/fesa`를 PRIVATE로 추가한다.
4. Candidate functions:
```cpp
namespace fesa::dense_blas_internal {
Result<MKL_INT> ToMklSize(std::size_t size);
void CopyValues(const double* source, std::size_t size, double* destination);
} // namespace fesa::dense_blas_internal
```
5. `MKL_INT` and MKL includes are permitted only in this private implementation boundary and
existing backend `.cpp`; no file under `/include/fesa/` may expose them.
6. Matrix/Vector의 duplicated conversion/copy helpers를 adapter call로 교체한다. Exception,
Status/failure meaning, row-major layout and BLAS call order stay unchanged.
## Acceptance Criteria
```powershell
cmake --build .harness/build --config Debug --target fesa_unit_tests
ctest --test-dir .harness/build -C Debug `
-R "DenseMath|DenseBlasInternal" --output-on-failure
rg -n "ToMklSize|CopyValues" src/fesa/math
rg -n "MKL_INT|mkl\.h" include/fesa
& "C:/Program Files/LLVM/bin/clang-format.exe" --dry-run --Werror `
src/fesa/math/dense_blas_internal.h src/fesa/math/dense_blas_internal.cpp `
src/fesa/math/vector.cpp src/fesa/math/matrix.cpp `
tests/unit/math/dense_blas_internal_test.cpp
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure
```
The public-header vendor scan must return no matches. The private helper scan must show one
definition family and the two intended consumers only.
## 검증 및 상태 갱신
- RED missing seam, focused conversion/copy behavior, scans and full CTest를 summary에 기록한다.
- Public vendor type leak or behavior regression이면 `error`로 기록한다.
- 성공 시 현재 Step만 `completed`로 갱신한다.
- timestamp, retry, commit, advancement는 Executor 소유다.
## 금지사항
- Public math API에 MKL type을 추가하지 마라.
- Matrix layout 또는 BLAS operation order를 바꾸지 마라.
- SIMD, allocation or runtime performance optimization을 하지 마라.
- 직접 commit하거나 hook script를 수동 실행하지 마라.
@@ -0,0 +1,131 @@
# Step 11: Source Target Resolver
## 담당 역할과 필수 스킬
- 담당 역할: `implementation-agent`
- 필수 스킬: `harness`, `fesa-cpp-msvc-tdd`
- 이 Step만 `RED -> observed failure -> minimal GREEN -> focused/full VERIFY`로 수행한다.
## 읽어야 할 파일
- `/AGENTS.md`
- `/docs/CODINGSTYLE.md`
- `/docs/ARCHITECTURE.md`
- `/docs/ADR.md`
- `/docs/linear-static-3d-euler-beam/io.md`
- `/docs/linear-static-mitc4-shell/io.md`
- `/docs/cpp-object-oriented-modular-refactoring/implementation-plan.md`
- `/include/fesa/core/source_identity.h`
- `/include/fesa/model/domain.h`, `/src/fesa/model/domain.cpp`
- `/src/fesa/io/abaqus/domain_mapper.cpp`
- `/src/fesa/fem/dof_manager.cpp`
- `/src/fesa/assembly/load_assembler.cpp`
- `/src/fesa/results/result_recovery.cpp`
- matching mapper/DOF/load/recovery tests
- `/src/fesa/CMakeLists.txt`, `/tests/CMakeLists.txt`
- `/phases/cpp-object-oriented-modular-refactoring/index.json`
- `/phases/cpp-object-oriented-modular-refactoring/step11.md`
## 작업
Requirement `R-DUP-002`의 ASCII/source-target owner를 구현한다.
1. `/tests/unit/core/ascii_test.cpp`
`/tests/unit/model/source_target_resolver_test.cpp`를 먼저 추가한다.
2. `C-DUP-004` tests cover ASCII-only lower/equality, positive source-label parsing,
separate node/element set namespaces, instance identity, declaration-order expansion,
duplicate/missing/ambiguous/nonpositive rejection and deterministic diagnostic order.
3. Missing headers/symbols로 RED compile failure를 기록한다.
4. Create `/include/fesa/core/ascii.h`, `/src/fesa/core/ascii.cpp`,
`/include/fesa/model/source_target_resolver.h`, and
`/src/fesa/model/source_target_resolver.cpp`; register both sources and both tests in CMake.
5. Candidate core functions:
```cpp
char AsciiLower(char value) noexcept;
bool AsciiCaseInsensitiveEquals(std::string_view lhs,
std::string_view rhs) noexcept;
Result<std::int64_t> ParsePositiveSourceLabel(std::string_view text);
```
6. Candidate model interface:
```cpp
enum class SourceEntityKind { kNode, kElement };
struct SourceTargetIndexEntry {
SourceEntityKind entity_kind;
std::string instance_name;
std::string target_name;
SourceEntityId source_id;
EntityIndex entity_index;
std::size_t declaration_order;
};
class SourceTargetIndex {
public:
explicit SourceTargetIndex(std::vector<SourceTargetIndexEntry> entries);
const std::vector<SourceTargetIndexEntry>& Entries() const noexcept;
};
struct SourceTargetQuery {
SourceEntityKind entity_kind;
std::string instance_name;
std::string target_name_or_label;
};
struct ResolvedSourceTarget {
SourceEntityId source_id;
EntityIndex entity_index;
};
class SourceTargetResolver {
public:
explicit SourceTargetResolver(const SourceTargetIndex& index) noexcept;
Result<std::vector<ResolvedSourceTarget>> Resolve(
const SourceTargetQuery& query) const;
};
```
7. `SourceTargetIndex` is an immutable index built from validated candidate or Domain semantic
records. It owns its compact entries; the resolver stores a non-owning reference, so the index
lifetime must outlive the resolver and Doxygen must state it.
8. Replace repeated `AsciiLower`, equal-name, positive-integer, and same-meaning source resolution
helpers only. Preserve each owner-specific diagnostic category/source location.
## Acceptance Criteria
```powershell
cmake --build .harness/build --config Debug --target fesa_unit_tests
ctest --test-dir .harness/build -C Debug `
-R "Ascii|SourceTargetResolver|InpDomainMapping|DofManager|LoadAssembly|ResultRecovery" `
--output-on-failure
rg -n "AsciiLower|EqualName|TryPositiveInteger" src/fesa
& "C:/Program Files/LLVM/bin/clang-format.exe" --dry-run --Werror `
include/fesa/core/ascii.h src/fesa/core/ascii.cpp `
include/fesa/model/source_target_resolver.h `
src/fesa/model/source_target_resolver.cpp `
tests/unit/core/ascii_test.cpp `
tests/unit/model/source_target_resolver_test.cpp
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure
```
The helper scan may show only the shared definitions and intentional calls, not repeated local
definitions. Full diagnostics and stable order tests must pass.
## 검증 및 상태 갱신
- RED, focused resolution cases, duplicate scan and full CTest를 summary에 기록한다.
- Identity/diagnostic order regression이면 `error`; missing upstream identity contract이면
`blocked`로 기록한다.
- 성공 시 현재 Step만 `completed`로 갱신한다.
- timestamp, retry, commit, advancement는 Executor 소유다.
## 금지사항
- Unicode case folding이나 locale behavior를 추가하지 마라. 이유: input contract is ASCII.
- Node와 element set namespace를 합치지 마라.
- Domain mapper를 responsibility files로 split하지 마라. 이유: Step 21 소유다.
- 직접 commit하거나 hook script를 수동 실행하지 마라.
@@ -0,0 +1,106 @@
# Step 12: Material and Element Property Hierarchy
## 담당 역할과 필수 스킬
- 담당 역할: `implementation-agent`
- 필수 스킬: `harness`, `fesa-cpp-msvc-tdd`
- 이 Step만 `RED -> observed failure -> minimal GREEN -> focused/full VERIFY`로 수행한다.
## 읽어야 할 파일
- `/AGENTS.md`
- `/docs/CODINGSTYLE.md`
- `/docs/ARCHITECTURE.md`
- `/docs/ADR.md`
- `/docs/superpowers/specs/2026-08-16-cpp-object-oriented-modular-refactoring-design.md`
- `/docs/cpp-object-oriented-modular-refactoring/implementation-plan.md`
- `/include/fesa/model/model_types.h`
- `/include/fesa/model/domain.h`, `/src/fesa/model/domain.cpp`
- `/tests/unit/model/model_types_test.cpp`, `/tests/unit/model/domain_test.cpp`
- `/src/fesa/CMakeLists.txt`, `/tests/CMakeLists.txt`
- `/phases/cpp-object-oriented-modular-refactoring/index.json`
- `/phases/cpp-object-oriented-modular-refactoring/step12.md`
## 작업
Requirement `R-MODEL-001`의 material/property type system만 구현한다. Domain polymorphic
ownership migration은 Step 13에서 수행한다.
1. `/tests/unit/materials/material_test.cpp`
`/tests/unit/properties/element_property_test.cpp`를 먼저 만든다.
2. `C-MODEL-001` tests create each concrete through `std::unique_ptr<Base>`, verify virtual
destruction, source/internal identity, concrete kind, exact current fields and invalid input
rejection. Missing base headers cause RED compile failure.
3. Candidate interfaces:
```cpp
enum class MaterialKind { kIsotropicLinearElastic };
class Material {
public:
virtual ~Material() = default;
virtual MaterialKind Kind() const noexcept = 0;
virtual const SourceEntityId& SourceId() const noexcept = 0;
};
class IsotropicLinearElasticMaterial final : public Material {
public:
double YoungsModulus() const noexcept;
double PoissonsRatio() const noexcept;
};
enum class ElementPropertyKind { kGeneralBeamSection, kShellSection };
class ElementProperty {
public:
virtual ~ElementProperty() = default;
virtual ElementPropertyKind Kind() const noexcept = 0;
virtual const SourceEntityId& SourceId() const noexcept = 0;
};
```
4. Create these exact production files and register their `.cpp` sources in CMake:
- `/include/fesa/materials/material.h`
- `/include/fesa/materials/isotropic_linear_elastic_material.h`
- `/src/fesa/materials/isotropic_linear_elastic_material.cpp`
- `/include/fesa/properties/element_property.h`
- `/include/fesa/properties/general_beam_section.h`
- `/include/fesa/properties/shell_section.h`
- `/src/fesa/properties/general_beam_section.cpp`
- `/src/fesa/properties/shell_section.cpp`
5. Add concrete `GeneralBeamSection` and `ShellSection` classes preserving their current validated
fields, units, source identity and optional frame meaning.
6. Move concrete record responsibility out of unrelated `model_types.h` only as required to avoid
duplicate definitions; update current compile consumers minimally.
7. No base contains density, plastic state, anisotropic tensor, thickness, area or no-op virtual
methods that are not common to every concrete.
## Acceptance Criteria
```powershell
cmake --build .harness/build --config Debug --target fesa_unit_tests
ctest --test-dir .harness/build -C Debug `
-R "Material|ElementProperty|DomainModel" --output-on-failure
& "C:/Program Files/LLVM/bin/clang-format.exe" --dry-run --Werror `
(rg --files include/fesa/materials include/fesa/properties -g "*.h") `
(rg --files src/fesa/materials src/fesa/properties -g "*.cpp") `
tests/unit/materials/material_test.cpp `
tests/unit/properties/element_property_test.cpp
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure
```
## 검증 및 상태 갱신
- RED missing interfaces, concrete validation, virtual ownership and full CTest를 summary에 기록한다.
- Any future-only field/interface or current property regression is an `error`.
- 성공 시 현재 Step만 `completed`로 갱신한다.
- timestamp, retry, commit, advancement는 Executor 소유다.
## 금지사항
- Density/plasticity/anisotropy APIs를 추가하지 마라. 이유: 승인된 현재 behavior가 아니다.
- Domain을 `shared_ptr` repository로 바꾸지 마라.
- ElementFactory 또는 numerical kernel을 수정하지 마라. 이유: Step 14 소유다.
- 직접 commit하거나 hook script를 수동 실행하지 마라.
@@ -0,0 +1,93 @@
# Step 13: Element Definition and Domain Ownership
## 담당 역할과 필수 스킬
- 담당 역할: `implementation-agent`
- 필수 스킬: `harness`, `fesa-cpp-msvc-tdd`
- 이 Step만 `RED -> observed failure -> minimal GREEN -> focused/full VERIFY`로 수행한다.
## 읽어야 할 파일
- `/AGENTS.md`
- `/docs/CODINGSTYLE.md`
- `/docs/ARCHITECTURE.md`
- `/docs/ADR.md`
- `/docs/cpp-object-oriented-modular-refactoring/implementation-plan.md`
- Step 11 `source_target_resolver` files
- Step 12 material/property headers and tests
- `/include/fesa/model/model_types.h`
- `/include/fesa/model/domain.h`, `/src/fesa/model/domain.cpp`
- `/include/fesa/analysis/analysis_model.h`, `/src/fesa/analysis/analysis_model.cpp`
- `/src/fesa/io/abaqus/domain_mapper.cpp`
- matching Domain, AnalysisModel and DomainMapper tests
- `/src/fesa/CMakeLists.txt`, `/tests/CMakeLists.txt`
- `/phases/cpp-object-oriented-modular-refactoring/index.json`
- `/phases/cpp-object-oriented-modular-refactoring/step13.md`
## 작업
Requirements `R-MODEL-001` and `R-ELEMENT-001`의 semantic ownership을 구현한다.
1. Domain/AnalysisModel/mapper tests에 `C-MODEL-002`를 먼저 추가한다. Tests verify mixed
B33/MITC4 definition ownership through base references, vector-position `EntityIndex`, insertion
order, const access, move-only Domain, and Domain-outlives-AnalysisModel contract.
2. Missing base/ownership API로 RED compile failure를 기록한다.
3. Candidate interface:
```cpp
enum class ElementDefinitionKind { kEulerBeam3D, kMitc4Shell };
class ElementDefinition {
public:
virtual ~ElementDefinition() = default;
virtual ElementDefinitionKind Kind() const noexcept = 0;
virtual const SourceEntityId& SourceId() const noexcept = 0;
virtual std::string_view SourceElementType() const noexcept = 0;
virtual const std::vector<EntityIndex>& NodeIndices() const noexcept = 0;
virtual EntityIndex PropertyIndex() const noexcept = 0;
};
```
4. Create `/include/fesa/elements/element_definition.h`. Keep concrete definitions in the
current `/include/fesa/elements/euler_beam_3d.h` and
`/include/fesa/elements/mitc4_shell.h` ownership modules rather than creating a second record
location.
5. Existing `EulerBeam3DDefinition` and `Mitc4ShellDefinition` become final concrete definitions;
preserve B33 vs S4/S4R source type and FESA internal identity.
6. Domain owns `std::vector<std::unique_ptr<ElementDefinition>>`,
`std::vector<std::unique_ptr<ElementProperty>>`, and
`std::vector<std::unique_ptr<Material>>`. Accessors return const base references or const
collection views; Domain copy is disabled and move is allowed if existing construction needs it.
7. Mapper builds a complete validated candidate before moving it into Domain. Failed mapping must
not leave a partially visible Domain.
8. AnalysisModel remains a non-owning active index/reference view and never copies Domain.
## Acceptance Criteria
```powershell
cmake --build .harness/build --config Debug --target fesa_unit_tests
ctest --test-dir .harness/build -C Debug `
-R "ElementDefinition|DomainModel|AnalysisModel|InpDomainMapping" --output-on-failure
& "C:/Program Files/LLVM/bin/clang-format.exe" --dry-run --Werror `
include/fesa/elements/element_definition.h `
include/fesa/model/domain.h src/fesa/model/domain.cpp `
tests/unit/model/domain_test.cpp tests/unit/analysis/analysis_model_test.cpp `
tests/unit/io/abaqus/domain_mapper_test.cpp
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure
```
## 검증 및 상태 갱신
- RED, stable ownership/order/lifetime focused tests, mapper and full CTest를 summary에 기록한다.
- Index/order/lifetime regression is `error`; missing ownership decision is `blocked`.
- 성공 시 현재 Step만 `completed`로 갱신한다.
- timestamp, retry, commit, advancement는 Executor 소유다.
## 금지사항
- `Clone()` or `shared_ptr`를 추가하지 마라. 이유: Domain has unique immutable ownership.
- Node/Element에 equation id를 저장하지 마라.
- Runtime Element methods를 semantic definition에 넣지 마라.
- 직접 commit하거나 hook script를 수동 실행하지 마라.
@@ -0,0 +1,130 @@
# Step 14: Runtime Element and Factory
## 담당 역할과 필수 스킬
- 담당 역할: `implementation-agent`
- 필수 스킬: `harness`, `fesa-cpp-msvc-tdd`
- 이 Step만 `RED -> observed failure -> minimal GREEN -> focused/full VERIFY`로 수행한다.
## 읽어야 할 파일
- `/AGENTS.md`
- `/docs/CODINGSTYLE.md`
- `/docs/ARCHITECTURE.md`
- `/docs/ADR.md`
- `/docs/linear-static-3d-euler-beam/formulation.md`
- `/docs/linear-static-mitc4-shell/formulation.md`
- `/docs/cpp-object-oriented-modular-refactoring/implementation-plan.md`
- Step 12 material/property hierarchy files
- Step 13 element definition and Domain files
- `/include/fesa/elements/euler_beam_3d.h`, `/src/fesa/elements/euler_beam_3d.cpp`
- `/include/fesa/elements/mitc4_shell.h`, `/src/fesa/elements/mitc4_shell.cpp`
- element/model/result record tests
- `/src/fesa/CMakeLists.txt`, `/tests/CMakeLists.txt`
- `/phases/cpp-object-oriented-modular-refactoring/index.json`
- `/phases/cpp-object-oriented-modular-refactoring/step14.md`
## 작업
Requirement `R-ELEMENT-001`의 numerical runtime boundary를 구현한다.
1. `/tests/unit/elements/element_factory_test.cpp`를 먼저 추가한다. `C-ELEMENT-001` covers
base-pointer virtual destruction, B33 and MITC4 factory success, stable DOF layout, stiffness
and recovery through base, unknown/mismatched property/material/null rejection.
2. Missing `element.h` and `element_factory.h` cause RED compile failure.
3. Create `/include/fesa/elements/element.h`,
`/include/fesa/elements/element_factory.h`, and
`/src/fesa/elements/element_factory.cpp`; register the source and factory test in CMake.
4. Candidate interfaces:
```cpp
struct ElementDofLayout {
SourceEntityId source_id;
std::vector<EntityIndex> node_indices;
std::vector<DofComponent> components_per_node;
};
struct ElementStiffnessContribution {
ElementDofLayout layout;
Matrix values;
};
struct BeamElementResultRows {
std::vector<EndpointResultRow> endpoint_rows;
std::vector<GaussResultRow> gauss_rows;
std::vector<StressS11Row> stress_rows;
};
struct ShellElementResultRows {
std::vector<ShellResultRow> rows;
double physical_strain_energy;
};
using ElementResultPayload =
std::variant<BeamElementResultRows, ShellElementResultRows>;
struct ElementResultBundle {
SourceEntityId source_id;
ElementResultPayload payload;
};
class Element {
public:
virtual ~Element() = default;
virtual const ElementDofLayout& DofLayout() const noexcept = 0;
virtual Result<ElementStiffnessContribution> ComputeStiffness() const = 0;
virtual Result<ElementResultBundle> Recover(
const Vector& full_displacement) const = 0;
};
using ElementView = std::vector<std::reference_wrapper<const Element>>;
class ElementFactory {
public:
Result<std::unique_ptr<Element>> Create(
const ElementDefinition& definition,
const Domain& domain) const;
};
```
5. The linear-static candidate owns `std::vector<std::unique_ptr<Element>>` and builds an
`ElementView` whose lifetime is bounded by that owner. Carrier type locations may be adjusted
to avoid circular public dependencies, but semantics and names must stay consistent for
Steps 1517.
6. Factory centralizes explicit definition/property/material kind compatibility, bounds checks,
and structured diagnostic. It may use a checked kind discriminator and concrete access after
validation; downstream consumers must not downcast.
7. Existing B33/MITC4 numerical kernels implement `Element` without changing formulation or adding
fields meaningless to the other element.
## Acceptance Criteria
```powershell
cmake --build .harness/build --config Debug --target fesa_unit_tests
ctest --test-dir .harness/build -C Debug `
-R "ElementFactory|EulerBeam3D|Mitc4Shell" --output-on-failure
rg -n "dynamic_cast" src/fesa include/fesa
& "C:/Program Files/LLVM/bin/clang-format.exe" --dry-run --Werror `
include/fesa/elements/element.h include/fesa/elements/element_factory.h `
src/fesa/elements/element_factory.cpp tests/unit/elements/element_factory_test.cpp
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure
```
The downcast scan must show no newly scattered consumer downcasts. If the centralized factory uses
a checked cast, document the preceding kind validation and keep it in the factory only.
## 검증 및 상태 갱신
- RED, success/rejection cases, base stiffness/recovery, downcast scan and full CTest를 summary에 기록한다.
- Formulation or result identity changes are `error`.
- 성공 시 현재 Step만 `completed`로 갱신한다.
- timestamp, retry, commit, advancement는 Executor 소유다.
## 금지사항
- Semantic definition and runtime kernel을 one class로 합치지 마라.
- Future element registry/global static registration을 추가하지 마라.
- Giant common result record with meaningless optional fields를 만들지 마라.
- 직접 commit하거나 hook script를 수동 실행하지 마라.
@@ -0,0 +1,86 @@
# Step 15: Generic DofManager
## 담당 역할과 필수 스킬
- 담당 역할: `implementation-agent`
- 필수 스킬: `harness`, `fesa-cpp-msvc-tdd`
- 이 Step만 `RED -> observed failure -> minimal GREEN -> focused/full VERIFY`로 수행한다.
## 읽어야 할 파일
- `/AGENTS.md`
- `/docs/CODINGSTYLE.md`
- `/docs/ARCHITECTURE.md`
- `/docs/ADR.md`
- `/docs/cpp-object-oriented-modular-refactoring/implementation-plan.md`
- Step 13 Domain/AnalysisModel files
- Step 14 `element.h`, `element_factory.h`, concrete runtime elements
- `/include/fesa/fem/dof_manager.h`, `/src/fesa/fem/dof_manager.cpp`
- `/tests/unit/fem/dof_manager_test.cpp`
- `/tests/unit/assembly/sparse_assembler_test.cpp`
- `/phases/cpp-object-oriented-modular-refactoring/index.json`
- `/phases/cpp-object-oriented-modular-refactoring/step15.md`
## 작업
Requirement `R-PIPELINE-001`의 DofManager portion과 `R-DUP-002`의 DOF invariant owner를
구현한다.
1. `dof_manager_test.cpp``C-DOF-001`을 먼저 추가한다. A test-only fake `Element`
supplies a layout not named B33 or MITC4; DofManager must number/scatter it in source order.
2. Tests also corrupt duplicate/full/free/constrained/equation mappings through an approved test seam
and expect `ValidateInvariants()` to reject each exact inconsistency.
3. Current DofManager cannot consume fake base layouts or expose owner validation, producing RED.
4. Candidate API:
```cpp
Status DofManager::Build(
const AnalysisModel& analysis_model,
const ElementView& elements);
Result<std::vector<std::size_t>> DofManager::ElementScatter(
const ElementDofLayout& layout) const;
Status DofManager::ValidateInvariants() const;
```
5. Replace B33/MITC4 concrete scatter/pattern branches with the ordered layout. Node DOF ownership,
constrained/free mappings, equation numbering and sparse pattern remain solely in DofManager.
6. Preserve stable node/source/component order, no/mixed/all-constraint behavior, and valid 0 free
equations. Do not store equation ids in Node/Element.
7. Remove same-meaning `ValidateDofOrder` helpers from other modules only after their callers use
`ValidateInvariants()` or an owner-issued immutable mapping.
## Acceptance Criteria
```powershell
cmake --build .harness/build --config Debug --target fesa_unit_tests
ctest --test-dir .harness/build -C Debug `
-R "DofManager|EssentialConstraints|SparseAssembly" --output-on-failure
$typeBranches = @(rg -n "EulerBeam3D|Mitc4Shell" src/fesa/fem/dof_manager.cpp)
if ($typeBranches.Count -ne 0) { $typeBranches; throw "Concrete element branch remains" }
rg -n "ValidateDofOrder" src/fesa
& "C:/Program Files/LLVM/bin/clang-format.exe" --dry-run --Werror `
include/fesa/fem/dof_manager.h src/fesa/fem/dof_manager.cpp `
tests/unit/fem/dof_manager_test.cpp
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure
```
`ValidateDofOrder` scan must show no duplicate local definitions. Existing public compatibility
wrappers may remain temporarily only if they delegate to DofManager and are removed by Step 20.
## 검증 및 상태 갱신
- RED fake-element/invariant failures, focused stable ordering, branch scan and full CTest를 summary에 기록한다.
- Equation or sparse pattern ordering regression is `error`.
- 성공 시 현재 Step만 `completed`로 갱신한다.
- timestamp, retry, commit, advancement는 Executor 소유다.
## 금지사항
- Element에 equation ids or global CSR를 저장하지 마라.
- DOF component order를 element kind switch로 재구성하지 마라.
- Sparse assembly algorithm을 수정하지 마라. 이유: Step 16 소유다.
- 직접 commit하거나 hook script를 수동 실행하지 마라.
@@ -0,0 +1,78 @@
# Step 16: Generic SparseAssembler
## 담당 역할과 필수 스킬
- 담당 역할: `implementation-agent`
- 필수 스킬: `harness`, `fesa-cpp-msvc-tdd`
- 이 Step만 `RED -> observed failure -> minimal GREEN -> focused/full VERIFY`로 수행한다.
## 읽어야 할 파일
- `/AGENTS.md`
- `/docs/CODINGSTYLE.md`
- `/docs/ARCHITECTURE.md`
- `/docs/ADR.md`
- `/docs/cpp-object-oriented-modular-refactoring/implementation-plan.md`
- Step 14 runtime Element contribution contract
- Step 15 DofManager and invariant contract
- `/include/fesa/assembly/sparse_assembler.h`, `/src/fesa/assembly/sparse_assembler.cpp`
- `/include/fesa/assembly/parallel_for.h`, `/src/fesa/assembly/parallel_for.cpp`
- `/tests/unit/assembly/sparse_assembler_test.cpp`
- `/tests/unit/elements/euler_beam_3d_test.cpp`
- `/tests/unit/elements/mitc4_shell_test.cpp`
- `/phases/cpp-object-oriented-modular-refactoring/index.json`
- `/phases/cpp-object-oriented-modular-refactoring/step16.md`
## 작업
Requirement `R-PIPELINE-001`의 assembly portion을 구현한다.
1. `sparse_assembler_test.cpp``C-ASSEMBLY-001`을 먼저 추가한다. A fake runtime Element
emits a known 2x2/3x3 local contribution with nonconsecutive full DOFs; tests verify exact CSR
structure/values and repeated serial/TBB byte identity.
2. Current assembler's concrete storage branch fails to assemble the fake, providing RED.
3. Candidate API:
```cpp
Result<SparseMatrix> SparseAssembler::Assemble(
const ElementView& elements,
const DofManager& dof_manager,
ParallelFor& parallel_for) const;
```
4. Each stable element index owns one local COO buffer created from
`Element::ComputeStiffness()` and DofManager scatter. Worker threads never mutate global CSR.
5. Concatenate and reduce in the existing stable tuple ordering. Do not replace exact fixed
reduction with atomics, unordered containers or nondeterministic task completion order.
6. Remove B33/MITC4 concrete branches from SparseAssembler after both current elements flow through
the interface.
## Acceptance Criteria
```powershell
cmake --build .harness/build --config Debug --target fesa_unit_tests
ctest --test-dir .harness/build -C Debug -R "SparseAssembly" --output-on-failure
$typeBranches = @(rg -n "EulerBeam3D|Mitc4Shell" src/fesa/assembly/sparse_assembler.cpp)
if ($typeBranches.Count -ne 0) { $typeBranches; throw "Concrete element branch remains" }
& "C:/Program Files/LLVM/bin/clang-format.exe" --dry-run --Werror `
include/fesa/assembly/sparse_assembler.h `
src/fesa/assembly/sparse_assembler.cpp `
tests/unit/assembly/sparse_assembler_test.cpp
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure
```
## 검증 및 상태 갱신
- RED fake contribution, exact CSR/repeated determinism, branch scan and full CTest를 summary에 기록한다.
- Any ordering/numeric regression is `error`; do not relax equality.
- 성공 시 현재 Step만 `completed`로 갱신한다.
- timestamp, retry, commit, advancement는 Executor 소유다.
## 금지사항
- Worker가 global CSR storage를 직접 수정하게 하지 마라.
- Floating-point reduction order or TBB policy를 변경하지 마라.
- Load assembly를 이 interface에 합치지 마라. 이유: separate responsibility.
- 직접 commit하거나 hook script를 수동 실행하지 마라.
@@ -0,0 +1,85 @@
# Step 17: Generic ResultRecovery
## 담당 역할과 필수 스킬
- 담당 역할: `implementation-agent`
- 필수 스킬: `harness`, `fesa-cpp-msvc-tdd`
- 이 Step만 `RED -> observed failure -> minimal GREEN -> focused/full VERIFY`로 수행한다.
## 읽어야 할 파일
- `/AGENTS.md`
- `/docs/CODINGSTYLE.md`
- `/docs/ARCHITECTURE.md`
- `/docs/ADR.md`
- `/docs/linear-static-3d-euler-beam/formulation.md`
- `/docs/linear-static-mitc4-shell/formulation.md`
- `/docs/linear-static-3d-euler-beam/io.md`
- `/docs/linear-static-mitc4-shell/io.md`
- `/docs/cpp-object-oriented-modular-refactoring/implementation-plan.md`
- Step 14 `ElementResultBundle` contract
- Step 15 DofManager and Step 16 assembly files
- `/include/fesa/results/result_recovery.h`, `/src/fesa/results/result_recovery.cpp`
- `/include/fesa/results/result_records.h`, `/include/fesa/analysis/analysis_state.h`
- matching result/element unit tests
- `/phases/cpp-object-oriented-modular-refactoring/index.json`
- `/phases/cpp-object-oriented-modular-refactoring/step17.md`
## 작업
Requirement `R-PIPELINE-001`의 recovery portion을 구현한다.
1. `result_recovery_test.cpp``C-RECOVERY-001`을 먼저 추가한다. A fake Element returns a
valid backend-neutral bundle and a failing bundle; tests verify stable insertion and whole-state
rollback without knowing a concrete element kind.
2. Current concrete B33/MITC4 branches fail the generic test, providing RED.
3. Candidate facade call:
```cpp
Status ResultRecovery::Recover(
const AnalysisModel& analysis_model,
const ElementView& elements,
const DofManager& dof_manager,
const SparseMatrix& full_stiffness,
const Vector& full_displacement,
const Vector& full_external_force,
AnalysisState& state) const;
```
4. Elements own element-local physical recovery; ResultRecovery owns full residual, reactions,
free equilibrium, stable bundle aggregation, cross-element/global evidence and atomic commit.
5. Beam end action, positive-local-x section resultant, Gauss generalized results and section-point
stress remain distinct rows. Shell physical recovery excludes drilling energy/results.
6. Remove B33/MITC4 kind branches from the facade. Distinct bundle variant/collections may be
visited without downcasting the Element itself.
## Acceptance Criteria
```powershell
cmake --build .harness/build --config Debug --target fesa_unit_tests
ctest --test-dir .harness/build -C Debug `
-R "ResultRecovery|AnalysisState|EulerBeam3D|Mitc4Shell" --output-on-failure
$typeBranches = @(rg -n "EulerBeam3D|Mitc4Shell" src/fesa/results/result_recovery.cpp)
if ($typeBranches.Count -ne 0) { $typeBranches; throw "Concrete element branch remains" }
& "C:/Program Files/LLVM/bin/clang-format.exe" --dry-run --Werror `
include/fesa/results/result_recovery.h `
src/fesa/results/result_recovery.cpp `
tests/unit/results/result_recovery_test.cpp
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure
```
## 검증 및 상태 갱신
- RED generic bundle, identity/sign/rollback tests, branch scan and full CTest를 summary에 기록한다.
- Row merge/average, sign, energy or atomicity regression is `error`.
- 성공 시 현재 Step만 `completed`로 갱신한다.
- timestamp, retry, commit, advancement는 Executor 소유다.
## 금지사항
- Different result locations를 average/merge하지 마라.
- Drilling stabilization을 physical shell results에 포함하지 마라.
- HDF5 schema or writer를 수정하지 마라.
- 직접 commit하거나 hook script를 수동 실행하지 마라.
@@ -0,0 +1,109 @@
# Step 18: Load Hierarchy
## 담당 역할과 필수 스킬
- 담당 역할: `implementation-agent`
- 필수 스킬: `harness`, `fesa-cpp-msvc-tdd`
- 이 Step만 `RED -> observed failure -> minimal GREEN -> focused/full VERIFY`로 수행한다.
## 읽어야 할 파일
- `/AGENTS.md`
- `/docs/CODINGSTYLE.md`
- `/docs/ARCHITECTURE.md`
- `/docs/ADR.md`
- `/docs/cpp-object-oriented-modular-refactoring/implementation-plan.md`
- Step 11 source-target resolver files
- Step 13 Domain/AnalysisModel files
- Step 15 DofManager files
- `/include/fesa/assembly/load_assembler.h`, `/src/fesa/assembly/load_assembler.cpp`
- `/tests/unit/assembly/load_assembler_test.cpp`
- `/tests/unit/analysis/analysis_model_test.cpp`
- `/src/fesa/io/abaqus/domain_mapper.cpp`
- `/src/fesa/CMakeLists.txt`, `/tests/CMakeLists.txt`
- `/phases/cpp-object-oriented-modular-refactoring/index.json`
- `/phases/cpp-object-oriented-modular-refactoring/step18.md`
## 작업
Requirement `R-LOAD-001`을 구현한다.
1. `/tests/unit/loads/load_test.cpp`와 LoadAssembler generic test를 먼저 추가한다.
`C-LOAD-001` uses a fake Load to emit ordered contributions, verifies signed duplicate target
accumulation and rejects nonfinite/index errors before global mutation.
2. Missing Load base/contribution API or concrete-vector-only assembler gives RED.
3. Create `/include/fesa/loads/load.h`,
`/include/fesa/loads/concentrated_nodal_load.h`, and
`/src/fesa/loads/concentrated_nodal_load.cpp`; register the source and load test in CMake.
4. Candidate interfaces:
```cpp
struct LoadContribution {
std::size_t source_order;
std::size_t full_dof_index;
double value;
};
struct LoadContext {
const Domain& domain;
const DofManager& dof_manager;
const SourceTargetResolver& target_resolver;
};
class Load {
public:
virtual ~Load() = default;
virtual Result<std::vector<LoadContribution>> ComputeContributions(
const LoadContext& context) const = 0;
};
class ConcentratedNodalLoad final : public Load {
public:
ConcentratedNodalLoad(SourceTargetQuery target,
std::array<double, 6> global_components,
std::size_t source_order);
Result<std::vector<LoadContribution>> ComputeContributions(
const LoadContext& context) const override;
private:
SourceTargetQuery target_;
std::array<double, 6> global_components_;
std::size_t source_order_;
};
```
5. Domain StepDefinition owns loads through `unique_ptr<Load>` and exposes const active order.
6. `LoadAssembler` requests contributions in active source order, validates them, then accumulates
into a candidate full vector in the existing deterministic order.
7. Current drilling-moment validation, exact-zero aggregate handling, nonzero prescribed effective
RHS behavior and diagnostics remain unchanged.
## Acceptance Criteria
```powershell
cmake --build .harness/build --config Debug --target fesa_unit_tests
ctest --test-dir .harness/build -C Debug `
-R "Load|LoadAssembly|AnalysisModel|InpDomainMapping" --output-on-failure
& "C:/Program Files/LLVM/bin/clang-format.exe" --dry-run --Werror `
(rg --files include/fesa/loads -g "*.h") `
(rg --files src/fesa/loads -g "*.cpp") `
include/fesa/assembly/load_assembler.h src/fesa/assembly/load_assembler.cpp `
tests/unit/loads/load_test.cpp tests/unit/assembly/load_assembler_test.cpp
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure
```
## 검증 및 상태 갱신
- RED fake load, ordered/validation focused tests and full CTest를 summary에 기록한다.
- Reduction/order/diagnostic regression is `error`.
- 성공 시 현재 Step만 `completed`로 갱신한다.
- timestamp, retry, commit, advancement는 Executor 소유다.
## 금지사항
- Load object가 global Vector를 직접 mutate하게 하지 마라.
- Distributed load, body force or new keyword를 구현하지 마라.
- Parallel accumulation or order optimization을 추가하지 마라.
- 직접 commit하거나 hook script를 수동 실행하지 마라.
@@ -0,0 +1,137 @@
# Step 19: Boundary Condition Policy
## 담당 역할과 필수 스킬
- 담당 역할: `implementation-agent`
- 필수 스킬: `harness`, `fesa-cpp-msvc-tdd`
- 이 Step만 `RED -> observed failure -> minimal GREEN -> focused/full VERIFY`로 수행한다.
## 읽어야 할 파일
- `/AGENTS.md`
- `/docs/CODINGSTYLE.md`
- `/docs/ARCHITECTURE.md`
- `/docs/ADR.md`
- `/docs/cpp-object-oriented-modular-refactoring/implementation-plan.md`
- Step 11 source resolver, Step 13 Domain and Step 15 DofManager files
- `/include/fesa/constraints/essential_constraints.h`
- `/src/fesa/constraints/essential_constraints.cpp`
- `/tests/unit/constraints/essential_constraints_test.cpp`
- `/tests/unit/fem/dof_manager_test.cpp`
- `/src/fesa/io/abaqus/domain_mapper.cpp`
- `/src/fesa/CMakeLists.txt`, `/tests/CMakeLists.txt`
- `/phases/cpp-object-oriented-modular-refactoring/index.json`
- `/phases/cpp-object-oriented-modular-refactoring/step19.md`
## 작업
Requirement `R-BC-001`을 구현한다.
1. `/tests/unit/constraints/boundary_condition_test.cpp`와 policy-focused tests를 먼저 추가한다.
`C-BC-001` uses a fake BoundaryCondition and concrete prescribed displacement to verify stable
definitions, duplicates/conflicts/nonfinite rejection and nonzero reconstruction.
2. Missing base/policy API provides RED.
3. Create `/include/fesa/constraints/boundary_condition.h`,
`/include/fesa/constraints/prescribed_displacement.h`,
`/include/fesa/constraints/essential_constraint_policy.h`,
`/src/fesa/constraints/prescribed_displacement.cpp`, and
`/src/fesa/constraints/essential_constraint_policy.cpp`; register sources/tests in CMake.
4. Candidate interfaces:
```cpp
struct ConstraintDefinition {
std::size_t source_order;
std::size_t full_dof_index;
double prescribed_value;
};
struct BoundaryConditionContext {
const Domain& domain;
const DofManager& dof_manager;
const SourceTargetResolver& target_resolver;
};
class BoundaryCondition {
public:
virtual ~BoundaryCondition() = default;
virtual Result<std::vector<ConstraintDefinition>> ResolveConstraints(
const BoundaryConditionContext& context) const = 0;
};
class PrescribedDisplacementBoundaryCondition final
: public BoundaryCondition {
public:
PrescribedDisplacementBoundaryCondition(SourceTargetQuery target,
DofComponent component,
double prescribed_value,
std::size_t source_order);
Result<std::vector<ConstraintDefinition>> ResolveConstraints(
const BoundaryConditionContext& context) const override;
private:
SourceTargetQuery target_;
DofComponent component_;
double prescribed_value_;
std::size_t source_order_;
};
struct PartitionedStiffness {
SparseMatrix k_ff;
SparseMatrix k_fc;
SparseMatrix k_cf;
SparseMatrix k_cc;
};
class EssentialConstraintPolicy {
public:
Result<PartitionedStiffness> Partition(
const SparseMatrix& full_stiffness,
const DofManager& dof_manager) const;
Vector GatherFree(const Vector& full_values,
const DofManager& dof_manager) const;
Vector GatherConstrained(const Vector& full_values,
const DofManager& dof_manager) const;
Vector ReconstructFull(const Vector& free_values,
const Vector& constrained_values,
const DofManager& dof_manager) const;
};
```
5. Domain StepDefinition owns boundary conditions through `unique_ptr<BoundaryCondition>`.
6. Move the existing `PartitionedStiffness` record plus stable elimination, Kff/Kfc/Kcf/Kcc
extraction, prescribed vector and full/reduced reconstruction behind
`EssentialConstraintPolicy` without changing algebra or order.
7. A valid all-constrained model keeps 0x0 Kff semantics. Conflicting definitions fail before
mutating an accepted candidate.
## Acceptance Criteria
```powershell
cmake --build .harness/build --config Debug --target fesa_unit_tests
ctest --test-dir .harness/build -C Debug `
-R "BoundaryCondition|EssentialConstraints|DofManager|LoadAssembly" --output-on-failure
& "C:/Program Files/LLVM/bin/clang-format.exe" --dry-run --Werror `
include/fesa/constraints/boundary_condition.h `
include/fesa/constraints/prescribed_displacement.h `
include/fesa/constraints/essential_constraint_policy.h `
(rg --files src/fesa/constraints -g "*.cpp") `
tests/unit/constraints/boundary_condition_test.cpp `
tests/unit/constraints/essential_constraints_test.cpp
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure
```
## 검증 및 상태 갱신
- RED fake boundary, partition/reconstruction/all-constrained tests and full CTest를 summary에 기록한다.
- Algebra/order or nonzero prescribed behavior regression is `error`.
- 성공 시 현재 Step만 `completed`로 갱신한다.
- timestamp, retry, commit, advancement는 Executor 소유다.
## 금지사항
- MPC, penalty, Lagrange multiplier or new BC keyword를 구현하지 마라.
- BoundaryCondition이 K matrix를 직접 partition하게 하지 마라.
- Prescribed displacement를 bool/enum mega-policy로 future behavior와 합치지 마라.
- 직접 commit하거나 hook script를 수동 실행하지 마라.
@@ -0,0 +1,76 @@
# Step 2: Architecture Boundaries
## 담당 역할과 필수 스킬
- 담당 역할: `implementation-agent`
- 필수 스킬: `harness`, `fesa-cpp-msvc-tdd`
- 이 Step은 구현 전 architecture contract를 고정하는 documentation-only Step이다.
## 읽어야 할 파일
- `/AGENTS.md`
- `/docs/CODINGSTYLE.md`
- `/docs/PRD.md`
- `/docs/ARCHITECTURE.md`
- `/docs/ADR.md`
- `/docs/superpowers/specs/2026-08-16-cpp-object-oriented-modular-refactoring-design.md`
- `/docs/cpp-object-oriented-modular-refactoring/implementation-plan.md`
- `/phases/cpp-object-oriented-modular-refactoring/index.json`
- `/phases/cpp-object-oriented-modular-refactoring/step2.md`
## 작업
Requirements `R-MODEL-001`, `R-ELEMENT-001`, `R-PIPELINE-001`, `R-LOAD-001`,
`R-BC-001`, `R-ANALYSIS-001`, `R-MODULE-001`의 ownership 방향을 문서화한다.
1. `/docs/ARCHITECTURE.md`에 다음 dependency/ownership graph를 반영한다.
```text
Domain owns ElementDefinition / ElementProperty / Material / StepDefinition
AnalysisModel is a non-owning stable-index view into Domain
ElementFactory creates runtime Element candidates from compatible definitions
DofManager -> ElementDofLayout
SparseAssembler -> ElementStiffnessContribution
ResultRecovery -> ElementResultBundle
LoadAssembler -> ordered LoadContribution
EssentialConstraintPolicy -> ConstraintDefinition
Analysis <- LinearStaticAnalysis
```
2. `/docs/ADR.md`에서 기존 ADR-007의 linear-static-specific protected hook contract를
최소 `Analysis::Run(const AnalysisRequest&)` base와 private
`LinearStaticAnalysis` lifecycle 결정으로 대체하거나 supersede한다.
3. ADR에 `ElementDefinition`/runtime `Element` 분리, Domain `unique_ptr` ownership,
no speculative material capability, load contribution/constraint policy 분리를 기록한다.
4. 기존 B33/MITC4 수치 및 HDF5/reference contract가 우선한다는 문구를 유지한다.
5. 문서에서 미래 MITC3/solid/dynamic/plastic 동작을 구현됐다고 표현하지 않는다.
Documentation-only contract 고정이므로 artificial RED를 만들지 않는다. 구현 Step은 이
문서를 먼저 읽고 test-first로 진행한다.
## Acceptance Criteria
```powershell
rg -n "ElementDefinition|ElementFactory|LoadContribution|ConstraintDefinition|Analysis::Run" `
docs/ARCHITECTURE.md docs/ADR.md
rg -n "unique_ptr|stable-index|non-owning|LinearStaticAnalysis" `
docs/ARCHITECTURE.md docs/ADR.md
git diff --check
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure
```
## 검증 및 상태 갱신
- 문서 search evidence와 full regression 결과를 summary에 남긴다.
- 승인 설계와 기존 ADR이 양립할 수 없으면 임의 결정하지 말고 `blocked`로 기록한다.
- 성공 시 현재 Step만 `completed`로 갱신한다.
- timestamp, retry, commit, advancement는 Executor 소유다.
## 금지사항
- C++ production, tests, CMake를 수정하지 마라. 이유: 이 Step은 architecture 기록만 소유한다.
- 새로운 물리 기능 또는 입력/HDF5 계약을 ADR에 추가하지 마라.
- 기존 formulation/reference 문서를 리팩터링에 맞춰 고치지 마라.
- 직접 commit하거나 hook script를 수동 실행하지 마라.
@@ -0,0 +1,112 @@
# Step 20: Analysis Hierarchy
## 담당 역할과 필수 스킬
- 담당 역할: `implementation-agent`
- 필수 스킬: `harness`, `fesa-cpp-msvc-tdd`
- 이 Step만 `RED -> observed failure -> minimal GREEN -> focused/full VERIFY`로 수행한다.
## 읽어야 할 파일
- `/AGENTS.md`
- `/docs/CODINGSTYLE.md`
- `/docs/ARCHITECTURE.md`
- `/docs/ADR.md`
- `/docs/linear-static-3d-euler-beam/requirements.md`
- `/docs/linear-static-mitc4-shell/requirements.md`
- `/docs/cpp-object-oriented-modular-refactoring/implementation-plan.md`
- Step 1519 generic element/load/constraint pipeline files
- `/include/fesa/analysis/analysis_model.h`
- `/include/fesa/analysis/analysis_state.h`
- `/include/fesa/analysis/linear_static_analysis.h`
- `/src/fesa/analysis/linear_static_analysis.cpp`
- `/src/fesa/app/fesa_application.cpp`
- `/tests/integration/analysis/linear_static_analysis_test.cpp`
- `/tests/integration/app/fesa_application_test.cpp`
- `/src/fesa/CMakeLists.txt`, `/tests/CMakeLists.txt`
- `/phases/cpp-object-oriented-modular-refactoring/index.json`
- `/phases/cpp-object-oriented-modular-refactoring/step20.md`
## 작업
Requirement `R-ANALYSIS-001`을 구현한다.
1. `/tests/unit/analysis/analysis_test.cpp`와 integration cases를 먼저 추가한다.
`C-ANALYSIS-001` invokes `LinearStaticAnalysis` through `std::unique_ptr<Analysis>` and verifies
virtual destruction, Status propagation, factorize-before-load, exactly one factorization,
0x0 all-constrained solve, failure atomicity and writer-after-validation.
2. Missing minimal base or old protected-hook contract causes RED.
3. Create `/include/fesa/analysis/analysis.h` and move the base/request contract there. Keep
`/include/fesa/analysis/linear_static_analysis.h` and
`/src/fesa/analysis/linear_static_analysis.cpp` as the concrete procedure owner; register
`/tests/unit/analysis/analysis_test.cpp` in CMake.
4. Candidate interface:
```cpp
struct AnalysisRequest {
std::filesystem::path input_path;
std::filesystem::path output_path;
};
class Analysis {
public:
virtual ~Analysis() = default;
virtual Status Run(const AnalysisRequest& request) = 0;
};
class LinearStaticAnalysis final : public Analysis {
public:
LinearStaticAnalysis(const ParallelFor& parallel_for,
LinearSolver& linear_solver,
ResultsWriter& results_writer);
Status Run(const AnalysisRequest& request) override;
private:
Status InitializeCandidate(const AnalysisRequest& request);
Status BuildAnalysisModel();
Status BuildDofMapAndSparsePattern();
Status AssembleAndPartitionStiffness();
Status FactorizeFreeSystem();
Status AssembleLoadsAndEffectiveRhs();
Status SubstituteAndReconstruct();
Status RecoverAndWrite();
};
```
5. The request keeps the existing input/output path contract and the concrete constructor keeps
existing backend dependency injection. The base class exposes only
destructor and `Run()`. Do not place linear-static lifecycle hooks in the base.
6. FesaApplication chooses the current linear-static concrete based on the already validated single
`*STATIC` procedure; it does not accumulate future-procedure conditionals.
7. Remove obsolete duplicated DOF-order validation wrappers after DofManager ownership is proven.
## Acceptance Criteria
```powershell
cmake --build .harness/build --config Debug --target fesa_unit_tests fesa_integration_tests
ctest --test-dir .harness/build -C Debug `
-R "Analysis$|LinearStaticCli|Mitc4ShellCli|FesaApplication" --output-on-failure
& "C:/Program Files/LLVM/bin/clang-format.exe" --dry-run --Werror `
include/fesa/analysis/analysis.h `
include/fesa/analysis/linear_static_analysis.h `
src/fesa/analysis/linear_static_analysis.cpp `
tests/unit/analysis/analysis_test.cpp `
tests/integration/analysis/linear_static_analysis_test.cpp
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure
```
## 검증 및 상태 갱신
- RED base/lifecycle failure, focused order/count/atomicity and full CTest를 summary에 기록한다.
- Approved lifecycle or output timing regression is `error`.
- 성공 시 현재 Step만 `completed`로 갱신한다.
- timestamp, retry, commit, advancement는 Executor 소유다.
## 금지사항
- Dynamic/eigen/spectrum/random analysis behavior or state를 추가하지 마라.
- Future procedure hooks를 Analysis base에 추가하지 마라.
- Factorization/load order를 변경하지 마라.
- 직접 commit하거나 hook script를 수동 실행하지 마라.
@@ -0,0 +1,95 @@
# Step 21: Domain Mapper Modules
## 담당 역할과 필수 스킬
- 담당 역할: `implementation-agent`
- 필수 스킬: `harness`, `fesa-cpp-msvc-tdd`
- 이 Step만 `RED -> observed failure -> minimal GREEN -> focused/full VERIFY`로 수행한다.
## 읽어야 할 파일
- `/AGENTS.md`
- `/docs/CODINGSTYLE.md`
- `/docs/ARCHITECTURE.md`
- `/docs/ADR.md`
- `/docs/linear-static-3d-euler-beam/io.md`
- `/docs/linear-static-mitc4-shell/io.md`
- `/docs/cpp-object-oriented-modular-refactoring/implementation-plan.md`
- Step 11 SourceTargetResolver
- Step 1214 semantic hierarchy/Domain files
- Step 1819 Load and BoundaryCondition files
- `/include/fesa/io/abaqus/domain_mapper.h`
- `/src/fesa/io/abaqus/domain_mapper.cpp`
- `/tests/unit/io/abaqus/domain_mapper_test.cpp`
- `/src/fesa/CMakeLists.txt`, `/tests/CMakeLists.txt`
- `/phases/cpp-object-oriented-modular-refactoring/index.json`
- `/phases/cpp-object-oriented-modular-refactoring/step21.md`
## 작업
Requirement `R-MODULE-001`의 mapper split을 구현한다.
1. `/tests/unit/io/abaqus/domain_mapping_components_test.cpp`를 먼저 추가한다.
`C-MODULE-001` exercises component seams with valid and invalid syntax records and verifies
topology, material/property, step/load/BC candidate content plus exact stable diagnostic order.
2. Missing private component headers causes RED compile failure.
3. Keep public facade
`Result<Domain> AbaqusDomainMapper::Map(const ParsedInput& input) const` in
`domain_mapper.h`. Candidate private modules under `/src/fesa/io/abaqus/`:
```text
domain_mapping_context.h shared candidate state, source locations and diagnostics
topology_mapper.h/.cpp nodes, elements, sets, identity instances
material_property_mapper.h/.cpp current isotropic material and beam/shell section assignments
step_definition_mapper.h/.cpp one STATIC step, concentrated loads, prescribed displacement
domain_builder.h/.cpp final cross-reference validation and atomic Domain construction
```
4. Private methods consume syntax/semantic candidate references and return `Status`; no component
commits to public Domain before final validation.
5. Preserve allowlist warnings, B31 rejection, S4/S4R common FESA-MITC4 mapping, set namespace,
source identity, declaration order and every existing diagnostic code/message/source location.
6. Reduce `domain_mapper.cpp` to orchestration. Do not add a registry or public parser plugin API.
## Acceptance Criteria
```powershell
cmake --build .harness/build --config Debug --target fesa_unit_tests
ctest --test-dir .harness/build -C Debug `
-R "InpDomainMapping|DomainMappingComponents|SourceTargetResolver" --output-on-failure
$componentFiles = @(
"src/fesa/io/abaqus/domain_mapping_context.h",
"src/fesa/io/abaqus/topology_mapper.cpp",
"src/fesa/io/abaqus/material_property_mapper.cpp",
"src/fesa/io/abaqus/step_definition_mapper.cpp",
"src/fesa/io/abaqus/domain_builder.cpp"
)
foreach ($componentFile in $componentFiles) {
if (-not (Test-Path -LiteralPath $componentFile -PathType Leaf)) {
throw "Missing mapper component: $componentFile"
}
}
rg -n "TopologyMapper|MaterialPropertyMapper|StepDefinitionMapper|DomainBuilder" `
src/fesa/io/abaqus/domain_mapper.cpp
& "C:/Program Files/LLVM/bin/clang-format.exe" --dry-run --Werror `
(rg --files src/fesa/io/abaqus -g "*.h" -g "*.cpp") `
tests/unit/io/abaqus/domain_mapper_test.cpp `
tests/unit/io/abaqus/domain_mapping_components_test.cpp
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure
```
## 검증 및 상태 갱신
- RED missing components, component/facade diagnostics, facade wiring and full CTest를 summary에 기록한다.
- Diagnostic/order/semantic mapping regression is `error`.
- 성공 시 현재 Step만 `completed`로 갱신한다.
- timestamp, retry, commit, advancement는 Executor 소유다.
## 금지사항
- Abaqus keyword subset or unsupported behavior를 넓히지 마라.
- Failed candidate를 partial Domain에 commit하지 마라.
- Reference input을 mapper refactor에 맞춰 변경하지 마라.
- 직접 commit하거나 hook script를 수동 실행하지 마라.
@@ -0,0 +1,94 @@
# Step 22: Result Recovery Modules
## 담당 역할과 필수 스킬
- 담당 역할: `implementation-agent`
- 필수 스킬: `harness`, `fesa-cpp-msvc-tdd`
- 이 Step만 `RED -> observed failure -> minimal GREEN -> focused/full VERIFY`로 수행한다.
## 읽어야 할 파일
- `/AGENTS.md`
- `/docs/CODINGSTYLE.md`
- `/docs/ARCHITECTURE.md`
- `/docs/ADR.md`
- `/docs/linear-static-3d-euler-beam/formulation.md`
- `/docs/linear-static-mitc4-shell/formulation.md`
- `/docs/linear-static-3d-euler-beam/io.md`
- `/docs/linear-static-mitc4-shell/io.md`
- `/docs/cpp-object-oriented-modular-refactoring/implementation-plan.md`
- Step 17 generic ResultRecovery files
- `/include/fesa/results/result_records.h`
- `/include/fesa/analysis/analysis_state.h`
- `/src/fesa/results/result_recovery.cpp`
- `/tests/unit/results/result_recovery_test.cpp`
- `/src/fesa/CMakeLists.txt`, `/tests/CMakeLists.txt`
- `/phases/cpp-object-oriented-modular-refactoring/index.json`
- `/phases/cpp-object-oriented-modular-refactoring/step22.md`
## 작업
Requirement `R-MODULE-001`의 recovery split을 구현한다.
1. `/tests/unit/results/result_recovery_components_test.cpp`를 먼저 추가한다.
`C-MODULE-002` directly tests candidate creation/validation for global equilibrium, beam rows,
shell rows and all-or-nothing commit, including a later-invalid bundle rollback.
2. Missing component headers/symbols provides RED.
3. Keep `ResultRecovery` as public facade. Candidate private modules:
```text
recovery_candidate.h/.cpp owns all mutable candidate rows/evidence before commit
global_equilibrium_recovery.h/.cpp computes K*d-F, reactions, free residual and global moments
beam_result_recovery.h/.cpp validates/orders distinct beam result identities
shell_result_recovery.h/.cpp validates/orders physical shell rows and energy
analysis_state_commit.h/.cpp validates complete candidate and atomically updates state
```
4. Private functions return `Status`/`Result<T>` and do not mutate `AnalysisState` until the final
commit module succeeds.
5. Preserve exact B33 endpoint/section/Gauss/stress distinctions, MITC4 GP/stress ordering,
drilling exclusion, equilibrium scale rules and global origin.
6. Reduce `result_recovery.cpp` to facade orchestration without changing public behavior.
## Acceptance Criteria
```powershell
cmake --build .harness/build --config Debug --target fesa_unit_tests
ctest --test-dir .harness/build -C Debug `
-R "ResultRecovery|ResultRecoveryComponents|AnalysisState" --output-on-failure
$componentFiles = @(
"src/fesa/results/recovery_candidate.cpp",
"src/fesa/results/global_equilibrium_recovery.cpp",
"src/fesa/results/beam_result_recovery.cpp",
"src/fesa/results/shell_result_recovery.cpp",
"src/fesa/results/analysis_state_commit.cpp"
)
foreach ($componentFile in $componentFiles) {
if (-not (Test-Path -LiteralPath $componentFile -PathType Leaf)) {
throw "Missing recovery component: $componentFile"
}
}
rg -n "GlobalEquilibriumRecovery|BeamResultRecovery|ShellResultRecovery|Commit" `
src/fesa/results/result_recovery.cpp
& "C:/Program Files/LLVM/bin/clang-format.exe" --dry-run --Werror `
(rg --files src/fesa/results -g "*.h" -g "*.cpp") `
tests/unit/results/result_recovery_test.cpp `
tests/unit/results/result_recovery_components_test.cpp
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure
```
## 검증 및 상태 갱신
- RED missing components, focused sign/order/rollback, facade wiring and full CTest를 summary에 기록한다.
- Any identity/sign/atomicity regression is `error`.
- 성공 시 현재 Step만 `completed`로 갱신한다.
- timestamp, retry, commit, advancement는 Executor 소유다.
## 금지사항
- Result rows를 station mismatch 평균으로 합치지 마라.
- Failed candidate에서 partial AnalysisState를 commit하지 마라.
- HDF5 concerns를 recovery components에 넣지 마라.
- 직접 commit하거나 hook script를 수동 실행하지 마라.
@@ -0,0 +1,98 @@
# Step 23: HDF5 Writer Modules
## 담당 역할과 필수 스킬
- 담당 역할: `implementation-agent`
- 필수 스킬: `harness`, `fesa-cpp-msvc-tdd`
- 이 Step만 `RED -> observed failure -> minimal GREEN -> focused/full VERIFY`로 수행한다.
## 읽어야 할 파일
- `/AGENTS.md`
- `/docs/CODINGSTYLE.md`
- `/docs/ARCHITECTURE.md`
- `/docs/ADR.md`
- `/docs/linear-static-3d-euler-beam/io.md`
- `/docs/linear-static-mitc4-shell/io.md`
- `/docs/cpp-object-oriented-modular-refactoring/implementation-plan.md`
- Step 22 recovery candidate/result records
- `/include/fesa/io/hdf5/hdf5_results_writer.h`
- `/src/fesa/io/hdf5/hdf5_results_writer.cpp`
- `/include/fesa/results/results_writer.h`
- `/tests/unit/io/hdf5/hdf5_results_writer_test.cpp`
- `/src/fesa/CMakeLists.txt`, `/tests/CMakeLists.txt`
- `/phases/cpp-object-oriented-modular-refactoring/index.json`
- `/phases/cpp-object-oriented-modular-refactoring/step23.md`
## 작업
Requirement `R-MODULE-001`의 HDF5 split을 구현한다.
1. `/tests/unit/io/hdf5/hdf5_writer_components_test.cpp`를 먼저 추가한다.
`C-MODULE-003` tests backend-neutral dataset plans, finite inventory validation, self-check
failure and atomic final-file preservation through private component seams.
2. Missing component headers/symbols provides RED.
3. Keep `Hdf5ResultsWriter` as the only public facade and keep all HDF5 ids/types private.
Candidate modules:
```text
hdf5_raii.h move-only private HDF5 handle wrappers
hdf5_primitives.h/.cpp scalar/string/array/group/attribute operations
hdf5_model_writer.h/.cpp exact model/source identity datasets
hdf5_result_writer.h/.cpp exact mandatory beam/shell/global result datasets
hdf5_self_check.h/.cpp reopen, shape, attribute and finite inventory checks
hdf5_atomic_file.h/.cpp candidate path, preservation and final replacement
```
4. Testable backend-neutral plan records may be private to `src/fesa/io/hdf5`; tests may receive a
PRIVATE include directory. Do not expose `hid_t`, HDF5 headers or storage handles in
`/include/fesa/`.
5. Preserve every schema-v0 path, shape, attribute, units, row order, mandatory-output behavior,
warning dataset, reopen self-check and existing-final preservation.
6. Reduce `hdf5_results_writer.cpp` to facade orchestration.
## Acceptance Criteria
```powershell
cmake --build .harness/build --config Debug --target fesa_unit_tests
ctest --test-dir .harness/build -C Debug `
-R "Hdf5ResultsWriter|Hdf5WriterComponents|ResultsWriter" --output-on-failure
$componentFiles = @(
"src/fesa/io/hdf5/hdf5_raii.h",
"src/fesa/io/hdf5/hdf5_primitives.cpp",
"src/fesa/io/hdf5/hdf5_model_writer.cpp",
"src/fesa/io/hdf5/hdf5_result_writer.cpp",
"src/fesa/io/hdf5/hdf5_self_check.cpp",
"src/fesa/io/hdf5/hdf5_atomic_file.cpp"
)
foreach ($componentFile in $componentFiles) {
if (-not (Test-Path -LiteralPath $componentFile -PathType Leaf)) {
throw "Missing HDF5 component: $componentFile"
}
}
rg -n "WriteModel|WriteResults|SelfCheck|Atomic" `
src/fesa/io/hdf5/hdf5_results_writer.cpp
$vendorLeaks = @(rg -n "hid_t|hdf5\.h|H5[A-Z]" include/fesa)
if ($vendorLeaks.Count -ne 0) { $vendorLeaks; throw "HDF5 type leaked into public headers" }
& "C:/Program Files/LLVM/bin/clang-format.exe" --dry-run --Werror `
(rg --files src/fesa/io/hdf5 -g "*.h" -g "*.cpp") `
tests/unit/io/hdf5/hdf5_results_writer_test.cpp `
tests/unit/io/hdf5/hdf5_writer_components_test.cpp
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure
```
## 검증 및 상태 갱신
- RED missing components, schema/atomicity focused suite, facade/vendor scans and full CTest를 summary에 기록한다.
- Schema, required output or preservation regression is `error`; never edit I/O docs to pass.
- 성공 시 현재 Step만 `completed`로 갱신한다.
- timestamp, retry, commit, advancement는 Executor 소유다.
## 금지사항
- HDF5 schema version, dataset paths/shapes/attributes를 변경하지 마라.
- HDF5 types/lifetime을 public solver core에 노출하지 마라.
- Invalid candidate로 existing final file을 replace하지 마라.
- 직접 commit하거나 hook script를 수동 실행하지 마라.
@@ -0,0 +1,163 @@
# Step 24: Final Quality and Reference Gate
## 담당 역할과 필수 스킬
- 담당 역할: `implementation-agent`
- 필수 스킬: `harness`, `fesa-cpp-msvc-tdd`, `superpowers:verification-before-completion`
- This is the final Implementation-owned verification Step. Execute
`ARTIFACT CHECK -> COMPARE -> CLASSIFY -> REPORT` in that literal order.
## 읽어야 할 파일
- `/.agents/skills/harness/SKILL.md`
- `/.codex/skills/fesa-cpp-msvc-tdd/SKILL.md`
- `/AGENTS.md`
- `/docs/CODINGSTYLE.md`
- `/docs/ARCHITECTURE.md`
- `/docs/ADR.md`
- `/docs/cpp-object-oriented-modular-refactoring/implementation-plan.md`
- `/docs/linear-static-3d-euler-beam/requirements.md`
- `/docs/linear-static-3d-euler-beam/reference-model.md`
- `/docs/linear-static-3d-euler-beam/io.md`
- `/docs/linear-static-mitc4-shell/requirements.md`
- `/docs/linear-static-mitc4-shell/reference-model.md`
- `/docs/linear-static-mitc4-shell/io.md`
- `/tests/reference/b33_reference_comparison_test.cpp`
- `/tests/reference/mitc4_reference_cases_test.cpp`
- all Step 023 summaries and changed files
- `/phases/cpp-object-oriented-modular-refactoring/index.json`
- `/phases/cpp-object-oriented-modular-refactoring/step24.md`
## 작업
Requirements `R-PRESERVE-001`, `R-STYLE-001`, `R-DOC-001`, `R-SCOPE-001` and every
traceability row를 최종 검증한다. No production behavior is added in this Step.
1. Review all prior diffs against the approved design. Remove only orphaned compatibility includes,
declarations or helpers created by this phase; do not clean unrelated pre-existing code.
2. Verify every production/test header under `include`, `src`, `tests` uses `.h`; every production
public/protected API follows PascalCase and production Doxygen policy; tests have no imposed
Doxygen boilerplate.
3. Run clang-format on every tracked C++ file in dry-run error mode and the selected clang-tidy
C++17 public-header check. Do not run Doxygen; generation is deferred by user decision.
4. Fresh configure and full MSVC x64 Debug `/W4 /WX` build/CTest.
5. ARTIFACT CHECK before comparison:
- Assert exact B33 input and three CSV files exist under `/reference/cantilever beam/`.
- Assert exact MITC4 S4 input and displacement CSV exist under `/reference/shell/`.
- Snapshot/diff reference tree against baseline commit `1e5758f`.
6. COMPARE by running only the approved B33 and MITC4 S4 reference suites. Confirm generated:
- `.harness/build/reference/cantilever-beam-b33/results.h5`
- `.harness/build/reference/mitc4-shell-s4-comparison/results.h5`
7. CLASSIFY missing/extra/duplicate/nonfinite/tolerance failure before reporting. B33 retains its
existing component-scale policy. MITC4 U1/U2/U3 use fixed `1.0e-5`; UR1/UR2/UR3 remain warning-only.
8. REPORT by creating/updating:
- `/docs/cpp-object-oriented-modular-refactoring/implementation-report.md`
- `/docs/cpp-object-oriented-modular-refactoring/build-test.md`
- `/docs/cpp-object-oriented-modular-refactoring/reference-comparison.md`
9. `implementation-report.md` records each Step RED/GREEN/VERIFY command and result summary.
10. `build-test.md` records metadata with `owner_agent: implementation-agent`, environment,
command/exit code/duration/output tail, test inventory, classification, no-change assertion,
handoff and open issues.
11. `reference-comparison.md` records exact artifact inventory, generated HDF5 paths, HDF5-to-CSV
identity/component projection, row prechecks, approved tolerances, per-row decisions and only
contract-applicable metrics, classification and no-change assertion.
## Acceptance Criteria
Style and policy:
```powershell
uv run --with pytest python -m pytest -v -rs
& "C:/Program Files/LLVM/bin/clang-format.exe" --version
& "C:/Program Files/LLVM/bin/clang-tidy.exe" --version
& "C:/Program Files/LLVM/bin/clang-tidy.exe" --verify-config
$cppFiles = @(rg --files include src tests -g "*.h" -g "*.cpp")
& "C:/Program Files/LLVM/bin/clang-format.exe" --dry-run --Werror $cppFiles
$publicHeaders = @(rg --files include/fesa -g "*.h")
foreach ($publicHeader in $publicHeaders) {
& "C:/Program Files/LLVM/bin/clang-tidy.exe" --config-file=.clang-tidy `
$publicHeader -- -x c++ -std=c++17 -Iinclude
if ($LASTEXITCODE -ne 0) {
throw "clang-tidy failed for $publicHeader"
}
}
$legacyHeaders = @(rg --files include src tests -g "*.hpp")
if ($legacyHeaders.Count -ne 0) {
$legacyHeaders
throw "Legacy .hpp headers remain"
}
```
Fresh MSVC build and full tests:
```powershell
$requiredBuildPaths = @(
"C:/git/googletest",
"C:/Program Files (x86)/Intel/oneAPI/mkl/2026.1/lib/cmake/mkl",
"C:/Program Files (x86)/Intel/oneAPI/tbb/2023.1/lib/cmake/tbb",
"C:/Program Files/HDF_Group/HDF5/2.1.1/cmake"
)
foreach ($requiredBuildPath in $requiredBuildPaths) {
if (-not (Test-Path -LiteralPath $requiredBuildPath)) {
throw "Missing $requiredBuildPath"
}
}
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"
cmake --build .harness/build --config Debug --target fesa_tests
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure
```
ARTIFACT CHECK, COMPARE and post-check:
```powershell
$declaredArtifacts = @(
"reference/cantilever beam/cantilever beam.inp",
"reference/cantilever beam/cantilever beam displacements.csv",
"reference/cantilever beam/cantilever beam elemental forces.csv",
"reference/cantilever beam/cantilever beam reactions.csv",
"reference/shell/shell.inp",
"reference/shell/shell displacements.csv"
)
foreach ($declaredArtifact in $declaredArtifacts) {
if (-not (Test-Path -LiteralPath $declaredArtifact -PathType Leaf)) {
throw "Missing declared artifact: $declaredArtifact"
}
}
git diff --exit-code 1e5758f -- reference
ctest --test-dir .harness/build -C Debug `
-R "B33ReferenceComparison|Mitc4S4Reference" --output-on-failure
$generatedResults = @(
".harness/build/reference/cantilever-beam-b33/results.h5",
".harness/build/reference/mitc4-shell-s4-comparison/results.h5"
)
foreach ($generatedResult in $generatedResults) {
if (-not (Test-Path -LiteralPath $generatedResult -PathType Leaf)) {
throw "Missing generated solver result: $generatedResult"
}
}
git diff --exit-code 1e5758f -- reference
git diff --check
```
## 검증 및 상태 갱신
- Do not mark complete until every command and report section has observed evidence.
- Success summary names style gate, full discovered test count, both generated results, blocking
comparison verdicts, reference no-change assertion and report paths.
- Implementation-owned compile/test/comparison failure is `error` with classification and exact
failed command. Missing tool or declared artifact is `blocked` with exact path.
- On success update only current Step to `completed`; final timestamps, commit and top-level phase
completion are Executor-owned.
## 금지사항
- Doxygen executable을 실행하거나 generated docs를 commit하지 마라. 이유: 사용자 결정으로 연기됐다.
- Reference artifact, input, CSV, tolerance or comparator contract를 변경하지 마라.
- Passing comparison만으로 release or physics readiness를 승인하지 마라.
- Failure를 숨기기 위해 clamp, missing-row ignore, average or tolerance relaxation을 추가하지 마라.
- 직접 commit하거나 hook script를 수동 실행하지 마라.
@@ -0,0 +1,99 @@
# Step 3: Foundation Google Style
## 담당 역할과 필수 스킬
- 담당 역할: `implementation-agent`
- 필수 스킬: `harness`, `fesa-cpp-msvc-tdd`
- 이 Step만 `RED -> observed failure -> minimal GREEN -> focused/full VERIFY`로 수행한다.
## 읽어야 할 파일
- `/AGENTS.md`
- `/docs/CODINGSTYLE.md`
- `/docs/ARCHITECTURE.md`
- `/docs/ADR.md`
- `/docs/cpp-object-oriented-modular-refactoring/implementation-plan.md`
- `/include/fesa/core/diagnostic.hpp`
- `/include/fesa/core/source_identity.hpp`
- `/include/fesa/core/status.hpp`
- `/include/fesa/math/vector.hpp`
- `/include/fesa/math/matrix.hpp`
- `/include/fesa/math/sparse_matrix.hpp`
- `/include/fesa/solvers/linear/linear_solver.hpp`
- `/include/fesa/solvers/linear/mkl_pardiso_solver.hpp`
- `/include/fesa/build_info.hpp`
- `/src/fesa/core/diagnostic.cpp`, `/src/fesa/core/status.cpp`
- `/src/fesa/math/vector.cpp`, `/src/fesa/math/matrix.cpp`,
`/src/fesa/math/sparse_matrix.cpp`
- `/src/fesa/solvers/linear/mkl_pardiso_solver.cpp`, `/src/fesa/build_info.cpp`
- `/tests/unit/core/diagnostic_test.cpp`, `/tests/unit/core/source_identity_test.cpp`,
`/tests/unit/core/status_test.cpp`
- `/tests/unit/math/vector_test.cpp`, `/tests/unit/math/matrix_test.cpp`,
`/tests/unit/math/sparse_matrix_test.cpp`
- `/tests/unit/solvers/linear/linear_solver_test.cpp`,
`/tests/unit/solvers/linear/mkl_pardiso_solver_test.cpp`
- `/tests/unit/build_info_test.cpp`
- `/src/fesa/CMakeLists.txt`, `/tests/CMakeLists.txt`
- `/phases/cpp-object-oriented-modular-refactoring/index.json`
- `/phases/cpp-object-oriented-modular-refactoring/step3.md`
## 작업
Requirement `R-STYLE-001`의 foundation slice와 `R-DOC-001`을 구현한다. 동작 또는
수치식은 변경하지 않는다.
1. Focused tests의 include를 `.h`로, 모든 function/accessor call을 PascalCase로 먼저
변경하고 missing header/member compile failure를 RED로 기록한다.
2. 다음 production headers를 같은 basename의 `.h`로 이동하고 full-path include guard를
사용한다: core headers, `vector`, `matrix`, `sparse_matrix`, `linear_solver`,
`mkl_pardiso_solver`, `build_info`.
3. 이 slice가 소유하는 public/protected function과 production internal function 이름을
PascalCase로 바꾼다. Parameters/local variables는 snake_case, class members는 trailing
underscore, enum values/constants는 `kPascalCase`로 바꾼다.
4. Public/protected declarations에 `@brief`와 필요한 ownership/failure/backend contract를
Doxygen으로 기록한다. Tests에는 Doxygen를 추가하지 않는다.
5. 모든 repository consumer include/callsite를 기계적으로 갱신하되 다른 모듈의 함수
정의나 책임은 바꾸지 않는다.
6. Matrix/Vector 연산 순서, MKL calls, Status category, diagnostic text는 보존한다.
## Acceptance Criteria
RED 후 GREEN focused/full verification:
```powershell
cmake -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"
cmake --build .harness/build --config Debug --target fesa_unit_tests
ctest --test-dir .harness/build -C Debug `
-R "DenseMath|SparseAssembly|Status|Diagnostic|LinearSolver|MklPardiso|BuildInfo" `
--output-on-failure
$files = @(
(rg --files include/fesa/core include/fesa/math include/fesa/solvers/linear `
-g "*.h"),
"include/fesa/build_info.h",
(rg --files src/fesa/core src/fesa/math src/fesa/solvers/linear -g "*.cpp"),
"src/fesa/build_info.cpp",
(rg --files tests/unit/core tests/unit/math tests/unit/solvers/linear -g "*.cpp"),
"tests/unit/build_info_test.cpp"
)
& "C:/Program Files/LLVM/bin/clang-format.exe" --dry-run --Werror $files
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure
```
## 검증 및 상태 갱신
- RED compile error, focused GREEN, formatting, full CTest를 summary에 남긴다.
- 성공 시 현재 Step만 `completed`; 반복 compile failure는 `error`로 기록한다.
- timestamp, retry, commit, advancement는 Executor 소유다.
## 금지사항
- `Vector3`나 BLAS adapter를 추가하지 마라. 이유: Step 7과 10의 semantic work다.
- 수치 expression/reduction 순서를 바꾸지 마라. 이유: style-only review unit이다.
- Test에 Doxygen를 추가하지 마라. 이유: 승인 문서화 범위는 production뿐이다.
- 직접 commit하거나 hook script를 수동 실행하지 마라.
@@ -0,0 +1,80 @@
# Step 4: Model and Element Google Style
## 담당 역할과 필수 스킬
- 담당 역할: `implementation-agent`
- 필수 스킬: `harness`, `fesa-cpp-msvc-tdd`
- 이 Step만 `RED -> observed failure -> minimal GREEN -> focused/full VERIFY`로 수행한다.
## 읽어야 할 파일
- `/AGENTS.md`
- `/docs/CODINGSTYLE.md`
- `/docs/ARCHITECTURE.md`
- `/docs/ADR.md`
- `/docs/linear-static-3d-euler-beam/formulation.md`
- `/docs/linear-static-mitc4-shell/formulation.md`
- `/docs/cpp-object-oriented-modular-refactoring/implementation-plan.md`
- `/include/fesa/model/domain.hpp`, `/include/fesa/model/model_types.hpp`,
`/include/fesa/model/shell_geometry.hpp`
- `/src/fesa/model/domain.cpp`, `/src/fesa/model/shell_geometry.cpp`
- `/include/fesa/elements/euler_beam_3d.hpp`,
`/include/fesa/elements/mitc4_shell.hpp`
- `/src/fesa/elements/euler_beam_3d.cpp`, `/src/fesa/elements/mitc4_shell.cpp`
- `/tests/unit/model/domain_test.cpp`, `/tests/unit/model/model_types_test.cpp`,
`/tests/unit/model/shell_geometry_test.cpp`
- `/tests/unit/elements/euler_beam_3d_test.cpp`,
`/tests/unit/elements/mitc4_shell_test.cpp`
- Step 3에서 전환한 foundation `.h` headers와 callsites
- `/phases/cpp-object-oriented-modular-refactoring/index.json`
- `/phases/cpp-object-oriented-modular-refactoring/step4.md`
## 작업
Requirement `R-STYLE-001`의 model/element slice와 `R-DOC-001`을 구현한다.
1. Model/element tests를 `.h` include와 PascalCase calls로 먼저 바꿔 RED compile failure를
확인한다.
2. `analysis_model.hpp`는 아직 analysis slice이므로 건드리지 않는다. 다음 소유 범위만
`.h`와 header guard로 전환한다: `model/domain`, `model/model_types`,
`model/shell_geometry`, `elements/euler_beam_3d`, `elements/mitc4_shell`.
3. Production function/accessor, enum, constant, member naming을 CODINGSTYLE에 맞추고
repository callsites를 갱신한다.
4. Production public/protected declarations와 비자명한 local-axis, director, stiffness,
recovery, sign/order helper에 Doxygen를 추가한다. Tests에는 추가하지 않는다.
5. B33/MITC4 formula, quadrature, physical/drilling separation, scale-aware validation,
result signs와 floating-point operation order를 그대로 유지한다.
## Acceptance Criteria
```powershell
cmake --build .harness/build --config Debug --target fesa_unit_tests
ctest --test-dir .harness/build -C Debug `
-R "DomainModel|Mitc4Geometry|EulerBeam3D|Mitc4Shell" --output-on-failure
$files = @(
(rg --files include/fesa/model include/fesa/elements -g "*.h"),
(rg --files src/fesa/model src/fesa/elements -g "*.cpp"),
(rg --files tests/unit/model tests/unit/elements -g "*.cpp")
)
& "C:/Program Files/LLVM/bin/clang-format.exe" --dry-run --Werror $files
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure
```
RED에서는 updated test callsite가 old production API와 불일치해야 한다. GREEN에서는
focused suites와 전체 CTest가 통과해야 한다.
## 검증 및 상태 갱신
- RED/Green commands와 test inventory를 현재 Step summary에 기록한다.
- 성공 시 현재 Step만 `completed`로 갱신한다.
- upstream formulation과 충돌하면 구현하지 말고 `blocked`로 기록한다.
- timestamp, retry, commit, advancement는 Executor 소유다.
## 금지사항
- 추상 element/material/property hierarchy를 추가하지 마라. 이유: Step 12–14 소유다.
- duplicate vector helper를 제거하지 마라. 이유: Step 79에서 test-first로 수행한다.
- formulation 또는 reference tolerance를 수정하지 마라.
- 직접 commit하거나 hook script를 수동 실행하지 마라.
@@ -0,0 +1,97 @@
# Step 5: Solver Workflow Google Style
## 담당 역할과 필수 스킬
- 담당 역할: `implementation-agent`
- 필수 스킬: `harness`, `fesa-cpp-msvc-tdd`
- 이 Step만 `RED -> observed failure -> minimal GREEN -> focused/full VERIFY`로 수행한다.
## 읽어야 할 파일
- `/AGENTS.md`
- `/docs/CODINGSTYLE.md`
- `/docs/ARCHITECTURE.md`
- `/docs/ADR.md`
- `/docs/cpp-object-oriented-modular-refactoring/implementation-plan.md`
- `/include/fesa/analysis/analysis_model.hpp`,
`/include/fesa/analysis/analysis_state.hpp`,
`/include/fesa/analysis/linear_static_analysis.hpp`
- `/src/fesa/analysis/analysis_model.cpp`, `/src/fesa/analysis/analysis_state.cpp`,
`/src/fesa/analysis/linear_static_analysis.cpp`
- `/include/fesa/assembly/load_assembler.hpp`, `/include/fesa/assembly/parallel_for.hpp`,
`/include/fesa/assembly/sparse_assembler.hpp`
- `/src/fesa/assembly/load_assembler.cpp`, `/src/fesa/assembly/parallel_for.cpp`,
`/src/fesa/assembly/sparse_assembler.cpp`
- `/include/fesa/constraints/essential_constraints.hpp`,
`/src/fesa/constraints/essential_constraints.cpp`
- `/include/fesa/fem/dof_manager.hpp`, `/src/fesa/fem/dof_manager.cpp`
- `/include/fesa/results/result_records.hpp`,
`/include/fesa/results/result_recovery.hpp`,
`/include/fesa/results/results_writer.hpp`
- `/src/fesa/results/result_recovery.cpp`
- `/tests/unit/analysis/analysis_model_test.cpp`,
`/tests/unit/analysis/analysis_state_test.cpp`
- `/tests/unit/assembly/load_assembler_test.cpp`,
`/tests/unit/assembly/parallel_for_test.cpp`,
`/tests/unit/assembly/sparse_assembler_test.cpp`
- `/tests/unit/constraints/essential_constraints_test.cpp`,
`/tests/unit/fem/dof_manager_test.cpp`
- `/tests/unit/results/result_records_test.cpp`,
`/tests/unit/results/result_recovery_test.cpp`,
`/tests/unit/results/results_writer_test.cpp`
- `/tests/integration/analysis/linear_static_analysis_test.cpp`
- Step 34에서 생성한 `.h` foundation/model/element headers
- `/phases/cpp-object-oriented-modular-refactoring/index.json`
- `/phases/cpp-object-oriented-modular-refactoring/step5.md`
## 작업
Requirement `R-STYLE-001`의 solver workflow slice와 `R-DOC-001`을 구현한다.
1. Matching unit/integration tests를 `.h` include와 PascalCase calls로 먼저 바꿔 RED
compile failure를 기록한다.
2. Analysis, assembly, constraints, fem, results production headers를 `.h`와 full-path
include guards로 전환한다.
3. Function/accessor, enum, constants, members와 repository callsites를 CODINGSTYLE에
맞춘다. Type names와 diagnostic text는 의미를 바꾸지 않는다.
4. Production public/protected declarations와 ordering, partition, factorization,
deterministic reduction, candidate commit에 관한 internal helpers에 Doxygen를 작성한다.
5. 다음 approved order를 변경하지 않는다: stiffness/partition, Kff factorization,
load/effective RHS, substitute/reconstruct, recovery/write.
6. Full residual `K*d-F`, source-order accumulation, 0x0 Kff validity, atomic state commit을
그대로 유지한다.
## Acceptance Criteria
```powershell
cmake --build .harness/build --config Debug --target fesa_unit_tests fesa_integration_tests
ctest --test-dir .harness/build -C Debug `
-R "DofManager|LoadAssembly|SparseAssembly|EssentialConstraints|AnalysisState|ResultRecovery|LinearStaticCli|Mitc4ShellCli" `
--output-on-failure
$files = @(
(rg --files include/fesa/analysis include/fesa/assembly include/fesa/constraints `
include/fesa/fem include/fesa/results -g "*.h"),
(rg --files src/fesa/analysis src/fesa/assembly src/fesa/constraints `
src/fesa/fem src/fesa/results -g "*.cpp"),
(rg --files tests/unit/analysis tests/unit/assembly tests/unit/constraints `
tests/unit/fem tests/unit/results tests/integration/analysis -g "*.cpp")
)
& "C:/Program Files/LLVM/bin/clang-format.exe" --dry-run --Werror $files
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure
```
## 검증 및 상태 갱신
- RED compile failure, focused/full GREEN과 formatting 결과를 summary에 기록한다.
- 성공 시 현재 Step만 `completed`로 갱신한다.
- lifecycle or numeric regression이면 `error`로 기록하고 다른 Step으로 진행하지 않는다.
- timestamp, retry, commit, advancement는 Executor 소유다.
## 금지사항
- Analysis/Load/Boundary/Element 추상화를 추가하지 마라. 이유: Step 14–20 소유다.
- sparse ordering, factorization order, result signs를 바꾸지 마라.
- Test에 Doxygen를 추가하지 마라.
- 직접 commit하거나 hook script를 수동 실행하지 마라.
@@ -0,0 +1,90 @@
# Step 6: I/O and Application Google Style
## 담당 역할과 필수 스킬
- 담당 역할: `implementation-agent`
- 필수 스킬: `harness`, `fesa-cpp-msvc-tdd`
- 이 Step만 `RED -> observed failure -> minimal GREEN -> focused/full VERIFY`로 수행한다.
## 읽어야 할 파일
- `/AGENTS.md`
- `/docs/CODINGSTYLE.md`
- `/docs/ARCHITECTURE.md`
- `/docs/ADR.md`
- `/docs/linear-static-3d-euler-beam/io.md`
- `/docs/linear-static-mitc4-shell/io.md`
- `/docs/cpp-object-oriented-modular-refactoring/implementation-plan.md`
- `/include/fesa/io/abaqus/domain_mapper.hpp`,
`/include/fesa/io/abaqus/input_reader.hpp`,
`/include/fesa/io/abaqus/input_syntax.hpp`
- `/src/fesa/io/abaqus/domain_mapper.cpp`, `/src/fesa/io/abaqus/input_reader.cpp`
- `/include/fesa/io/hdf5/hdf5_results_writer.hpp`,
`/src/fesa/io/hdf5/hdf5_results_writer.cpp`
- `/include/fesa/app/fesa_application.hpp`, `/src/fesa/app/fesa_application.cpp`,
`/src/fesa/app/main.cpp`
- `/tests/unit/io/abaqus/domain_mapper_test.cpp`,
`/tests/unit/io/abaqus/input_reader_test.cpp`,
`/tests/unit/io/abaqus/input_syntax_test.cpp`
- `/tests/unit/io/hdf5/hdf5_results_writer_test.cpp`,
`/tests/integration/app/fesa_application_test.cpp`
- `/tests/reference/reference_comparison.hpp`,
`/tests/reference/mitc4_reference_comparison.hpp`
- `/tests/reference/reference_comparison.cpp`,
`/tests/reference/reference_comparison_test.cpp`,
`/tests/reference/b33_reference_comparison_test.cpp`,
`/tests/reference/mitc4_reference_comparison.cpp`,
`/tests/reference/mitc4_reference_comparison_test.cpp`,
`/tests/reference/mitc4_reference_cases_test.cpp`
- Step 35가 생성한 `.h` headers와 callsites
- `/phases/cpp-object-oriented-modular-refactoring/index.json`
- `/phases/cpp-object-oriented-modular-refactoring/step6.md`
## 작업
Requirement `R-STYLE-001`의 I/O/application slice와 `R-DOC-001`을 구현한다.
1. I/O, app, reference helper tests의 include와 calls를 먼저 전환해 RED compile failure를
기록한다.
2. Production I/O/application headers와 test-only reference helper headers를 `.h`
full-path guards로 전환한다.
3. Production 및 test C++ functions/accessors를 PascalCase로 전환하고 variables/members,
enums/constants를 CODINGSTYLE에 맞춘다.
4. Production parser/mapping/HDF5/application declarations와 atomic finalization,
source identity, backend lifetime에 관한 internal helper에 Doxygen를 추가한다.
5. Test files에는 Doxygen를 추가하지 않는다.
6. Abaqus keyword subset, diagnostics, HDF5 path/attributes/dataset order, atomic replacement,
comparator tolerance와 required/warning quantity를 변경하지 않는다.
## Acceptance Criteria
```powershell
cmake --build .harness/build --config Debug --target fesa_unit_tests `
fesa_integration_tests fesa_reference_tests
ctest --test-dir .harness/build -C Debug `
-R "InpSyntax|InpDomainMapping|Hdf5ResultsWriter|FesaApplication|ReferenceComparison|B33ReferenceComparison|Mitc4Reference|Mitc4S4Reference" `
--output-on-failure
$files = @(
(rg --files include/fesa/io include/fesa/app -g "*.h"),
(rg --files src/fesa/io src/fesa/app -g "*.cpp"),
(rg --files tests/unit/io tests/integration/app tests/reference -g "*.h" -g "*.cpp")
)
& "C:/Program Files/LLVM/bin/clang-format.exe" --dry-run --Werror $files
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure
```
## 검증 및 상태 갱신
- RED/Green evidence와 HDF5/reference focused inventory를 summary에 기록한다.
- 성공 시 현재 Step만 `completed`로 갱신한다.
- schema/reference regression이면 `error`로 기록하고 artifacts를 고치지 않는다.
- timestamp, retry, commit, advancement는 Executor 소유다.
## 금지사항
- Mapper/HDF5 writer를 아직 분할하지 마라. 이유: Step 21과 23 소유다.
- Reference CSV, `.inp`, tolerance 또는 comparator 의미를 변경하지 마라.
- Generated Doxygen를 만들지 마라.
- 직접 commit하거나 hook script를 수동 실행하지 마라.
@@ -0,0 +1,86 @@
# Step 7: Vector3 Value Type
## 담당 역할과 필수 스킬
- 담당 역할: `implementation-agent`
- 필수 스킬: `harness`, `fesa-cpp-msvc-tdd`
- 이 Step만 `RED -> observed failure -> minimal GREEN -> focused/full VERIFY`로 수행한다.
## 읽어야 할 파일
- `/AGENTS.md`
- `/docs/CODINGSTYLE.md`
- `/docs/ARCHITECTURE.md`
- `/docs/ADR.md`
- `/docs/cpp-object-oriented-modular-refactoring/implementation-plan.md`
- `/include/fesa/math/vector.h`
- `/src/fesa/math/vector.cpp`
- `/tests/unit/math/vector_test.cpp`
- `/src/fesa/CMakeLists.txt`, `/tests/CMakeLists.txt`
- `/phases/cpp-object-oriented-modular-refactoring/index.json`
- `/phases/cpp-object-oriented-modular-refactoring/step7.md`
## 작업
Requirement `R-DUP-001`의 reusable value type만 구현한다. Existing consumers는 아직
migrate하지 않는다.
1. `/tests/unit/math/vector3_test.cpp`를 먼저 만들고 `C-VEC3-001`을 작성한다.
2. Test는 component access, exact add/subtract/scalar operations, Dot, Cross orientation,
Norm, finite/nonfinite, zero/nonfinite normalization rejection을 검증한다.
3. Test가 missing `fesa/math/vector3.h`로 compile failure가 나는 RED를 기록한다.
4. Candidate interface는 다음 의미를 제공한다.
```cpp
class Vector3 {
public:
constexpr Vector3() noexcept;
constexpr Vector3(double x, double y, double z) noexcept;
constexpr double X() const noexcept;
constexpr double Y() const noexcept;
constexpr double Z() const noexcept;
constexpr double operator[](std::size_t index) const noexcept;
constexpr Vector3 operator+(const Vector3& rhs) const noexcept;
constexpr Vector3 operator-(const Vector3& rhs) const noexcept;
constexpr Vector3 operator*(double scalar) const noexcept;
double Dot(const Vector3& rhs) const noexcept;
Vector3 Cross(const Vector3& rhs) const noexcept;
double Norm() const noexcept;
std::optional<Vector3> Normalized() const noexcept;
bool IsFinite() const noexcept;
};
```
5. `Normalized()`는 arbitrary tolerance, clamp, diagnostic을 소유하지 않는다. Exact zero
또는 nonfinite norm만 empty result로 거부하고 scale-aware geometry rejection은 caller에
남긴다.
6. Trivial implementation은 header-only로 둘 수 있다. 별도 `.cpp`를 만들면 CMake에
등록하고 두 경우 모두 production Doxygen를 작성한다.
## Acceptance Criteria
```powershell
cmake --build .harness/build --config Debug --target fesa_unit_tests
ctest --test-dir .harness/build -C Debug -R "Vector3" --output-on-failure
& "C:/Program Files/LLVM/bin/clang-format.exe" --dry-run --Werror `
include/fesa/math/vector3.h tests/unit/math/vector3_test.cpp
& "C:/Program Files/LLVM/bin/clang-tidy.exe" --config-file=.clang-tidy `
include/fesa/math/vector3.h -- -x c++ -std=c++17 -Iinclude
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure
```
## 검증 및 상태 갱신
- Missing header RED, arithmetic GREEN, tidy/format/full CTest를 summary에 기록한다.
- 성공 시 현재 Step만 `completed`로 갱신한다.
- normalization policy가 승인 설계와 충돌하면 `blocked`로 기록한다.
- timestamp, retry, commit, advancement는 Executor 소유다.
## 금지사항
- Dynamic `Vector` storage/API를 Vector3에 합치지 마라. 이유: 서로 다른 ownership/size 계약이다.
- Tolerance 또는 FESA diagnostic을 Vector3에 넣지 마라.
- Beam/shell/results/I/O consumers를 수정하지 마라. 이유: Step 8–9 소유다.
- 직접 commit하거나 hook script를 수동 실행하지 마라.
@@ -0,0 +1,72 @@
# Step 8: Element and Geometry Vector3 Migration
## 담당 역할과 필수 스킬
- 담당 역할: `implementation-agent`
- 필수 스킬: `harness`, `fesa-cpp-msvc-tdd`
- 이 Step만 `RED -> observed failure -> minimal GREEN -> focused/full VERIFY`로 수행한다.
## 읽어야 할 파일
- `/AGENTS.md`
- `/docs/CODINGSTYLE.md`
- `/docs/linear-static-3d-euler-beam/formulation.md`
- `/docs/linear-static-mitc4-shell/formulation.md`
- `/docs/cpp-object-oriented-modular-refactoring/implementation-plan.md`
- `/include/fesa/math/vector3.h`, `/tests/unit/math/vector3_test.cpp`
- `/include/fesa/elements/euler_beam_3d.h`, `/src/fesa/elements/euler_beam_3d.cpp`
- `/include/fesa/elements/mitc4_shell.h`, `/src/fesa/elements/mitc4_shell.cpp`
- `/include/fesa/model/shell_geometry.h`, `/src/fesa/model/shell_geometry.cpp`
- matching element/model unit tests
- `/phases/cpp-object-oriented-modular-refactoring/index.json`
- `/phases/cpp-object-oriented-modular-refactoring/step8.md`
## 작업
Requirement `R-DUP-001`의 element/model consumer migration을 구현한다.
1. Existing element/model tests에 `C-DUP-001` exact regression assertions를 먼저 추가한다.
Rotated axes, warped shell geometry, stiffness, recovery and patch cases가 migration 전
captured results와 exact equality를 유지하도록 한다.
2. New assertions가 현재 duplicated helper seam을 직접 대체할 수 없어 compile failure 또는
missing typed interface failure가 나는 RED를 기록한다.
3. Euler beam, MITC4, shell geometry에서 local `Add`, `Subtract`, `Scale`, `Dot`, `Cross`,
`Norm`, finite helper를 제거하고 `Vector3`를 사용한다.
4. Weighted and derivative sums may remain formulation-specific expressions, but their primitive
vector operations must use `Vector3` and their evaluation order must remain unchanged.
5. Caller가 기존 scale-aware geometry tolerance와 exact diagnostic category/message를 소유한다.
6. B33 transform, MITC4 director/tangent frame, Jacobian and drilling/physical separation을
변경하지 않는다.
## Acceptance Criteria
```powershell
cmake --build .harness/build --config Debug --target fesa_unit_tests
ctest --test-dir .harness/build -C Debug `
-R "Vector3|EulerBeam3D|Mitc4Shell|Mitc4Geometry" --output-on-failure
rg -n "(double|Vector3) (Dot|Cross|Norm|Add|Subtract|Scale)\(" `
src/fesa/elements src/fesa/model
& "C:/Program Files/LLVM/bin/clang-format.exe" --dry-run --Werror `
src/fesa/elements/euler_beam_3d.cpp src/fesa/elements/mitc4_shell.cpp `
src/fesa/model/shell_geometry.cpp
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure
```
The `rg` command must return no duplicate local primitive definition; member calls such as
`.Dot()` are allowed.
## 검증 및 상태 갱신
- RED seam failure, exact focused regressions, duplicate scan과 full CTest를 summary에 기록한다.
- 수치 결과가 달라지면 commonization을 억지로 진행하지 말고 `error`로 기록한다.
- 성공 시 현재 Step만 `completed`로 갱신한다.
- timestamp, retry, commit, advancement는 Executor 소유다.
## 금지사항
- Formulation-specific sign/weighted sum을 이름 유사성만으로 합치지 마라.
- Runtime performance optimization 또는 loop reordering을 하지 마라.
- ResultRecovery/mapper/HDF5를 수정하지 마라. 이유: Step 9 소유다.
- 직접 commit하거나 hook script를 수동 실행하지 마라.
@@ -0,0 +1,74 @@
# Step 9: Result and I/O Vector3 Migration
## 담당 역할과 필수 스킬
- 담당 역할: `implementation-agent`
- 필수 스킬: `harness`, `fesa-cpp-msvc-tdd`
- 이 Step만 `RED -> observed failure -> minimal GREEN -> focused/full VERIFY`로 수행한다.
## 읽어야 할 파일
- `/AGENTS.md`
- `/docs/CODINGSTYLE.md`
- `/docs/ARCHITECTURE.md`
- `/docs/linear-static-3d-euler-beam/io.md`
- `/docs/linear-static-mitc4-shell/io.md`
- `/docs/cpp-object-oriented-modular-refactoring/implementation-plan.md`
- `/include/fesa/math/vector3.h`
- Step 8에서 migration한 element/model files
- `/include/fesa/results/result_recovery.h`, `/src/fesa/results/result_recovery.cpp`
- `/include/fesa/io/abaqus/domain_mapper.h`, `/src/fesa/io/abaqus/domain_mapper.cpp`
- `/include/fesa/io/hdf5/hdf5_results_writer.h`,
`/src/fesa/io/hdf5/hdf5_results_writer.cpp`
- matching result/I/O tests
- `/phases/cpp-object-oriented-modular-refactoring/index.json`
- `/phases/cpp-object-oriented-modular-refactoring/step9.md`
## 작업
Requirement `R-DUP-001`의 remaining production consumers를 구현한다.
1. ResultRecovery, DomainMapper, Hdf5ResultsWriter tests에 `C-DUP-002` characterization을
먼저 추가한다: global moment origin, shell frame/director serialization, finite rejection,
stable row/dataset identity and atomic replacement.
2. Tests가 new shared `Vector3` seam을 참조하도록 해 old local helper state에서 RED를 확인한다.
3. 세 production files의 repeated fixed-size add/subtract/scale/dot/cross/norm/finite helpers를
`Vector3` calls로 바꾸고 helper definitions를 제거한다.
4. HDF5 storage remains three scalar components in the exact existing dataset/schema; `Vector3`
must not become an HDF5 public or compound datatype.
5. Result location/sign, global-origin moment balance, source identity, mapper diagnostics와
floating-point accumulation order를 유지한다.
## Acceptance Criteria
```powershell
cmake --build .harness/build --config Debug --target fesa_unit_tests
ctest --test-dir .harness/build -C Debug `
-R "ResultRecovery|InpDomainMapping|Hdf5ResultsWriter" --output-on-failure
rg -n "(double|Vector3) (Dot|Cross|Norm|Add|Subtract|Scale)\(" `
src/fesa/results src/fesa/io
& "C:/Program Files/LLVM/bin/clang-format.exe" --dry-run --Werror `
src/fesa/results/result_recovery.cpp `
src/fesa/io/abaqus/domain_mapper.cpp `
src/fesa/io/hdf5/hdf5_results_writer.cpp
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure
```
The duplicate scan must return no local primitive definitions. Existing HDF5 and reference
tests must pass without tolerance/schema edits.
## 검증 및 상태 갱신
- RED, focused suites, duplicate scan, full CTest를 summary에 기록한다.
- Schema, identity or numeric regression이면 `error`로 기록하고 artifacts를 수정하지 않는다.
- 성공 시 현재 Step만 `completed`로 갱신한다.
- timestamp, retry, commit, advancement는 Executor 소유다.
## 금지사항
- HDF5 schema 또는 stored component representation을 변경하지 마라.
- Result identity/location을 공통 Vector3 record로 합치지 마라.
- Mapper/recovery/writer file split을 수행하지 마라. 이유: Step 21–23 소유다.
- 직접 commit하거나 hook script를 수동 실행하지 마라.
+4
View File
@@ -8,6 +8,10 @@
"dir": "linear-static-mitc4-shell",
"status": "completed",
"completed_at": "2026-08-13T10:14:08+0900"
},
{
"dir": "cpp-object-oriented-modular-refactoring",
"status": "pending"
}
]
}