# Linear Static MITC4 Shell Implementation Plan

> **For agentic implementation workers:** 이 문서는 사용자 승인 전 `draft`다. 승인 후
> Implementation Planning Agent가 같은 내용으로 Harness phase planning files만
> materialize한다. Implementation Agent는 승인된 phase의 pending Step을
> `docs/HARNESS.md`와 `docs/HARNESS_WORKFLOW.md`에 따라 하나씩 실행해야 하며,
> Harness hook/runner lifecycle을 우회해서는 안 된다.

## 1. Metadata

- feature_id: `linear-static-mitc4-shell`
- document_type: `implementation-plan`
- status: `ready-for-implementation`
- approval_state: `harness-step-draft-approved-2026-08-12`
- owner_agent: `implementation-planning-agent`
- date: `2026-08-12`
- source_requirement: `docs/requirements/linear-static-mitc4-shell.md`
- source_research: `docs/research/linear-static-mitc4-shell-research.md`
- source_formulation: `docs/formulations/mitc4-shell-formulation.md`
- source_numerical_review:
  `docs/numerical-reviews/linear-static-mitc4-shell-review.md`
- source_io_definition:
  `docs/io-definitions/linear-static-mitc4-shell-io.md`
- source_reference_models:
  `docs/reference-models/linear-static-mitc4-shell-reference-models.md`
- target_platform: `Windows x64 / MSVC / C++17`
- build_system: `CMake + CTest`
- execution_infrastructure: `Python Harness`
- current_numerical_verdict: `pass-for-implementation-planning`
- harness_task_name_candidate: `linear-static-mitc4-shell`
- implementation_authorized: `true-user-requested-2026-08-12`
- harness_execution_authorized: `true-user-requested-2026-08-12`
- phase_files_authorized: `true-user-approved-2026-08-12`

### Goal

승인된 Abaqus `.inp` subset의 `S4` 및 `S4R` source element를 하나의 FESA
`FESA-MITC4` 선형 정적 shell formulation으로 해석하고, 물리적으로 분리된 fixed
drilling stabilization, deterministic sparse assembly, mandatory HDF5 shell results,
두 declared displacement reference case를 end-to-end로 연결한다.

### Architecture

기존 B33 경로를 파괴하거나 speculative common element hierarchy를 만들지 않는다.
Domain에 shell semantic records를 추가하고, 별도 concrete `Mitc4Shell` kernel과
shell-specific recovery를 만든다. 기존 `Analysis` lifecycle, six-DOF nodal
load/constraint, sparse COO reduction, `LinearSolver`, generic `ResultsWriter` 경계,
HDF5 temporary/self-check/atomic replacement는 재사용한다.

### Tech Stack

- C++17, MSVC `/W4 /WX`
- CMake 3.25+, Visual Studio 18 2026 generator, x64 Debug
- GoogleTest/CTest
- Intel oneAPI MKL and TBB
- HDF5 schema version 0
- Python 3 Harness runner and repository hooks

### Global Constraints

1. 모든 production behavior는 같은 Step 안에서 `RED -> observed failure ->
   minimal GREEN -> focused VERIFY -> full VERIFY`를 닫는다.
2. production C++ 파일 변경은 관련 C++ test와 함께 수행한다.
3. public solver headers에 MKL, TBB, HDF5, Win32/vendor type을 노출하지 않는다.
4. Node/Element에 equation ID를 저장하지 않고 `DofManager`만 numbering, scatter,
   constrained/free mapping 및 sparse pattern을 소유한다.
5. `S4`와 `S4R`은 같은 FESA numerical path를 사용하며 source metadata만 다르다.
6. physical 20-DOF kernel과 four numerical drilling coordinates를 recovery/output에서
   분리한다.
7. reference files를 생성, 수정, rename, repair, normalize하지 않으며 Abaqus를
   실행하지 않는다.
8. future geometrically nonlinear residual/tangent, distributed loads, mixed beam-shell
   models, reduced integration/hourglass, drilling calibration/energy output,
   `NR-O03`/`NR-O04`는 구현 범위 밖이다.
9. 이 `draft`의 승인은 phase planning files 작성만 허용한다. Harness 실행은 별도의
   명시적 사용자 요청이 있어야 한다.

## 2. Readiness Check

| gate | evidence | status | planning consequence |
| --- | --- | --- | --- |
| Requirements | `docs/requirements/linear-static-mitc4-shell.md`, 001-072 approved | pass | 모든 must를 task/test에 추적 |
| Research | `docs/research/linear-static-mitc4-shell-research.md` | pass | source-backed MITC4 tying/director/drilling 경계 유지 |
| Formulation | `docs/formulations/mitc4-shell-formulation.md`, `approved-for-implementation-planning` | pass | linear sections만 구현; Section 15 future nonlinear 제외 |
| Numerical Review | `docs/numerical-reviews/linear-static-mitc4-shell-review.md` | pass | critical blocker 없음; planning authorized |
| I/O | `docs/io-definitions/linear-static-mitc4-shell-io.md`, `approved-for-implementation-planning` | pass | keyword, diagnostic, HDF5 schema를 그대로 구현 |
| Reference Model | `docs/reference-models/linear-static-mitc4-shell-reference-models.md` | pass | 두 input/CSV pair만 read-only 사용 |
| Repository seams | parser/model, element/analysis, result/reference 영역 read-only 조사 | pass | candidate files와 current signatures 확인 |
| Toolchain paths | GoogleTest/MKL/TBB/HDF5 config directories 존재 | pass | Section 10의 exact configure command 사용 가능 |

Toolchain path evidence was resolved in this workspace on `2026-08-12`with
`Test-Path -LiteralPath`returning `True`for all four literal directories used in
Sections 10 and 12. They are environment-resolved paths, not placeholders. Each Step
copies the fail-fast path precheck before CMake so a changed machine configuration
stops before RED/GREEN evidence is recorded.

Declared read-only reference inventory:

| case | source | displacement CSV | SHA-256 |
| --- | --- | --- | --- |
| S4 | `reference/shell/shell.inp` | `reference/shell/shell displacements.csv` | input `4005851E1AB22FD3A16AC17A8D5DA3E051233F69F37419079F3553AD134ECFCF`; CSV `C81D94E0B4A849F87AA0F79C83A79B94D5661AC79E44ED826919AB432C87746B` |
| S4R | `reference/shellR/shellR.inp` | `reference/shellR/shellR displacements.csv` | input `1325940FB42B78961CF25E84379BF2693846FAD22473E7688AC5456B37B18CB4`; CSV `8887ACC5ED007CB97583A9FDC1150B48B9297E269A5BA8EBA6C1A5F6306E98CB` |

README, `metadata.json`, Abaqus provenance/version, canonical naming 및 추가 portfolio는
readiness gate가 아니다. 현재 열린 product/numerical 결정은 없다. 남은 승인 항목은
Section 12의 multi-Step Harness draft뿐이다.

## 3. Implementation Scope

### Included behavior

- exactly one `*STEP, *STATIC`, small displacement/small rotation
- four-node `S4`/`S4R` parsing and one internal `FESA-MITC4` identity
- stable source instance/label/type and four-node source ordering
- homogeneous isotropic `E,nu` and centered single-layer constant `t`
- deterministic positive-thickness nodal directors and right-handed frames
- six global nodal DOFs; 24-entry shell scatter
- physical membrane, bending, transverse shear with MITC edge-midpoint tying
- common `2x2x2` Gauss integration for S4 and S4R
- fixed `k_d=10^-3 min(R+)` drilling stabilization from the eight physical
  tangent-rotation diagonals only
- nodal BC and global CLOAD; aggregate director-parallel moment rejection
- deterministic global stiffness, constrained partition, factorize-before-load,
  effective RHS, solve, full residual/reaction
- physical-only shell recovery, energy/equilibrium/verification metrics
- exact mandatory HDF5 model/result schema and failure-atomic finalization
- direct HDF5-to-Abaqus-displacement comparison: U blocking, UR warning-only

### Non-goals

- Abaqus `S4`/`S4R` algorithm equivalence
- B31 mapping, mixed B33/MITC4 model execution or common public element hierarchy
- `*DLOAD`, pressure, gravity, body/edge/follower load
- composite, offsets, variable thickness, explicit normal/orientation
- reduced integration, hourglass control, MITC4+
- nonlinear state, finite director update, nonlinear residual/tangent execution
- drilling physical strain/load/result/stress/energy, coefficient sweep or calibration
- `NR-O03` smooth-angle and `NR-O04` warp/distortion threshold sweeps
- extra shell benchmarks as a completion gate
- Abaqus execution or reference artifact mutation

## 4. Work Breakdown

Tasks are ordered by implementation dependency. Harness executes Steps 0-13 in strict
order even when the minimal dependency set below is smaller.

| task | depends on |
| --- | --- |
| TASK-00 | none |
| TASK-01 | TASK-00 |
| TASK-02 | TASK-01 |
| TASK-03 | TASK-02 |
| TASK-04 | TASK-03 |
| TASK-05 | TASK-04 |
| TASK-06 | TASK-00; executed after TASK-05 |
| TASK-07 | TASK-04, TASK-06 |
| TASK-08 | TASK-02, TASK-07 |
| TASK-09 | TASK-05, TASK-08 |
| TASK-10 | TASK-05, TASK-09 |
| TASK-11 | TASK-09, TASK-10 |
| TASK-12 | TASK-01, TASK-07, TASK-08, TASK-10, TASK-11 |
| TASK-13 | TASK-11, TASK-12 |
| TASK-14 | TASK-13 |
| TASK-15 | TASK-13 |
| TASK-16 | TASK-00 through TASK-15 |

### TASK-00: `shell-semantic-model`

- Own only model semantic records and immutable Domain access.
- Candidate additions: `Mitc4ShellDefinition`, `ShellSection`, source type enum/value,
  internal formulation identity, four-node indices, material/section indices, node
  director/frame storage.
- Preserve current B33 records and stable source/internal identity; reject mixed models
  at mapping rather than designing a heterogeneous solver hierarchy.
- Tests: `MITC4-MODEL-001`, `MITC4-MODEL-002`.

### TASK-01: `shell-domain-mapping`

- Extend `AbaqusDomainMapper::map(const ParsedInput&)`; keep `AbaqusInputReader`
  syntax-only.
- Accept exact S4/S4R and single-layer SHELL SECTION grammar, resolve ELSET/material,
  identity wrappers and six-DOF BC/CLOAD.
- Fail closed with exact I/O diagnostic classes for connectivity, assignment,
  unsupported option/procedure/mixed model/distributed load.
- Tests: `MITC4-MAP-001` through `MITC4-MAP-004`.

### TASK-02: `shell-director-geometry`

- Add deterministic geometry preprocessing after instance expansion: element normal
  candidates, area-weighted nodal director, pairwise orientation validation and nodal
  frame tie-break.
- Validate center, eight stiffness points, four tying points and committed recovery
  points for finite bases, nonzero surface measure and positive finite Jacobian.
- Do not introduce calibrated angle, warp or distortion thresholds.
- Tests: `MITC4-GEO-001` through `MITC4-GEO-004`.

### TASK-03: `mitc4-kinematics-constitutive`

- Create concrete candidate `Mitc4Shell` without a public base hierarchy.
- Implement shape identities, local frames, `T_p`/`T_d` channel maps, direct
  membrane/bending terms, all four covariant MITC tying samples/interpolation,
  engineering-shear factors, `C_ps/C_5/A/D/A_s` and fixed point order.
- Keep all intermediate physical coordinates at 20 DOFs.
- Tests: `MITC4-KIN-001` through `MITC4-KIN-005`.

### TASK-04: `mitc4-stiffness-drilling`

- Form physical `K20` with common `2x2x2` integration and embed by congruence.
- Build `R+` only from the eight physical tangent-rotation diagonals, use exact
  `k_d=10^-3 min(R+)` and `T_d^T(k_d I4)T_d`; fail empty/nonfinite `R+`.
- Tests: `MITC4-KERNEL-001` through `MITC4-KERNEL-006`.

### TASK-05: `mitc4-physical-recovery`

- Add only the element-kernel physical recovery seam for generalized strain/resultant,
  bottom/middle/top stress and physical element energy.
- Prove pure numerical drill action contributes zero to every physical recovery value.
- Tests: `MITC4-KERNEL-007`, `MITC4-PHYSREC-001`.

### TASK-06: `shell-dof-scatter`

- Retain six per-node full DOFs and add typed 24-entry shell scatter/pattern access;
  preserve existing 12-entry B33 behavior.
- Preserve stable full/free/constrained numbering and all-constrained `0x0 Kff`.
- Tests: `MITC4-DOF-001` through `MITC4-DOF-003`.

### TASK-07: `shell-sparse-assembly`

- Dispatch shell topology to `Mitc4Shell::globalStiffness()`.
- Emit 576 element-local COO entries with stable `elementOrder`/`localOrder` into
  worker-owned buffers; preserve canonical fixed reduction and diagonal slots.
- Tests: `MITC4-ASM-001` through `MITC4-ASM-003`.

### TASK-08: `shell-load-validation`

- Reuse global six-DOF `LoadAssembler` and existing constraint partition.
- Aggregate CLOAD deterministically before testing exact-zero or
  `rho_M=abs(dot(d,M))/norm(M)<=1e-12`; rejected moments never reach stabilization.
- Preserve force/moment units and factorization-before-load lifecycle.
- Tests: `MITC4-LOAD-001` through `MITC4-LOAD-004`.

### TASK-09: `shell-analysis-state`

- Add shell result rows to `AnalysisState` and `result_records.hpp`: four fixed
  midsurface locations, local frames, eight generalized strains/resultants,
  bottom/middle/top stress, physical energy, equilibrium and verification metrics.
- Preserve stable row order and expose candidate-owned containers only; perform no
  element calculation in this task.
- Tests: `MITC4-STATE-001` through `MITC4-STATE-003`.

### TASK-10: `shell-result-recovery`

- Recover full residual `K*d-F` for nodal reaction/equilibrium evidence but call the
  kernel physical-only recovery for shell quantities.
- Validate candidates fully before committing state; keep stable row order.
- Tests: `MITC4-REC-001` through `MITC4-REC-005`.

### TASK-11: `shell-hdf5-output`

- Extend `Hdf5ResultsWriter` behind the unchanged generic `ResultsWriter::write`
  boundary.
- Add exact schema paths/shapes/component attributes from the I/O contract without
  changing B33 dataset meaning.
- Reuse temporary write, finite/schema self-check, close/reopen and atomic replace.
- Tests: `MITC4-H5-001` through `MITC4-H5-004`.

### TASK-12: `shell-linear-static-flow`

- Route a shell Domain through the existing eight-hook `Analysis::run()` lifecycle.
- Preserve assemble/partition, factorize, load/effective RHS, substitute,
  reconstruct, full residual/recover, atomic write order and single factorization.
- Validate nonzero prescribed values, singular support and valid all-constrained solve.
- Tests: `MITC4-FLOW-001` through `MITC4-FLOW-004`.

### TASK-13: `shell-reference-comparison`

- Add a test-only MITC4 comparator rather than widening beam-specific assumptions.
- Consume exactly one declared input and displacement CSV per case; map instance,
  source node and six displacement components directly to HDF5.
- Precheck header/row set/duplicates/nonfinite/schema/identity before numeric work.
- Apply `1e-9+1e-6*reference_scale_c`; U blocks, UR only emits deterministic warning;
  record all required metrics and worst row.
- Tests: `MITC4-REF-001` through `MITC4-REF-006`.

### TASK-14: `shell-s4-end-to-end`

- This is declared-case sub-work owned by TASK-13/Step 13's test-only reference module,
  not an independent production-module Step.
- Run the declared S4 deck through CLI, authoritative HDF5, schema checks and
  read-only comparator.
- Assert source type `S4`, internal `FESA-MITC4` and U pass/UR report behavior.
- Tests: `MITC4-E2E-S4-001`, `MITC4-E2E-S4-002`.

### TASK-15: `shell-s4r-end-to-end`

- This is declared-case sub-work owned by TASK-13/Step 13's test-only reference module,
  not an independent production-module Step.
- Run the declared S4R deck through the identical numerical route.
- Assert only source metadata differs from an otherwise identical S4 semantic fixture;
  no reduced integration/hourglass branch exists.
- Tests: `MITC4-E2E-S4R-001`, `MITC4-E2E-S4R-002`.

### TASK-16: `mitc4-full-verification`

- Run MSVC x64 Debug full build, CTest discovery, focused feature suites and full CTest.
- Audit warnings, deterministic repeat evidence, required HDF5 inventory, reference
  immutability and git diff scope.
- Produce only downstream implementation evidence; do not claim reference verification,
  physics sanity or release readiness.
- Tests/audits: `MITC4-VERIFY-001` through `MITC4-VERIFY-004`.

## 5. TDD Test Plan

| test id | initial RED assertion | minimal GREEN behavior | focused verification |
| --- | --- | --- | --- |
| MITC4-MODEL-001 | four-node S4/S4R records/director/source identity do not exist | immutable shell records preserve source and internal identity | `DomainModel.*` |
| MITC4-MODEL-002 | shell section/material/thickness ownership unavailable | one resolved centered homogeneous assignment per element | `DomainModel.*` |
| MITC4-MAP-001 | valid S4/S4R and SHELL SECTION reject | both source types map to FESA-MITC4 | `InpDomainMapping.*` |
| MITC4-MAP-002 | duplicate/unresolved/conflicting section cases lack exact errors | exact assignment/material validation | `InpDomainMapping.*` |
| MITC4-MAP-003 | excluded shell options/mixed models may be ignored | exact fail-closed diagnostics | `InpDomainMapping.*` |
| MITC4-MAP-004 | second/nonstatic/NLGEOM/DLOAD cases lack shell boundary tests | exact procedure/load rejection; no-op output unchanged | `InpDomainMapping.*` |
| MITC4-GEO-001 | planar/rotated/warped directors unavailable | deterministic unit director and right-handed frame | `Mitc4Geometry.*` |
| MITC4-GEO-002 | incident orientation/tie-break is untested | stable area-weighted result across repeated order | `Mitc4Geometry.*` |
| MITC4-GEO-003 | duplicate/bow-tie/zero/reversed/nonfinite geometry may pass | exact geometry failures | `Mitc4Geometry.*` |
| MITC4-GEO-004 | required-point Jacobian inventory absent | every required point finite and positive | `Mitc4Geometry.*` |
| MITC4-KIN-001 | shape/derivative identities unavailable | partition/unity/derivative identities | `Mitc4ShellKinematics.*` |
| MITC4-KIN-002 | frame/T transforms unavailable | orthonormal/right-handed frames and channel selection | `Mitc4ShellKinematics.*` |
| MITC4-KIN-003 | tying values/weights unavailable | four hand-computed covariant tying values | `Mitc4ShellKinematics.*` |
| MITC4-KIN-004 | constitutive/section matrices unavailable | exact coefficients, symmetry, positivity, unit rescaling | `Mitc4ShellConstitutive.*` |
| MITC4-KIN-005 | quadrature order not fixed | exact common 2x2x2 points/weights | `Mitc4ShellKinematics.*` |
| MITC4-KERNEL-001 | no 24x24 shell stiffness | finite symmetric 24x24 stiffness | `Mitc4ShellKernel.*` |
| MITC4-KERNEL-002 | energy congruence unavailable | 20/24 virtual work and energy equal within 1e-12 | `Mitc4ShellKernel.*` |
| MITC4-KERNEL-003 | rigid/rank checks fail | six physical rigid modes, physical rank 14, stabilized rank 18 | `Mitc4ShellKernel.*` |
| MITC4-KERNEL-004 | deformation energy/patch fields unavailable | positive membrane/bending/shear/twist modes | `Mitc4ShellPatch.*` |
| MITC4-KERNEL-005 | R+ membership/coefficient not implemented | exact rotational-only min and 1e-3 factor | `Mitc4ShellDrilling.*` |
| MITC4-KERNEL-006 | empty R+ and pure drill behavior unspecified | deterministic failure; pure drill stabilized | `Mitc4ShellDrilling.*` |
| MITC4-KERNEL-007 | drilling contaminates recovery/energy | physical recovery/energy exact zero for pure drill | `Mitc4ShellDrilling.*` |
| MITC4-PHYSREC-001 | kernel recovery contract is not independently callable | exact physical strain/resultant/stress/energy for hand field | `Mitc4ShellPhysicalRecovery.*` |
| MITC4-DOF-001 | shell scatter fixed at 12 | stable 24-entry scatter in node/component order | `DofManager.*` |
| MITC4-DOF-002 | shell pattern unavailable | sorted unique pattern with all diagonals | `DofManager.*` |
| MITC4-DOF-003 | constraint roundtrip lacks shell-sized system | no/mixed/all constraints and nonzero values roundtrip | `DofManager.*; EssentialConstraints.*` |
| MITC4-ASM-001 | assembler rejects four-node element | 576 stable local contributions assemble | `SparseAssembly.*` |
| MITC4-ASM-002 | thread/repetition may reorder | serial/TBB/repeated CSR bytes and values match | `SparseAssembly.*` |
| MITC4-ASM-003 | S4/S4R could branch numerically | identical semantic fixtures produce identical K | `SparseAssembly.*` |
| MITC4-LOAD-001 | shell force/moment fixture unavailable | six global components aggregate stably | `LoadAssembly.*` |
| MITC4-LOAD-002 | director-parallel exact-zero branch untested | zero aggregate moment accepted | `LoadAssembly.*` |
| MITC4-LOAD-003 | rho boundary/rejection untested | <=1e-12 accepted; >1e-12 exact diagnostic | `LoadAssembly.*` |
| MITC4-LOAD-004 | rejected moment might enter drill channel | failure occurs before RHS/substitution | `LoadAssembly.*` |
| MITC4-STATE-001 | AnalysisState has no shell row containers | exact shell row/component/location types are owned | `AnalysisState.*` |
| MITC4-STATE-002 | physical energy/equilibrium/metrics are absent | finite candidate global evidence is stored | `AnalysisState.*` |
| MITC4-STATE-003 | shell candidate rollback is unavailable | invalid candidate leaves prior state unchanged | `AnalysisState.*` |
| MITC4-REC-001 | shell row types absent | four ordered location/frame/strain/resultant rows | `ResultRecovery.*` |
| MITC4-REC-002 | bottom/middle/top stress absent | direct S11/S22/S12 recovery in fixed order | `ResultRecovery.*` |
| MITC4-REC-003 | energy may include drilling | physical strain energy excludes stabilization | `ResultRecovery.*` |
| MITC4-REC-004 | reaction/equilibrium semantics may diverge | full residual, force/moment balance, normalized metrics | `ResultRecovery.*` |
| MITC4-REC-005 | invalid partial rows may commit | nonfinite/inventory failure preserves old state | `ResultRecovery.*` |
| MITC4-H5-001 | shell metadata/model schema missing | exact metadata, elements, director/frame, material/section | `Hdf5ResultsWriter.*` |
| MITC4-H5-002 | mandatory shell result paths missing | exact displacement/reaction/frame/strain/resultant/stress/global rows | `Hdf5ResultsWriter.*` |
| MITC4-H5-003 | output request could filter or drilling paths appear | inventory unconditional; forbidden paths absent | `Hdf5ResultsWriter.*` |
| MITC4-H5-004 | invalid shell candidate may replace final file | self-check failure preserves prior final | `Hdf5ResultsWriter.*` |
| MITC4-FLOW-001 | shell cannot traverse Analysis lifecycle | exact hook order and one factorization | `LinearStaticCli.*` |
| MITC4-FLOW-002 | prescribed shell RHS/reconstruction absent | Ff-Kfc*dc and full displacement correct | `LinearStaticCli.*` |
| MITC4-FLOW-003 | singular/all-constrained behavior unproven | singular fails; 0x0 Kff succeeds | `LinearStaticCli.*` |
| MITC4-FLOW-004 | failed output may commit state | candidate state/output commits only after validation | `LinearStaticCli.*` |
| MITC4-REF-001 | six-column CSV header unsupported | exact MITC4 header maps instance/node/U/UR | `Mitc4ReferenceComparison.*` |
| MITC4-REF-002 | invalid row inventory may be ignored | missing/extra/duplicate/nonfinite/schema mismatch fails first | `Mitc4ReferenceComparison.*` |
| MITC4-REF-003 | tolerance could clamp/row-normalize | exact component group scale and mixed tolerance | `Mitc4ReferenceComparison.*` |
| MITC4-REF-004 | UR may block verdict | U blocks; UR only warns | `Mitc4ReferenceComparison.*` |
| MITC4-REF-005 | report metrics/order incomplete | row decisions, max, normalized, RMS, vector, worst row deterministic | `Mitc4ReferenceComparison.*` |
| MITC4-REF-006 | comparator may require administrative files | only declared input/CSV/HDF5 required | `Mitc4ReferenceComparison.*` |
| MITC4-E2E-S4-001 | S4 deck cannot produce valid shell HDF5 | CLI succeeds with exact S4 metadata/schema | `Mitc4S4Reference.*` |
| MITC4-E2E-S4-002 | S4 U comparison unavailable | all U rows pass; UR fully reported | `Mitc4S4Reference.*` |
| MITC4-E2E-S4R-001 | S4R deck selects no/other path | same FESA-MITC4 integration rule | `Mitc4S4RReference.*` |
| MITC4-E2E-S4R-002 | S4R U comparison unavailable | all U rows pass; UR fully reported | `Mitc4S4RReference.*` |
| MITC4-VERIFY-001 | feature tests not discoverable | all planned suites discovered/labeled | CTest JSON inventory |
| MITC4-VERIFY-002 | warnings/regressions unknown | MSVC Debug full build passes /W4 /WX | full build |
| MITC4-VERIFY-003 | nondeterminism unknown | repeated focused/full tests pass | full CTest |
| MITC4-VERIFY-004 | artifact governance unknown | reference hashes/path and git diff unchanged | read-only audit |

Numerical thresholds are fixed: frame/symmetry/transformation-energy `<=1e-12`;
rigid action, linear residual and global equilibrium `<=1e-10`. Patch tests compare
against independently hand-computed analytical fields and signs, not the production
routine itself.

## 6. CMake/CTest Plan

### Existing topology to preserve

- production library: `fesa_solver`
- CLI: `fesa_cli`
- unit: `fesa_unit_tests`
- integration: `fesa_integration_tests`
- reference: `fesa_reference_tests`
- aggregate: `fesa_tests`

No new executable target is required. New kernel/test/comparator source files are
explicitly registered in existing source lists. Add `linear-static-mitc4-shell` as an
additive CTest label without removing the B33 label. Because
`gtest_discover_tests()` currently applies target-wide labels, focused Step
verification uses exact suite regexes; label-based MITC4 filtering is enabled only
if per-test labeling can be added without relabeling unrelated B33 tests.

Candidate registrations:

- `src/fesa/CMakeLists.txt`: candidate `model/shell_geometry.cpp`,
  `elements/mitc4_shell.cpp` and any separate shell recovery implementation.
- `tests/CMakeLists.txt`: candidate `shell_geometry_test.cpp`,
  `mitc4_shell_test.cpp`, optional focused shell recovery/HDF5 tests, and MITC4
  reference comparator/test sources.
- Preserve existing runtime staging for MKL/TBB/HDF5 on all three test executables.

CTest discovery must show every suite named in Section 5 before implementation is
considered verified.

## 7. Candidate Files and Ownership

All signatures in this section are candidates for the Implementation Agent to confirm
against the approved contracts during the owning Step; they are not new approved APIs.

| owner/module | candidate files | candidate interface/direction |
| --- | --- | --- |
| model | `include/fesa/model/model_types.hpp`, `include/fesa/model/domain.hpp`, `src/fesa/model/domain.cpp` | separate shell records/accessors; no equation IDs |
| shell semantic geometry | candidate new `include/fesa/model/shell_geometry.hpp`, `src/fesa/model/shell_geometry.cpp` | director/frame and required-point geometry validation without parser/kernel dependency |
| Abaqus semantic map | `include/fesa/io/abaqus/domain_mapper.hpp`, `src/fesa/io/abaqus/domain_mapper.cpp` | keep `map(const ParsedInput&) -> Result<Domain>` |
| analysis view | `include/fesa/analysis/analysis_model.hpp`, `src/fesa/analysis/analysis_model.cpp` | non-owning active shell view only if record representation requires |
| shell kernel | new `include/fesa/elements/mitc4_shell.hpp`, `src/fesa/elements/mitc4_shell.cpp` | concrete create/stiffness/physical-recover API |
| DOF | `include/fesa/fem/dof_manager.hpp`, `src/fesa/fem/dof_manager.cpp` | typed `array<size_t,24>` shell scatter beside B33 scatter |
| sparse assembly | `src/fesa/assembly/sparse_assembler.cpp` | topology dispatch; unchanged public assemble signature |
| load | `src/fesa/assembly/load_assembler.cpp` only if aggregate director projection cannot live in semantic validation | reuse full six-DOF assembly |
| state/results | `include/fesa/analysis/analysis_state.hpp`, `src/fesa/analysis/analysis_state.cpp`, `include/fesa/results/result_records.hpp` | additive shell rows/global metrics |
| recovery | `include/fesa/results/result_recovery.hpp`, `src/fesa/results/result_recovery.cpp` or new shell-specific cpp | candidate-then-commit; physical/drill split |
| HDF5 | `src/fesa/io/hdf5/hdf5_results_writer.cpp` | generic public writer unchanged |
| lifecycle | `src/fesa/analysis/linear_static_analysis.cpp` | preserve existing hook order |
| app | `tests/integration/app/fesa_application_test.cpp`; production app only if feature dispatch needs it | CLI syntax unchanged |
| reference tests | new `tests/reference/mitc4_reference_comparison.hpp/.cpp` and tests | test-only direct HDF5/CSV comparator |
| build graph | `src/fesa/CMakeLists.txt`, `tests/CMakeLists.txt` | explicit additive source/test registration |

Candidate kernel seam:

```cpp
class Mitc4Shell {
public:
    static Result<Mitc4Shell> create(
        std::array<const Node*, 4> nodes,
        std::array<Vector3, 4> initialDirectors,
        const ShellSection& section,
        const LinearElasticMaterial& material);

    [[nodiscard]] Matrix physicalLocalStiffness20() const;
    [[nodiscard]] Matrix globalStiffness24() const;
    [[nodiscard]] Result<ShellRecovery> recoverPhysical(
        const Vector& globalElementDisplacement24) const;
};
```

This candidate explicitly avoids returning drill energy/results and avoids a common
public `Element` hierarchy. Exact value/reference ownership and math types are decided
inside TASK-03 after compiling the first RED test.

## 8. Data Flow Contract

```text
.inp bytes
  -> AbaqusInputReader (syntax/source locations only)
  -> AbaqusDomainMapper (approved semantics, S4/S4R provenance, section/material)
  -> geometry/director preprocessing
  -> immutable Domain
  -> non-owning AnalysisModel
  -> DofManager (6 DOF/node, 24-entry shell scatter, free/constrained maps)
  -> Mitc4Shell physical K20 + fixed drill embedding -> global K24
  -> worker-local COO -> stable SparseMatrix reduction
  -> Kff/Kfc/Kcf/Kcc partition -> Kff factorize
  -> aggregate CLOAD/director check -> Ff-Kfc*dc
  -> substitute -> full displacement
  -> full residual K*d-F
  -> physical-only shell recovery + global evidence
  -> validated candidate AnalysisState
  -> temporary results.h5 -> schema self-check -> atomic finalization

authoritative results.h5
  -> test-only MITC4 HDF5 projection
  -> exact source instance/node/component row-set precheck
  -> read-only declared Abaqus displacement CSV
  -> U blocking / UR warning-only deterministic report
```

Invariants:

- Domain outlives AnalysisModel; no Domain copying.
- Source labels/instances/types never become equation indices.
- `S4`/`S4R` source type is metadata; both call the same kernel/quadrature.
- full residual uses stabilized global K; shell strain/resultant/stress/physical energy
  use physical recovery only.
- HDF5 `nodal/reaction` is full residual; constraint mask decides reaction versus free
  residual evidence.
- result rows use fixed GP1..GP4 and BOTTOM/MIDDLE/TOP identity; no averaging or Abaqus
  integration-point relabeling.
- state/output mutation occurs only after complete validation.

## 9. Acceptance Traceability Matrix

The inclusive ranges below cover every must requirement `001` through `072` exactly
once without gap or overlapping requirement range.

| requirement range | owning tasks | test/evidence id | reference model id | acceptance |
| --- | --- | --- | --- | --- |
| 001 | TASK-01, TASK-12 | MAP-004, FLOW-001 | N/A | one static step only; deterministic rejection otherwise |
| 002-004 | TASK-00, TASK-01, TASK-11, TASK-14, TASK-15 | MODEL-001, MAP-001, H5-001, both E2E suites | `shell-s4`, `shell-s4r` | S4/S4R one kernel; distinct stable source identity |
| 005 | TASK-00, TASK-06, TASK-11 | MODEL-001, DOF-001/003, H5-001/002 | N/A | exact six-component order; no distributed equation ownership |
| 006-010 | TASK-00, TASK-01 | MODEL-002, MAP-002/003 | N/A | finite E,nu,t; one assignment; unsupported meanings fail |
| 011-016 | TASK-02, TASK-03 | GEO-001..004, KIN-002 | N/A | deterministic unit directors; exact geometry predicates |
| 017-020 | TASK-01, TASK-08 | MAP-004, LOAD-001..004 | N/A | six-DOF BC/CLOAD; drilling/distributed load fails |
| 021-023 | TASK-01 | MAP-001..004 and existing no-op regression | N/A | approved parser subset/identity wrappers/no-op policy |
| 024-030 | TASK-00, TASK-06, TASK-07, TASK-09, TASK-10, TASK-12, TASK-16 | MODEL, DOF, ASM, STATE, REC, FLOW, VERIFY suites | N/A | ownership, deterministic assembly, lifecycle, residual reaction |
| 031-038 | TASK-03, TASK-04, TASK-05, TASK-07, TASK-10 | KIN, KERNEL, PHYSREC, ASM-003, REC-003 | N/A | physical 5-DOF embedding, exact drilling, same quadrature, invariants |
| 039-048 | TASK-09, TASK-10, TASK-11, TASK-12 | STATE-001..003, REC-001..005, H5-001..004, FLOW-004 | N/A | mandatory finite schema/results and atomic commit |
| 049 | TASK-00 through TASK-16 | every production Task records RED/failure/GREEN/focused/full VERIFY; VERIFY-001..003 | `shell-s4`, `shell-s4r` where reference-dependent | TDD evidence, related C++ tests, MSVC Debug no-warning build and full CTest |
| 050 | TASK-02 through TASK-05, TASK-07 | GEO-001/002, KIN-001/002, KERNEL-001..004, ASM-002 | N/A | frames, Jacobian, symmetry, transformation, six modes, positivity and repeatability |
| 051 | TASK-02 through TASK-05, TASK-10, TASK-12 | GEO-001, KERNEL-001..003, REC-004, FLOW-002 | N/A | exact normalized 1e-12 and 1e-10 algebraic thresholds |
| 052 | TASK-03 through TASK-05, TASK-10 | KIN-003/004, KERNEL-004, PHYSREC-001, REC-001/002 | N/A | independent membrane, bending, shear, twist fields and recovery signs/order |
| 053 | TASK-04, TASK-05, TASK-14, TASK-15 | KERNEL-001..007, PHYSREC-001, both declared E2E suites | `shell-s4`, `shell-s4r` | formulation invariants/patches and both reference cases pass |
| 054 | TASK-02 | GEO-001..004 | N/A | exact valid/rejected geometry inventory; no NR-O03/O04 |
| 055 | TASK-16 | VERIFY scope audit | N/A | extra benchmark portfolio is explicitly nonblocking and absent from completion gate |
| 056 | TASK-04, TASK-05, TASK-07, TASK-10 | KERNEL-005..007, PHYSREC-001, ASM-001/002, REC-003 | N/A | exact fixed drilling, deterministic rank/action and physical-output exclusion |
| 057 | TASK-10, TASK-12, downstream Physics Evaluation | REC-002..004, FLOW-002, later physics report | `shell-s4`, `shell-s4r` | implementation exposes equilibrium/sign/energy evidence; physical plausibility verdict is downstream |
| 058-060 | TASK-13, TASK-14, TASK-15 | REF-003, both E2E comparison tests | `shell-s4`, `shell-s4r` | exact U mixed tolerance without clamp |
| 061-062 | TASK-13, TASK-14, TASK-15 | REF-004/005, both E2E tests | `shell-s4`, `shell-s4r` | UR same tolerance, deterministic warning only |
| 063-064 | TASK-13 | REF-001/002/005 | `shell-s4`, `shell-s4r` | schema/row failure before numeric comparison; full metrics |
| 065-068 | TASK-13, TASK-14, TASK-15 | REF-001/002/006, both case prechecks | `shell-s4`, `shell-s4r` | exact four read-only paths; unique finite mapped rows |
| 069-071 | TASK-14, TASK-15 | both E2E suites | `shell-s4`, `shell-s4r` | declared S4/S4R; U blocks and UR warns; no other equality gate |
| 072 | TASK-13 through TASK-16 | REF-006, VERIFY-004 and git/hash audit | `shell-s4`, `shell-s4r` | no reference solver run or artifact mutation |

## 10. Validation Commands

These commands are the environment-resolved Windows x64 Debug baseline. Planning does
not execute build/tests. Each approved Harness Step first runs this literal path
precheck and then repeats the relevant build/test subset after its RED and GREEN
changes.

```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 "Required configured build path is absent: $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
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure
```

Focused commands:

```powershell
cmake --build .harness/build --config Debug --target fesa_unit_tests
ctest --test-dir .harness/build -C Debug -R "DomainModel|InpDomainMapping|Mitc4Geometry|Mitc4Shell|DofManager|EssentialConstraints|SparseAssembly|LoadAssembly|ResultRecovery|Hdf5ResultsWriter" --output-on-failure

cmake --build .harness/build --config Debug --target fesa_integration_tests
ctest --test-dir .harness/build -C Debug -R "LinearStaticCli|Mitc4ShellCli" --output-on-failure

cmake --build .harness/build --config Debug --target fesa_reference_tests
ctest --test-dir .harness/build -C Debug -R "Mitc4ReferenceComparison|Mitc4S4Reference|Mitc4S4RReference" --output-on-failure
```

Planning-document verification:

```powershell
git diff --check -- docs/implementation-plans/linear-static-mitc4-shell-implementation-plan.md
git status --short
git diff --name-only
```

Reference immutability audit is read-only and fails on any mismatch:

```powershell
$expectedReferenceHashes = [ordered]@{
  "reference/shell/shell.inp" = "4005851E1AB22FD3A16AC17A8D5DA3E051233F69F37419079F3553AD134ECFCF"
  "reference/shell/shell displacements.csv" = "C81D94E0B4A849F87AA0F79C83A79B94D5661AC79E44ED826919AB432C87746B"
  "reference/shellR/shellR.inp" = "1325940FB42B78961CF25E84379BF2693846FAD22473E7688AC5456B37B18CB4"
  "reference/shellR/shellR displacements.csv" = "8887ACC5ED007CB97583A9FDC1150B48B9297E269A5BA8EBA6C1A5F6306E98CB"
}
foreach ($referencePath in $expectedReferenceHashes.Keys) {
  $actualHash = (Get-FileHash -Algorithm SHA256 -LiteralPath $referencePath).Hash
  if ($actualHash -ne $expectedReferenceHashes[$referencePath]) {
    throw "Reference artifact changed: $referencePath"
  }
}
```

Do not invoke `scripts/hooks/*.py` manually. Harness runner installs/uses the configured
PreToolUse and Stop hooks automatically. Do not invoke `scripts/execute.py` until the
user separately authorizes execution.

## 11. Risks and Downstream Handoff

| risk | controlling plan decision | stop condition |
| --- | --- | --- |
| beam-only ModelDefinition leaks through every layer | add shell semantic records first; preserve B33 access | stop if a Step requires unapproved mixed-model hierarchy |
| fixed 12-DOF scatter breaks B33 | typed beam/shell scatter paths and B33 regressions | stop on any B33 focused/full regression |
| drilling contaminates physical output | separate physical recovery from stabilized full K | stop if pure-drill recovery/energy is nonzero |
| director/frame sign nondeterminism | source-order, area-weight and tie-break tests | stop on repeat/order/thread difference |
| S4R accidentally selects reduced integration | one internal formulation and ASM/E2E equality tests | stop if source type reaches quadrature dispatch |
| full residual confused with element resultants | keep reaction from Kd-F, physical recovery separately | stop if reaction is reconstructed from shell resultants |
| writer expansion changes B33 schema | additive shell branches plus full B33 CTest | stop on B33 schema regression |
| comparator inherits B33 four-file/Frame assumptions | dedicated test-only MITC4 comparator | stop if administrative files become required |
| reference artifacts staged by Harness | clean isolated worktree, hash/diff audit | stop immediately on any reference path change |
| future nonlinear equations enter production | scope and code review prohibition | stop if nonlinear state/tangent is allocated or called |

### Implementation Agent

- Read the approved implementation plan, `docs/HARNESS.md` and
  `docs/HARNESS_WORKFLOW.md` before every Step.
- Execute only the Harness-selected pending Step and use the repository hooks/scripts
  through the documented runner lifecycle.
- Never choose the next Step, edit executor-owned timestamps/statuses, batch multiple
  Steps, or implement outside the Step's file ownership.
- Record the RED command and observed failure before GREEN.

### Build/Test Executor Agent

- Use Section 10 exact CMake/MSVC/CTest baseline after implementation Steps finish.
- Report new warnings, discovery gaps and exact failing test names without changing
  upstream contracts.

### Correction Agent

- Apply only minimal failure-driven corrections inside approved file ownership.
- Do not reinterpret MITC4 mathematics, I/O schema or tolerance.

### Reference Verification Agent

- Consume authoritative HDF5 and declared read-only CSV directly.
- Create the separate reference-verification report; only U affects pass/fail and every
  UR warning remains visible.

### Physics Evaluation and Release Agents

- Physics evaluates equilibrium, directions, symmetry, energy and result signs after
  reference verification.
- Release readiness remains blocked until implementation, build/test, reference and
  physics gates all provide evidence.

## 12. Harness Step Draft

This approved draft is materialized under `phases/linear-static-mitc4-shell/`.
Every Step is zero-based, kebab-case and closes RED/GREEN/VERIFY before the
Executor advances it. TASK-14/TASK-15 are declared-case sub-work inside Step 13's
single test-only reference module; TASK-16 is downstream Build/Test Executor evidence,
not an Implementation Agent phase Step. During materialization, the exact required-reading
paths, configure block, focused command and full VERIFY block shown here are copied
verbatim into every `stepN.md`; a materialized Step never refers back to this draft or
to an external conversation.

Every materialized Step copies this mandatory reading inventory before its
Step-specific paths:

- `AGENTS.md`
- `docs/PRD.md`, `docs/ARCHITECTURE.md`, `docs/ADR.md`
- `docs/HARNESS.md`, `docs/HARNESS_WORKFLOW.md`
- this approved implementation plan and all source contracts listed in Metadata
- `.codex/hooks.json`
- `phases/index.json`, `phases/linear-static-mitc4-shell/index.json` and its own
  `phases/linear-static-mitc4-shell/stepN.md`
- every path created/modified by prerequisite Steps and their step output/status

If any mandatory or Step-specific path is missing or contradicts the approved plan,
the Implementation Agent records `blocked` for the Executor-selected current Step and
stops; it does not invent the missing contract.

Step-specific path ledger copied into the corresponding materialized Step:

| Step | exact source/prerequisite paths |
| ---: | --- |
| 0 | `include/fesa/model/model_types.hpp`; `include/fesa/model/domain.hpp`; `src/fesa/model/domain.cpp`; `tests/unit/model/model_types_test.cpp`; `tests/unit/model/domain_test.cpp` |
| 1 | Step 0 paths; `include/fesa/io/abaqus/domain_mapper.hpp`; `src/fesa/io/abaqus/domain_mapper.cpp`; `tests/unit/io/abaqus/domain_mapper_test.cpp` |
| 2 | Step 0-1 paths; candidate new `include/fesa/model/shell_geometry.hpp`; `src/fesa/model/shell_geometry.cpp`; `tests/unit/model/shell_geometry_test.cpp`; `src/fesa/CMakeLists.txt`; `tests/CMakeLists.txt` |
| 3 | Step 2 paths; candidate new `include/fesa/elements/mitc4_shell.hpp`; `src/fesa/elements/mitc4_shell.cpp`; `tests/unit/elements/mitc4_shell_test.cpp`; `src/fesa/CMakeLists.txt`; `tests/CMakeLists.txt` |
| 4 | Step 3 MITC4 kernel/header/test paths |
| 5 | Step 3-4 MITC4 kernel/header/test paths |
| 6 | Step 0 paths; `include/fesa/fem/dof_manager.hpp`; `src/fesa/fem/dof_manager.cpp`; `tests/unit/fem/dof_manager_test.cpp`; `tests/unit/constraints/essential_constraints_test.cpp` |
| 7 | Steps 4/6 paths; `include/fesa/assembly/sparse_assembler.hpp`; `src/fesa/assembly/sparse_assembler.cpp`; `tests/unit/assembly/sparse_assembler_test.cpp` |
| 8 | Steps 2/7 paths; `include/fesa/assembly/load_assembler.hpp`; `src/fesa/assembly/load_assembler.cpp`; `tests/unit/assembly/load_assembler_test.cpp` |
| 9 | Step 5 paths; `include/fesa/results/result_records.hpp`; `include/fesa/analysis/analysis_state.hpp`; `src/fesa/analysis/analysis_state.cpp`; `tests/unit/results/result_records_test.cpp` |
| 10 | Steps 5/9 paths; `include/fesa/results/result_recovery.hpp`; `src/fesa/results/result_recovery.cpp`; `tests/unit/results/result_recovery_test.cpp` |
| 11 | Steps 9/10 paths; `include/fesa/io/hdf5/hdf5_results_writer.hpp`; `src/fesa/io/hdf5/hdf5_results_writer.cpp`; `tests/unit/io/hdf5/hdf5_results_writer_test.cpp` |
| 12 | Steps 7-11 paths; `include/fesa/analysis/linear_static_analysis.hpp`; `src/fesa/analysis/linear_static_analysis.cpp`; `tests/integration/analysis/linear_static_analysis_test.cpp`; `tests/integration/app/fesa_application_test.cpp` |
| 13 | Steps 11/12 paths; candidate new `tests/reference/mitc4_reference_comparison.hpp`, `tests/reference/mitc4_reference_comparison.cpp`, `tests/reference/mitc4_reference_comparison_test.cpp`, `tests/reference/mitc4_reference_cases_test.cpp`; `tests/CMakeLists.txt`; the four exact read-only reference paths in Section 2 |

The configure command copied before each Step's RED build is:

```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 "Required configured build path is absent: $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"
```

The full VERIFY block copied at the end of every Step is:

```powershell
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
```

### Step 0 — `shell-semantic-model`

- Required reading: requirements 002-016/024, I/O Sections 3/5, architecture model
  ownership, current `model_types.hpp`/`domain.*` and their tests.
- Prerequisite: approved plan only; no production dependency on a prior Step.
- RED: add MODEL-001/002 tests and CMake registration if needed; run:
  `cmake --build .harness/build --config Debug --target fesa_unit_tests` then
  `ctest --test-dir .harness/build -C Debug -R "DomainModel" --output-on-failure`.
  Record the missing shell type/accessor failure. Unexpected pass is a stop.
- GREEN: minimally add shell semantic records/Domain const access; no parser/kernel.
- VERIFY: rerun the focused commands and common full VERIFY.
- Prohibitions: no equation IDs, element hierarchy, mixed-model execution, parser edits.

### Step 1 — `shell-domain-mapping`

- Required reading: Step 0 outputs, requirements 001-010/017-023, I/O Sections 1-3/8-9,
  current `domain_mapper.*` and parser/model tests.
- Prerequisite: Step 0 `completed`.
- RED: add MAP-001..004; build `fesa_unit_tests` and run
  `ctest --test-dir .harness/build -C Debug -R "InpDomainMapping" --output-on-failure`.
  Record valid S4/S4R rejection and exact negative diagnostic failures.
- GREEN: minimally extend semantic mapping; keep `input_reader` syntax-only.
- VERIFY: focused parser/model tests, then common full VERIFY.
- Prohibitions: no element math, no silent unsupported keyword, no reference edits.

### Step 2 — `shell-director-geometry`

- Required reading: requirements 011-016, formulation Sections 4/9/17, Numerical Review
  5.2/5.5/6.1, I/O 3.3/9, completed semantic model/mapping.
- Prerequisite: Step 1 `completed`.
- RED: add GEO-001..004; build unit target and run
  `ctest --test-dir .harness/build -C Debug -R "Mitc4Geometry" --output-on-failure`.
- GREEN: implement deterministic director/frame and exact geometry inventory validation.
- VERIFY: focused geometry/mapping tests, then common full VERIFY.
- Prohibitions: no calibrated angle/warp/distortion threshold; no NR-O03/O04.

### Step 3 — `mitc4-kinematics-constitutive`

- Required reading: formulation Sections 3-11/17, Numerical Review 5.1-5.6/6.1,
  current math adapters and Euler kernel style.
- Prerequisite: Step 2 `completed`.
- RED: add KIN-001..005 in new `mitc4_shell_test.cpp`, register it, build unit target,
  run `ctest --test-dir .harness/build -C Debug -R "Mitc4ShellKinematics|Mitc4ShellConstitutive" --output-on-failure`.
- GREEN: minimally add concrete shell kernel kinematics/constitutive seams; no global
  assembly or drilling.
- VERIFY: focused kernel tests, then common full VERIFY.
- Prohibitions: no public base hierarchy, no S4R branch, no nonlinear tangent code.

### Step 4 — `mitc4-stiffness-drilling`

- Required reading: formulation Sections 10-14/17, requirements 031-038/050-056,
  Numerical Review 5.7/6.1-6.2, completed Step 3 kernel.
- Prerequisite: Step 3 `completed`.
- RED: add KERNEL-001..006; build unit target and run
  `ctest --test-dir .harness/build -C Debug -R "Mitc4ShellKernel|Mitc4ShellPatch|Mitc4ShellDrilling" --output-on-failure`.
- GREEN: implement K20, 20-to-24 congruence and exact fixed drilling only.
- VERIFY: focused kernel suite, then common full VERIFY.
- Prohibitions: translations in R+, coefficient sweep, recovery/result output, future nonlinear.

### Step 5 — `mitc4-physical-recovery`

- Required reading: formulation Sections 14/16, requirements 035/042-046/052/056,
  I/O result component/location order, completed Step 4 kernel.
- Prerequisite: Step 4 `completed`.
- RED: add KERNEL-007 and PHYSREC-001; build unit target and run
  `ctest --test-dir .harness/build -C Debug -R "Mitc4ShellDrilling|Mitc4ShellPhysicalRecovery" --output-on-failure`.
- GREEN: minimally add kernel-local physical recovery and physical energy API only.
- VERIFY: focused physical recovery/drilling tests, then common full VERIFY.
- Prohibitions: no AnalysisState/global result rows, no drilling contribution or HDF5.

### Step 6 — `shell-dof-scatter`

- Required reading: requirements 005/025, architecture DofManager ownership, current
  `dof_manager.*` and constraint tests, completed shell model.
- Prerequisite: Step 5 `completed`.
- RED: add DOF-001..003; build unit target and run
  `ctest --test-dir .harness/build -C Debug -R "DofManager|EssentialConstraints" --output-on-failure`.
- GREEN: minimally add typed 24-entry scatter/pattern while preserving 12-entry B33.
- VERIFY: focused DOF/constraint tests, then common full VERIFY.
- Prohibitions: no equation IDs in model, no constraint/load ownership move.

### Step 7 — `shell-sparse-assembly`

- Required reading: requirements 027/030/037, architecture deterministic COO rule,
  current `sparse_assembler.cpp`/`sparse_matrix.cpp` tests, completed kernel/scatter.
- Prerequisite: Step 6 `completed`.
- RED: add ASM-001..003; build unit target and run
  `ctest --test-dir .harness/build -C Debug -R "SparseAssembly" --output-on-failure`.
- GREEN: minimally dispatch shell and emit stable 576-entry local buffers.
- VERIFY: focused assembly tests, then common full VERIFY.
- Prohibitions: no worker global CSR mutation, unordered reduction or S4R integration branch.

### Step 8 — `shell-load-validation`

- Required reading: requirements 017-020/028, formulation 8/13, I/O 4.2-4.3,
  current `load_assembler.*` and constraint lifecycle.
- Prerequisite: Step 7 `completed`.
- RED: add LOAD-001..004; build unit target and run
  `ctest --test-dir .harness/build -C Debug -R "LoadAssembly|EssentialConstraints" --output-on-failure`.
- GREEN: minimally add aggregate nodal moment/director validation and reuse full DOF load.
- VERIFY: focused load/constraint tests, then common full VERIFY.
- Prohibitions: no distributed/equivalent/follower load; no drill load channel.

### Step 9 — `shell-analysis-state`

- Required reading: requirements 026/041-046/048, I/O 6.3-6.5,
  current `analysis_state.*`/`result_records.hpp` and completed physical recovery types.
- Prerequisite: Step 8 `completed`.
- RED: add STATE-001..003; build unit target and run
  `ctest --test-dir .harness/build -C Debug -R "AnalysisState" --output-on-failure`.
- GREEN: minimally add candidate-owned shell row/global evidence containers and
  validation/commit mechanics.
- VERIFY: focused AnalysisState tests, then common full VERIFY.
- Prohibitions: no element calculation, ResultRecovery orchestration or HDF5 writing.

### Step 10 — `shell-result-recovery`

- Required reading: requirements 029/035/041-046/048, formulation 14/16, I/O 6.3-6.5,
  current `result_recovery.*` and completed Steps 5/9.
- Prerequisite: Step 9 `completed`.
- RED: add REC-001..005; build unit target and run
  `ctest --test-dir .harness/build -C Debug -R "ResultRecovery" --output-on-failure`.
- GREEN: minimally orchestrate full-residual evidence and physical shell recovery into
  a fully validated candidate, then commit it.
- VERIFY: focused recovery tests, then common full VERIFY.
- Prohibitions: no new result record type, location averaging, drill recovery or writer edit.

### Step 11 — `shell-hdf5-output`

- Required reading: requirements 039-048, I/O Section 6 exact schema, ADR atomic output,
  current HDF5 writer/self-check tests, completed recovery records.
- Prerequisite: Step 10 `completed`.
- RED: add H5-001..004; build unit target and run
  `ctest --test-dir .harness/build -C Debug -R "Hdf5ResultsWriter" --output-on-failure`.
- GREEN: add exact additive shell schema behind unchanged ResultsWriter boundary.
- VERIFY: focused HDF5 tests, then common full VERIFY.
- Prohibitions: no B33 schema reinterpretation, CSV solver output, partial final file.

### Step 12 — `shell-linear-static-flow`

- Required reading: requirements 024-030, architecture eight-hook lifecycle, I/O CLI
  contract, current `linear_static_analysis.*`/application integration tests.
- Prerequisite: Step 11 `completed`.
- RED: add FLOW-001..004; build integration target and run
  `ctest --test-dir .harness/build -C Debug -R "LinearStaticCli|Mitc4ShellCli" --output-on-failure`.
- GREEN: minimally route shell through existing lifecycle; preserve one factorization.
- VERIFY: focused integration tests, then common full VERIFY.
- Prohibitions: no analysis lifecycle reorder, no 0x0 singular conversion, no early state commit.

### Step 13 — `shell-reference-comparison`

- Required reading: requirements 058-072, I/O Section 7, Reference Model contract,
  both declared S4/S4R paths and hashes, and current B33 comparator only as reusable
  identity/report precedent.
- Scope ownership: this one test-only reference module owns TASK-13 comparator behavior
  plus TASK-14/TASK-15 declared-case tests; it owns no solver production module.
- Prerequisite: Step 12 `completed` and valid MITC4 HDF5 fixture.
- RED: add REF-001..006 plus E2E-S4-001/002 and E2E-S4R-001/002 before the comparator
  implementation; build the reference target and run
  `ctest --test-dir .harness/build -C Debug -R "Mitc4ReferenceComparison|Mitc4S4Reference|Mitc4S4RReference" --output-on-failure`.
  Record the missing comparator/declared-case failure.
- GREEN: minimally add test-only comparator for exact shell CSV/HDF5 contract.
- If a declared case exposes a production defect outside this reference-test module,
  stop the Step and route a focused correction to the owning prior module; do not patch
  unrelated production layers inside this Step.
- VERIFY: focused comparator and both declared-case tests, then common full VERIFY.
- Prohibitions: no reference artifact writes/Abaqus run, no metadata/README gate, no UR blocking.

After explicit approval, planning may create only:

- `phases/index.json` with task status `pending` and no creation timestamp;
- `phases/linear-static-mitc4-shell/index.json` with Steps 0-13 initially `pending` and
  no executor-owned timestamps;
- `phases/linear-static-mitc4-shell/stepN.md` containing the approved self-contained
  directions.

Approval does not authorize `python scripts/execute.py linear-static-mitc4-shell` or
`--push`.

## 13. Open Issues

| id | item | blocking now | resolution owner |
| --- | --- | --- | --- |
| OI-001 | Section 12 multi-Step Harness draft was explicitly approved on 2026-08-12 and materialized. | resolved | user |
| OI-002 | Candidate shell semantic representation and exact C++ value/reference types are not public API decisions. | no | owning RED test in Steps 0/3 |
| OI-003 | Per-test MITC4 CTest label can be added without relabeling B33 tests인지 확인한다. Exact suite regex remains sufficient. | no | Step 0 and downstream TASK-14 CMake verification |

No mathematical, I/O, reference-inventory or tolerance decision remains open for
implementation planning. The user separately authorized implementation and Harness
execution on 2026-08-12; the Executor still owns branch, Step selection, timestamps,
commits and advancement.
