# 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를 수동 실행하지 마라.
