# Step 1: mesh-keyword-parser ## Read First Read these files before editing: - `/AGENTS.md` - `/docs/PRD.md` - `/docs/ARCHITECTURE.md` - `/docs/ADR.md` - `/docs/io-definitions/abaqus-input-parser-io.md` - `/src/fesa/model/domain.hpp` - `/src/fesa/model/node.hpp` - `/src/fesa/model/element.hpp` - `/tests/unit/model_domain_test.cpp` Review step 0 output before implementing. Keep this step limited to parser API and mesh keyword mapping. ## Task Add the first C++ parser slice under `/src/fesa/io/abaqus/`. Required behavior: - Provide a small `InputParser` that accepts an in-memory `.inp` string and returns a parse result containing `fesa::model::Domain` and `fesa::core::Status`. - Parse `*HEADING` as accepted but not yet stored. - Parse `*NODE` data lines into `Domain::add_node`. - Parse `*ELEMENT, TYPE=` data lines into `Domain::add_element`. - Support only two-node line/bar element names needed by the current model: `T2D2`, `T3D2`, `B31`, and `C3D2`. - Map `T2D2`, `T3D2`, and `C3D2` to `ElementTopology::truss2`; map `B31` to `ElementTopology::bar2`. - Use `PropertyId{0}` for elements in this first mesh-only slice because section parsing is introduced later. - Treat keywords and parameter names case-insensitively. - Skip blank lines and comment lines that begin with `**`. Keep implementation C++17/MSVC-compatible. Do not introduce external libraries, regex-heavy parser frameworks, JavaScript, TypeScript, or npm fallbacks. ## Tests To Write First Add `/tests/unit/abaqus_input_parser_mesh_test.cpp` before production code. The test must first fail because `fesa/io/abaqus/input_parser.hpp` does not exist, then pass after implementation. It should verify: - a small input with `*HEADING`, `*NODE`, and `*ELEMENT, TYPE=T3D2` returns `Status::is_ok() == true`; - the returned `Domain` contains the expected node ids and 3D coordinates; - the returned `Domain` contains the expected element id, topology, connectivity, and `PropertyId{0}`; - keyword and parameter casing are accepted case-insensitively. ## Acceptance Criteria ```powershell ctest --test-dir build/msvc-debug --output-on-failure -C Debug -R abaqus_input_parser_mesh_test python -m unittest discover -s scripts -p "test_*.py" python scripts/validate_workspace.py ``` ## Verification Procedure 1. Run the targeted CTest after writing the test and before production code; confirm the failure is due to the missing parser API. 2. Implement the minimum code needed for the test to pass. 3. Run all acceptance criteria commands. 4. Confirm C++ production changes have a related C++ test file. 5. Update `phases/abaqus-input-parser/index.json` step 1: - success: `"status": "completed"`, `"summary": "Mesh keyword parser maps NODE and ELEMENT data into Domain"` - error after three attempts: `"status": "error"`, `"error_message": ""` - blocked: `"status": "blocked"`, `"blocked_reason": ""` ## Forbidden - Do not add set, material, section, load, boundary condition, output request, include-file, or HDF5 behavior in this step. - Do not mutate reference artifacts.