Files
FESADev/docs/cpp-object-oriented-modular-refactoring/implementation-plan.md
T
2026-08-16 02:49:35 +09:00

24 KiB

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:

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

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:

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:

$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:

$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.