diff --git a/phases/deterministic-parallel-assembly/index.json b/phases/deterministic-parallel-assembly/index.json
index 4d1db16..c51a9d5 100644
--- a/phases/deterministic-parallel-assembly/index.json
+++ b/phases/deterministic-parallel-assembly/index.json
@@ -21,7 +21,10 @@
{
"step": 2,
"name": "thread-count-determinism",
- "status": "pending"
+ "status": "completed",
+ "summary": "Added 10-run bitwise CSR, RHS, displacement, and reaction checks at 1, 2, and 16 threads plus a production serial/parallel assembly benchmark.",
+ "started_at": "2026-08-01T23:21:27+0900",
+ "completed_at": "2026-08-01T23:36:17+0900"
}
],
"created_at": "2026-08-01T22:17:55+0900"
diff --git a/phases/deterministic-parallel-assembly/step2-output.json b/phases/deterministic-parallel-assembly/step2-output.json
new file mode 100644
index 0000000..32b46fc
--- /dev/null
+++ b/phases/deterministic-parallel-assembly/step2-output.json
@@ -0,0 +1,7 @@
+{
+ "step": 2,
+ "name": "thread-count-determinism",
+ "exitCode": 0,
+ "stdout": "{\"type\":\"thread.started\",\"thread_id\":\"019fbdb3-896c-7b93-881c-a49cd19a822c\"}\n{\"type\":\"item.completed\",\"item\":{\"id\":\"item_0\",\"type\":\"error\",\"message\":\"`--dangerously-bypass-hook-trust` is enabled. Enabled hooks may run without review for this invocation.\"}}\n{\"type\":\"item.completed\",\"item\":{\"id\":\"item_1\",\"type\":\"error\",\"message\":\"`--dangerously-bypass-hook-trust` is enabled. Enabled hooks may run without review for this invocation.\"}}\n{\"type\":\"turn.started\"}\n{\"type\":\"item.completed\",\"item\":{\"id\":\"item_2\",\"type\":\"agent_message\",\"text\":\"`harness`와 Superpowers의 계획·TDD·완료 검증 절차를 적용하겠습니다. 먼저 해당 스킬 지침과 Step 2 메타데이터·기존 Step 0/1 구현을 확인한 뒤, 실패 테스트 → 최소 구현 → AC 전체 검증 순서로 진행하겠습니다.\"}}\n{\"type\":\"item.started\",\"item\":{\"id\":\"item_3\",\"type\":\"command_execution\",\"command\":\"\\\"C:\\\\\\\\WINDOWS\\\\\\\\System32\\\\\\\\WindowsPowerShell\\\\\\\\v1.0\\\\\\\\powershell.exe\\\" -Command \\\"Get-Content -Raw 'C:\\\\\\\\Users\\\\\\\\baram\\\\\\\\.codex\\\\\\\\plugins\\\\\\\\cache\\\\\\\\openai-curated-remote\\\\\\\\superpowers\\\\\\\\6.2.0\\\\\\\\skills\\\\\\\\using-superpowers\\\\\\\\SKILL.md'; Get-Content -Raw 'C:\\\\\\\\git\\\\\\\\FESA\\\\\\\\.agents\\\\\\\\skills\\\\\\\\harness\\\\\\\\SKILL.md'\\\"\",\"aggregated_output\":\"\",\"exit_code\":null,\"status\":\"in_progress\"}}\n{\"type\":\"item.completed\",\"item\":{\"id\":\"item_3\",\"type\":\"command_execution\",\"command\":\"\\\"C:\\\\\\\\WINDOWS\\\\\\\\System32\\\\\\\\WindowsPowerShell\\\\\\\\v1.0\\\\\\\\powershell.exe\\\" -Command \\\"Get-Content -Raw 'C:\\\\\\\\Users\\\\\\\\baram\\\\\\\\.codex\\\\\\\\plugins\\\\\\\\cache\\\\\\\\openai-curated-remote\\\\\\\\superpowers\\\\\\\\6.2.0\\\\\\\\skills\\\\\\\\using-superpowers\\\\\\\\SKILL.md'; Get-Content -Raw 'C:\\\\\\\\git\\\\\\\\FESA\\\\\\\\.agents\\\\\\\\skills\\\\\\\\harness\\\\\\\\SKILL.md'\\\"\",\"aggregated_output\":\"---\\nname: using-superpowers\\ndescription: Use when starting any conversation - establishes how to find and use skills, requiring skill invocation before ANY response including clarifying questions\\n---\\n\\n\\nIf you were dispatched as a subagent to execute a specific task, ignore this skill.\\n\\n\\n\\nIf you think there is even a 1% chance a skill might apply to what you are doing, you ABSOLUTELY MUST invoke the skill.\\n\\nIF A SKILL APPLIES TO YOUR TASK, YOU DO NOT HAVE A CHOICE. YOU MUST USE IT.\\n\\nThis is not negotiable. You cannot rationalize your way out of this.\\n\\n\\n## The Rule\\n\\n**Invoke relevant or requested skills BEFORE any response or action** ??including clarifying questions, exploring the codebase, or checking files. If it turns out wrong for the situation, you don't have to use it.\\n\\n**Before entering plan mode:** if you haven't already brainstormed, invoke the brainstorming skill first.\\n\\nThen announce \\\"Using [skill] to [purpose]\\\" and follow the skill exactly. If it has a checklist, create a todo per item.\\n\\n## Skill Priority\\n\\nWhen multiple skills apply, process skills come first ??they set the approach, then implementation skills (frontend-design, etc.) carry it out. Brainstorming and systematic-debugging are Superpowers' most common process skills, but the rule holds for any of them.\\n\\n- \\\"Let's build X\\\" ??superpowers:brainstorming first, then implementation skills.\\n- \\\"Fix this bug\\\" ??superpowers:systematic-debugging first, then domain skills.\\n\\n## Red Flags\\n\\nThese thoughts mean STOP?봸ou're rationalizing:\\n\\n| Thought | Reality |\\n|---------|---------|\\n| \\\"This is just a simple question\\\" | Questions are tasks. Check for skills. |\\n| \\\"I need more context first\\\" | Skill check comes BEFORE clarifying questions. |\\n| \\\"Let me explore the codebase first\\\" | Skills tell you HOW to explore. Check first. |\\n| \\\"I can check git/files quickly\\\" | Files lack conversation context. Check for skills. |\\n| \\\"Let me gather information first\\\" | Skills tell you HOW to gather information. |\\n| \\\"This doesn't need a formal skill\\\" | If a skill exists, use it. |\\n| \\\"I remember this skill\\\" | Skills evolve. Read current version. |\\n| \\\"This doesn't count as a task\\\" | Action = task. Check for skills. |\\n| \\\"The skill is overkill\\\" | Simple things become complex. Use it. |\\n| \\\"I'll just do this one thing first\\\" | Check BEFORE doing anything. |\\n| \\\"This feels productive\\\" | Undisciplined action wastes time. Skills prevent this. |\\n| \\\"I know what that means\\\" | Knowing the concept ??using the skill. Invoke it. |\\n\\n## Platform Adaptation\\n\\nIf your harness appears here, read its reference file for special instructions:\\n\\n- Codex: `references/codex-tools.md`\\n- Pi: `references/pi-tools.md`\\n- Antigravity: `references/antigravity-tools.md`\\n\\n## User Instructions\\n\\nUser instructions (CLAUDE.md, AGENTS.md, GEMINI.md, etc, direct requests) take precedence over skills, which in turn override default behavior. Only skip skill workflows or instructions when your human partner has explicitly told you to.\\n\\r\\n---\\r\\nname: harness\\r\\ndescription: Use when planning agentic implementation phases, creating phases/index.json and self-contained step files, or running the Harness step executor.\\r\\n---\\r\\n\\r\\n# Harness Workflow\\r\\n\\r\\n???꾨줈?앺듃??Harness ?꾨젅?꾩썙?щ? ?ъ슜?쒕떎. ?꾨옒 ?뚰겕?뚮줈???곕씪 ?묒뾽?쒕떎.\\r\\n\\r\\n## A. ?먯깋\\r\\n\\r\\n`AGENTS.md`? `docs/` ?섏쐞 臾몄꽌(PRD, ARCHITECTURE, ADR ??瑜??쎄퀬 ?꾨줈?앺듃??湲고쉷,\\r\\n?꾪궎?띿쿂, ?ㅺ퀎 ?섎룄瑜??뚯븙?쒕떎. 蹂묐젹 ?먯깋???ㅼ젣濡??좎슜?섍퀬 ?꾩옱 ?몄뀡?먯꽌 ?덉슜??\\n?뚮쭔 Codex subagent瑜??좏깮?곸쑝濡??ъ슜?쒕떎.\\r\\n\\r\\n## B. ?쇱쓽\\r\\n\\r\\n援ы쁽???꾪빐 援ъ껜?뷀븯嫄곕굹 湲곗닠?곸쑝濡?寃곗젙?댁빞 ???ы빆???덉쑝硫??ъ슜?먯뿉寃???踰덉뿉\\r\\n?섎굹???쒖떆?섍퀬 ?쇱쓽?쒕떎.\\r\\n\\r\\n## C. Step ?ㅺ퀎\\r\\n\\r\\n?ъ슜?먭? 援ы쁽 怨꾪쉷 ?묒꽦??吏?쒗븯硫??щ윭 step?쇰줈 ?섎돏 珥덉븞???묒꽦???쇰뱶諛깆쓣\\r\\n?붿껌?쒕떎.\\r\\n\\r\\n?ㅺ퀎 ?먯튃:\\r\\n\\r\\n1. **Scope 理쒖냼??* ???섎굹??step?먯꽌 ?섎굹???덉씠???먮뒗 紐⑤뱢留??ㅻ,?? ?щ윭\\r\\n 紐⑤뱢???숈떆???섏젙?댁빞 ?섎㈃ step??履쇨컿??\\r\\n2. **?먭린?꾧껐??* ??媛?step ?뚯씪? ?낅┰??Codex ?ㅽ뻾?먯꽌 ?ъ슜?쒕떎. ?몃? ???\\n 李몄“瑜?湲덉??섍퀬 ?꾩슂???뺣낫瑜?紐⑤몢 ?뚯씪 ?덉뿉 ?곷뒗??\\r\\n3. **?ъ쟾 以鍮?媛뺤젣** ??愿??臾몄꽌? ?댁쟾 step?먯꽌 ?앹꽦?섍굅???섏젙???뚯씪 寃쎈줈瑜?\\n 紐낆떆?쒕떎.\\r\\n4. **?쒓렇?덉쿂 ?섏? 吏??* ???⑥닔? ?대옒?ㅼ쓽 ?명꽣?섏씠?ㅻ? ?쒖떆?섍퀬 ?대? 援ы쁽?\\r\\n Codex ?щ웾??留↔릿?? 硫깅벑?? 蹂댁븞, ?곗씠??臾닿껐??媛숈? ?듭떖 洹쒖튃? 紐낆떆?쒕떎.\\r\\n5. **AC???ㅽ뻾 媛?ν븳 command** ??異붿긽??議곌굔 ????ㅼ젣 鍮뚮뱶? ?뚯뒪??command瑜?\\n ?ы븿?쒕떎.\\r\\n6. **二쇱쓽?ы빆? 援ъ껜?곸쑝濡?* ??\\\"X瑜??섏? 留덈씪. ?댁쑀: Y\\\" ?뺤떇?쇰줈 ?곷뒗??\\r\\n7. **?ㅼ씠諛?* ??step name? ?듭떖 ?묒뾽???쒗쁽?섎뒗 kebab-case slug濡??뺥븳??\\r\\n\\r\\n## D. ?뚯씪 ?앹꽦\\r\\n\\r\\n?ъ슜?먭? 珥덉븞???뱀씤???꾩뿉留??ㅼ쓬 ?뚯씪???앹꽦?쒕떎.\\r\\n\\r\\n### D-1. `phases/index.json`\\r\\n\\r\\n?щ윭 task瑜?愿由ы븯??top-level ?몃뜳?ㅻ떎. ?대? 議댁옱?섎㈃ `phases` 諛곗뿴??????ぉ??\\n異붽??쒕떎.\\r\\n\\r\\n```json\\r\\n{\\r\\n \\\"phases\\\": [\\r\\n {\\r\\n \\\"dir\\\": \\\"0-mvp\\\",\\r\\n \\\"status\\\": \\\"pending\\\"\\r\\n }\\r\\n ]\\r\\n}\\r\\n```\\r\\n\\r\\n- `dir`: task ?붾젆?곕━紐?\\n- `status`: `pending` | `completed` | `error` | `blocked`\\r\\n- timestamp??executor媛 ?곹깭瑜?諛붽? ??湲곕줉?섎?濡??앹꽦 ???l? ?딅뒗??\\r\\n\\r\\n### D-2. `phases/{task-name}/index.json`\\r\\n\\r\\n```json\\r\\n{\\r\\n \\\"project\\\": \\\"\\\",\\r\\n \\\"steps\\\": [\\r\\n { \\\"step\\\": 0, \\\"name\\\": \\\"project-setup\\\", \\\"status\\\": \\\"pending\\\" },\\r\\n { \\\"step\\\": 1, \\\"name\\\": \\\"core-types\\\", \\\"status\\\": \\\"pending\\\" },\\r\\n { \\\"step\\\": 2, \\\"name\\\": \\\"api-layer\\\", \\\"status\\\": \\\"pending\\\" }\\r\\n ]\\r\\n}\\r\\n```\\r\\n\\r\\n?꾨뱶 洹쒖튃:\\r\\n\\r\\n- `project`: `AGENTS.md`???뺤쓽???꾨줈?앺듃紐?\\n- `phase`: task ?대쫫?대ʼn ?붾젆?곕━紐낃낵 ?쇱튂\\r\\n- `steps[].step`: 0遺???쒖옉?섎뒗 ?쒕쾲\\r\\n- `steps[].name`: kebab-case slug\\r\\n- `steps[].status`: 珥덇린媛?`pending`\\r\\n\\r\\n?곹깭? 湲곕줉 二쇱껜:\\r\\n\\r\\n| ?꾩씠 | 湲곕줉 ?꾨뱶 | 湲곕줉 二쇱껜 |\\r\\n|------|-----------|-----------|\\r\\n| `completed` | `summary`, `completed_at` | Codex媛 summary, executor媛 timestamp |\\r\\n| `error` | `error_message`, `failed_at` | Codex媛 message, executor媛 timestamp |\\r\\n| `blocked` | `blocked_reason`, `blocked_at` | Codex媛 reason, executor媛 timestamp |\\r\\n\\r\\n`summary`?먮뒗 ?ㅼ쓬 step???좎슜???앹꽦 ?뚯씪怨??듭떖 寃곗젙????以꾨줈 ?곷뒗??\\r\\ntask `created_at`怨?step `started_at`? executor媛 湲곕줉?섎?濡??앹꽦 ???l? ?딅뒗??\\r\\n\\r\\n### D-3. `phases/{task-name}/step{N}.md`\\r\\n\\r\\n````markdown\\r\\n# Step {N}: {?대쫫}\\r\\n\\r\\n## ?쎌뼱?????뚯씪\\r\\n\\r\\n癒쇱? ?꾨옒 ?뚯씪???쎄퀬 ?꾨줈?앺듃???꾪궎?띿쿂? ?ㅺ퀎 ?섎룄瑜??뚯븙?섎씪:\\r\\n\\r\\n- `/AGENTS.md`\\r\\n- `/docs/ARCHITECTURE.md`\\r\\n- `/docs/ADR.md`\\r\\n- ?댁쟾 step?먯꽌 ?앹꽦?섍굅???섏젙???뚯씪 寃쎈줈\\r\\n\\r\\n?댁쟾 step??肄붾뱶瑜?瑗쇨세???쎄퀬 ?ㅺ퀎 ?섎룄瑜??댄빐?????묒뾽?섎씪.\\r\\n\\r\\n## ?묒뾽\\r\\n\\r\\n援ъ껜?곸씤 援ы쁽 吏?쒕? ?뚯씪 寃쎈줈, ?대옒?ㅼ? ?⑥닔 ?쒓렇?덉쿂, 濡쒖쭅 ?ㅻ챸怨??④퍡 ?곷뒗??\\r\\n援ы쁽泥대뒗 Codex??留↔린???ㅺ퀎 ?섎룄?먯꽌 踰쀬뼱?섎㈃ ???섎뒗 ?듭떖 洹쒖튃? 紐낆떆?쒕떎.\\r\\n\\r\\n## Acceptance Criteria\\r\\n\\r\\n?꾨줈?앺듃 ?뺤떇??留욌뒗 紐낅졊???ъ슜?쒕떎. `.harness/config.json`???덉쑝硫??대떦 preset,\\r\\nsolution, configuration, platform, test command瑜??곗꽑?쒕떎.\\r\\n\\r\\n```powershell\\r\\n# CMake\\r\\ncmake --build .harness/build --config Debug\\r\\nctest --test-dir .harness/build -C Debug --output-on-failure\\r\\n\\r\\n# 吏곸젒 MSBuild\\r\\nMSBuild.exe MyProject.sln /m /p:Configuration=Debug /p:Platform=x64\\r\\n.\\\\build\\\\tests\\\\Debug\\\\MyProjectTests.exe\\r\\n```\\r\\n\\r\\n## 寃利??덉감\\r\\n\\r\\n1. Acceptance Criteria command瑜??ㅽ뻾?쒕떎.\\r\\n2. ARCHITECTURE ?붾젆?곕━ 援ъ“瑜??곕Ⅴ?붿? ?뺤씤?쒕떎.\\r\\n3. ADR 湲곗닠 ?ㅽ깮怨?`AGENTS.md` CRITICAL 洹쒖튃???뺤씤?쒕떎.\\r\\n4. 寃곌낵???곕씪 task index???대떦 step??媛깆떊?쒕떎.\\r\\n - ?깃났: `status`瑜?`completed`濡?諛붽씀怨???以?`summary` 湲곕줉\\r\\n - ?섏젙 3?????ㅽ뙣: `status`瑜?`error`濡?諛붽씀怨?`error_message` 湲곕줉\\r\\n - ?ъ슜??媛쒖엯 ?꾩슂: `status`瑜?`blocked`濡?諛붽씀怨?`blocked_reason` 湲곕줉 ??以묐떒\\r\\n\\r\\n## 湲덉??ы빆\\r\\n\\r\\n- ??step??踰붿쐞 諛?湲곕뒫??異붽??섏? 留덈씪. ?댁쑀: step???낅┰?깆쓣 源⑤쑉由곕떎.\\r\\n- 湲곗〈 ?뚯뒪?몃? 源⑤쑉由ъ? 留덈씪. ?댁쑀: ?댁쟾 ?숈옉???뚭??쒗궓??\\r\\n````\\r\\n\\r\\n## E. ?ㅽ뻾\\r\\n\\r\\n```bash\\r\\npython scripts/execute.py {task-name}\\r\\npython scripts/execute.py {task-name} --push\\r\\n```\\r\\n\\r\\n?섍꼍?먯꽌 Python 3 ?ㅽ뻾 紐낅졊??`python3`?대㈃ 洹?紐낅졊??????ъ슜?쒕떎.\\r\\n\\r\\nexecutor媛 泥섎━?섎뒗 ?묒뾽:\\r\\n\\r\\n- `feat-{task-name}` 釉뚮옖移??앹꽦 ?먮뒗 checkout\\r\\n- `AGENTS.md`? `docs/*.md` guardrail 二쇱엯\\r\\n- ?꾨즺 step??summary瑜??ㅼ쓬 prompt???꾩쟻\\r\\n- ?ㅽ뙣 ??理쒕? 3???ъ떆?꾪븯硫??댁쟾 ?ㅻ쪟瑜?prompt???꾨떖\\r\\n- 肄붾뱶 蹂寃쎄낵 metadata瑜?遺꾨━??commit\\r\\n- `started_at`, `completed_at`, `failed_at`, `blocked_at` 湲곕줉\\r\\n\\r\\n?먮윭 蹂듦뎄:\\r\\n\\r\\n- `error`: ?대떦 status瑜?`pending`?쇰줈 諛붽씀怨?`error_message`瑜???젣?????ъ떎??\\n- `blocked`: ?먯씤???닿껐?섍퀬 status瑜?`pending`?쇰줈 諛붽씀怨?`blocked_reason`????젣??\\n ???ъ떎??\\n\\r\\n\",\"exit_code\":0,\"status\":\"completed\"}}\n{\"type\":\"item.completed\",\"item\":{\"id\":\"item_4\",\"type\":\"agent_message\",\"text\":\"`using-superpowers` 지침에 따라 구현 전 설계 확인, TDD, 실행 계획 준수, 완료 전 검증 스킬도 함께 적용합니다. Step 문서가 이미 승인된 구현 계획이므로 범위를 재설계하지 않고, 명시된 결정성 불변식과 테스트 구조만 짧게 확정하겠습니다.\"}}\n{\"type\":\"item.started\",\"item\":{\"id\":\"item_5\",\"type\":\"command_execution\",\"command\":\"\\\"C:\\\\\\\\WINDOWS\\\\\\\\System32\\\\\\\\WindowsPowerShell\\\\\\\\v1.0\\\\\\\\powershell.exe\\\" -Command \\\"Get-Content -Raw 'C:\\\\\\\\Users\\\\\\\\baram\\\\\\\\.codex\\\\\\\\plugins\\\\\\\\cache\\\\\\\\openai-curated-remote\\\\\\\\superpowers\\\\\\\\6.2.0\\\\\\\\skills\\\\\\\\using-superpowers\\\\\\\\references\\\\\\\\codex-tools.md'; Get-Content -Raw 'C:\\\\\\\\Users\\\\\\\\baram\\\\\\\\.codex\\\\\\\\plugins\\\\\\\\cache\\\\\\\\openai-curated-remote\\\\\\\\superpowers\\\\\\\\6.2.0\\\\\\\\skills\\\\\\\\brainstorming\\\\\\\\SKILL.md'; Get-Content -Raw 'C:\\\\\\\\Users\\\\\\\\baram\\\\\\\\.codex\\\\\\\\plugins\\\\\\\\cache\\\\\\\\openai-curated-remote\\\\\\\\superpowers\\\\\\\\6.2.0\\\\\\\\skills\\\\\\\\executing-plans\\\\\\\\SKILL.md'; Get-Content -Raw 'C:\\\\\\\\Users\\\\\\\\baram\\\\\\\\.codex\\\\\\\\plugins\\\\\\\\cache\\\\\\\\openai-curated-remote\\\\\\\\superpowers\\\\\\\\6.2.0\\\\\\\\skills\\\\\\\\test-driven-development\\\\\\\\SKILL.md'; Get-Content -Raw 'C:\\\\\\\\Users\\\\\\\\baram\\\\\\\\.codex\\\\\\\\plugins\\\\\\\\cache\\\\\\\\openai-curated-remote\\\\\\\\superpowers\\\\\\\\6.2.0\\\\\\\\skills\\\\\\\\verification-before-completion\\\\\\\\SKILL.md'; Get-Content -Raw 'C:\\\\\\\\Users\\\\\\\\baram\\\\\\\\.codex\\\\\\\\plugins\\\\\\\\cache\\\\\\\\openai-curated-remote\\\\\\\\superpowers\\\\\\\\6.2.0\\\\\\\\skills\\\\\\\\requesting-code-review\\\\\\\\SKILL.md'\\\"\",\"aggregated_output\":\"\",\"exit_code\":null,\"status\":\"in_progress\"}}\n{\"type\":\"item.completed\",\"item\":{\"id\":\"item_5\",\"type\":\"command_execution\",\"command\":\"\\\"C:\\\\\\\\WINDOWS\\\\\\\\System32\\\\\\\\WindowsPowerShell\\\\\\\\v1.0\\\\\\\\powershell.exe\\\" -Command \\\"Get-Content -Raw 'C:\\\\\\\\Users\\\\\\\\baram\\\\\\\\.codex\\\\\\\\plugins\\\\\\\\cache\\\\\\\\openai-curated-remote\\\\\\\\superpowers\\\\\\\\6.2.0\\\\\\\\skills\\\\\\\\using-superpowers\\\\\\\\references\\\\\\\\codex-tools.md'; Get-Content -Raw 'C:\\\\\\\\Users\\\\\\\\baram\\\\\\\\.codex\\\\\\\\plugins\\\\\\\\cache\\\\\\\\openai-curated-remote\\\\\\\\superpowers\\\\\\\\6.2.0\\\\\\\\skills\\\\\\\\brainstorming\\\\\\\\SKILL.md'; Get-Content -Raw 'C:\\\\\\\\Users\\\\\\\\baram\\\\\\\\.codex\\\\\\\\plugins\\\\\\\\cache\\\\\\\\openai-curated-remote\\\\\\\\superpowers\\\\\\\\6.2.0\\\\\\\\skills\\\\\\\\executing-plans\\\\\\\\SKILL.md'; Get-Content -Raw 'C:\\\\\\\\Users\\\\\\\\baram\\\\\\\\.codex\\\\\\\\plugins\\\\\\\\cache\\\\\\\\openai-curated-remote\\\\\\\\superpowers\\\\\\\\6.2.0\\\\\\\\skills\\\\\\\\test-driven-development\\\\\\\\SKILL.md'; Get-Content -Raw 'C:\\\\\\\\Users\\\\\\\\baram\\\\\\\\.codex\\\\\\\\plugins\\\\\\\\cache\\\\\\\\openai-curated-remote\\\\\\\\superpowers\\\\\\\\6.2.0\\\\\\\\skills\\\\\\\\verification-before-completion\\\\\\\\SKILL.md'; Get-Content -Raw 'C:\\\\\\\\Users\\\\\\\\baram\\\\\\\\.codex\\\\\\\\plugins\\\\\\\\cache\\\\\\\\openai-curated-remote\\\\\\\\superpowers\\\\\\\\6.2.0\\\\\\\\skills\\\\\\\\requesting-code-review\\\\\\\\SKILL.md'\\\"\",\"aggregated_output\":\"## Subagent dispatch requires multi-agent support\\n\\nAdd to your Codex config (`~/.codex/config.toml`):\\n\\n```toml\\n[features]\\nmulti_agent = true\\n```\\n\\nThis enables `spawn_agent`, `wait_agent`, and `close_agent` for skills like `dispatching-parallel-agents` and `subagent-driven-development`. When using subagent-driven-development, close reviewer subagents when their review returns. Keep each implementer subagent open until its task's review passes ??the fix loop resumes the implementer ??then close it. If your harness cannot send another message to a spawned agent, dispatch each fix round as a fresh implementer carrying the brief, the report file, and the findings.\\n\\n## Environment Detection\\n\\nSkills that create worktrees or finish branches should detect their\\nenvironment with read-only git commands before proceeding:\\n\\n```bash\\nGIT_DIR=$(cd \\\"$(git rev-parse --git-dir)\\\" 2>/dev/null && pwd -P)\\nGIT_COMMON=$(cd \\\"$(git rev-parse --git-common-dir)\\\" 2>/dev/null && pwd -P)\\nBRANCH=$(git branch --show-current)\\n```\\n\\n- `GIT_DIR != GIT_COMMON` ??already in a linked worktree (skip creation)\\n- `BRANCH` empty ??detached HEAD (cannot branch/push/PR from sandbox)\\n\\nSee `using-git-worktrees` Step 0 and `finishing-a-development-branch`\\nStep 1 for how each skill uses these signals.\\n\\n## Codex App Finishing\\n\\nWhen the sandbox blocks branch/push operations (detached HEAD in an\\nexternally managed worktree), the agent commits all work and informs\\nthe user to use the App's native controls:\\n\\n- **\\\"Create branch\\\"** ??names the branch, then commit/push/PR via App UI\\n- **\\\"Hand off to local\\\"** ??transfers work to the user's local checkout\\n\\nThe agent can still run tests, stage files, and output suggested branch\\nnames, commit messages, and PR descriptions for the user to copy.\\n\\r\\n---\\nname: brainstorming\\ndescription: \\\"You MUST use this before any creative work - creating features, building components, adding functionality, or modifying behavior. Explores user intent, requirements and design before implementation.\\\"\\n---\\n\\n# Brainstorming Ideas Into Designs\\n\\nHelp turn ideas into fully formed designs and specs through natural collaborative dialogue.\\n\\nStart by understanding the current project context, then ask questions one at a time to refine the idea. Once you understand what you're building, present the design and get user approval.\\n\\n\\nDo NOT invoke any implementation skill, write any code, scaffold any project, or take any implementation action until you have presented a design and the user has approved it. This applies to EVERY project regardless of perceived simplicity.\\n\\n\\n## Anti-Pattern: \\\"This Is Too Simple To Need A Design\\\"\\n\\nEvery project goes through this process. A todo list, a single-function utility, a config change ??all of them. \\\"Simple\\\" projects are where unexamined assumptions cause the most wasted work. The design can be short (a few sentences for truly simple projects), but you MUST present it and get approval.\\n\\n## Checklist\\n\\nYou MUST create a task for each of these items and complete them in order:\\n\\n1. **Explore project context** ??check files, docs, recent commits\\n2. **Offer the visual companion just-in-time** ??NOT upfront. The first time a question would genuinely be clearer shown than described, offer it then (its own message); on approval its browser tab opens for you. If no visual question ever arises, never offer it. See the Visual Companion section below.\\n3. **Ask clarifying questions** ??one at a time, understand purpose/constraints/success criteria\\n4. **Propose 2-3 approaches** ??with trade-offs and your recommendation\\n5. **Present design** ??in sections scaled to their complexity, get user approval after each section\\n6. **Write design doc** ??save to `docs/superpowers/specs/YYYY-MM-DD--design.md` and commit\\n7. **Spec self-review** ??quick inline check for placeholders, contradictions, ambiguity, scope (see below)\\n8. **User reviews written spec** ??ask user to review the spec file before proceeding\\n9. **Transition to implementation** ??invoke writing-plans skill to create implementation plan\\n\\n## Process Flow\\n\\n```dot\\ndigraph brainstorming {\\n \\\"Explore project context\\\" [shape=box];\\n \\\"Ask clarifying questions\\\" [shape=box];\\n \\\"Propose 2-3 approaches\\\" [shape=box];\\n \\\"Present design sections\\\" [shape=box];\\n \\\"User approves design?\\\" [shape=diamond];\\n \\\"Write design doc\\\" [shape=box];\\n \\\"Spec self-review\\\\n(fix inline)\\\" [shape=box];\\n \\\"User reviews spec?\\\" [shape=diamond];\\n \\\"Invoke writing-plans skill\\\" [shape=doublecircle];\\n\\n \\\"Explore project context\\\" -> \\\"Ask clarifying questions\\\";\\n \\\"Ask clarifying questions\\\" -> \\\"Propose 2-3 approaches\\\";\\n \\\"Propose 2-3 approaches\\\" -> \\\"Present design sections\\\";\\n \\\"Present design sections\\\" -> \\\"User approves design?\\\";\\n \\\"User approves design?\\\" -> \\\"Present design sections\\\" [label=\\\"no, revise\\\"];\\n \\\"User approves design?\\\" -> \\\"Write design doc\\\" [label=\\\"yes\\\"];\\n \\\"Write design doc\\\" -> \\\"Spec self-review\\\\n(fix inline)\\\";\\n \\\"Spec self-review\\\\n(fix inline)\\\" -> \\\"User reviews spec?\\\";\\n \\\"User reviews spec?\\\" -> \\\"Write design doc\\\" [label=\\\"changes requested\\\"];\\n \\\"User reviews spec?\\\" -> \\\"Invoke writing-plans skill\\\" [label=\\\"approved\\\"];\\n}\\n```\\n\\n**The terminal state is invoking writing-plans.** Do NOT invoke frontend-design, mcp-builder, or any other implementation skill. The ONLY skill you invoke after brainstorming is writing-plans.\\n\\n## The Process\\n\\n**Understanding the idea:**\\n\\n- Check out the current project state first (files, docs, recent commits)\\n- Before asking detailed questions, assess scope: if the request describes multiple independent subsystems (e.g., \\\"build a platform with chat, file storage, billing, and analytics\\\"), flag this immediately. Don't spend questions refining details of a project that needs to be decomposed first.\\n- If the project is too large for a single spec, help the user decompose into sub-projects: what are the independent pieces, how do they relate, what order should they be built? Then brainstorm the first sub-project through the normal design flow. Each sub-project gets its own spec ??plan ??implementation cycle.\\n- For appropriately-scoped projects, ask questions one at a time to refine the idea\\n- Prefer multiple choice questions when possible, but open-ended is fine too\\n- Only one question per message - if a topic needs more exploration, break it into multiple questions\\n- Focus on understanding: purpose, constraints, success criteria\\n\\n**Exploring approaches:**\\n\\n- Propose 2-3 different approaches with trade-offs\\n- Present options conversationally with your recommendation and reasoning\\n- Lead with your recommended option and explain why\\n- YAGNI ruthlessly - remove unnecessary features from every approach and design\\n\\n**Presenting the design:**\\n\\n- Once you believe you understand what you're building, present the design\\n- Scale each section to its complexity: a few sentences if straightforward, up to 200-300 words if nuanced\\n- Ask after each section whether it looks right so far\\n- Cover: architecture, components, data flow, error handling, testing\\n- Be ready to go back and clarify if something doesn't make sense\\n\\n**Design for isolation and clarity:**\\n\\n- Break the system into smaller units that each have one clear purpose, communicate through well-defined interfaces, and can be understood and tested independently\\n- For each unit, you should be able to answer: what does it do, how do you use it, and what does it depend on?\\n- Can someone understand what a unit does without reading its internals? Can you change the internals without breaking consumers? If not, the boundaries need work.\\n- Smaller, well-bounded units are also easier for you to work with - you reason better about code you can hold in context at once, and your edits are more reliable when files are focused. When a file grows large, that's often a signal that it's doing too much.\\n\\n**Working in existing codebases:**\\n\\n- Explore the current structure before proposing changes. Follow existing patterns.\\n- Where existing code has problems that affect the work (e.g., a file that's grown too large, unclear boundaries, tangled responsibilities), include targeted improvements as part of the design - the way a good developer improves code they're working in.\\n- Don't propose unrelated refactoring. Stay focused on what serves the current goal.\\n\\n## After the Design\\n\\n**Documentation:**\\n\\n- Write the validated design (spec) to `docs/superpowers/specs/YYYY-MM-DD--design.md`\\n - (User preferences for spec location override this default)\\n- Use elements-of-style:writing-clearly-and-concisely skill if available\\n- Commit the design document to git\\n\\n**Spec Self-Review:**\\nAfter writing the spec document, look at it with fresh eyes:\\n\\n1. **Placeholder scan:** Any \\\"TBD\\\", \\\"TODO\\\", incomplete sections, or vague requirements? Fix them.\\n2. **Internal consistency:** Do any sections contradict each other? Does the architecture match the feature descriptions?\\n3. **Scope check:** Is this focused enough for a single implementation plan, or does it need decomposition?\\n4. **Ambiguity check:** Could any requirement be interpreted two different ways? If so, pick one and make it explicit.\\n\\nFix any issues inline. No need to re-review ??just fix and move on.\\n\\n**User Review Gate:**\\nAfter the spec review loop passes, ask the user to review the written spec before proceeding:\\n\\n> \\\"Spec written and committed to ``. Please review it and let me know if you want to make any changes before we start writing out the implementation plan.\\\"\\n\\nWait for the user's response. If they request changes, make them and re-run the spec review loop. Only proceed once the user approves.\\n\\n**Implementation:**\\n\\n- Invoke the writing-plans skill to create a detailed implementation plan\\n- Do NOT invoke any other skill. writing-plans is the next step.\\n\\n## Visual Companion\\n\\nA browser-based companion for showing mockups, diagrams, and visual options during brainstorming. Available as a tool ??not a mode. Accepting the companion means it's available for questions that benefit from visual treatment; it does NOT mean every question goes through the browser.\\n\\n**Offering the companion (just-in-time):** Do NOT offer it upfront. Wait until a question would genuinely be clearer shown than told ??a real mockup / layout / diagram question, not merely a UI *topic*. The first time that happens, offer it then, as its own message:\\n> \\\"This next part might be easier if I show you ??I can put together mockups, diagrams, and comparisons in a browser tab as we go. It's still new and can be token-intensive. Want me to? I'll open it for you.\\\"\\n\\n**This offer MUST be its own message.** Only the offer ??no clarifying question, summary, or other content. Wait for the user's response. If they accept, start the server with `--open` so their browser opens to the first screen automatically. If they decline, continue text-only and don't offer again unless they raise it.\\n\\n**Per-question decision:** Even after the user accepts, decide FOR EACH QUESTION whether to use the browser or the terminal. The test: **would the user understand this better by seeing it than reading it?**\\n\\n- **Use the browser** for content that IS visual ??mockups, wireframes, layout comparisons, architecture diagrams, side-by-side visual designs\\n- **Use the terminal** for content that is text ??requirements questions, conceptual choices, tradeoff lists, A/B/C/D text options, scope decisions\\n\\nA question about a UI topic is not automatically a visual question. \\\"What does personality mean in this context?\\\" is a conceptual question ??use the terminal. \\\"Which wizard layout works better?\\\" is a visual question ??use the browser.\\n\\nIf they agree to the companion, read the detailed guide before proceeding:\\n`skills/brainstorming/visual-companion.md`\\n\\r\\n---\\nname: executing-plans\\ndescription: Use when you have a written implementation plan to execute in a separate session with review checkpoints\\n---\\n\\n# Executing Plans\\n\\n## Overview\\n\\nLoad plan, review critically, execute all tasks, report when complete.\\n\\n**Announce at start:** \\\"I'm using the executing-plans skill to implement this plan.\\\"\\n\\n**Note:** Tell your human partner that Superpowers works much better with access to subagents (Claude Code, Codex CLI, Codex App, Copilot CLI, and Gemini CLI all qualify; see the per-platform tool refs in `../using-superpowers/references/`). If subagents are available, use superpowers:subagent-driven-development instead of this skill.\\n\\n## The Process\\n\\n### Step 1: Load and Review Plan\\n1. Ensure an isolated workspace: use superpowers:using-git-worktrees to create one or verify the existing one\\n2. Read plan file\\n3. Review critically - identify any questions or concerns about the plan\\n4. If concerns: Raise them with your human partner before starting\\n5. If no concerns: Create todos for the plan items and proceed\\n\\n### Step 2: Execute Tasks\\n\\nFor each task:\\n1. Mark as in_progress\\n2. Follow each step exactly (plan has bite-sized steps)\\n3. Run verifications as specified\\n4. Mark as completed\\n\\n### Step 3: Complete Development\\n\\nAfter all tasks complete and verified:\\n- Announce: \\\"I'm using the finishing-a-development-branch skill to complete this work.\\\"\\n- **REQUIRED SUB-SKILL:** Use superpowers:finishing-a-development-branch\\n- Follow that skill to verify tests, present options, execute choice\\n\\n## When to Stop and Ask for Help\\n\\n**STOP executing immediately when:**\\n- Hit a blocker (missing dependency, test fails, instruction unclear)\\n- Plan has critical gaps preventing starting\\n- You don't understand an instruction\\n- Verification fails repeatedly\\n\\n**Ask for clarification rather than guessing.**\\n\\n## When to Revisit Earlier Steps\\n\\n**Return to Review (Step 1) when:**\\n- Partner updates the plan based on your feedback\\n- Fundamental approach needs rethinking\\n\\n**Don't force through blockers** - stop and ask.\\n\\n## Remember\\n- Review plan critically first\\n- Follow plan steps exactly\\n- Don't skip verifications\\n- Reference skills when plan says to\\n- Stop when blocked, don't guess\\n- Never start implementation on main/master branch without explicit user consent\\n\\r\\n---\\nname: test-driven-development\\ndescription: Use when implementing any feature or bugfix, before writing implementation code\\n---\\n\\n# Test-Driven Development (TDD)\\n\\n## Overview\\n\\nWrite the test first. Watch it fail. Write minimal code to pass.\\n\\n**Core principle:** If you didn't watch the test fail, you don't know if it tests the right thing.\\n\\n**Violating the letter of the rules is violating the spirit of the rules.**\\n\\n## When to Use\\n\\n**Always:**\\n- New features\\n- Bug fixes\\n- Refactoring\\n- Behavior changes\\n\\n**Exceptions (ask your human partner):**\\n- Throwaway prototypes\\n- Generated code\\n- Configuration files\\n\\nThinking \\\"skip TDD just this once\\\"? Stop. That's rationalization.\\n\\n## The Iron Law\\n\\n```\\nNO PRODUCTION CODE WITHOUT A FAILING TEST FIRST\\n```\\n\\nWrite code before the test? Delete it. Start over.\\n\\n**No exceptions:**\\n- Don't keep it as \\\"reference\\\"\\n- Don't \\\"adapt\\\" it while writing tests\\n- Don't look at it\\n- Delete means delete\\n\\nImplement fresh from tests. Period.\\n\\n## Red-Green-Refactor\\n\\n```dot\\ndigraph tdd_cycle {\\n rankdir=LR;\\n red [label=\\\"RED\\\\nWrite failing test\\\", shape=box, style=filled, fillcolor=\\\"#ffcccc\\\"];\\n verify_red [label=\\\"Verify fails\\\\ncorrectly\\\", shape=diamond];\\n green [label=\\\"GREEN\\\\nMinimal code\\\", shape=box, style=filled, fillcolor=\\\"#ccffcc\\\"];\\n verify_green [label=\\\"Verify passes\\\\nAll green\\\", shape=diamond];\\n refactor [label=\\\"REFACTOR\\\\nClean up\\\", shape=box, style=filled, fillcolor=\\\"#ccccff\\\"];\\n next [label=\\\"Next\\\", shape=ellipse];\\n\\n red -> verify_red;\\n verify_red -> green [label=\\\"yes\\\"];\\n verify_red -> red [label=\\\"wrong\\\\nfailure\\\"];\\n green -> verify_green;\\n verify_green -> refactor [label=\\\"yes\\\"];\\n verify_green -> green [label=\\\"no\\\"];\\n refactor -> verify_green [label=\\\"stay\\\\ngreen\\\"];\\n verify_green -> next;\\n next -> red;\\n}\\n```\\n\\n### RED - Write Failing Test\\n\\nWrite one minimal test showing what should happen.\\n\\n\\n```typescript\\ntest('retries failed operations 3 times', async () => {\\n let attempts = 0;\\n const operation = () => {\\n attempts++;\\n if (attempts < 3) throw new Error('fail');\\n return 'success';\\n };\\n\\n const result = await retryOperation(operation);\\n\\n expect(result).toBe('success');\\n expect(attempts).toBe(3);\\n});\\n```\\nClear name, tests real behavior, one thing\\n\\n\\n\\n```typescript\\ntest('retry works', async () => {\\n const mock = jest.fn()\\n .mockRejectedValueOnce(new Error())\\n .mockRejectedValueOnce(new Error())\\n .mockResolvedValueOnce('success');\\n await retryOperation(mock);\\n expect(mock).toHaveBeenCalledTimes(3);\\n});\\n```\\nVague name, tests mock not code\\n\\n\\n**Requirements:**\\n- One behavior\\n- Clear name\\n- Real code (no mocks unless unavoidable)\\n\\n### Verify RED - Watch It Fail\\n\\n**MANDATORY. Never skip.**\\n\\n```bash\\nnpm test path/to/test.test.ts\\n```\\n\\nConfirm:\\n- Test fails (not errors)\\n- Failure message is expected\\n- Fails because feature missing (not typos)\\n\\n**Test passes?** You're testing existing behavior. Fix test.\\n\\n**Test errors?** Fix error, re-run until it fails correctly.\\n\\n### GREEN - Minimal Code\\n\\nWrite simplest code to pass the test.\\n\\n\\n```typescript\\nasync function retryOperation(fn: () => Promise): Promise {\\n for (let i = 0; i < 3; i++) {\\n try {\\n return await fn();\\n } catch (e) {\\n if (i === 2) throw e;\\n }\\n }\\n throw new Error('unreachable');\\n}\\n```\\nJust enough to pass\\n\\n\\n\\n```typescript\\nasync function retryOperation(\\n fn: () => Promise,\\n options?: {\\n maxRetries?: number;\\n backoff?: 'linear' | 'exponential';\\n onRetry?: (attempt: number) => void;\\n }\\n): Promise {\\n // YAGNI\\n}\\n```\\nOver-engineered\\n\\n\\nDon't add features, refactor other code, or \\\"improve\\\" beyond the test.\\n\\n### Verify GREEN - Watch It Pass\\n\\n**MANDATORY.**\\n\\n```bash\\nnpm test path/to/test.test.ts\\n```\\n\\nConfirm:\\n- Test passes\\n- Other tests still pass\\n- Output pristine (no errors, warnings)\\n\\n**Test fails?** Fix code, not test.\\n\\n**Other tests fail?** Fix now.\\n\\n### REFACTOR - Clean Up\\n\\nAfter green only:\\n- Remove duplication\\n- Improve names\\n- Extract helpers\\n\\nKeep tests green. Don't add behavior.\\n\\n### Repeat\\n\\nNext failing test for next feature.\\n\\n## Good Tests\\n\\n| Quality | Good | Bad |\\n|---------|------|-----|\\n| **Minimal** | One thing. \\\"and\\\" in name? Split it. | `test('validates email and domain and whitespace')` |\\n| **Clear** | Name describes behavior | `test('test1')` |\\n| **Shows intent** | Demonstrates desired API | Obscures what code should do |\\n\\nWhen writing or changing any test, read [writing-good-tests.md](writing-good-tests.md) for the rules that keep tests honest:\\n- Name the production change that would make the test fail ??before writing it\\n- Assert on real behavior, never on mock behavior\\n- Keep test-only code in test utilities, out of production classes\\n- Understand a dependency's side effects before mocking it\\n\\n## Common Rationalizations\\n\\n| Excuse | Reality |\\n|--------|---------|\\n| \\\"Too simple to test\\\" | Simple code breaks. Test takes 30 seconds. |\\n| \\\"I'll test after\\\" | Tests written after pass immediately ??which proves nothing. They may test the wrong thing, test the implementation instead of the behavior, or miss the edge case you forgot. You never watched it fail, so you never proved it can catch the bug. Test-first forces that failure. |\\n| \\\"Tests after achieve same goals (spirit not ritual)\\\" | Tests-after answer \\\"what does this do?\\\"; tests-first answer \\\"what should this do?\\\" Tests written after are biased by the code you already wrote ??you verify the cases you remembered, not the ones you'd have discovered. Coverage without proof the tests work. |\\n| \\\"Already manually tested\\\" | Manual testing is ad-hoc: no record of what you covered, no way to re-run it when the code changes, easy to forget cases under pressure. \\\"Worked when I tried it\\\" ??comprehensive. Automated tests run the same way every time. |\\n| \\\"Deleting X hours is wasteful\\\" | Sunk cost fallacy ??that time is already spent either way. The real choice: rewrite with TDD (high confidence) vs. keep it and bolt tests on after (low confidence, likely bugs). Keeping code you can't trust is the waste. |\\n| \\\"Keep as reference, write tests first\\\" | You'll adapt it. That's testing after. Delete means delete. |\\n| \\\"Need to explore first\\\" | Fine. Throw away exploration, start with TDD. |\\n| \\\"Test hard = design unclear\\\" | Listen to test. Hard to test = hard to use. |\\n| \\\"TDD will slow me down\\\" | TDD IS the pragmatic path: catches bugs before commit, prevents regressions, lets you refactor without fear. \\\"Pragmatic\\\" shortcuts mean debugging in production ??slower, not faster. |\\n| \\\"Manual test faster\\\" | Manual doesn't prove edge cases. You'll re-test every change. |\\n| \\\"Existing code has no tests\\\" | You're improving it. Add tests for existing code. |\\n\\n## Red Flags - STOP and Start Over\\n\\n- Code before test\\n- Test after implementation\\n- Test passes immediately\\n- Can't explain why test failed\\n- Tests added \\\"later\\\"\\n- Rationalizing \\\"just this once\\\"\\n- \\\"I already manually tested it\\\"\\n- \\\"Tests after achieve the same purpose\\\"\\n- \\\"It's about spirit not ritual\\\"\\n- \\\"Keep as reference\\\" or \\\"adapt existing code\\\"\\n- \\\"Already spent X hours, deleting is wasteful\\\"\\n- \\\"TDD is dogmatic, I'm being pragmatic\\\"\\n- \\\"This is different because...\\\"\\n\\n**All of these mean: Delete code. Start over with TDD.**\\n\\n## Example: Bug Fix\\n\\n**Bug:** Empty email accepted\\n\\n**RED**\\n```typescript\\ntest('rejects empty email', async () => {\\n const result = await submitForm({ email: '' });\\n expect(result.error).toBe('Email required');\\n});\\n```\\n\\n**Verify RED**\\n```bash\\n$ npm test\\nFAIL: expected 'Email required', got undefined\\n```\\n\\n**GREEN**\\n```typescript\\nfunction submitForm(data: FormData) {\\n if (!data.email?.trim()) {\\n return { error: 'Email required' };\\n }\\n // ...\\n}\\n```\\n\\n**Verify GREEN**\\n```bash\\n$ npm test\\nPASS\\n```\\n\\n**REFACTOR**\\nExtract validation for multiple fields if needed.\\n\\n## Verification Checklist\\n\\nBefore marking work complete:\\n\\n- [ ] Every new function/method has a test\\n- [ ] Watched each test fail before implementing\\n- [ ] Each test failed for expected reason (feature missing, not typo)\\n- [ ] Wrote minimal code to pass each test\\n- [ ] All tests pass\\n- [ ] Output pristine (no errors, warnings)\\n- [ ] Tests use real code (mocks only if unavoidable)\\n- [ ] Edge cases and errors covered\\n\\nCan't check all boxes? You skipped TDD. Start over.\\n\\n## When Stuck\\n\\n| Problem | Solution |\\n|---------|----------|\\n| Don't know how to test | Write wished-for API. Write assertion first. Ask your human partner. |\\n| Test too complicated | Design too complicated. Simplify interface. |\\n| Must mock everything | Code too coupled. Use dependency injection. |\\n| Test setup huge | Extract helpers. Still complex? Simplify design. |\\n\\n## Debugging Integration\\n\\nBug found? Write failing test reproducing it. Follow TDD cycle. Test proves fix and prevents regression.\\n\\nNever fix bugs without a test.\\n\\n## Final Rule\\n\\n```\\nProduction code ??test exists and failed first\\nOtherwise ??not TDD\\n```\\n\\nNo exceptions without your human partner's permission.\\n\\r\\n---\\nname: verification-before-completion\\ndescription: Use when about to claim work is complete, fixed, or passing, before committing or creating PRs - requires running verification commands and confirming output before making any success claims; evidence before assertions always\\n---\\n\\n# Verification Before Completion\\n\\n## Overview\\n\\n**Core principle:** Evidence before claims, always.\\n\\n**Violating the letter of this rule is violating the spirit of this rule.**\\n\\n## The Iron Law\\n\\n```\\nNO COMPLETION CLAIMS WITHOUT FRESH VERIFICATION EVIDENCE\\n```\\n\\nIf you haven't run the verification command in this message, you cannot claim it passes.\\n\\n## The Gate Function\\n\\n```\\nBEFORE claiming any status or expressing satisfaction:\\n\\n1. IDENTIFY: What command proves this claim?\\n2. RUN: Execute the FULL command (fresh, complete)\\n3. READ: Full output, check exit code, count failures\\n4. VERIFY: Does output confirm the claim?\\n - If NO: State actual status with evidence\\n - If YES: State claim WITH evidence\\n5. ONLY THEN: Make the claim\\n\\nSkip any step = lying, not verifying\\n```\\n\\n## Common Failures\\n\\n| Claim | Requires | Not Sufficient |\\n|-------|----------|----------------|\\n| Tests pass | Test command output: 0 failures | Previous run, \\\"should pass\\\" |\\n| Linter clean | Linter output: 0 errors | Partial check, extrapolation |\\n| Build succeeds | Build command: exit 0 | Linter passing, logs look good |\\n| Bug fixed | Test original symptom: passes | Code changed, assumed fixed |\\n| Regression test works | Red-green cycle verified | Test passes once |\\n| Agent completed | VCS diff shows changes | Agent reports \\\"success\\\" |\\n| Requirements met | Line-by-line checklist | Tests passing |\\n\\n## Red Flags - STOP\\n\\n- Using \\\"should\\\", \\\"probably\\\", \\\"seems to\\\"\\n- Expressing satisfaction before verification (\\\"Great!\\\", \\\"Perfect!\\\", \\\"Done!\\\", etc.)\\n- About to commit/push/PR without verification\\n- Trusting agent success reports\\n- Relying on partial verification\\n- Thinking \\\"just this once\\\"\\n- Tired and wanting work over\\n- **ANY wording implying success without having run verification**\\n\\n## Rationalization Prevention\\n\\n| Excuse | Reality |\\n|--------|---------|\\n| \\\"Should work now\\\" | RUN the verification |\\n| \\\"I'm confident\\\" | Confidence ??evidence |\\n| \\\"Just this once\\\" | No exceptions |\\n| \\\"Linter passed\\\" | Linter ??compiler |\\n| \\\"Agent said success\\\" | Verify independently |\\n| \\\"I'm tired\\\" | Exhaustion ??excuse |\\n| \\\"Partial check is enough\\\" | Partial proves nothing |\\n| \\\"Different words so rule doesn't apply\\\" | Spirit over letter |\\n\\n## Key Patterns\\n\\n**Tests:**\\n```\\n??[Run test command] [See: 34/34 pass] \\\"All tests pass\\\"\\n??\\\"Should pass now\\\" / \\\"Looks correct\\\"\\n```\\n\\n**Regression tests (TDD Red-Green):**\\n```\\n??Write ??Run (pass) ??Revert fix ??Run (MUST FAIL) ??Restore ??Run (pass)\\n??\\\"I've written a regression test\\\" (without red-green verification)\\n```\\n\\n**Build:**\\n```\\n??[Run build] [See: exit 0] \\\"Build passes\\\"\\n??\\\"Linter passed\\\" (linter doesn't check compilation)\\n```\\n\\n**Requirements:**\\n```\\n??Re-read plan ??Create checklist ??Verify each ??Report gaps or completion\\n??\\\"Tests pass, phase complete\\\"\\n```\\n\\n**Agent delegation:**\\n```\\n??Agent reports success ??Check VCS diff ??Verify changes ??Report actual state\\n??Trust agent report\\n```\\n\\n## When To Apply\\n\\n**ALWAYS before:**\\n- ANY variation of success/completion claims\\n- ANY expression of satisfaction\\n- ANY positive statement about work state\\n- Committing, PR creation, task completion\\n- Moving to next task\\n- Delegating to agents\\n\\n**Rule applies to:**\\n- Exact phrases\\n- Paraphrases and synonyms\\n- Implications of success\\n- ANY communication suggesting completion/correctness\\n\\r\\n---\\nname: requesting-code-review\\ndescription: Use when completing tasks, implementing major features, or before merging to verify work meets requirements\\n---\\n\\n# Requesting Code Review\\n\\nDispatch a code reviewer subagent to catch issues before they cascade. The reviewer gets precisely crafted context for evaluation ??never your session's history.\\n\\n**Core principle:** Review early, review often.\\n\\n## When to Request Review\\n\\n**Mandatory:**\\n- After each task in subagent-driven development\\n- After completing major feature\\n- Before merge to main\\n\\n**Optional but valuable:**\\n- When stuck (fresh perspective)\\n- Before refactoring (baseline check)\\n- After fixing complex bug\\n\\n## How to Request\\n\\n**1. Get git SHAs:**\\n```bash\\nBASE_SHA=$(git rev-parse HEAD~1) # or origin/main\\nHEAD_SHA=$(git rev-parse HEAD)\\n```\\n\\n**2. Dispatch code reviewer subagent:**\\n\\nDispatch a `general-purpose` subagent, filling the template at [code-reviewer.md](code-reviewer.md)\\n\\n**Placeholders:**\\n- `{DESCRIPTION}` - Brief summary of what you built\\n- `{PLAN_OR_REQUIREMENTS}` - What it should do\\n- `{BASE_SHA}` - Starting commit\\n- `{HEAD_SHA}` - Ending commit\\n\\n**3. Act on feedback:**\\n- Fix Critical issues immediately\\n- Fix Important issues before proceeding\\n- Note Minor issues for later\\n- Push back if reviewer is wrong (with reasoning)\\n\\n## Example\\n\\n```\\n[Just completed Task 2: Add verification function]\\n\\nYou: Let me request code review before proceeding.\\n\\nBASE_SHA=$(git log --oneline | grep \\\"Task 1\\\" | head -1 | awk '{print $1}')\\nHEAD_SHA=$(git rev-parse HEAD)\\n\\n[Dispatch code reviewer subagent]\\n DESCRIPTION: Added verifyIndex() and repairIndex() with 4 issue types\\n PLAN_OR_REQUIREMENTS: Task 2 from docs/superpowers/plans/deployment-plan.md\\n BASE_SHA: a7981ec\\n HEAD_SHA: 3df7661\\n\\n[Subagent returns]:\\n Strengths: Clean architecture, real tests\\n Issues:\\n Important: Missing progress indicators\\n Minor: Magic number (100) for reporting interval\\n Assessment: Ready to proceed\\n\\nYou: [Fix progress indicators]\\n[Continue to Task 3]\\n```\\n\\n## Common Rationalizations\\n\\n| Excuse | Reality |\\n|--------|---------|\\n| \\\"I'll just review the diff myself instead of dispatching a reviewer\\\" | You're the coordinator ??reviewing the diff inline burns the context window you need to keep driving the work. Dispatch a reviewer subagent: the diff and the evaluation live in its context, and only the findings come back to you. |\\n| \\\"The reviewer needs my whole session history to understand the change\\\" | Hand it precisely crafted context, never your session's history. That keeps the reviewer on the work product, not your thought process. |\\n\\n## Red Flags\\n\\n**Never:**\\n- Skip review because \\\"it's simple\\\"\\n- Ignore Critical issues\\n- Proceed with unfixed Important issues\\n- Argue with valid technical feedback\\n\\n**If reviewer wrong:**\\n- Push back with technical reasoning\\n- Show code/tests that prove it works\\n- Request clarification\\n\\nSee template at: [code-reviewer.md](code-reviewer.md)\\n\\r\\n\",\"exit_code\":0,\"status\":\"completed\"}}\n{\"type\":\"item.completed\",\"item\":{\"id\":\"item_6\",\"type\":\"agent_message\",\"text\":\"설계는 기존 승인된 Step 2 계약으로 고정합니다: production `assemble_parallel` 경로를 그대로 호출하고, 동일 Domain에 대해 1·2·가용 동시성의 CSR/RHS와 최종 변위·반력을 exact equality로 10회 이상 비교합니다. benchmark도 동일 production serial/parallel API만 호출하며 시간은 출력만 합니다. 별도 API·성능 기준·MKL 병렬 확장은 추가하지 않습니다.\"}}\n{\"type\":\"item.started\",\"item\":{\"id\":\"item_7\",\"type\":\"todo_list\",\"items\":[{\"text\":\"Step 2 문서, Git/의존성 baseline, 기존 assembly·analysis 테스트 패턴 점검\",\"completed\":false},{\"text\":\"ThreadCountDeterminism 통합 테스트를 먼저 추가하고 focused 실행으로 동작 확인\",\"completed\":false},{\"text\":\"production API를 사용하는 측정용 benchmark와 최소 CMake 등록 추가\",\"completed\":false},{\"text\":\"Acceptance Criteria 전체 실행 및 결정성/경고 확인\",\"completed\":false},{\"text\":\"독립 코드 리뷰 반영 후 phase index Step 2 완료 메타데이터 갱신\",\"completed\":false}]}}\n{\"type\":\"item.started\",\"item\":{\"id\":\"item_8\",\"type\":\"command_execution\",\"command\":\"\\\"C:\\\\\\\\WINDOWS\\\\\\\\System32\\\\\\\\WindowsPowerShell\\\\\\\\v1.0\\\\\\\\powershell.exe\\\" -Command \\\"Get-Content -Raw 'C:\\\\\\\\Users\\\\\\\\baram\\\\\\\\.codex\\\\\\\\plugins\\\\\\\\cache\\\\\\\\openai-curated-remote\\\\\\\\superpowers\\\\\\\\6.2.0\\\\\\\\skills\\\\\\\\using-git-worktrees\\\\\\\\SKILL.md'; Get-Content -Raw 'C:\\\\\\\\Users\\\\\\\\baram\\\\\\\\.codex\\\\\\\\plugins\\\\\\\\cache\\\\\\\\openai-curated-remote\\\\\\\\superpowers\\\\\\\\6.2.0\\\\\\\\skills\\\\\\\\test-driven-development\\\\\\\\writing-good-tests.md'\\\"\",\"aggregated_output\":\"\",\"exit_code\":null,\"status\":\"in_progress\"}}\n{\"type\":\"item.completed\",\"item\":{\"id\":\"item_8\",\"type\":\"command_execution\",\"command\":\"\\\"C:\\\\\\\\WINDOWS\\\\\\\\System32\\\\\\\\WindowsPowerShell\\\\\\\\v1.0\\\\\\\\powershell.exe\\\" -Command \\\"Get-Content -Raw 'C:\\\\\\\\Users\\\\\\\\baram\\\\\\\\.codex\\\\\\\\plugins\\\\\\\\cache\\\\\\\\openai-curated-remote\\\\\\\\superpowers\\\\\\\\6.2.0\\\\\\\\skills\\\\\\\\using-git-worktrees\\\\\\\\SKILL.md'; Get-Content -Raw 'C:\\\\\\\\Users\\\\\\\\baram\\\\\\\\.codex\\\\\\\\plugins\\\\\\\\cache\\\\\\\\openai-curated-remote\\\\\\\\superpowers\\\\\\\\6.2.0\\\\\\\\skills\\\\\\\\test-driven-development\\\\\\\\writing-good-tests.md'\\\"\",\"aggregated_output\":\"---\\nname: using-git-worktrees\\ndescription: Use when starting feature work that needs isolation from current workspace or before executing implementation plans - ensures an isolated workspace exists via native tools or git worktree fallback\\n---\\n\\n# Using Git Worktrees\\n\\n## Overview\\n\\nEnsure work happens in an isolated workspace. Prefer your platform's native worktree tools. Fall back to manual git worktrees only when no native tool is available.\\n\\n**Core principle:** Detect existing isolation first. Then use native tools. Then fall back to git. Never fight the harness.\\n\\n**Announce at start:** \\\"I'm using the using-git-worktrees skill to set up an isolated workspace.\\\"\\n\\n## Step 0: Detect Existing Isolation\\n\\n**Before creating anything, check if you are already in an isolated workspace.**\\n\\n```bash\\nGIT_DIR=$(cd \\\"$(git rev-parse --git-dir)\\\" 2>/dev/null && pwd -P)\\nGIT_COMMON=$(cd \\\"$(git rev-parse --git-common-dir)\\\" 2>/dev/null && pwd -P)\\nBRANCH=$(git branch --show-current)\\n```\\n\\n**Submodule guard:** `GIT_DIR != GIT_COMMON` is also true inside git submodules. Before concluding \\\"already in a worktree,\\\" verify you are not in a submodule:\\n\\n```bash\\n# If this returns a path, you're in a submodule, not a worktree ??treat as normal repo\\ngit rev-parse --show-superproject-working-tree 2>/dev/null\\n```\\n\\n**If `GIT_DIR != GIT_COMMON` (and not a submodule):** You are already in a linked worktree. Skip to Step 2 (Project Setup). Do NOT create another worktree.\\n\\nReport with branch state:\\n- On a branch: \\\"Already in isolated workspace at `` on branch ``.\\\"\\n- Detached HEAD: \\\"Already in isolated workspace at `` (detached HEAD, externally managed). Branch creation needed at finish time.\\\"\\n\\n**If `GIT_DIR == GIT_COMMON` (or in a submodule):** You are in a normal repo checkout.\\n\\nHas the user already indicated their worktree preference in your instructions? If not, ask for consent before creating a worktree:\\n\\n> \\\"Would you like me to set up an isolated worktree? It protects your current branch from changes.\\\"\\n\\nHonor any existing declared preference without asking. If the user declines consent, work in place and skip to Step 2.\\n\\n## Step 1: Create Isolated Workspace\\n\\n**You have two mechanisms. Try them in this order.**\\n\\n### 1a. Native Worktree Tools (preferred)\\n\\nThe user has asked for an isolated workspace (Step 0 consent). Do you already have a way to create a worktree? It might be a tool with a name like `EnterWorktree`, `WorktreeCreate`, a `/worktree` command, or a `--worktree` flag. If you do, use it and skip to Step 2.\\n\\nNative tools handle directory placement, branch creation, and cleanup automatically. Using `git worktree add` when you have a native tool creates phantom state your harness can't see or manage.\\n\\nOnly proceed to Step 1b if you have no native worktree tool available.\\n\\n### 1b. Git Worktree Fallback\\n\\n**Only use this if Step 1a does not apply** ??you have no native worktree tool available. Create a worktree manually using git.\\n\\n#### Directory Selection\\n\\nFollow this priority order. Explicit user preference always beats observed filesystem state.\\n\\n1. **Check your instructions for a declared worktree directory preference.** If the user has already specified one, use it without asking.\\n\\n2. **Check for an existing project-local worktree directory:**\\n ```bash\\n ls -d .worktrees 2>/dev/null # Preferred (hidden)\\n ls -d worktrees 2>/dev/null # Alternative\\n ```\\n If found, use it. If both exist, `.worktrees` wins.\\n\\n3. **If there is no other guidance available**, default to `.worktrees/` at the project root.\\n\\n#### Safety Verification (project-local directories only)\\n\\n**MUST verify directory is ignored before creating worktree:**\\n\\n```bash\\ngit check-ignore -q .worktrees 2>/dev/null || git check-ignore -q worktrees 2>/dev/null\\n```\\n\\n**If NOT ignored:** Add to .gitignore, commit the change, then proceed.\\n\\n**Why critical:** Prevents accidentally committing worktree contents to repository.\\n\\n#### Create the Worktree\\n\\n```bash\\n# Determine path based on chosen location\\npath=\\\"$LOCATION/$BRANCH_NAME\\\"\\n\\ngit worktree add \\\"$path\\\" -b \\\"$BRANCH_NAME\\\"\\ncd \\\"$path\\\"\\n```\\n\\n**Sandbox fallback:** If `git worktree add` fails with a permission error (sandbox denial), tell the user the sandbox blocked worktree creation and you're working in the current directory instead. Then run setup and baseline tests in place.\\n\\n## Step 2: Project Setup\\n\\nAuto-detect and run appropriate setup:\\n\\n```bash\\n# Node.js\\nif [ -f package.json ]; then npm install; fi\\n\\n# Rust\\nif [ -f Cargo.toml ]; then cargo build; fi\\n\\n# Python\\nif [ -f requirements.txt ]; then pip install -r requirements.txt; fi\\nif [ -f pyproject.toml ]; then poetry install; fi\\n\\n# Go\\nif [ -f go.mod ]; then go mod download; fi\\n```\\n\\n## Step 3: Verify Clean Baseline\\n\\nRun tests to ensure workspace starts clean:\\n\\n```bash\\n# Use project-appropriate command\\nnpm test / cargo test / pytest / go test ./...\\n```\\n\\n**If tests fail:** Report failures, ask whether to proceed or investigate.\\n\\n**If tests pass:** Report ready.\\n\\n### Report\\n\\n```\\nWorktree ready at \\nTests passing ( tests, 0 failures)\\nReady to implement \\n```\\n\\n## Quick Reference\\n\\n| Situation | Action |\\n|-----------|--------|\\n| Already in linked worktree | Skip creation (Step 0) |\\n| In a submodule | Treat as normal repo (Step 0 guard) |\\n| Native worktree tool available | Use it (Step 1a) |\\n| No native tool | Git worktree fallback (Step 1b) |\\n| `.worktrees/` exists | Use it (verify ignored) |\\n| `worktrees/` exists | Use it (verify ignored) |\\n| Both exist | Use `.worktrees/` |\\n| Neither exists | Check instruction file, then default `.worktrees/` |\\n| Directory not ignored | Add to .gitignore + commit |\\n| Permission error on create | Sandbox fallback, work in place |\\n| Tests fail during baseline | Report failures + ask |\\n| No package.json/Cargo.toml | Skip dependency install |\\n\\n## Common Rationalizations\\n\\n| Excuse | Reality |\\n|--------|---------|\\n| \\\"I'm obviously not in a worktree ??no need to check\\\" | Run Step 0. Harness-created isolation and submodules both fool eyeballing; the detection commands settle it. |\\n| \\\"`git worktree add` is quicker than hunting for a native tool\\\" | A native tool (e.g. `EnterWorktree`) owns placement, branching, and cleanup. Bypassing it is the #1 mistake ??it creates phantom state your harness can't see or manage. |\\n| \\\"The worktree directory is surely ignored already\\\" | Run `git check-ignore`. An unignored worktree directory commits the whole tree into the repo. |\\n| \\\"Any directory name works\\\" | Explicit instructions beat an existing project-local directory, which beats the `.worktrees/` default. |\\n| \\\"The workspace is fresh ??baseline tests can wait\\\" | A dirty baseline makes every later failure ambiguous. Run the tests now; proceeding past failures is your human partner's call. |\\n\\r\\n# Writing Good Tests\\n\\n**Load this reference when:** writing or changing tests, adding mocks, or\\nadding cleanup/helper methods for tests.\\n\\n## Overview\\n\\nA test exists to catch a specific break. Two principles govern everything\\nhere:\\n\\n```\\n1. Every test names the break it catches\\n2. Every test exercises the real thing\\n```\\n\\nStrict TDD produces both naturally: a test written first and watched\\nfailing against real code has already proven it can fail, and only earns\\na mock when the real dependency proves slow or external.\\n\\n## Principle 1: Name the Break\\n\\nBefore writing the test body, answer: **what production change should\\nmake this test fail ??and is that change a bug or a decision?** A test\\nearns its place by catching a wrong branch, missing side effect, wrong\\nargument, boundary case, or broken contract.\\n\\n**Derive expectations independently.** Use literals and hand-checked\\nfixtures; table-driven tests with literal `want` values are the preferred\\nshape. An expectation computed by the code under test ??or its helpers ??passes no matter what that code does:\\n\\n```typescript\\n// ??Mirror assertion: the same builder computes both sides ??always true\\nconst expected = buildSearchQuery({ tag: 'urgent' });\\nexpect(buildSearchQuery({ tag: 'urgent' })).toBe(expected);\\n\\n// ??Hand-derived literal\\nexpect(buildSearchQuery({ tag: 'urgent' })).toBe('tag:\\\"urgent\\\"');\\n```\\n\\n**No change detectors.** If only intentional decisions can fail a test ??a constant's value, exact message wording, private structure ??it fires\\non redesign and sleeps through bugs. Test the behavior that depends on\\nthe decision: not `expect(MAX_RETRIES).toBe(5)` but \\\"a failing call is\\nretried 5 times and the 6th attempt never happens.\\\"\\n\\n**Behavior, not text.** Asserting that a script, skill, or config\\ncontains an exact line proves only that the source is the source. Run\\nscripts against controlled inputs and assert outputs, side effects, or\\nexit codes. Documents that instruct agents are tested by the consuming\\nagent's behavior (superpowers:writing-skills); prose for humans earns no\\ntest at all.\\n\\n**Your code, not the framework.** Test the contract your code makes at\\nits boundaries ??the route you register, the query you emit, the payload\\nyou produce. Upstream mechanics are their maintainers' tests to write\\n(the classic: asserting your router invokes a registered handler ??that\\nis the framework's test, not yours). When upstream behavior genuinely\\nsurprised you, write one narrow characterization test naming the\\nassumption. The same boundary applies inside your code: constructors,\\ngetters, constants, and trivial forwarding earn tests only when they\\nvalidate, normalize, default, derive, enforce, or cause side effects ??otherwise assert the first consumer-visible result that depends on them.\\n\\n### Gate Function\\n\\n```\\nBEFORE writing the test body:\\n Name the production change that would make this test fail.\\n\\n Cannot name one ??redesign around an observable behavior\\n \\\"The source text changed\\\" ??run the artifact and assert its effects\\n Only intentional decisions ??change detector; test the behavior\\n that depends on the decision\\n\\n Confirm the expected value is derived without the code under test.\\n IF it reuses the code's logic or helpers:\\n Replace it with a literal or hand-checked fixture\\n```\\n\\n## Principle 2: Exercise the Real Thing\\n\\n**The mock earns no assertions.** A mock assertion passes when the mock\\nis present and fails when it is absent ??it says nothing about the\\ncomponent. Assert the real component's behavior; if the mock is what you\\nare checking, unmock it or delete the assertion.\\n\\n```typescript\\n// ??Real behavior\\nexpect(screen.getByRole('navigation')).toBeInTheDocument();\\n\\n// ??Mock existence\\nexpect(screen.getByTestId('sidebar-mock')).toBeInTheDocument();\\n```\\n\\n**your human partner's correction:** \\\"Are we testing the behavior of a\\nmock?\\\"\\n\\n**Mock at the right level.** Learn every side effect of the real method\\nbefore replacing it; mock the slow or external operation and keep what\\nthe test depends on real. When unsure, run the test against the real\\nimplementation first and observe what actually needs to happen.\\n\\n```typescript\\n// ??The mock swallows the config write that duplicate detection reads\\nvi.mock('ToolCatalog', () => ({\\n discoverAndCacheTools: vi.fn().mockResolvedValue(undefined)\\n}));\\n\\n// ??Mock only the slow server startup; the config write stays real\\nvi.mock('MCPServerManager');\\n```\\n\\n**Make doubles specific.** When arguments, call counts, or ordering are\\npart of the contract, assert them ??a fake that accepts anything verifies\\nnothing. Give each branch (success, error, malformed) its own fixture or\\nspy, so the wrong branch cannot satisfy the expectation.\\n\\n**Mirror real data completely.** Mock the complete structure as it exists\\nin reality ??all documented fields ??not just the ones your test reads.\\nPartial mocks fail silently when downstream code reads an omitted field:\\nthe test passes while integration breaks.\\n\\n**Production classes carry production methods only.** Cleanup that only\\ntests need lives in test utilities, never as a `destroy()` on the\\nproduction class. Ask: is this method called only from tests? Does this\\nclass own this resource's lifecycle? Wrong answers ??test utility.\\n\\n**Prefer real components over complex mocks.** When mock setup outgrows\\nthe test logic, mocks miss methods the real components have, or tests\\nbreak when the mock changes, switch to an integration test with real\\ncomponents. **your human partner's question:** \\\"Do we need to be using a\\nmock here?\\\"\\n\\n### Gate Function\\n\\n```\\nBEFORE adding a mock or test helper:\\n List the real method's side effects; keep the ones the test\\n depends on real ??mock the slow/external level below them.\\n\\n Mock responses mirror the complete real structure.\\n\\n A method only tests call lives in test utilities, not production.\\n\\n About to assert on the mock itself?\\n Unmock it or delete the assertion.\\n```\\n\\n## Tests Ship With the Implementation\\n\\nThe TDD cycle ??failing test, minimal implementation, refactor ??is what\\n\\\"complete\\\" means. Ship the tests the behavior needs and only those:\\ntrivial code and human prose earn none, and a test written to satisfy\\nprocess costs maintenance forever.\\n\\n## The Mutation Check\\n\\nBefore finishing, mentally mutate the production code; at least one test\\nshould fail for each realistic mutation:\\n\\n- Wrong constant or argument\\n- Wrong branch handler\\n- Missing state change or side effect\\n- Empty or default return\\n- Missing validation for zero, empty, nil, unauthorized, or malformed input\\n\\nA mutation nothing catches marks the behavior as unprotected ??or the\\ntest as tautological.\\n\\n## Quick Reference\\n\\n| When you... | Do |\\n|-------------|-----|\\n| Write any test | Name the break it catches ??a bug, not a decision |\\n| Build an expected value | Derive it by hand; never with the code under test |\\n| Test a script or document | Run it / pressure-test its consumer; never grep its text |\\n| Reach for a dependency test | Test your boundary contract, not their documented mechanics |\\n| Want to assert on a mocked element | Test the real component, or unmock it |\\n| Are about to mock a method | Learn its side effects; mock the slow/external level |\\n| Build a mock response | Mirror the real structure completely |\\n| Need cleanup only tests use | Put it in test utilities |\\n| Watch mock setup balloon | Switch to an integration test with real components |\\n| Finish a test file | Run the mutation check |\\n\\n## Warning Signs\\n\\n- Setup and assertion share the same object, guaranteeing equality\\n- The test can fail only through a panic, crash, or missing selector\\n- The test fails on every intentional change, never on accidental breakage\\n- Expected values are hidden behind loops, builders, or helpers\\n- The test greps source text, or asserts a removed symbol stays removed\\n- The test would still matter if only the framework remained\\n- The test exists for coverage, checking no side effect or outcome\\n- An assertion checks a `*-mock` test ID, or fails if you remove the mock\\n- A method is called only from test files\\n- Mock setup is more than half the test, or you can't explain why the mock is needed\\n- Mocking \\\"just to be safe\\\"\\n\\r\\n\",\"exit_code\":0,\"status\":\"completed\"}}\n{\"type\":\"item.completed\",\"item\":{\"id\":\"item_9\",\"type\":\"agent_message\",\"text\":\"현재 저장소는 Harness가 관리하는 작업 공간일 수 있으므로 새 worktree를 만들지 않기 전에 먼저 격리 여부와 브랜치를 확인하겠습니다. 실행 계획 스킬은 subagent 기반 검토를 요구하므로 구현은 현재 작업 공간에서 제가 통제하고, 완료 후 독립 리뷰만 별도 에이전트에 맡기며 AC는 제가 직접 재실행하겠습니다.\"}}\n{\"type\":\"item.started\",\"item\":{\"id\":\"item_10\",\"type\":\"command_execution\",\"command\":\"\\\"C:\\\\\\\\WINDOWS\\\\\\\\System32\\\\\\\\WindowsPowerShell\\\\\\\\v1.0\\\\\\\\powershell.exe\\\" -Command \\\"Get-Content -Raw 'C:\\\\\\\\Users\\\\\\\\baram\\\\\\\\.codex\\\\\\\\plugins\\\\\\\\cache\\\\\\\\openai-curated-remote\\\\\\\\superpowers\\\\\\\\6.2.0\\\\\\\\skills\\\\\\\\subagent-driven-development\\\\\\\\SKILL.md'; Get-Content -Raw 'C:\\\\\\\\Users\\\\\\\\baram\\\\\\\\.codex\\\\\\\\plugins\\\\\\\\cache\\\\\\\\openai-curated-remote\\\\\\\\superpowers\\\\\\\\6.2.0\\\\\\\\skills\\\\\\\\requesting-code-review\\\\\\\\code-reviewer.md'\\\"\",\"aggregated_output\":\"\",\"exit_code\":null,\"status\":\"in_progress\"}}\n{\"type\":\"item.completed\",\"item\":{\"id\":\"item_10\",\"type\":\"command_execution\",\"command\":\"\\\"C:\\\\\\\\WINDOWS\\\\\\\\System32\\\\\\\\WindowsPowerShell\\\\\\\\v1.0\\\\\\\\powershell.exe\\\" -Command \\\"Get-Content -Raw 'C:\\\\\\\\Users\\\\\\\\baram\\\\\\\\.codex\\\\\\\\plugins\\\\\\\\cache\\\\\\\\openai-curated-remote\\\\\\\\superpowers\\\\\\\\6.2.0\\\\\\\\skills\\\\\\\\subagent-driven-development\\\\\\\\SKILL.md'; Get-Content -Raw 'C:\\\\\\\\Users\\\\\\\\baram\\\\\\\\.codex\\\\\\\\plugins\\\\\\\\cache\\\\\\\\openai-curated-remote\\\\\\\\superpowers\\\\\\\\6.2.0\\\\\\\\skills\\\\\\\\requesting-code-review\\\\\\\\code-reviewer.md'\\\"\",\"aggregated_output\":\"---\\nname: subagent-driven-development\\ndescription: Use when executing implementation plans with independent tasks in the current session\\n---\\n\\n# Subagent-Driven Development\\n\\nExecute plan by dispatching a fresh implementer subagent per task, a task review (spec compliance + code quality) after each, and a broad whole-branch review at the end.\\n\\n**Why subagents:** You delegate tasks to specialized agents with isolated context. By precisely crafting their instructions and context, you ensure they stay focused and succeed at their task. They should never inherit your session's context or history ??you construct exactly what they need. This also preserves your own context for coordination work.\\n\\n**Core principle:** Fresh subagent per task + task review (spec + quality) + broad final review = high quality, fast iteration\\n\\n**Narration:** between tool calls, narrate at most one short line ??the\\nledger and the tool results carry the record.\\n\\n**Continuous execution:** Do not pause to check in with your human partner between tasks. Execute all tasks from the plan without stopping. The only reasons to stop are: BLOCKED status you cannot resolve, ambiguity that genuinely prevents progress, or all tasks complete. \\\"Should I continue?\\\" prompts and progress summaries waste their time ??they asked you to execute the plan, so execute it.\\n\\n## When to Use\\n\\n```dot\\ndigraph when_to_use {\\n \\\"Have implementation plan?\\\" [shape=diamond];\\n \\\"Tasks mostly independent?\\\" [shape=diamond];\\n \\\"Stay in this session?\\\" [shape=diamond];\\n \\\"subagent-driven-development\\\" [shape=box];\\n \\\"executing-plans\\\" [shape=box];\\n \\\"Manual execution or brainstorm first\\\" [shape=box];\\n\\n \\\"Have implementation plan?\\\" -> \\\"Tasks mostly independent?\\\" [label=\\\"yes\\\"];\\n \\\"Have implementation plan?\\\" -> \\\"Manual execution or brainstorm first\\\" [label=\\\"no\\\"];\\n \\\"Tasks mostly independent?\\\" -> \\\"Stay in this session?\\\" [label=\\\"yes\\\"];\\n \\\"Tasks mostly independent?\\\" -> \\\"Manual execution or brainstorm first\\\" [label=\\\"no - tightly coupled\\\"];\\n \\\"Stay in this session?\\\" -> \\\"subagent-driven-development\\\" [label=\\\"yes\\\"];\\n \\\"Stay in this session?\\\" -> \\\"executing-plans\\\" [label=\\\"no - parallel session\\\"];\\n}\\n```\\n\\n**vs. Executing Plans (parallel session):**\\n- Same session (no context switch)\\n- Fresh subagent per task (no context pollution)\\n- Review after each task (spec compliance + code quality), broad review at the end\\n- Faster iteration (no human-in-loop between tasks)\\n\\n## The Process\\n\\n```dot\\ndigraph process {\\n rankdir=TB;\\n\\n subgraph cluster_per_task {\\n label=\\\"Per Task\\\";\\n \\\"Dispatch implementer subagent (./implementer-prompt.md)\\\" [shape=box];\\n \\\"Implementer asks questions?\\\" [shape=diamond];\\n \\\"Answer questions, provide context\\\" [shape=box];\\n \\\"Implementer implements, tests, commits, self-reviews\\\" [shape=box];\\n \\\"Generate review package, dispatch task reviewer (./task-reviewer-prompt.md)\\\" [shape=box];\\n \\\"Spec ??and quality approved?\\\" [shape=diamond];\\n \\\"Finding conflicts with plan text?\\\" [shape=diamond];\\n \\\"Ask human partner which governs\\\" [shape=box];\\n \\\"Fix round R of 5: R?? resume implementer; R?? fresh implementer, more capable model\\\" [shape=box];\\n \\\"Dispatch scoped re-review (./re-review-prompt.md)\\\" [shape=box];\\n \\\"All findings addressed?\\\" [shape=diamond];\\n \\\"R = 5?\\\" [shape=diamond];\\n \\\"Adjudicate each open finding\\\" [shape=box];\\n \\\"Any load-bearing finding?\\\" [shape=diamond];\\n \\\"STOP: report BLOCKED to human partner\\\" [shape=box];\\n \\\"Park findings in ledger with rulings\\\" [shape=box];\\n \\\"Append completion to ledger, mark todo complete\\\" [shape=box];\\n }\\n\\n \\\"Setup: worktree, ledger check, read plan, pre-flight review\\\" [shape=box];\\n \\\"More tasks remain?\\\" [shape=diamond];\\n \\\"Dispatch final code reviewer (../requesting-code-review/code-reviewer.md)\\\" [shape=box];\\n \\\"Final findings? ONE fix dispatch, one scoped re-review, adjudicate residuals\\\" [shape=box];\\n \\\"Final review clean: delete this plan's workspace\\\" [shape=box];\\n \\\"Use superpowers:finishing-a-development-branch\\\" [shape=box style=filled fillcolor=lightgreen];\\n\\n \\\"Setup: worktree, ledger check, read plan, pre-flight review\\\" -> \\\"Dispatch implementer subagent (./implementer-prompt.md)\\\";\\n \\\"Dispatch implementer subagent (./implementer-prompt.md)\\\" -> \\\"Implementer asks questions?\\\";\\n \\\"Implementer asks questions?\\\" -> \\\"Answer questions, provide context\\\" [label=\\\"yes\\\"];\\n \\\"Answer questions, provide context\\\" -> \\\"Implementer implements, tests, commits, self-reviews\\\";\\n \\\"Implementer asks questions?\\\" -> \\\"Implementer implements, tests, commits, self-reviews\\\" [label=\\\"no\\\"];\\n \\\"Implementer implements, tests, commits, self-reviews\\\" -> \\\"Generate review package, dispatch task reviewer (./task-reviewer-prompt.md)\\\";\\n \\\"Generate review package, dispatch task reviewer (./task-reviewer-prompt.md)\\\" -> \\\"Spec ??and quality approved?\\\";\\n \\\"Spec ??and quality approved?\\\" -> \\\"Append completion to ledger, mark todo complete\\\" [label=\\\"yes\\\"];\\n \\\"Spec ??and quality approved?\\\" -> \\\"Finding conflicts with plan text?\\\" [label=\\\"no\\\"];\\n \\\"Finding conflicts with plan text?\\\" -> \\\"Ask human partner which governs\\\" [label=\\\"yes\\\"];\\n \\\"Ask human partner which governs\\\" -> \\\"Fix round R of 5: R?? resume implementer; R?? fresh implementer, more capable model\\\";\\n \\\"Finding conflicts with plan text?\\\" -> \\\"Fix round R of 5: R?? resume implementer; R?? fresh implementer, more capable model\\\" [label=\\\"no\\\"];\\n \\\"Fix round R of 5: R?? resume implementer; R?? fresh implementer, more capable model\\\" -> \\\"Dispatch scoped re-review (./re-review-prompt.md)\\\";\\n \\\"Dispatch scoped re-review (./re-review-prompt.md)\\\" -> \\\"All findings addressed?\\\";\\n \\\"All findings addressed?\\\" -> \\\"Append completion to ledger, mark todo complete\\\" [label=\\\"yes\\\"];\\n \\\"All findings addressed?\\\" -> \\\"R = 5?\\\" [label=\\\"no\\\"];\\n \\\"R = 5?\\\" -> \\\"Fix round R of 5: R?? resume implementer; R?? fresh implementer, more capable model\\\" [label=\\\"no - next round\\\"];\\n \\\"R = 5?\\\" -> \\\"Adjudicate each open finding\\\" [label=\\\"yes - breaker trips\\\"];\\n \\\"Adjudicate each open finding\\\" -> \\\"Any load-bearing finding?\\\";\\n \\\"Any load-bearing finding?\\\" -> \\\"STOP: report BLOCKED to human partner\\\" [label=\\\"yes\\\"];\\n \\\"Any load-bearing finding?\\\" -> \\\"Park findings in ledger with rulings\\\" [label=\\\"no\\\"];\\n \\\"Park findings in ledger with rulings\\\" -> \\\"Append completion to ledger, mark todo complete\\\";\\n \\\"Append completion to ledger, mark todo complete\\\" -> \\\"More tasks remain?\\\";\\n \\\"More tasks remain?\\\" -> \\\"Dispatch implementer subagent (./implementer-prompt.md)\\\" [label=\\\"yes\\\"];\\n \\\"More tasks remain?\\\" -> \\\"Dispatch final code reviewer (../requesting-code-review/code-reviewer.md)\\\" [label=\\\"no\\\"];\\n \\\"Dispatch final code reviewer (../requesting-code-review/code-reviewer.md)\\\" -> \\\"Final findings? ONE fix dispatch, one scoped re-review, adjudicate residuals\\\";\\n \\\"Final findings? ONE fix dispatch, one scoped re-review, adjudicate residuals\\\" -> \\\"Final review clean: delete this plan's workspace\\\";\\n \\\"Final review clean: delete this plan's workspace\\\" -> \\\"Use superpowers:finishing-a-development-branch\\\";\\n}\\n```\\n\\n## Setup\\n\\nEnsure the work happens in an isolated workspace: use\\nsuperpowers:using-git-worktrees to create one or verify the existing one.\\nNever start implementation on a main/master branch without your human\\npartner's explicit consent.\\n\\nConversation memory does not survive compaction. In real sessions,\\ncontrollers that lost their place have re-dispatched entire completed task\\nsequences ??the single most expensive failure observed. Track progress in\\na ledger file, not only in todos.\\n\\n- Each plan owns a workspace: at skill start, run this skill's\\n `scripts/sdd-workspace PLAN_FILE` ??it prints the plan's git-ignored\\n directory (`/.superpowers/sdd//`), home to\\n every artifact for THIS plan: ledger, briefs, reports, review packages.\\n Another plan's directory is never yours to read or write.\\n- Check for this plan's ledger at `/progress.md`. If its first\\n line names your plan file, tasks with a `Task : complete` line are DONE\\n ??do not re-dispatch them; resume at the first task without one. A task\\n whose last line is a fix round is mid-loop: resume the loop at the next\\n round. A ledger whose first line names a different plan file ??or a stray\\n ledger at the old flat path `.superpowers/sdd/progress.md` ??is another\\n plan's progress: leave it in place and start your own, fresh.\\n- Create the ledger with its identity as the first line:\\n `# SDD ledger ??plan: `.\\n- The ledger is your recovery map: the commits it names exist in git even\\n when your context no longer remembers creating them. After compaction,\\n trust the ledger and `git log` over your own recollection.\\n- `git clean -fdx` will destroy the workspace (it's git-ignored scratch); if\\n that happens, recover from `git log`.\\n\\nRead the plan once, note its context and Global Constraints, and create a\\ntodo per task.\\n\\nBefore dispatching Task 1, scan the plan once for conflicts:\\n\\n- tasks that contradict each other or the plan's Global Constraints\\n- anything the plan explicitly mandates that the review rubric treats as a\\n defect (a test that asserts nothing, verbatim duplication of a logic block)\\n\\nPresent everything you find to your human partner as one batched question ??each finding beside the plan text that mandates it, asking which governs ??before execution begins, not one interrupt per discovery mid-plan. If the\\nscan is clean, proceed without comment. The review loop remains the net for\\nconflicts that only emerge from implementation.\\n\\n## Model Selection\\n\\nUse the least powerful model that can handle each role to conserve cost and increase speed.\\n\\n**Mechanical implementation tasks** (isolated functions, clear specs, 1-2 files): use a fast, cheap model. Most implementation tasks are mechanical when the plan is well-specified.\\n\\n**Integration and judgment tasks** (multi-file coordination, pattern matching, debugging): use a standard model.\\n\\n**Architecture and design tasks**: use the most capable available model.\\nThe final whole-branch review is one of these ??dispatch it on the most\\ncapable available model, not the session default.\\n\\n**Review tasks**: choose the model with the same judgment, scaled to the\\ndiff's size, complexity, and risk. A small mechanical diff does not need the\\nmost capable model; a subtle concurrency change does. Scoped re-reviews of\\nsmall fix diffs take a cheap-to-mid tier.\\n\\n**Fix-loop escalation (rounds 4-5)**: use a model at least one tier above\\nthe implementer that got stuck.\\n\\n**Always specify the model explicitly when dispatching a subagent.** An\\nomitted model inherits your session's model ??often the most capable and\\nmost expensive ??which silently defeats this section.\\n\\n**Turn count beats token price.** Wall-clock and context cost scale with how\\nmany turns a subagent takes, and the cheapest models routinely take 2-3횞 the\\nturns on multi-step work ??costing more overall. Use a mid-tier model as the\\nfloor for reviewers and for implementers working from prose descriptions.\\nWhen the task's plan text contains the complete code to write, the\\nimplementation is transcription plus testing: use the cheapest tier for\\nthat implementer. Single-file mechanical fixes also take the cheapest tier.\\n\\n**Task complexity signals (implementation tasks):**\\n- Touches 1-2 files with a complete spec ??cheap model\\n- Touches multiple files with integration concerns ??standard model\\n- Requires design judgment or broad codebase understanding ??most capable model\\n\\n## The Task Loop\\n\\nEverything you paste into a dispatch prompt ??and everything a subagent\\nprints back ??stays resident in your context for the rest of the session\\nand is re-read on every later turn. Hand artifacts over as files.\\n\\n### 1. Dispatch the implementer\\n\\nRecord BASE (`git rev-parse HEAD`) before dispatching ??the review package\\nand fix-round diffs need it.\\n\\n- **Task brief:** before dispatching an implementer, run this skill's\\n `scripts/task-brief PLAN_FILE N` ??it extracts the task's full text to a\\n uniquely named file and prints the path. Compose the dispatch so the\\n brief stays the single source of\\n requirements. Your dispatch should contain: (1) one line on where this\\n task fits in the project; (2) the brief path, introduced as \\\"read this\\n first ??it is your requirements, with the exact values to use verbatim\\\";\\n (3) interfaces and decisions from earlier tasks that the brief cannot\\n know; (4) your resolution of any ambiguity you noticed in the brief;\\n (5) the report-file path and report contract. Exact values (numbers,\\n magic strings, signatures, test cases) appear only in the brief. Never\\n make a subagent read the whole plan file.\\n- **Report file:** name the implementer's report file after the brief\\n (brief `??task-N-brief.md` ??report `??task-N-report.md`) and put it in\\n the dispatch prompt. The implementer writes the full report there and\\n returns only status, commits, a one-line test summary, and concerns.\\n- A dispatch prompt describes one task, not the session's history. Do not\\n paste accumulated prior-task summaries (\\\"state after Tasks 1-3\\\") into\\n later dispatches ??a real session's dispatch hit 42k chars of which 99%\\n was pasted history. A fresh subagent needs its task, the interfaces it\\n touches, and the global constraints. Nothing else.\\n- If an earlier task parked a finding in the area this task touches, carry\\n a pointer to that ledger entry in the dispatch.\\n- Record the implementer's agent identity from the dispatch result ?? fix-loop rounds 1-3 resume this agent.\\n- Never dispatch multiple implementation subagents in parallel (conflicts).\\n\\nTemplate: [implementer-prompt.md](implementer-prompt.md)\\n\\n### 2. Handle the report\\n\\nImplementer subagents report one of four statuses. Handle each appropriately:\\n\\n**DONE:** Generate the review package (`scripts/review-package PLAN_FILE BASE HEAD`, from this skill's directory ??it prints the unique file path it wrote; BASE is the commit you recorded before dispatching the implementer ??never `HEAD~1`, which silently drops all but the last commit of a multi-commit task), then dispatch the task reviewer with the printed path.\\n\\n**DONE_WITH_CONCERNS:** The implementer completed the work but flagged doubts. Read the concerns before proceeding. If the concerns are about correctness or scope, address them before review. If they're observations (e.g., \\\"this file is getting large\\\"), note them and proceed to review.\\n\\n**NEEDS_CONTEXT:** The implementer needs information that wasn't provided. Provide the missing context and re-dispatch.\\n\\n**BLOCKED:** The implementer cannot complete the task. Assess the blocker:\\n1. If it's a context problem, provide more context and re-dispatch with the same model\\n2. If the task requires more reasoning, re-dispatch with a more capable model\\n3. If the task is too large, break it into smaller pieces\\n4. If the plan itself is wrong, escalate to the human\\n\\n**Never** ignore an escalation or force the same model to retry without changes. If the implementer said it's stuck, something needs to change.\\n\\nIf the implementer asks questions ??before starting or mid-task ??answer\\nclearly and completely, provide additional context if needed, and don't\\nrush it into implementation.\\n\\n### 3. Review the task\\n\\nPer-task reviews are task-scoped gates. The broad review happens once, at the\\nfinal whole-branch review. Never skip the task review, and never accept a\\nreport missing either verdict ??spec compliance AND task quality are both\\nrequired. Implementer self-review never replaces the task review; both are\\nneeded.\\n\\n- Hand the reviewer its diff as a file: run this skill's\\n `scripts/review-package PLAN_FILE BASE HEAD` and pass the reviewer the file path\\n it prints (or, without bash: `git log --oneline`, `git diff --stat`,\\n and `git diff -U10` for the range, redirected to one uniquely named\\n file). The output never enters your own context, and the reviewer sees\\n the commit list, stat summary, and full diff with context in one Read\\n call. Use the BASE you recorded before dispatching the implementer ?? never `HEAD~1`, which silently truncates multi-commit tasks. Never\\n dispatch a task reviewer without a diff file.\\n- **Reviewer inputs:** the task reviewer gets three paths ??the same brief\\n file, the report file, and the review package ??plus the global\\n constraints that bind the task.\\n- The global-constraints block you hand the reviewer is its attention\\n lens. Copy the binding requirements verbatim from the plan's Global\\n Constraints section or the spec: exact values, exact formats, and the\\n stated relationships between components (\\\"same layout as X\\\", \\\"matches\\n Y\\\"). The reviewer's template already carries the process rules (YAGNI,\\n test hygiene, review method) ??the constraints block is for what THIS\\n project's spec demands.\\n- Do not add open-ended directives like \\\"check all uses\\\" or \\\"run race tests\\n if useful\\\" without a concrete, task-specific reason\\n- Do not ask a reviewer to re-run tests the implementer already ran on the\\n same code ??the implementer's report carries the test evidence\\n- Do not pre-judge findings for the reviewer ??never instruct a reviewer to\\n ignore or not flag a specific issue. If you believe a finding would be a\\n false positive, let the reviewer raise it and adjudicate it in the review\\n loop. If the prompt you are writing contains \\\"do not flag,\\\" \\\"don't treat X\\n as a defect,\\\" \\\"at most Minor,\\\" or \\\"the plan chose\\\" ??stop: you are\\n pre-judging, usually to spare yourself a review loop.\\nThe task reviewer may report \\\"?좑툘 Cannot verify from diff\\\" items ??requirements\\nthat live in unchanged code or span tasks. These do not block the rest of the\\nreview, but you must resolve each one yourself before marking the task\\ncomplete: you hold the plan and cross-task context the reviewer\\nlacks. If you confirm an item is a real gap, treat it as a failed spec\\nreview ??it enters the fix loop with the other findings.\\n\\nTemplate: [task-reviewer-prompt.md](task-reviewer-prompt.md)\\n\\n### 4. The fix loop\\n\\nThe loop triggers when the review reports spec ?? any Critical or Important\\nfinding, or a ?좑툘 item you confirmed as a real gap.\\n\\nBefore the loop starts, two routes leave it immediately:\\n\\n- Record Minor findings in the progress ledger as you go\\n (`Task : minor (deferred): `), and point the final\\n whole-branch review at that list so it can triage which must be fixed\\n before merge. A roll-up nobody reads is a silent discard. Minor findings\\n never enter the loop.\\n- A finding labeled plan-mandated ??or any finding that conflicts with\\n what the plan's text requires ??is the human's decision, like any plan\\n contradiction: present the finding and the plan text, ask which governs.\\n Do not dismiss the finding because the plan mandates it, and do not\\n dispatch a fix that contradicts the plan without asking.\\nEverything else enters the loop. A fix round is one fix dispatch plus one\\nscoped re-review. Five rounds maximum per task:\\n\\n**Rounds 1-3 ??resume the original implementer.** Send it the open findings\\nverbatim. Its context is intact: it knows the task, the code, and its own\\nchoices. If your harness cannot send another message to a live subagent,\\ndispatch a fresh implementer carrying the brief path, the report-file path,\\nand the findings ??the report file is the persistent memory either way.\\n\\n**Rounds 4-5 ??dispatch a fresh implementer on a more capable model** (per\\nModel Selection), with the brief path, the report-file path, the open\\nfindings, and this framing: \\\"A prior implementer attempted this task\\n[N] times; you own it now. Read the report file for what was tried.\\\" A loop\\nthat survives three resumes usually means the implementer cannot see its\\nown problem ??fresh eyes and a capability bump in one move.\\n\\n**Every round, either way:** the implementer fixes, re-runs the tests\\ncovering the amended code, appends its fix report to the same report file,\\nand returns the short contract. Before re-dispatching the reviewer, confirm\\nthe fix report contains the covering tests, the command run, and the\\noutput; dispatch the re-review once all three are present. Name the\\ncovering test files in the fix message ??a one-line fix does not need the\\nwhole suite.\\n\\n**The re-review is scoped.** Run `scripts/review-package PLAN_FILE FIX_BASE HEAD`\\nwhere FIX_BASE is the head the previous review saw, and dispatch\\n[re-review-prompt.md](re-review-prompt.md) with the findings list, the\\nbrief, the report file, and the printed diff path. The re-reviewer verdicts\\neach finding ADDRESSED or NOT ADDRESSED and flags new breakage in the fix\\ndiff only. New Critical/Important breakage in the fix diff joins the open\\nfindings list. Out-of-scope observations go to the ledger as deferred\\nminors ??they never extend the loop.\\n\\n**After each round,** append to the ledger:\\n`Task : fix round /5 ( addressed, open ??; commits ..)`\\n\\nNever fix findings yourself in the controller session ??your context stays\\nclean for coordination, and controller fixes skip review.\\n\\n**The breaker.** When round 5's re-review still leaves findings open, stop\\ndispatching. Adjudicate each open finding yourself ??you hold the plan and\\nthe cross-task context the reviewer lacks:\\n\\n- **The reviewer is wrong, or the point is contestable:** park it ?? `Task : parked ?? ??ruling: `. The final\\n review sees both sides.\\n- **Real, but nothing downstream builds on it:** park it the same way, with\\n a ruling that says it's real and deferred.\\n- **Real and load-bearing** ??a later task builds on it, or it reveals a\\n plan defect: STOP. Append `Task : BLOCKED ??` and report to\\n your human partner with the finding, the plan text it collides with, and\\n the fix history. Parking a structural failure lets every dependent task\\n build on it and hands the final review a problem it cannot fix either.\\n\\nAdjudicate only at the cap. Adjudicating earlier to end a loop is\\npre-judging with a different name. Every adjudication is a ledger entry ??a silent discard is forbidden.\\n\\n### 5. Complete the task\\n\\nWhen the review comes back clean ??or every open finding is parked with a\\nruling at the cap ??append the completion line to the ledger in the same\\nmessage as your other bookkeeping:\\n\\n- `Task : complete (commits .., review clean)`\\n- `Task : complete (commits .., parked)` after a\\n tripped breaker\\n\\nThen mark the todo complete and move on. Never move to the next task while\\nthe review has open Critical/Important issues that are neither fixed nor\\nparked-with-ruling at the cap.\\n\\n## Final Review\\n\\nThe final whole-branch review gets a package too: run\\n`scripts/review-package PLAN_FILE MERGE_BASE HEAD` (MERGE_BASE = the commit the\\nbranch started from, e.g. `git merge-base main HEAD`) and include the\\nprinted path in the final review dispatch, so the final reviewer reads\\none file instead of re-deriving the branch diff with git commands. Dispatch\\non the most capable available model (see Model Selection), using\\nsuperpowers:requesting-code-review's\\n[code-reviewer.md](../requesting-code-review/code-reviewer.md). Point it at\\nthe ledger's deferred-minor and parked lines so it can triage which must be\\nfixed before merge.\\n\\nIf the final whole-branch review returns findings, dispatch ONE fix subagent\\nwith the complete findings list ??not one fixer per finding.\\nPer-finding fixers each rebuild context and re-run suites; a real\\nsession's final-review fix wave cost more than all its tasks combined.\\nThen run exactly one scoped re-review of the fix wave\\n(`scripts/review-package PLAN_FILE FIX_BASE HEAD` over the fix range,\\n[re-review-prompt.md](re-review-prompt.md)).\\nAdjudicate any residual findings as in the task loop's breaker: park with\\nrulings, or stop on load-bearing ones. There is no second fix wave ??residual load-bearing findings surface to your human partner when\\nfinishing-a-development-branch presents the options.\\n\\n## Finish\\n\\nWhen the final whole-branch review is clean and its fixes are merged,\\ndelete this plan's workspace (`rm -rf `) ??the git history is\\nthe record now. Sibling directories belong to other plans; leave them\\nalone.\\n\\nUse superpowers:finishing-a-development-branch.\\n\\n## Common Rationalizations\\n\\n| Excuse | Reality |\\n|--------|---------|\\n| \\\"Close enough on spec compliance\\\" | Reviewer found spec gaps = not done. Fix or hit the cap and adjudicate ??those are the only exits. |\\n| \\\"I'll fix it myself, dispatching is overhead\\\" | Controller fixes pollute your context and skip review. Resume the implementer. |\\n| \\\"One more round will converge\\\" | Past the cap, rounds don't converge ??the failure is structural. Adjudicate and route. |\\n| \\\"The reviewer will just find something new anyway\\\" | Scoped re-reviews verify fixes; they cannot wander. New findings on untouched code go to the ledger, not the loop. |\\n| \\\"This finding is obviously wrong, I'll drop it\\\" | You adjudicate only at the cap, and every ruling is a ledger entry. Silent discards are forbidden. |\\n| \\\"The fix was small, skip the re-review\\\" | Unreviewed fixes are how regressions land. Every round ends with a scoped re-review. |\\n| \\\"Reviews slow the loop down\\\" | The loop without reviews is just unverified churn. Reviews are the loop's brakes and steering. |\\n| \\\"Ledger bookkeeping is overhead\\\" | The ledger is what survives compaction. Controllers without one have re-dispatched entire completed task sequences. |\\n\\n## Example Workflow\\n\\n```\\nYou: I'm using Subagent-Driven Development to execute this plan.\\n\\n[Setup: worktree verified]\\n[Read plan file once: docs/superpowers/plans/feature-plan.md]\\n[Resolve workspace: scripts/sdd-workspace docs/superpowers/plans/feature-plan.md ??no ledger inside, fresh start]\\n[Create todos for all tasks]\\n\\nTask 1: Hook installation script\\n\\n[Run task-brief for Task 1; dispatch implementer with brief + report paths + context]\\n\\nImplementer: \\\"Before I begin - should the hook be installed at user or system level?\\\"\\n\\nYou: \\\"User level (~/.config/superpowers/hooks/)\\\"\\n\\nImplementer: [Later]\\n - Implemented install-hook command\\n - Added tests, 5/5 passing\\n - Self-review: Found I missed --force flag, added it\\n - Committed\\n\\n[Run review-package PLAN_FILE BASE HEAD; dispatch task reviewer with the printed path]\\nTask reviewer: Spec ??- all requirements met, nothing extra.\\n Strengths: Good test coverage, clean. Issues: None. Task quality: Approved.\\n\\n[Ledger: Task 1: complete (commits a1b2c3d..d4e5f6a, review clean)]\\n\\nTask 2: Recovery modes\\n\\n[Run task-brief for Task 2; dispatch implementer with brief + report paths + context]\\n\\nImplementer: [No questions]\\n - Added verify/repair modes\\n - 8/8 tests passing\\n - Committed\\n\\n[Run review-package PLAN_FILE BASE HEAD; dispatch task reviewer with the printed path]\\nTask reviewer: Spec ??\\n - Missing: Progress reporting (spec says \\\"report every 100 items\\\")\\n Issues (Important): Magic number (100)\\n\\n[Fix round 1: resume the implementer with both findings]\\nImplementer: Added progress reporting, extracted PROGRESS_INTERVAL constant.\\n Re-ran test/recovery.test.js ??10/10 passing. Fix report appended.\\n\\n[Run review-package PLAN_FILE FIX_BASE HEAD; dispatch scoped re-review]\\nRe-reviewer: Missing progress reporting ??ADDRESSED (src/recovery.js:41).\\n Magic number ??ADDRESSED (src/recovery.js:7). New breakage: none.\\n Verdict: all findings addressed.\\n\\n[Ledger: Task 2: fix round 1/5 (2 addressed, 0 open; commits d4e5f6a..b7c8d9e)]\\n[Ledger: Task 2: complete (commits d4e5f6a..b7c8d9e, review clean)]\\n\\n...\\n\\n[After all tasks]\\n[Run review-package PLAN_FILE MERGE_BASE HEAD; dispatch final code-reviewer, most capable model]\\nFinal reviewer: All requirements met. Deferred minors triaged: none block merge.\\n\\n[Delete this plan's workspace ??the record now lives in git]\\n\\nDone! Using superpowers:finishing-a-development-branch.\\n```\\n\\r\\n# Code Reviewer Prompt Template\\n\\nUse this template when dispatching a code reviewer subagent.\\n\\n**Purpose:** Review completed work against requirements and code quality standards before it cascades into more work.\\n\\n```\\nSubagent (general-purpose):\\n description: \\\"Review code changes\\\"\\n prompt: |\\n You are a Senior Code Reviewer with expertise in software architecture,\\n design patterns, and best practices. Your job is to review completed work\\n against its plan or requirements and identify issues before they cascade.\\n\\n ## What Was Implemented\\n\\n [DESCRIPTION]\\n\\n ## Requirements / Plan\\n\\n [PLAN_OR_REQUIREMENTS]\\n\\n ## Git Range to Review\\n\\n **Base:** [BASE_SHA]\\n **Head:** [HEAD_SHA]\\n\\n ```bash\\n git diff --stat [BASE_SHA]..[HEAD_SHA]\\n git diff [BASE_SHA]..[HEAD_SHA]\\n ```\\n\\n ## Read-Only Review\\n\\n Your review is read-only on this checkout. Do not mutate the working tree, the index, HEAD, or branch state in any way. Use tools like `git show`, `git diff`, and `git log` to inspect history. If you need a working copy of a different revision, check it out into a separate temporary directory (e.g. `git worktree add /tmp/review-[SHA] [SHA]`) ??never move HEAD on this checkout.\\n\\n ## What to Check\\n\\n **Plan alignment:**\\n - Does the implementation match the plan / requirements?\\n - Are deviations justified improvements, or problematic departures?\\n - Is all planned functionality present?\\n\\n **Code quality:**\\n - Clean separation of concerns?\\n - Proper error handling?\\n - Type safety where applicable?\\n - DRY without premature abstraction?\\n - Edge cases handled?\\n\\n **Architecture:**\\n - Sound design decisions?\\n - Reasonable scalability and performance?\\n - Security concerns?\\n - Integrates cleanly with surrounding code?\\n\\n **Testing:**\\n - Tests verify real behavior, not mocks?\\n - Edge cases covered?\\n - Integration tests where they matter?\\n - All tests passing?\\n\\n **Production readiness:**\\n - Migration strategy if schema changed?\\n - Backward compatibility considered?\\n - Documentation complete?\\n - No obvious bugs?\\n\\n ## Calibration\\n\\n Categorize issues by actual severity. Not everything is Critical.\\n Acknowledge what was done well before listing issues ??accurate praise\\n helps the implementer trust the rest of the feedback.\\n\\n If you find significant deviations from the plan, flag them specifically\\n so the implementer can confirm whether the deviation was intentional.\\n If you find issues with the plan itself rather than the implementation,\\n say so.\\n\\n ## Output Format\\n\\n ### Strengths\\n [What's well done? Be specific.]\\n\\n ### Issues\\n\\n #### Critical (Must Fix)\\n [Bugs, security issues, data loss risks, broken functionality]\\n\\n #### Important (Should Fix)\\n [Architecture problems, missing features, poor error handling, test gaps]\\n\\n #### Minor (Nice to Have)\\n [Code style, optimization opportunities, documentation polish]\\n\\n For each issue:\\n - File:line reference\\n - What's wrong\\n - Why it matters\\n - How to fix (if not obvious)\\n\\n ### Recommendations\\n [Improvements for code quality, architecture, or process]\\n\\n ### Assessment\\n\\n **Ready to merge?** [Yes | No | With fixes]\\n\\n **Reasoning:** [1-2 sentence technical assessment]\\n\\n ## Critical Rules\\n\\n **DO:**\\n - Categorize by actual severity\\n - Be specific (file:line, not vague)\\n - Explain WHY each issue matters\\n - Acknowledge strengths\\n - Give a clear verdict\\n\\n **DON'T:**\\n - Say \\\"looks good\\\" without checking\\n - Mark nitpicks as Critical\\n - Give feedback on code you didn't actually read\\n - Be vague (\\\"improve error handling\\\")\\n - Avoid giving a clear verdict\\n```\\n\\n**Placeholders:**\\n- `[DESCRIPTION]` ??brief summary of what was built\\n- `[PLAN_OR_REQUIREMENTS]` ??what it should do (plan file path, task text, or requirements)\\n- `[BASE_SHA]` ??starting commit\\n- `[HEAD_SHA]` ??ending commit\\n\\n**Reviewer returns:** Strengths, Issues (Critical / Important / Minor), Recommendations, Assessment\\n\\n## Example Output\\n\\n```\\n### Strengths\\n- Clean database schema with proper migrations (db.ts:15-42)\\n- Comprehensive test coverage (18 tests, all edge cases)\\n- Good error handling with fallbacks (summarizer.ts:85-92)\\n\\n### Issues\\n\\n#### Important\\n1. **Missing help text in CLI wrapper**\\n - File: index-conversations:1-31\\n - Issue: No --help flag, users won't discover --concurrency\\n - Fix: Add --help case with usage examples\\n\\n2. **Date validation missing**\\n - File: search.ts:25-27\\n - Issue: Invalid dates silently return no results\\n - Fix: Validate ISO format, throw error with example\\n\\n#### Minor\\n1. **Progress indicators**\\n - File: indexer.ts:130\\n - Issue: No \\\"X of Y\\\" counter for long operations\\n - Impact: Users don't know how long to wait\\n\\n### Recommendations\\n- Add progress reporting for user experience\\n- Consider config file for excluded projects (portability)\\n\\n### Assessment\\n\\n**Ready to merge: With fixes**\\n\\n**Reasoning:** Core implementation is solid with good architecture and tests. Important issues (help text, date validation) are easily fixed and don't affect core functionality.\\n```\\n\\r\\n\",\"exit_code\":0,\"status\":\"completed\"}}\n{\"type\":\"item.started\",\"item\":{\"id\":\"item_11\",\"type\":\"command_execution\",\"command\":\"\\\"C:\\\\\\\\WINDOWS\\\\\\\\System32\\\\\\\\WindowsPowerShell\\\\\\\\v1.0\\\\\\\\powershell.exe\\\" -Command '$gitDir = (Resolve-Path (git rev-parse --git-dir)).Path; $gitCommon = (Resolve-Path (git rev-parse --git-common-dir)).Path; $branch = git branch --show-current; $super = git rev-parse --show-superproject-working-tree; [pscustomobject]@{GitDir=$gitDir; GitCommon=$gitCommon; Branch=$branch; Superproject=$super} | Format-List; git status --short --branch; git rev-parse HEAD; git rev-parse origin/dev; git rev-list --left-right --count origin/dev...dev; Get-ChildItem Env:MKL_DIR,Env:TBB_DIR,Env:HDF5_DIR,Env:GTest_DIR -ErrorAction SilentlyContinue | Format-Table -AutoSize'\",\"aggregated_output\":\"\",\"exit_code\":null,\"status\":\"in_progress\"}}\n{\"type\":\"item.completed\",\"item\":{\"id\":\"item_11\",\"type\":\"command_execution\",\"command\":\"\\\"C:\\\\\\\\WINDOWS\\\\\\\\System32\\\\\\\\WindowsPowerShell\\\\\\\\v1.0\\\\\\\\powershell.exe\\\" -Command '$gitDir = (Resolve-Path (git rev-parse --git-dir)).Path; $gitCommon = (Resolve-Path (git rev-parse --git-common-dir)).Path; $branch = git branch --show-current; $super = git rev-parse --show-superproject-working-tree; [pscustomobject]@{GitDir=$gitDir; GitCommon=$gitCommon; Branch=$branch; Superproject=$super} | Format-List; git status --short --branch; git rev-parse HEAD; git rev-parse origin/dev; git rev-list --left-right --count origin/dev...dev; Get-ChildItem Env:MKL_DIR,Env:TBB_DIR,Env:HDF5_DIR,Env:GTest_DIR -ErrorAction SilentlyContinue | Format-Table -AutoSize'\",\"aggregated_output\":\"\\r\\n\\r\\nGitDir : C:\\\\git\\\\FESA\\\\.git\\r\\nGitCommon : C:\\\\git\\\\FESA\\\\.git\\r\\nBranch : feat-deterministic-parallel-assembly\\r\\nSuperproject : \\r\\n\\r\\n\\r\\n\\r\\n## feat-deterministic-parallel-assembly\\n M phases/deterministic-parallel-assembly/index.json\\ndc6baed8edb302cff6a52536b2164d448a57f591\\n6ac474f19b9d5ad7b588cbce807df11f45c7bcb1\\n0\\t0\\n\\r\\nName Value \\r\\n---- ----- \\r\\nMKL_DIR C:\\\\Program Files (x86)\\\\Intel\\\\oneAPI\\\\2026.1\\\\lib\\\\cmake\\\\mkl \\r\\nTBB_DIR C:\\\\Program Files (x86)\\\\Intel\\\\oneAPI\\\\2026.1\\\\lib\\\\cmake\\\\tbb \\r\\nHDF5_DIR C:\\\\Program Files\\\\HDF_Group\\\\HDF5\\\\2.1.1\\\\cmake \\r\\nGTEST_DIR C:\\\\Users\\\\baram\\\\AppData\\\\Local\\\\FESA\\\\dependencies\\\\googletest-1.17.0-v145-x64-crt\\\\lib\\\\cmake\\\\GTest\\r\\n\\r\\n\\r\\nwarning: could not open directory '.harness/fallback-pytest-basetemp-82aadc57b8df4a27bf47b31b7c9393d2/': Permission denied\\nwarning: could not open directory '.harness/pytest-basetemp-ac0985ddc9224918b6d0476471cc5f39/': Permission denied\\nwarning: could not open directory '.harness/pytest-basetemp-step0b/': Permission denied\\nwarning: could not open directory '.harness/pytest-basetemp-step1-current/': Permission denied\\nwarning: could not open directory '.harness/pytest-cache-files-65hly0n3/': Permission denied\\nwarning: could not open directory '.harness/pytest-cache-files-sor_s7m3/': Permission denied\\nwarning: could not open directory '.harness/pytest-cache-files-sqpzrqiw/': Permission denied\\nwarning: could not open directory '.harness/pytest-cache-files-vf1p08il/': Permission denied\\nwarning: could not open directory '.harness/pytest-cache-files-y84afu_7/': Permission denied\\nwarning: could not open directory '.harness/pytest-cache-files-zjj4_p73/': Permission denied\\nwarning: could not open directory '.harness/pytest-step1-0768500edb86428286367c01aed9db54/pytest-of-Mimi/': Permission denied\\nwarning: could not open directory '.harness/pytest-step3-temp/pytest-of-Mimi/': Permission denied\\nwarning: could not open directory '.harness/step3-pytest-basetemp/': Permission denied\\nwarning: could not open directory 'gitFESA.harnessbuildpytest-basetemp/': Permission denied\\nwarning: could not open directory 'gitFESA.harnesspytest-basetemp-step0/': Permission denied\\nwarning: could not open directory 'gitFESAoutbuildpytest-basetemp-step1/': Permission denied\\nwarning: could not open directory 'pytest-cache-files-13i94o94/': Permission denied\\nwarning: could not open directory 'pytest-cache-files-pnbzv9xt/': Permission denied\\nwarning: could not open directory 'pytest-cache-files-vtfbrhqu/': Permission denied\\nwarning: could not open directory 'pytest-cache-files-wy6fhgsc/': Permission denied\\n\",\"exit_code\":0,\"status\":\"completed\"}}\n{\"type\":\"item.completed\",\"item\":{\"id\":\"item_12\",\"type\":\"agent_message\",\"text\":\"작업 브랜치는 이미 `feat-deterministic-parallel-assembly`이며 Step 0/1 커밋 위에 있습니다. 새 worktree는 만들지 않고 Harness가 준비한 현재 브랜치에서 진행하겠습니다. 기존 변경은 phase index 하나뿐이므로 실행기 메타데이터로 간주해 보존합니다.\"}}\n{\"type\":\"item.started\",\"item\":{\"id\":\"item_13\",\"type\":\"command_execution\",\"command\":\"\\\"C:\\\\\\\\WINDOWS\\\\\\\\System32\\\\\\\\WindowsPowerShell\\\\\\\\v1.0\\\\\\\\powershell.exe\\\" -Command 'rg --files phases/deterministic-parallel-assembly include/fesa/assembly src/fesa/assembly tests/unit/assembly tests/integration/assembly tests/performance | Sort-Object; Get-Content -Raw phases/deterministic-parallel-assembly/index.json; Get-Content -Raw phases/deterministic-parallel-assembly/step2.md; Get-Content -Raw include/fesa/assembly/assembler.hpp; Get-Content -Raw CMakeLists.txt; git diff -- phases/deterministic-parallel-assembly/index.json; git log --oneline --decorate -8'\",\"aggregated_output\":\"\",\"exit_code\":null,\"status\":\"in_progress\"}}\n{\"type\":\"item.completed\",\"item\":{\"id\":\"item_13\",\"type\":\"command_execution\",\"command\":\"\\\"C:\\\\\\\\WINDOWS\\\\\\\\System32\\\\\\\\WindowsPowerShell\\\\\\\\v1.0\\\\\\\\powershell.exe\\\" -Command 'rg --files phases/deterministic-parallel-assembly include/fesa/assembly src/fesa/assembly tests/unit/assembly tests/integration/assembly tests/performance | Sort-Object; Get-Content -Raw phases/deterministic-parallel-assembly/index.json; Get-Content -Raw phases/deterministic-parallel-assembly/step2.md; Get-Content -Raw include/fesa/assembly/assembler.hpp; Get-Content -Raw CMakeLists.txt; git diff -- phases/deterministic-parallel-assembly/index.json; git log --oneline --decorate -8'\",\"aggregated_output\":\"include/fesa/assembly\\\\assembler.hpp\\r\\ninclude/fesa/assembly\\\\contribution.hpp\\r\\ninclude/fesa/assembly\\\\equation_system.hpp\\r\\ninclude/fesa/assembly\\\\serial_assembler.hpp\\r\\ninclude/fesa/assembly\\\\symmetric_csr.hpp\\r\\nphases/deterministic-parallel-assembly\\\\index.json\\r\\nphases/deterministic-parallel-assembly\\\\step0.md\\r\\nphases/deterministic-parallel-assembly\\\\step0-output.json\\r\\nphases/deterministic-parallel-assembly\\\\step1.md\\r\\nphases/deterministic-parallel-assembly\\\\step1-output.json\\r\\nphases/deterministic-parallel-assembly\\\\step2.md\\r\\nsrc/fesa/assembly\\\\contribution.cpp\\r\\nsrc/fesa/assembly\\\\parallel_assembler.cpp\\r\\nsrc/fesa/assembly\\\\serial_assembler.cpp\\r\\ntests/unit/assembly\\\\parallel_assembler_test.cpp\\r\\ntests/unit/assembly\\\\serial_assembler_test.cpp\\r\\n{\\r\\n \\\"project\\\": \\\"FESA\\\",\\r\\n \\\"phase\\\": \\\"deterministic-parallel-assembly\\\",\\r\\n \\\"steps\\\": [\\r\\n {\\r\\n \\\"step\\\": 0,\\r\\n \\\"name\\\": \\\"canonical-contribution-order\\\",\\r\\n \\\"status\\\": \\\"completed\\\",\\r\\n \\\"summary\\\": \\\"Added canonical MatrixContribution ordering and deterministic upper-triangle CSR merge with bitwise permutation, cancellation, signed-zero, and serial-oracle coverage.\\\",\\r\\n \\\"started_at\\\": \\\"2026-08-01T22:17:55+0900\\\",\\r\\n \\\"completed_at\\\": \\\"2026-08-01T23:06:21+0900\\\"\\r\\n },\\r\\n {\\r\\n \\\"step\\\": 1,\\r\\n \\\"name\\\": \\\"tbb-element-evaluation\\\",\\r\\n \\\"status\\\": \\\"completed\\\",\\r\\n \\\"summary\\\": \\\"Added AssemblyOptions and oneTBB Beam element evaluation with element-local contributions, canonical serial merge, explicit execution limits, and bitwise serial parity tests.\\\",\\r\\n \\\"started_at\\\": \\\"2026-08-01T23:06:22+0900\\\",\\r\\n \\\"completed_at\\\": \\\"2026-08-01T23:21:27+0900\\\"\\r\\n },\\r\\n {\\r\\n \\\"step\\\": 2,\\r\\n \\\"name\\\": \\\"thread-count-determinism\\\",\\r\\n \\\"status\\\": \\\"pending\\\",\\r\\n \\\"started_at\\\": \\\"2026-08-01T23:21:27+0900\\\"\\r\\n }\\r\\n ],\\r\\n \\\"created_at\\\": \\\"2026-08-01T22:17:55+0900\\\"\\r\\n}\\r\\n# Step 2: Thread Count Determinism\\n\\n## ?쎌뼱?????뚯씪\\n\\n- `/AGENTS.md`\\n- `/docs/PRD.md`\\n- `/docs/ARCHITECTURE.md`\\n- `/docs/ADR.md`\\n- `/include/fesa/assembly/assembler.hpp`\\n- `/tests/unit/assembly/`\\n- `/tests/integration/assembly/`\\n\\n## ?묒뾽\\n\\nthread count? 諛섎났 ?ㅽ뻾??assembly 諛?理쒖쥌 ?좏삎 ?뺤쟻 寃곌낵瑜?諛붽씀吏 ?딅뒗 ?듯빀\\n寃利앷낵 痢≪젙??benchmark瑜?異붽??쒕떎.\\n\\n- `tests/integration/assembly/thread_count_determinism_test.cpp`\\n- `tests/performance/assembly_benchmark.cpp`\\n- thread counts 1, 2, available concurrency?먯꽌 CSR, RHS, displacement, reaction?? bit-for-bit 鍮꾧탳?쒕떎.\\n- 理쒖냼 10??諛섎났?쇰줈 scheduling 蹂???뚭?瑜??뺤씤?쒕떎.\\n- benchmark??serial/parallel ?쒓컙怨?element count瑜?異쒕젰?섎릺 speedup??assertion?섏?\\n ?딅뒗??\\n\\n## Acceptance Criteria\\n\\n```powershell\\ncmake --build --preset windows-debug\\nctest --preset windows-debug -R ThreadCountDeterminism --output-on-failure\\n.\\\\out\\\\build\\\\windows-debug\\\\Debug\\\\fesa_assembly_benchmark.exe\\nctest --preset windows-debug --output-on-failure\\n```\\n\\n## 寃利??덉감\\n\\n1. ?ㅼ뼇??thread count ?듯빀 ?뚯뒪?몃? 癒쇱? ?ㅽ뻾?쒕떎.\\n2. 李⑥씠媛 ?덉쑝硫?canonical key/merge ?먯씤??怨좎튂怨?tolerance 鍮꾧탳濡??泥댄븯吏 ?딅뒗??\\n3. benchmark output??湲곕줉?섍퀬 ?꾩껜 ?뚯뒪?몃? ?ㅽ뻾?쒕떎.\\n4. index summary??tested thread counts瑜?湲곕줉?쒕떎.\\n\\n## 湲덉??ы빆\\n\\n- benchmark?먯꽌 ?띾룄 ?μ긽??pass 議곌굔?쇰줈 留뚮뱾吏 留덈씪. ?댁쑀: ?섍꼍 ?섏〈?곸씠??\\n- MKL thread ?섎? assembly test? 以묒꺽???ㅼ슦吏 留덈씪. ?댁쑀: 痢≪젙???ㅼ뿼?쒕떎.\\n- release ?깅뒫 紐⑺몴瑜??꾩쓽濡?留뚮뱾吏 留덈씪. ?댁쑀: 臾몄꽌?붾맂 痢≪젙留??붽뎄?쒕떎.\\n\\r\\n#pragma once\\n\\n#include \\n\\n#include \\n#include \\n#include \\n\\nnamespace fesa {\\n\\nstruct AssemblyOptions final {\\n std::size_t max_threads;\\n std::size_t grain_size;\\n};\\n\\n[[nodiscard]] EquationSystem assemble_parallel(\\n const Domain& domain,\\n const DofManager& dofs,\\n AssemblyOptions options);\\n\\n} // namespace fesa\\n\\r\\ncmake_minimum_required(VERSION 3.30)\\r\\n\\r\\nproject(FESA VERSION 0.1.0 LANGUAGES CXX)\\r\\n\\r\\nif(NOT MSVC)\\r\\n message(FATAL_ERROR \\\"FESA requires the Microsoft Visual C++ compiler (MSVC v145).\\\")\\r\\nendif()\\r\\n\\r\\nif(NOT CMAKE_VS_PLATFORM_TOOLSET STREQUAL \\\"v145\\\")\\r\\n message(\\r\\n FATAL_ERROR\\r\\n \\\"FESA requires the v145 platform toolset; configured toolset is \\\"\\r\\n \\\"'${CMAKE_VS_PLATFORM_TOOLSET}'.\\\"\\r\\n )\\r\\nendif()\\r\\n\\r\\nif(NOT CMAKE_GENERATOR_PLATFORM STREQUAL \\\"x64\\\")\\r\\n message(FATAL_ERROR \\\"FESA requires the x64 generator platform.\\\")\\r\\nendif()\\r\\n\\r\\nif(NOT CMAKE_SIZEOF_VOID_P EQUAL 8)\\r\\n message(FATAL_ERROR \\\"FESA requires a 64-bit target.\\\")\\r\\nendif()\\r\\n\\r\\ninclude(CTest)\\r\\ninclude(cmake/FesaDependencies.cmake)\\r\\n\\r\\nadd_library(fesa_core STATIC\\r\\n src/fesa/analysis/linear_static_analysis.cpp\\n src/fesa/analysis/run_solver.cpp\\n src/fesa/assembly/contribution.cpp\\n src/fesa/assembly/parallel_assembler.cpp\\n src/fesa/assembly/serial_assembler.cpp\\n src/fesa/constraints/essential_bc.cpp\\r\\n src/fesa/core/version.cpp\\r\\n src/fesa/elements/beam/beam3d2.cpp\\r\\n src/fesa/fem/beam_frame.cpp\\r\\n src/fesa/fem/dof_manager.cpp\\r\\n src/fesa/fem/gauss_rule.cpp\\r\\n src/fesa/fem/line2_shape.cpp\\r\\n src/fesa/io/abaqus/active_input.cpp\\r\\n src/fesa/io/abaqus/parser.cpp\\r\\n src/fesa/io/abaqus/semantic_mapper.cpp\\r\\n src/fesa/io/abaqus/set_resolver.cpp\\r\\n src/fesa/io/hdf5/writer.cpp\\r\\n src/fesa/model/domain.cpp\\r\\n src/fesa/model/domain_builder.cpp\\r\\n src/fesa/results/result_database.cpp\\r\\n src/fesa/solvers/linear/pardiso_linear_solver.cpp\\r\\n)\\r\\n\\r\\ntarget_include_directories(fesa_core\\r\\n PUBLIC\\r\\n \\\"${CMAKE_CURRENT_SOURCE_DIR}/include\\\"\\r\\n)\\r\\n\\r\\ntarget_compile_features(fesa_core PUBLIC cxx_std_20)\\r\\ntarget_compile_options(fesa_core PRIVATE /W4 /permissive- /EHsc)\\r\\ntarget_link_libraries(fesa_core PRIVATE MKL::MKL TBB::tbb HDF5::HDF5)\\n\\r\\nadd_executable(fesa\\r\\n src/fesa/cli/main.cpp\\r\\n)\\r\\n\\r\\ntarget_link_libraries(fesa PRIVATE fesa_core)\\r\\ntarget_compile_features(fesa PRIVATE cxx_std_20)\\r\\ntarget_compile_options(fesa PRIVATE /W4 /permissive- /EHsc)\\r\\n\\r\\nif(BUILD_TESTING)\\r\\n add_subdirectory(tests)\\r\\nendif()\\r\\n\\r\\ndiff --git a/phases/deterministic-parallel-assembly/index.json b/phases/deterministic-parallel-assembly/index.json\\nindex 4d1db16..3f2595f 100644\\n--- a/phases/deterministic-parallel-assembly/index.json\\n+++ b/phases/deterministic-parallel-assembly/index.json\\n@@ -21,7 +21,8 @@\\n {\\n \\\"step\\\": 2,\\n \\\"name\\\": \\\"thread-count-determinism\\\",\\n- \\\"status\\\": \\\"pending\\\"\\n+ \\\"status\\\": \\\"pending\\\",\\n+ \\\"started_at\\\": \\\"2026-08-01T23:21:27+0900\\\"\\n }\\n ],\\n \\\"created_at\\\": \\\"2026-08-01T22:17:55+0900\\\"\\ndc6baed (HEAD -> feat-deterministic-parallel-assembly) chore(deterministic-parallel-assembly): step 1 output\\n6c2e1f3 feat(deterministic-parallel-assembly): step 1 — tbb-element-evaluation\\nb9bb439 chore(deterministic-parallel-assembly): step 0 output\\n40a7e6c feat(deterministic-parallel-assembly): step 0 — canonical-contribution-order\\n6ac474f (origin/dev, origin/HEAD, dev) docs(handoff): prepare parallel assembly phase\\ncbb621b fix(input): validate inactive Part records\\naf886f3 fix(input): enforce strict Abaqus subset contract\\n9269847 chore(abaqus-subset-completion): mark phase completed\\nrg: tests/integration/assembly: 지정된 파일을 찾을 수 없습니다. (os error 2)\\nrg: tests/performance: 지정된 파일을 찾을 수 없습니다. (os error 2)\\n\",\"exit_code\":0,\"status\":\"completed\"}}\n{\"type\":\"item.started\",\"item\":{\"id\":\"item_14\",\"type\":\"command_execution\",\"command\":\"\\\"C:\\\\\\\\WINDOWS\\\\\\\\System32\\\\\\\\WindowsPowerShell\\\\\\\\v1.0\\\\\\\\powershell.exe\\\" -Command 'Get-Content -Raw tests/CMakeLists.txt; Get-Content -Raw tests/unit/assembly/parallel_assembler_test.cpp; Get-Content -Raw tests/unit/assembly/serial_assembler_test.cpp; Get-Content -Raw src/fesa/assembly/parallel_assembler.cpp; Get-Content -Raw src/fesa/assembly/serial_assembler.cpp; Get-Content -Raw include/fesa/analysis/linear_static_analysis.hpp; Get-Content -Raw src/fesa/analysis/linear_static_analysis.cpp; rg -n \\\"LinearStaticAnalysis|assemble_parallel|Pardiso|mkl_set|thread\\\" tests include src CMakeLists.txt tests/CMakeLists.txt'\",\"aggregated_output\":\"\",\"exit_code\":null,\"status\":\"in_progress\"}}\n{\"type\":\"item.completed\",\"item\":{\"id\":\"item_14\",\"type\":\"command_execution\",\"command\":\"\\\"C:\\\\\\\\WINDOWS\\\\\\\\System32\\\\\\\\WindowsPowerShell\\\\\\\\v1.0\\\\\\\\powershell.exe\\\" -Command 'Get-Content -Raw tests/CMakeLists.txt; Get-Content -Raw tests/unit/assembly/parallel_assembler_test.cpp; Get-Content -Raw tests/unit/assembly/serial_assembler_test.cpp; Get-Content -Raw src/fesa/assembly/parallel_assembler.cpp; Get-Content -Raw src/fesa/assembly/serial_assembler.cpp; Get-Content -Raw include/fesa/analysis/linear_static_analysis.hpp; Get-Content -Raw src/fesa/analysis/linear_static_analysis.cpp; rg -n \\\"LinearStaticAnalysis|assemble_parallel|Pardiso|mkl_set|thread\\\" tests include src CMakeLists.txt tests/CMakeLists.txt'\",\"aggregated_output\":\"add_test(\\r\\n NAME VersionCommand\\r\\n COMMAND \\\"${CMAKE_BINARY_DIR}/$/fesa.exe\\\" --version\\r\\n)\\r\\n\\r\\nset_tests_properties(\\r\\n VersionCommand\\r\\n PROPERTIES\\r\\n PASS_REGULAR_EXPRESSION \\\"[0-9]+\\\\\\\\.[0-9]+\\\\\\\\.[0-9]+\\\"\\r\\n)\\r\\n\\r\\nset_property(\\r\\n TEST VersionCommand\\r\\n PROPERTY ENVIRONMENT_MODIFICATION\\r\\n ${FESA_DEPENDENCY_RUNTIME_MODIFICATIONS}\\r\\n)\\r\\n\\r\\nadd_executable(fesa_dependency_smoke_test\\r\\n unit/dependencies/dependency_smoke_test.cpp\\r\\n)\\r\\n\\r\\ntarget_compile_features(fesa_dependency_smoke_test PRIVATE cxx_std_20)\\r\\ntarget_compile_options(fesa_dependency_smoke_test PRIVATE /W4 /permissive- /EHsc)\\r\\n\\r\\ntarget_link_libraries(fesa_dependency_smoke_test\\r\\n PRIVATE\\r\\n MKL::MKL\\r\\n TBB::tbb\\r\\n HDF5::HDF5\\r\\n GTest::gtest_main\\r\\n GTest::gtest\\r\\n GTest::gmock\\r\\n)\\r\\n\\r\\nadd_test(\\r\\n NAME DependencySmoke\\r\\n COMMAND \\\"$\\\"\\r\\n)\\r\\n\\r\\nset_property(\\r\\n TEST DependencySmoke\\r\\n PROPERTY ENVIRONMENT_MODIFICATION\\r\\n ${FESA_DEPENDENCY_RUNTIME_MODIFICATIONS}\\r\\n)\\r\\n\\r\\nadd_test(\\r\\n NAME ProductionConfigureWithoutGTest\\r\\n COMMAND\\r\\n \\\"${CMAKE_COMMAND}\\\"\\r\\n --fresh\\r\\n -S \\\"${CMAKE_SOURCE_DIR}\\\"\\r\\n -B \\\"${CMAKE_BINARY_DIR}/testing/production-no-gtest\\\"\\r\\n -G \\\"${CMAKE_GENERATOR}\\\"\\r\\n -A \\\"${CMAKE_GENERATOR_PLATFORM}\\\"\\r\\n -T \\\"${CMAKE_VS_PLATFORM_TOOLSET}\\\"\\r\\n -DBUILD_TESTING=OFF\\r\\n -DCMAKE_DISABLE_FIND_PACKAGE_GTest=TRUE\\r\\n \\\"-DMKL_DIR=${MKL_DIR}\\\"\\r\\n \\\"-DTBB_DIR=${TBB_DIR}\\\"\\r\\n \\\"-DHDF5_DIR=${HDF5_DIR}\\\"\\r\\n)\\r\\n\\r\\nadd_executable(fesa_core_value_tests\\r\\n unit/core/diagnostic_test.cpp\\r\\n unit/core/entity_id_test.cpp\\r\\n unit/core/status_test.cpp\\r\\n unit/core/vec3_test.cpp\\r\\n unit/core/version_test.cpp\\r\\n)\\r\\n\\r\\ntarget_compile_features(fesa_core_value_tests PRIVATE cxx_std_20)\\r\\ntarget_compile_options(fesa_core_value_tests PRIVATE /W4 /permissive- /EHsc)\\r\\n\\r\\ntarget_link_libraries(fesa_core_value_tests\\r\\n PRIVATE\\r\\n fesa_core\\r\\n GTest::gtest_main\\r\\n)\\r\\n\\r\\nadd_test(\\r\\n NAME CoreValueTypes\\r\\n COMMAND \\\"$\\\"\\r\\n)\\r\\n\\r\\nadd_executable(fesa_model_value_tests\\r\\n unit/model/domain_builder_test.cpp\\r\\n unit/model/entity_origin_test.cpp\\r\\n unit/model/model_types_test.cpp\\r\\n)\\r\\n\\r\\ntarget_compile_features(fesa_model_value_tests PRIVATE cxx_std_20)\\r\\ntarget_compile_options(fesa_model_value_tests PRIVATE /W4 /permissive- /EHsc)\\r\\n\\r\\ntarget_link_libraries(fesa_model_value_tests\\r\\n PRIVATE\\r\\n fesa_core\\r\\n GTest::gtest_main\\r\\n)\\r\\n\\r\\nadd_test(\\r\\n NAME ModelTypes\\r\\n COMMAND \\\"$\\\" --gtest_filter=ModelTypes.*\\r\\n)\\r\\n\\r\\nadd_test(\\r\\n NAME EntityOrigin\\r\\n COMMAND \\\"$\\\" --gtest_filter=EntityOrigin.*\\r\\n)\\r\\n\\r\\nadd_test(\\r\\n NAME DomainBuilder\\r\\n COMMAND \\\"$\\\" --gtest_filter=DomainBuilder.*\\r\\n)\\r\\n\\r\\nadd_test(\\r\\n NAME DomainValidation\\r\\n COMMAND \\\"$\\\" --gtest_filter=*DomainValidation*\\r\\n)\\r\\n\\r\\nadd_executable(fesa_abaqus_parser_tests\\r\\n unit/io/abaqus/active_input_test.cpp\\r\\n unit/io/abaqus/input_contract_test.cpp\\r\\n unit/io/abaqus/material_section_mapping_test.cpp\\r\\n unit/io/abaqus/parser_test.cpp\\r\\n unit/io/abaqus/set_resolution_test.cpp\\r\\n)\\r\\n\\r\\ntarget_compile_features(fesa_abaqus_parser_tests PRIVATE cxx_std_20)\\r\\ntarget_compile_options(fesa_abaqus_parser_tests PRIVATE /W4 /permissive- /EHsc)\\r\\ntarget_compile_definitions(\\r\\n fesa_abaqus_parser_tests\\r\\n PRIVATE\\r\\n FESA_TEST_SOURCE_DIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}\\\"\\r\\n)\\r\\n\\r\\ntarget_link_libraries(fesa_abaqus_parser_tests\\r\\n PRIVATE\\r\\n fesa_core\\r\\n GTest::gtest_main\\r\\n)\\r\\n\\r\\nadd_test(\\r\\n NAME AbaqusParser\\r\\n COMMAND \\\"$\\\"\\r\\n --gtest_filter=AbaqusParser.*\\r\\n)\\r\\n\\r\\nadd_test(\\r\\n NAME ScopedDeck\\r\\n COMMAND \\\"$\\\"\\r\\n --gtest_filter=ScopedDeck.*\\r\\n)\\r\\n\\r\\nadd_test(\\r\\n NAME AbaqusInputContract\\r\\n COMMAND \\\"$\\\"\\r\\n --gtest_filter=AbaqusInputContract/*\\r\\n)\\r\\n\\r\\nadd_test(\\r\\n NAME SetResolution\\r\\n COMMAND \\\"$\\\"\\r\\n --gtest_filter=SetResolution.*\\r\\n)\\r\\n\\r\\nadd_test(\\r\\n NAME PartSet\\r\\n COMMAND \\\"$\\\"\\r\\n --gtest_filter=PartSet.*\\r\\n)\\r\\n\\r\\nadd_test(\\r\\n NAME AssemblySet\\r\\n COMMAND \\\"$\\\"\\r\\n --gtest_filter=AssemblySet.*\\r\\n)\\r\\n\\r\\nadd_test(\\r\\n NAME ActiveInput\\r\\n COMMAND \\\"$\\\"\\r\\n --gtest_filter=ActiveInput.*\\r\\n)\\r\\n\\r\\nadd_test(\\r\\n NAME SemanticScope\\r\\n COMMAND \\\"$\\\"\\r\\n --gtest_filter=SemanticScope.*\\r\\n)\\r\\n\\r\\nadd_test(\\r\\n NAME MaterialMapping\\r\\n COMMAND \\\"$\\\"\\r\\n --gtest_filter=MaterialMapping.*\\r\\n)\\r\\n\\r\\nadd_test(\\r\\n NAME BeamSection\\r\\n COMMAND \\\"$\\\"\\r\\n --gtest_filter=BeamSection.*\\r\\n)\\r\\n\\r\\nadd_test(\\r\\n NAME ShearDefault\\r\\n COMMAND \\\"$\\\"\\r\\n --gtest_filter=ShearDefault.*\\r\\n)\\r\\n\\r\\nadd_executable(fesa_deck_to_domain_tests\\r\\n integration/io/minimal_deck_to_domain_test.cpp\\r\\n)\\r\\n\\r\\ntarget_compile_features(fesa_deck_to_domain_tests PRIVATE cxx_std_20)\\r\\ntarget_compile_options(fesa_deck_to_domain_tests PRIVATE /W4 /permissive- /EHsc)\\r\\ntarget_compile_definitions(\\r\\n fesa_deck_to_domain_tests\\r\\n PRIVATE\\r\\n FESA_TEST_SOURCE_DIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}\\\"\\r\\n)\\r\\n\\r\\ntarget_link_libraries(fesa_deck_to_domain_tests\\r\\n PRIVATE\\r\\n fesa_core\\r\\n GTest::gtest_main\\r\\n)\\r\\n\\r\\nadd_test(\\r\\n NAME DeckToDomain\\r\\n COMMAND \\\"$\\\"\\r\\n --gtest_filter=DeckToDomain.*\\r\\n)\\r\\n\\r\\nadd_test(\\r\\n NAME SingleInstance\\r\\n COMMAND \\\"$\\\"\\r\\n --gtest_filter=ActiveInstance.*\\r\\n)\\r\\n\\r\\nadd_test(\\r\\n NAME StepMapping\\r\\n COMMAND \\\"$\\\"\\r\\n --gtest_filter=StepMapping.*\\r\\n)\\r\\n\\r\\nadd_test(\\r\\n NAME Boundary\\r\\n COMMAND \\\"$\\\"\\r\\n --gtest_filter=Boundary.*\\r\\n)\\r\\n\\r\\nadd_test(\\r\\n NAME Cload\\r\\n COMMAND \\\"$\\\"\\r\\n --gtest_filter=Cload.*\\r\\n)\\r\\n\\r\\nadd_test(\\r\\n NAME SuppliedCantilever\\r\\n COMMAND \\\"$\\\"\\r\\n --gtest_filter=SuppliedCantilever.*\\r\\n)\\r\\n\\r\\nadd_executable(fesa_fem_primitives_tests\\r\\n unit/fem/beam_frame_test.cpp\\r\\n unit/fem/dof_manager_test.cpp\\r\\n unit/fem/gauss_rule_test.cpp\\r\\n unit/fem/line2_shape_test.cpp\\r\\n)\\r\\n\\r\\ntarget_compile_features(fesa_fem_primitives_tests PRIVATE cxx_std_20)\\r\\ntarget_compile_options(\\r\\n fesa_fem_primitives_tests\\r\\n PRIVATE\\r\\n /W4\\r\\n /permissive-\\r\\n /EHsc\\r\\n)\\r\\n\\r\\ntarget_link_libraries(fesa_fem_primitives_tests\\r\\n PRIVATE\\r\\n fesa_core\\r\\n GTest::gtest_main\\r\\n)\\r\\n\\r\\nadd_test(\\r\\n NAME Quadrature\\r\\n COMMAND \\\"$\\\"\\r\\n --gtest_filter=Quadrature.*\\r\\n)\\r\\n\\r\\nadd_test(\\r\\n NAME ShapeFunction\\r\\n COMMAND \\\"$\\\"\\r\\n --gtest_filter=ShapeFunction.*\\r\\n)\\r\\n\\r\\nadd_test(\\r\\n NAME Jacobian\\r\\n COMMAND \\\"$\\\"\\r\\n --gtest_filter=Jacobian.*\\r\\n)\\r\\n\\r\\nadd_test(\\r\\n NAME DofManager\\r\\n COMMAND \\\"$\\\"\\r\\n --gtest_filter=DofManager.*\\r\\n)\\r\\n\\r\\nadd_test(\\r\\n NAME EquationNumbering\\r\\n COMMAND \\\"$\\\"\\r\\n --gtest_filter=EquationNumbering.*\\r\\n)\\r\\n\\r\\nadd_test(\\r\\n NAME BeamFrame\\r\\n COMMAND \\\"$\\\"\\r\\n --gtest_filter=BeamFrame.*\\r\\n)\\r\\n\\r\\nadd_test(\\r\\n NAME BeamTransformation\\r\\n COMMAND \\\"$\\\"\\r\\n --gtest_filter=BeamTransformation.*\\r\\n)\\r\\n\\r\\nadd_executable(fesa_beam3d2_tests\\r\\n unit/elements/beam3d2_test.cpp\\r\\n)\\r\\n\\r\\ntarget_compile_features(fesa_beam3d2_tests PRIVATE cxx_std_20)\\r\\ntarget_compile_options(\\r\\n fesa_beam3d2_tests\\r\\n PRIVATE\\r\\n /W4\\r\\n /permissive-\\r\\n /EHsc\\r\\n)\\r\\n\\r\\ntarget_link_libraries(fesa_beam3d2_tests\\r\\n PRIVATE\\r\\n fesa_core\\r\\n GTest::gtest_main\\r\\n)\\r\\n\\r\\nadd_test(\\r\\n NAME Beam3D2\\r\\n COMMAND \\\"$\\\"\\r\\n --gtest_filter=Beam3D2.*\\r\\n)\\r\\n\\r\\nadd_test(\\r\\n NAME Timoshenko\\r\\n COMMAND \\\"$\\\"\\r\\n --gtest_filter=Timoshenko.*\\r\\n)\\r\\n\\r\\nadd_test(\\r\\n NAME RigidBody\\r\\n COMMAND \\\"$\\\"\\r\\n --gtest_filter=RigidBody.*\\r\\n)\\r\\n\\r\\nadd_executable(fesa_serial_assembly_tests\\r\\n unit/assembly/serial_assembler_test.cpp\\r\\n)\\r\\n\\r\\ntarget_compile_features(fesa_serial_assembly_tests PRIVATE cxx_std_20)\\r\\ntarget_compile_options(\\r\\n fesa_serial_assembly_tests\\r\\n PRIVATE\\r\\n /W4\\r\\n /permissive-\\r\\n /EHsc\\r\\n)\\r\\n\\r\\ntarget_link_libraries(fesa_serial_assembly_tests\\r\\n PRIVATE\\r\\n fesa_core\\r\\n GTest::gtest_main\\r\\n)\\r\\n\\r\\nadd_test(\\r\\n NAME SparsePattern\\r\\n COMMAND \\\"$\\\"\\r\\n --gtest_filter=SparsePattern.*\\r\\n)\\r\\n\\r\\nadd_test(\\r\\n NAME SerialAssembly\\r\\n COMMAND \\\"$\\\"\\r\\n --gtest_filter=SerialAssembly.*\\r\\n)\\r\\n\\r\\nadd_test(\\n NAME SymmetricCsr\\n COMMAND \\\"$\\\"\\n --gtest_filter=SymmetricCsr.*\\n)\\n\\nadd_test(\\n NAME CanonicalContribution\\n COMMAND \\\"$\\\"\\n --gtest_filter=CanonicalContribution.*\\n)\\n\\nadd_test(\\n NAME DeterministicMerge\\n COMMAND \\\"$\\\"\\n --gtest_filter=DeterministicMerge.*\\n)\\n\\nadd_executable(fesa_parallel_assembly_tests\\n unit/assembly/parallel_assembler_test.cpp\\n)\\n\\ntarget_compile_features(fesa_parallel_assembly_tests PRIVATE cxx_std_20)\\ntarget_compile_options(\\n fesa_parallel_assembly_tests\\n PRIVATE\\n /W4\\n /permissive-\\n /EHsc\\n)\\n\\ntarget_link_libraries(fesa_parallel_assembly_tests\\n PRIVATE\\n fesa_core\\n GTest::gtest_main\\n)\\n\\nadd_test(\\n NAME ParallelAssembly\\n COMMAND \\\"$\\\"\\n --gtest_filter=ParallelAssembly.*\\n)\\n\\nadd_test(\\n NAME TbbElementEvaluation\\n COMMAND \\\"$\\\"\\n --gtest_filter=TbbElementEvaluation.*\\n)\\n\\nset_property(\\n TEST ParallelAssembly TbbElementEvaluation\\n PROPERTY ENVIRONMENT_MODIFICATION\\n ${FESA_DEPENDENCY_RUNTIME_MODIFICATIONS}\\n)\\n\\nadd_executable(fesa_constraint_tests\\n unit/constraints/essential_bc_test.cpp\\r\\n)\\r\\n\\r\\ntarget_compile_features(fesa_constraint_tests PRIVATE cxx_std_20)\\r\\ntarget_compile_options(\\r\\n fesa_constraint_tests\\r\\n PRIVATE\\r\\n /W4\\r\\n /permissive-\\r\\n /EHsc\\r\\n)\\r\\n\\r\\ntarget_link_libraries(fesa_constraint_tests\\r\\n PRIVATE\\r\\n fesa_core\\r\\n GTest::gtest_main\\r\\n)\\r\\n\\r\\nadd_test(\\r\\n NAME EssentialBc\\r\\n COMMAND \\\"$\\\"\\r\\n --gtest_filter=EssentialBc.*\\r\\n)\\r\\n\\r\\nadd_test(\\r\\n NAME ConstraintElimination\\r\\n COMMAND \\\"$\\\"\\r\\n --gtest_filter=ConstraintElimination.*\\r\\n)\\r\\n\\r\\nadd_test(\\r\\n NAME Reaction\\r\\n COMMAND \\\"$\\\"\\r\\n --gtest_filter=Reaction.*\\r\\n)\\r\\n\\r\\nadd_executable(fesa_linear_solver_tests\\r\\n unit/solvers/linear/pardiso_linear_solver_test.cpp\\r\\n)\\r\\n\\r\\ntarget_compile_features(fesa_linear_solver_tests PRIVATE cxx_std_20)\\r\\ntarget_compile_options(\\r\\n fesa_linear_solver_tests\\r\\n PRIVATE\\r\\n /W4\\r\\n /permissive-\\r\\n /EHsc\\r\\n)\\r\\n\\r\\ntarget_link_libraries(fesa_linear_solver_tests\\r\\n PRIVATE\\r\\n fesa_core\\r\\n GTest::gtest_main\\r\\n)\\r\\n\\r\\nadd_test(\\r\\n NAME PardisoLinearSolver\\r\\n COMMAND \\\"$\\\"\\r\\n)\\r\\n\\r\\nset_property(\\r\\n TEST PardisoLinearSolver\\r\\n PROPERTY ENVIRONMENT_MODIFICATION\\r\\n ${FESA_DEPENDENCY_RUNTIME_MODIFICATIONS}\\r\\n)\\r\\n\\r\\nadd_executable(fesa_result_database_tests\\r\\n unit/results/result_database_test.cpp\\r\\n)\\r\\n\\r\\ntarget_compile_features(fesa_result_database_tests PRIVATE cxx_std_20)\\r\\ntarget_compile_options(\\r\\n fesa_result_database_tests\\r\\n PRIVATE\\r\\n /W4\\r\\n /permissive-\\r\\n /EHsc\\r\\n)\\r\\n\\r\\ntarget_link_libraries(fesa_result_database_tests\\r\\n PRIVATE\\r\\n fesa_core\\r\\n GTest::gtest_main\\r\\n)\\r\\n\\r\\nadd_test(\\r\\n NAME NodalFrame\\r\\n COMMAND \\\"$\\\"\\r\\n --gtest_filter=NodalFrame.*\\r\\n)\\r\\n\\r\\nadd_test(\\r\\n NAME ResultDatabase\\r\\n COMMAND \\\"$\\\"\\r\\n --gtest_filter=ResultDatabase.*\\r\\n)\\r\\n\\r\\nadd_executable(fesa_hdf5_results_tests\\r\\n integration/io/hdf5_results_test.cpp\\r\\n)\\r\\n\\r\\ntarget_compile_features(fesa_hdf5_results_tests PRIVATE cxx_std_20)\\r\\ntarget_compile_options(\\r\\n fesa_hdf5_results_tests\\r\\n PRIVATE\\r\\n /W4\\r\\n /permissive-\\r\\n /EHsc\\r\\n)\\r\\ntarget_compile_definitions(\\r\\n fesa_hdf5_results_tests\\r\\n PRIVATE\\r\\n FESA_TEST_BINARY_DIR=\\\"${CMAKE_BINARY_DIR}\\\"\\r\\n)\\r\\n\\r\\ntarget_link_libraries(fesa_hdf5_results_tests\\r\\n PRIVATE\\r\\n fesa_core\\r\\n HDF5::HDF5\\r\\n GTest::gtest_main\\r\\n)\\r\\n\\r\\nadd_test(\\r\\n NAME Hdf5\\r\\n COMMAND \\\"$\\\"\\r\\n --gtest_filter=Hdf5.*\\r\\n)\\r\\n\\r\\nadd_test(\\r\\n NAME ResultRoundTrip\\r\\n COMMAND \\\"$\\\"\\r\\n --gtest_filter=ResultRoundTrip.*\\r\\n)\\r\\n\\r\\nset_property(\\r\\n TEST Hdf5 ResultRoundTrip\\r\\n PROPERTY ENVIRONMENT_MODIFICATION\\r\\n ${FESA_DEPENDENCY_RUNTIME_MODIFICATIONS}\\r\\n)\\r\\n\\r\\nadd_executable(fesa_linear_static_analysis_tests\\r\\n unit/analysis/linear_static_analysis_test.cpp\\r\\n)\\r\\n\\r\\ntarget_compile_features(\\r\\n fesa_linear_static_analysis_tests PRIVATE cxx_std_20\\r\\n)\\r\\ntarget_compile_options(\\r\\n fesa_linear_static_analysis_tests\\r\\n PRIVATE\\r\\n /W4\\r\\n /permissive-\\r\\n /EHsc\\r\\n)\\r\\n\\r\\ntarget_link_libraries(fesa_linear_static_analysis_tests\\r\\n PRIVATE\\r\\n fesa_core\\r\\n GTest::gtest_main\\r\\n)\\r\\n\\r\\nadd_test(\\r\\n NAME LinearStaticAnalysis\\r\\n COMMAND \\\"$\\\"\\r\\n --gtest_filter=LinearStaticAnalysis.*\\r\\n)\\r\\n\\r\\nadd_test(\\r\\n NAME StaticEquilibrium\\r\\n COMMAND \\\"$\\\"\\r\\n --gtest_filter=StaticEquilibrium.*\\r\\n)\\r\\n\\r\\nset_property(\\r\\n TEST LinearStaticAnalysis StaticEquilibrium\\r\\n PROPERTY ENVIRONMENT_MODIFICATION\\r\\n ${FESA_DEPENDENCY_RUNTIME_MODIFICATIONS}\\r\\n)\\r\\n\\r\\nadd_executable(fesa_pipeline_integration_tests\\r\\n integration/pipeline/minimal_cantilever_test.cpp\\r\\n)\\r\\n\\r\\ntarget_compile_features(\\r\\n fesa_pipeline_integration_tests PRIVATE cxx_std_20\\r\\n)\\r\\ntarget_compile_options(\\r\\n fesa_pipeline_integration_tests\\r\\n PRIVATE\\r\\n /W4\\r\\n /permissive-\\r\\n /EHsc\\r\\n)\\r\\ntarget_compile_definitions(\\r\\n fesa_pipeline_integration_tests\\r\\n PRIVATE\\r\\n FESA_CLI_PATH=\\\"$\\\"\\r\\n FESA_TEST_BINARY_DIR=\\\"${CMAKE_BINARY_DIR}\\\"\\r\\n FESA_TEST_SOURCE_DIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}\\\"\\r\\n)\\r\\ntarget_link_libraries(fesa_pipeline_integration_tests\\r\\n PRIVATE\\r\\n fesa_core\\r\\n GTest::gtest_main\\r\\n)\\r\\nadd_dependencies(fesa_pipeline_integration_tests fesa)\\r\\n\\r\\nadd_test(\\r\\n NAME MinimalCantileverPipeline\\r\\n COMMAND \\\"$\\\"\\r\\n --gtest_filter=MinimalCantileverPipeline.*\\r\\n)\\r\\n\\r\\nset_property(\\r\\n TEST MinimalCantileverPipeline\\r\\n PROPERTY ENVIRONMENT_MODIFICATION\\r\\n ${FESA_DEPENDENCY_RUNTIME_MODIFICATIONS}\\r\\n)\\r\\n\\r\\n#include \\n#include \\n\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n\\n#include \\n\\n#include \\n\\nnamespace {\\n\\nfesa::Domain finish_domain(\\n fesa::DomainBuilder builder,\\n fesa::StepDefinition step) {\\n builder.set_step(std::move(step));\\n auto result = std::move(builder).build();\\n if (!result.domain.has_value()) {\\n throw std::runtime_error{\\\"Test Domain failed validation.\\\"};\\n }\\n return std::move(*result.domain);\\n}\\n\\nfesa::Domain build_beam_domain(const bool branched) {\\n fesa::DomainBuilder builder;\\n const std::array positions{{\\n {0.0, 0.0, 0.0},\\n {1.0, 0.0, 0.0},\\n {2.0, 0.0, 0.0},\\n {3.0, 0.0, 0.0},\\n {1.0, 0.0, 1.0},\\n {1.0, 1.0, 1.0},\\n }};\\n const std::size_t node_count = branched ? positions.size() : 4;\\n for (std::size_t index = 0; index < node_count; ++index) {\\n builder.add_node({\\n fesa::NodeId{static_cast(index)},\\n fesa::EntityOrigin{\\n \\\"BeamPart\\\",\\n \\\"Beam-1\\\",\\n static_cast(index + 1),\\n },\\n positions[index],\\n });\\n }\\n builder.add_material({\\n fesa::MaterialId{0},\\n \\\"Steel\\\",\\n 210.0e9,\\n 0.3,\\n });\\n builder.add_section({\\n fesa::SectionId{0},\\n \\\"General\\\",\\n 0.02,\\n 3.0e-5,\\n 4.0e-5,\\n 2.0e-5,\\n 0.015,\\n 0.016,\\n fesa::ShearPropertySource::input,\\n fesa::Vec3{0.0, 1.0, 0.0},\\n {},\\n });\\n\\n const std::array elements{{\\n {\\n fesa::ElementId{40},\\n fesa::EntityOrigin{\\\"BeamPart\\\", \\\"Beam-1\\\", 300},\\n {fesa::NodeId{2}, fesa::NodeId{3}},\\n fesa::MaterialId{0},\\n fesa::SectionId{0},\\n },\\n {\\n fesa::ElementId{10},\\n fesa::EntityOrigin{\\\"BeamPart\\\", \\\"Beam-1\\\", 100},\\n {fesa::NodeId{0}, fesa::NodeId{1}},\\n fesa::MaterialId{0},\\n fesa::SectionId{0},\\n },\\n {\\n fesa::ElementId{30},\\n fesa::EntityOrigin{\\\"BeamPart\\\", \\\"Beam-1\\\", 200},\\n {fesa::NodeId{1}, fesa::NodeId{2}},\\n fesa::MaterialId{0},\\n fesa::SectionId{0},\\n },\\n {\\n fesa::ElementId{0},\\n fesa::EntityOrigin{\\\"BeamPart\\\", \\\"Beam-1\\\", 500},\\n {fesa::NodeId{1}, fesa::NodeId{5}},\\n fesa::MaterialId{0},\\n fesa::SectionId{0},\\n },\\n {\\n fesa::ElementId{20},\\n fesa::EntityOrigin{\\\"BeamPart\\\", \\\"Beam-1\\\", 400},\\n {fesa::NodeId{1}, fesa::NodeId{4}},\\n fesa::MaterialId{0},\\n fesa::SectionId{0},\\n },\\n }};\\n const std::size_t element_count = branched ? elements.size() : 3;\\n for (std::size_t index = 0; index < element_count; ++index) {\\n builder.add_beam_element(elements[index]);\\n }\\n\\n return finish_domain(\\n std::move(builder),\\n {\\n \\\"Load\\\",\\n {},\\n {\\n {fesa::NodeId{3}, {1.0, 2.0, 3.0, 4.0, 5.0, 6.0}},\\n {fesa::NodeId{1}, {1.0e16, 1.0, 0.0, 0.0, 0.0, 0.0}},\\n {fesa::NodeId{1}, {-1.0e16, 2.0, 0.0, 0.0, 0.0, 0.0}},\\n },\\n });\\n}\\n\\nstd::vector bits(const std::vector& values) {\\n std::vector result;\\n result.reserve(values.size());\\n for (const double value : values) {\\n result.push_back(std::bit_cast(value));\\n }\\n return result;\\n}\\n\\nvoid expect_bitwise_equal(\\n const fesa::EquationSystem& expected,\\n const fesa::EquationSystem& actual) {\\n EXPECT_EQ(actual.stiffness.order, expected.stiffness.order);\\n EXPECT_EQ(\\n actual.stiffness.row_offsets,\\n expected.stiffness.row_offsets);\\n EXPECT_EQ(\\n actual.stiffness.column_indices,\\n expected.stiffness.column_indices);\\n EXPECT_EQ(bits(actual.stiffness.values), bits(expected.stiffness.values));\\n EXPECT_EQ(bits(actual.force), bits(expected.force));\\n}\\n\\nTEST(ParallelAssembly, MatchesSerialForFixedBeamChain) {\\n const fesa::Domain domain = build_beam_domain(false);\\n const fesa::DofManager dofs = fesa::DofManager::build(domain);\\n const fesa::EquationSystem serial = fesa::assemble_serial(domain, dofs);\\n\\n expect_bitwise_equal(\\n serial,\\n fesa::assemble_parallel(domain, dofs, {1, 1}));\\n expect_bitwise_equal(\\n serial,\\n fesa::assemble_parallel(domain, dofs, {4, 2}));\\n}\\n\\nTEST(ParallelAssembly, MatchesSerialForFixedBranchedDomain) {\\n const fesa::Domain domain = build_beam_domain(true);\\n const fesa::DofManager dofs = fesa::DofManager::build(domain);\\n const fesa::EquationSystem serial = fesa::assemble_serial(domain, dofs);\\n\\n expect_bitwise_equal(\\n serial,\\n fesa::assemble_parallel(domain, dofs, {1, 2}));\\n expect_bitwise_equal(\\n serial,\\n fesa::assemble_parallel(domain, dofs, {3, 1}));\\n}\\n\\nTEST(TbbElementEvaluation, RejectsZeroExecutionLimits) {\\n const fesa::Domain domain = build_beam_domain(false);\\n const fesa::DofManager dofs = fesa::DofManager::build(domain);\\n\\n EXPECT_THROW(\\n static_cast(\\n fesa::assemble_parallel(domain, dofs, {0, 1})),\\n std::invalid_argument);\\n EXPECT_THROW(\\n static_cast(\\n fesa::assemble_parallel(domain, dofs, {1, 0})),\\n std::invalid_argument);\\n}\\n\\n} // namespace\\n\\r\\n#include \\n#include \\n\\r\\n#include \\r\\n#include \\r\\n#include \\r\\n#include \\r\\n#include \\r\\n#include \\r\\n#include \\r\\n#include \\r\\n#include \\r\\n#include \\r\\n\\r\\n#include \\r\\n\\r\\n#include \\r\\n\\r\\nnamespace {\\r\\n\\r\\nfesa::IsotropicElastic unit_material() {\\r\\n return {\\r\\n fesa::MaterialId{0},\\r\\n \\\"Unit\\\",\\r\\n 1.0,\\r\\n 0.25,\\r\\n };\\r\\n}\\r\\n\\r\\nfesa::BeamSection unit_section() {\\r\\n return {\\r\\n fesa::SectionId{0},\\r\\n \\\"Unit\\\",\\r\\n 1.0,\\r\\n 1.0,\\r\\n 1.0,\\r\\n 1.0,\\r\\n 1.0,\\r\\n 1.0,\\r\\n fesa::ShearPropertySource::input,\\r\\n fesa::Vec3{0.0, 1.0, 0.0},\\r\\n {},\\r\\n };\\r\\n}\\r\\n\\r\\nfesa::Domain finish_domain(\\r\\n fesa::DomainBuilder builder,\\r\\n fesa::StepDefinition step) {\\r\\n builder.set_step(std::move(step));\\r\\n auto result = std::move(builder).build();\\r\\n if (!result.domain.has_value()) {\\r\\n throw std::runtime_error{\\\"Test Domain failed validation.\\\"};\\r\\n }\\r\\n return std::move(*result.domain);\\r\\n}\\r\\n\\r\\nfesa::Domain build_chain_domain(const bool reverse_storage_order) {\\r\\n fesa::DomainBuilder builder;\\r\\n std::array nodes{{\\r\\n {\\r\\n fesa::NodeId{20},\\r\\n fesa::EntityOrigin{\\\"BeamPart\\\", \\\"Beam-1\\\", 2},\\r\\n fesa::Vec3{2.0, 0.0, 0.0},\\r\\n },\\r\\n {\\r\\n fesa::NodeId{4},\\r\\n fesa::EntityOrigin{\\\"BeamPart\\\", \\\"Beam-1\\\", 100},\\r\\n fesa::Vec3{0.0, 0.0, 0.0},\\r\\n },\\r\\n {\\r\\n fesa::NodeId{10},\\r\\n fesa::EntityOrigin{\\\"BeamPart\\\", \\\"Beam-1\\\", 50},\\r\\n fesa::Vec3{1.0, 0.0, 0.0},\\r\\n },\\r\\n }};\\r\\n if (reverse_storage_order) {\\r\\n std::ranges::reverse(nodes);\\r\\n }\\r\\n for (fesa::Node& node : nodes) {\\r\\n builder.add_node(std::move(node));\\r\\n }\\r\\n\\r\\n builder.add_material(unit_material());\\r\\n builder.add_section(unit_section());\\r\\n\\r\\n std::array elements{{\\r\\n {\\r\\n fesa::ElementId{1},\\r\\n fesa::EntityOrigin{\\\"BeamPart\\\", \\\"Beam-1\\\", 200},\\r\\n {fesa::NodeId{10}, fesa::NodeId{20}},\\r\\n fesa::MaterialId{0},\\r\\n fesa::SectionId{0},\\r\\n },\\r\\n {\\r\\n fesa::ElementId{0},\\r\\n fesa::EntityOrigin{\\\"BeamPart\\\", \\\"Beam-1\\\", 10},\\r\\n {fesa::NodeId{4}, fesa::NodeId{10}},\\r\\n fesa::MaterialId{0},\\r\\n fesa::SectionId{0},\\r\\n },\\r\\n }};\\r\\n if (reverse_storage_order) {\\r\\n std::ranges::reverse(elements);\\r\\n }\\r\\n for (fesa::BeamElement& element : elements) {\\r\\n builder.add_beam_element(std::move(element));\\r\\n }\\r\\n\\r\\n return finish_domain(\\r\\n std::move(builder),\\r\\n {\\r\\n \\\"Load\\\",\\r\\n {},\\r\\n {\\r\\n {\\r\\n fesa::NodeId{20},\\r\\n {3.0, 4.0, 5.0, 6.0, 7.0, 8.0},\\r\\n },\\r\\n {\\r\\n fesa::NodeId{10},\\r\\n {1.0, 2.0, 3.0, 4.0, 5.0, 6.0},\\r\\n },\\r\\n {\\r\\n fesa::NodeId{10},\\r\\n {-1.0, 10.0, -3.0, 0.0, 0.0, 0.0},\\r\\n },\\r\\n },\\r\\n });\\r\\n}\\r\\n\\r\\nfesa::Domain build_parallel_domain(\\r\\n const std::vector& element_labels) {\\r\\n fesa::DomainBuilder builder;\\r\\n builder.add_node({\\r\\n fesa::NodeId{4},\\r\\n fesa::EntityOrigin{\\\"BeamPart\\\", \\\"Beam-1\\\", 1},\\r\\n fesa::Vec3{0.0, 0.0, 0.0},\\r\\n });\\r\\n builder.add_node({\\r\\n fesa::NodeId{10},\\r\\n fesa::EntityOrigin{\\\"BeamPart\\\", \\\"Beam-1\\\", 2},\\r\\n fesa::Vec3{1.0, 0.0, 0.0},\\r\\n });\\r\\n builder.add_material(unit_material());\\r\\n builder.add_section(unit_section());\\r\\n\\r\\n for (std::size_t index = 0; index < element_labels.size(); ++index) {\\r\\n builder.add_beam_element({\\r\\n fesa::ElementId{static_cast(index)},\\r\\n fesa::EntityOrigin{\\r\\n \\\"BeamPart\\\",\\r\\n \\\"Beam-1\\\",\\r\\n element_labels[index],\\r\\n },\\r\\n {fesa::NodeId{4}, fesa::NodeId{10}},\\r\\n fesa::MaterialId{0},\\r\\n fesa::SectionId{0},\\r\\n });\\r\\n }\\r\\n return finish_domain(std::move(builder), {\\\"Load\\\", {}, {}});\\r\\n}\\r\\n\\r\\nfesa::Domain build_rounding_domain(const bool large_element_first) {\\r\\n fesa::DomainBuilder builder;\\r\\n builder.add_node({\\r\\n fesa::NodeId{4},\\r\\n fesa::EntityOrigin{\\\"BeamPart\\\", \\\"Beam-1\\\", 1},\\r\\n fesa::Vec3{0.0, 0.0, 0.0},\\r\\n });\\r\\n builder.add_node({\\r\\n fesa::NodeId{10},\\r\\n fesa::EntityOrigin{\\\"BeamPart\\\", \\\"Beam-1\\\", 2},\\r\\n fesa::Vec3{1.0, 0.0, 0.0},\\r\\n });\\r\\n\\r\\n for (std::size_t index = 0; index < 3; ++index) {\\r\\n fesa::IsotropicElastic material = unit_material();\\r\\n material.id =\\r\\n fesa::MaterialId{static_cast(index)};\\r\\n material.name = \\\"Material-\\\" + std::to_string(index);\\r\\n material.young = index == 2 ? 1.0e16 : 1.0;\\r\\n builder.add_material(std::move(material));\\r\\n }\\r\\n builder.add_section(unit_section());\\r\\n\\r\\n std::array storage_order{0, 1, 2};\\r\\n if (large_element_first) {\\r\\n storage_order = {2, 0, 1};\\r\\n }\\r\\n for (const std::size_t index : storage_order) {\\n constexpr std::array element_ids{1, 2, 0};\\n builder.add_beam_element({\\n fesa::ElementId{element_ids[index]},\\n fesa::EntityOrigin{\\r\\n \\\"BeamPart\\\",\\r\\n \\\"Beam-1\\\",\\r\\n static_cast((index + 1) * 10),\\r\\n },\\r\\n {fesa::NodeId{4}, fesa::NodeId{10}},\\r\\n fesa::MaterialId{static_cast(index)},\\r\\n fesa::SectionId{0},\\r\\n });\\r\\n }\\r\\n return finish_domain(std::move(builder), {\\\"Load\\\", {}, {}});\\r\\n}\\r\\n\\r\\nfesa::Domain build_orphan_node_domain() {\\r\\n fesa::DomainBuilder builder;\\r\\n builder.add_node({\\r\\n fesa::NodeId{0},\\r\\n fesa::EntityOrigin{\\\"BeamPart\\\", \\\"Beam-1\\\", 1},\\r\\n fesa::Vec3{0.0, 0.0, 0.0},\\r\\n });\\r\\n builder.add_node({\\r\\n fesa::NodeId{1},\\r\\n fesa::EntityOrigin{\\\"BeamPart\\\", \\\"Beam-1\\\", 2},\\r\\n fesa::Vec3{1.0, 0.0, 0.0},\\r\\n });\\r\\n builder.add_node({\\r\\n fesa::NodeId{2},\\r\\n fesa::EntityOrigin{\\\"BeamPart\\\", \\\"Beam-1\\\", 3},\\r\\n fesa::Vec3{2.0, 0.0, 0.0},\\r\\n });\\r\\n builder.add_material(unit_material());\\r\\n builder.add_section(unit_section());\\r\\n builder.add_beam_element({\\r\\n fesa::ElementId{0},\\r\\n fesa::EntityOrigin{\\\"BeamPart\\\", \\\"Beam-1\\\", 1},\\r\\n {fesa::NodeId{0}, fesa::NodeId{1}},\\r\\n fesa::MaterialId{0},\\r\\n fesa::SectionId{0},\\r\\n });\\r\\n return finish_domain(std::move(builder), {\\\"Load\\\", {}, {}});\\r\\n}\\r\\n\\r\\ndouble csr_value(\\n const fesa::SymmetricCsr& matrix,\\r\\n std::size_t row,\\r\\n std::size_t column) {\\r\\n if (column < row) {\\r\\n std::swap(row, column);\\r\\n }\\r\\n const auto begin = matrix.column_indices.begin() + matrix.row_offsets[row];\\r\\n const auto end =\\r\\n matrix.column_indices.begin() + matrix.row_offsets[row + 1];\\r\\n const auto found = std::lower_bound(\\r\\n begin, end, static_cast(column));\\r\\n if (found == end || *found != static_cast(column)) {\\r\\n throw std::out_of_range{\\\"CSR entry is not present.\\\"};\\r\\n }\\r\\n return matrix.values[static_cast(\\n std::distance(matrix.column_indices.begin(), found))];\\n}\\n\\nstd::vector value_bits(\\n const fesa::SymmetricCsr& matrix) {\\n std::vector bits;\\n bits.reserve(matrix.values.size());\\n for (const double value : matrix.values) {\\n bits.push_back(std::bit_cast(value));\\n }\\n return bits;\\n}\\n\\nTEST(CanonicalContribution, OrdersByCoordinateElementAndLocalOrder) {\\n const std::vector contributions{\\n {1, 2, fesa::ElementId{9}, 4, 9.0},\\n {0, 2, fesa::ElementId{3}, 8, 3.8},\\n {0, 2, fesa::ElementId{3}, 2, 3.2},\\n {0, 2, fesa::ElementId{1}, 7, 1.7},\\n {0, 0, fesa::ElementId{5}, 0, 5.0},\\n };\\n\\n const std::vector canonical =\\n fesa::canonicalize_contributions(contributions);\\n\\n ASSERT_EQ(canonical.size(), contributions.size());\\n EXPECT_EQ(canonical[0].row, 0);\\n EXPECT_EQ(canonical[0].column, 0);\\n EXPECT_EQ(canonical[0].element, fesa::ElementId{5});\\n EXPECT_EQ(canonical[1].element, fesa::ElementId{1});\\n EXPECT_EQ(canonical[2].element, fesa::ElementId{3});\\n EXPECT_EQ(canonical[2].local_order, 2);\\n EXPECT_EQ(canonical[3].element, fesa::ElementId{3});\\n EXPECT_EQ(canonical[3].local_order, 8);\\n EXPECT_EQ(canonical[4].row, 1);\\n EXPECT_EQ(canonical[4].column, 2);\\n}\\n\\nTEST(DeterministicMerge, IsBitwiseStableAcrossInputPermutations) {\\n const std::vector contributions{\\n {0, 1, fesa::ElementId{2}, 0, 1.0},\\n {0, 1, fesa::ElementId{0}, 0, 1.0e16},\\n {0, 1, fesa::ElementId{1}, 0, -1.0e16},\\n {1, 1, fesa::ElementId{1}, 1, -0.0},\\n {1, 1, fesa::ElementId{0}, 1, +0.0},\\n };\\n const std::vector canonical =\\n fesa::canonicalize_contributions(contributions);\\n const fesa::SymmetricCsr expected =\\n fesa::merge_contributions(2, canonical);\\n\\n std::array permutation{0, 1, 2, 3, 4};\\n do {\\n std::vector shuffled;\\n shuffled.reserve(contributions.size());\\n for (const std::size_t index : permutation) {\\n shuffled.push_back(contributions[index]);\\n }\\n const std::vector shuffled_canonical =\\n fesa::canonicalize_contributions(shuffled);\\n const fesa::SymmetricCsr actual =\\n fesa::merge_contributions(2, shuffled_canonical);\\n\\n EXPECT_EQ(actual.order, expected.order);\\n EXPECT_EQ(actual.row_offsets, expected.row_offsets);\\n EXPECT_EQ(actual.column_indices, expected.column_indices);\\n EXPECT_EQ(value_bits(actual), value_bits(expected));\\n } while (std::ranges::next_permutation(permutation).found);\\n\\n EXPECT_EQ(\\n std::bit_cast(csr_value(expected, 0, 1)),\\n std::bit_cast(1.0));\\n EXPECT_EQ(\\n std::bit_cast(csr_value(expected, 1, 1)),\\n std::bit_cast(+0.0));\\n}\\n\\nTEST(SparsePattern, BuildsExpectedTwoElementChainStructure) {\\n const fesa::Domain domain = build_chain_domain(false);\\r\\n const fesa::DofManager dofs = fesa::DofManager::build(domain);\\r\\n\\r\\n const fesa::EquationSystem system =\\r\\n fesa::assemble_serial(domain, dofs);\\r\\n\\r\\n EXPECT_EQ(\\r\\n system.stiffness.row_offsets,\\r\\n (std::vector{\\r\\n 0,\\r\\n 12,\\r\\n 23,\\r\\n 33,\\r\\n 42,\\r\\n 50,\\r\\n 57,\\r\\n 69,\\r\\n 80,\\r\\n 90,\\r\\n 99,\\r\\n 107,\\r\\n 114,\\r\\n 120,\\r\\n 125,\\r\\n 129,\\r\\n 132,\\r\\n 134,\\r\\n 135,\\r\\n }));\\r\\n\\r\\n std::vector expected_columns;\\r\\n for (std::int32_t row = 0; row < 18; ++row) {\\r\\n const std::int32_t last_column = row < 6 ? 11 : 17;\\r\\n for (std::int32_t column = row; column <= last_column; ++column) {\\r\\n expected_columns.push_back(column);\\r\\n }\\r\\n }\\r\\n EXPECT_EQ(system.stiffness.column_indices, expected_columns);\\r\\n}\\r\\n\\r\\nTEST(SymmetricCsr, StoresSortedUpperTriangleWithValidOffsets) {\\r\\n const fesa::Domain domain = build_chain_domain(false);\\r\\n const fesa::DofManager dofs = fesa::DofManager::build(domain);\\r\\n const fesa::SymmetricCsr matrix =\\r\\n fesa::assemble_serial(domain, dofs).stiffness;\\r\\n\\r\\n ASSERT_EQ(matrix.order, 18);\\r\\n ASSERT_EQ(matrix.row_offsets.size(), matrix.order + 1);\\r\\n ASSERT_EQ(matrix.row_offsets.front(), 0);\\r\\n ASSERT_EQ(\\r\\n static_cast(matrix.row_offsets.back()),\\r\\n matrix.column_indices.size());\\r\\n ASSERT_EQ(matrix.column_indices.size(), matrix.values.size());\\r\\n\\r\\n for (std::size_t row = 0; row < matrix.order; ++row) {\\r\\n const auto begin =\\r\\n matrix.column_indices.begin() + matrix.row_offsets[row];\\r\\n const auto end =\\r\\n matrix.column_indices.begin() + matrix.row_offsets[row + 1];\\r\\n EXPECT_TRUE(std::ranges::is_sorted(begin, end));\\r\\n EXPECT_EQ(std::adjacent_find(begin, end), end);\\r\\n for (auto entry = begin; entry != end; ++entry) {\\r\\n EXPECT_GE(*entry, static_cast(row));\\r\\n EXPECT_LT(*entry, static_cast(matrix.order));\\r\\n }\\r\\n }\\r\\n}\\r\\n\\r\\nTEST(SparsePattern, IncludesZeroDiagonalForEveryOrphanNodeDof) {\\r\\n const fesa::Domain domain = build_orphan_node_domain();\\r\\n const fesa::SymmetricCsr matrix =\\r\\n fesa::assemble_serial(\\r\\n domain, fesa::DofManager::build(domain))\\r\\n .stiffness;\\r\\n\\r\\n ASSERT_EQ(matrix.order, 18);\\r\\n for (std::size_t row = 0; row < matrix.order; ++row) {\\r\\n const auto begin =\\r\\n matrix.column_indices.begin() + matrix.row_offsets[row];\\r\\n const auto end =\\r\\n matrix.column_indices.begin() + matrix.row_offsets[row + 1];\\r\\n const auto diagonal = std::lower_bound(\\r\\n begin, end, static_cast(row));\\r\\n ASSERT_NE(diagonal, end);\\r\\n EXPECT_EQ(*diagonal, static_cast(row));\\r\\n }\\r\\n for (std::size_t row = 12; row < 18; ++row) {\\r\\n EXPECT_DOUBLE_EQ(csr_value(matrix, row, row), 0.0);\\r\\n }\\r\\n}\\r\\n\\r\\nTEST(SerialAssembly, AssemblesHandCalculatedAxialChainAndFullLoad) {\\r\\n const fesa::Domain domain = build_chain_domain(false);\\r\\n const fesa::DofManager dofs = fesa::DofManager::build(domain);\\r\\n\\r\\n const fesa::EquationSystem system =\\r\\n fesa::assemble_serial(domain, dofs);\\r\\n\\r\\n EXPECT_DOUBLE_EQ(csr_value(system.stiffness, 0, 0), 1.0);\\r\\n EXPECT_DOUBLE_EQ(csr_value(system.stiffness, 0, 6), -1.0);\\r\\n EXPECT_DOUBLE_EQ(csr_value(system.stiffness, 6, 6), 2.0);\\r\\n EXPECT_DOUBLE_EQ(csr_value(system.stiffness, 6, 12), -1.0);\\r\\n EXPECT_DOUBLE_EQ(csr_value(system.stiffness, 12, 12), 1.0);\\r\\n\\r\\n EXPECT_EQ(\\r\\n system.force,\\r\\n (std::vector{\\r\\n 0.0,\\r\\n 0.0,\\r\\n 0.0,\\r\\n 0.0,\\r\\n 0.0,\\r\\n 0.0,\\r\\n 0.0,\\r\\n 12.0,\\r\\n 0.0,\\r\\n 4.0,\\r\\n 5.0,\\r\\n 6.0,\\r\\n 3.0,\\r\\n 4.0,\\r\\n 5.0,\\r\\n 6.0,\\r\\n 7.0,\\r\\n 8.0,\\r\\n }));\\r\\n}\\r\\n\\r\\nTEST(SerialAssembly, MergesDuplicateElementContributions) {\\r\\n const fesa::Domain single_domain = build_parallel_domain({10});\\r\\n const fesa::Domain duplicate_domain =\\r\\n build_parallel_domain({30, 10, 20});\\r\\n const fesa::EquationSystem single = fesa::assemble_serial(\\r\\n single_domain, fesa::DofManager::build(single_domain));\\r\\n const fesa::EquationSystem duplicate = fesa::assemble_serial(\\r\\n duplicate_domain, fesa::DofManager::build(duplicate_domain));\\r\\n\\r\\n EXPECT_EQ(\\r\\n duplicate.stiffness.row_offsets,\\r\\n single.stiffness.row_offsets);\\r\\n EXPECT_EQ(\\r\\n duplicate.stiffness.column_indices,\\r\\n single.stiffness.column_indices);\\r\\n ASSERT_EQ(duplicate.stiffness.values.size(), single.stiffness.values.size());\\r\\n for (std::size_t index = 0; index < single.stiffness.values.size();\\r\\n ++index) {\\r\\n const double value = single.stiffness.values[index];\\r\\n EXPECT_DOUBLE_EQ(\\r\\n duplicate.stiffness.values[index], (value + value) + value);\\r\\n }\\r\\n}\\r\\n\\r\\nTEST(SerialAssembly, ReducesByElementOriginNotDomainStorageOrder) {\\r\\n const fesa::Domain origin_order_domain =\\r\\n build_rounding_domain(false);\\r\\n const fesa::Domain storage_order_domain =\\r\\n build_rounding_domain(true);\\r\\n\\r\\n const double origin_order_value = csr_value(\\r\\n fesa::assemble_serial(\\r\\n origin_order_domain,\\r\\n fesa::DofManager::build(origin_order_domain))\\r\\n .stiffness,\\r\\n 0,\\r\\n 0);\\r\\n const double storage_order_value = csr_value(\\r\\n fesa::assemble_serial(\\r\\n storage_order_domain,\\r\\n fesa::DofManager::build(storage_order_domain))\\r\\n .stiffness,\\r\\n 0,\\r\\n 0);\\r\\n const double expected = (1.0 + 1.0) + 1.0e16;\\r\\n\\r\\n EXPECT_EQ(\\r\\n std::bit_cast(origin_order_value),\\r\\n std::bit_cast(expected));\\r\\n EXPECT_EQ(\\r\\n std::bit_cast(storage_order_value),\\r\\n std::bit_cast(expected));\\r\\n}\\r\\n\\r\\nTEST(SerialAssembly, IsIndependentOfDomainStorageAndExternalLabelOrder) {\\r\\n const fesa::Domain first_domain = build_chain_domain(false);\\r\\n const fesa::Domain second_domain = build_chain_domain(true);\\r\\n\\r\\n const fesa::EquationSystem first = fesa::assemble_serial(\\r\\n first_domain, fesa::DofManager::build(first_domain));\\r\\n const fesa::EquationSystem second = fesa::assemble_serial(\\r\\n second_domain, fesa::DofManager::build(second_domain));\\r\\n\\r\\n EXPECT_EQ(first.stiffness.order, second.stiffness.order);\\r\\n EXPECT_EQ(\\r\\n first.stiffness.row_offsets, second.stiffness.row_offsets);\\r\\n EXPECT_EQ(\\r\\n first.stiffness.column_indices,\\r\\n second.stiffness.column_indices);\\r\\n EXPECT_EQ(first.stiffness.values, second.stiffness.values);\\r\\n EXPECT_EQ(first.force, second.force);\\r\\n}\\r\\n\\r\\nTEST(SerialAssembly, PropagatesBeamKernelFailure) {\\r\\n fesa::DomainBuilder builder;\\r\\n builder.add_node({\\r\\n fesa::NodeId{0},\\r\\n fesa::EntityOrigin{\\\"BeamPart\\\", \\\"Beam-1\\\", 1},\\r\\n fesa::Vec3{0.0, 0.0, 0.0},\\r\\n });\\r\\n builder.add_node({\\r\\n fesa::NodeId{1},\\r\\n fesa::EntityOrigin{\\\"BeamPart\\\", \\\"Beam-1\\\", 2},\\r\\n fesa::Vec3{1.0, 0.0, 0.0},\\r\\n });\\r\\n auto material = unit_material();\\r\\n material.young = std::numeric_limits::max();\\r\\n builder.add_material(std::move(material));\\r\\n auto section = unit_section();\\r\\n section.area = std::numeric_limits::max();\\r\\n builder.add_section(std::move(section));\\r\\n builder.add_beam_element({\\r\\n fesa::ElementId{0},\\r\\n fesa::EntityOrigin{\\\"BeamPart\\\", \\\"Beam-1\\\", 1},\\r\\n {fesa::NodeId{0}, fesa::NodeId{1}},\\r\\n fesa::MaterialId{0},\\r\\n fesa::SectionId{0},\\r\\n });\\r\\n const fesa::Domain domain =\\r\\n finish_domain(std::move(builder), {\\\"Load\\\", {}, {}});\\r\\n\\r\\n try {\\r\\n static_cast(fesa::assemble_serial(\\r\\n domain, fesa::DofManager::build(domain)));\\r\\n FAIL() << \\\"Expected a Beam kernel failure.\\\";\\r\\n } catch (const std::runtime_error& error) {\\r\\n EXPECT_NE(\\r\\n std::string{error.what()}.find(\\\"model.nonfinite_value\\\"),\\r\\n std::string::npos);\\r\\n }\\r\\n}\\r\\n\\r\\n} // namespace\\r\\n\\r\\n#include \\n\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n\\n#include \\n#include \\n\\n#include \\n#include \\n#include \\n\\nnamespace fesa {\\nnamespace {\\n\\nstruct ElementEvaluation final {\\n std::vector contributions;\\n std::optional error;\\n};\\n\\nauto origin_key(const EntityOrigin& origin) {\\n return std::tie(\\n origin.instance_name,\\n origin.local_label,\\n origin.part_name);\\n}\\n\\nstd::string kernel_error_message(\\n const BeamElement& element,\\n const BeamKernelResult& result) {\\n std::string message =\\n \\\"Beam element \\\" + std::to_string(element.origin.local_label) +\\n \\\" kernel failed\\\";\\n for (const Diagnostic& diagnostic : result.diagnostics) {\\n message += \\\": \\\" + diagnostic.code + \\\" - \\\" + diagnostic.message;\\n }\\n return message;\\n}\\n\\nstd::vector canonical_element_order(const Domain& domain) {\\n std::vector order(domain.beam_elements().size());\\n std::iota(order.begin(), order.end(), std::size_t{0});\\n std::ranges::sort(\\n order,\\n [&domain](const std::size_t left, const std::size_t right) {\\n return origin_key(domain.beam_elements()[left].origin) <\\n origin_key(domain.beam_elements()[right].origin);\\n });\\n return order;\\n}\\n\\nstd::vector canonical_contribution_element_ids(\\n const std::vector& order) {\\n // Domain ElementIds are not ordered by input identity. These tie-break\\n // IDs encode the existing serial assembler's element-origin order.\\n std::vector ids(order.size(), ElementId{0});\\n for (std::size_t rank = 0; rank < order.size(); ++rank) {\\n ids[order[rank]] = ElementId{static_cast(rank)};\\n }\\n return ids;\\n}\\n\\nElementEvaluation evaluate_element(\\n const Domain& domain,\\n const DofManager& dofs,\\n const BeamElement& element,\\n const ElementId canonical_id) {\\n const BeamKernelResult result = compute_beam3d2({\\n {\\n domain.node(element.nodes[0]).position,\\n domain.node(element.nodes[1]).position,\\n },\\n domain.material(element.material),\\n domain.section(element.section),\\n });\\n if (!result.contribution.has_value()) {\\n return {{}, kernel_error_message(element, result)};\\n }\\n\\n ElementEvaluation evaluation;\\n evaluation.contributions.reserve(78);\\n const std::array full_dofs =\\n dofs.element_full_dofs(element);\\n for (std::size_t local_row = 0; local_row < full_dofs.size();\\n ++local_row) {\\n for (std::size_t local_column = local_row;\\n local_column < full_dofs.size();\\n ++local_column) {\\n evaluation.contributions.push_back({\\n std::min(\\n full_dofs[local_row],\\n full_dofs[local_column]),\\n std::max(\\n full_dofs[local_row],\\n full_dofs[local_column]),\\n canonical_id,\\n static_cast(\\n local_row * full_dofs.size() + local_column),\\n result.contribution\\n ->global_stiffness[local_row][local_column],\\n });\\n }\\n }\\n return evaluation;\\n}\\n\\nstd::vector assemble_force(\\n const Domain& domain,\\n const DofManager& dofs) {\\n std::vector force(dofs.full_dof_count(), 0.0);\\n for (const NodalLoad& load : domain.step().nodal_loads) {\\n for (std::size_t component = 0; component < load.values.size();\\n ++component) {\\n const auto dof = static_cast(component);\\n force[dofs.full_dof({load.node, dof})] +=\\n load.values[component];\\n }\\n }\\n return force;\\n}\\n\\nvoid validate_options(const AssemblyOptions options) {\\n if (options.max_threads == 0) {\\n throw std::invalid_argument{\\n \\\"Assembly max_threads must be greater than zero.\\\"};\\n }\\n if (options.max_threads >\\n static_cast(std::numeric_limits::max())) {\\n throw std::invalid_argument{\\n \\\"Assembly max_threads exceeds the TBB task arena range.\\\"};\\n }\\n if (options.grain_size == 0) {\\n throw std::invalid_argument{\\n \\\"Assembly grain_size must be greater than zero.\\\"};\\n }\\n}\\n\\n} // namespace\\n\\nEquationSystem assemble_parallel(\\n const Domain& domain,\\n const DofManager& dofs,\\n const AssemblyOptions options) {\\n validate_options(options);\\n\\n const std::vector element_order =\\n canonical_element_order(domain);\\n const std::vector element_ids =\\n canonical_contribution_element_ids(element_order);\\n std::vector evaluations(\\n domain.beam_elements().size());\\n\\n oneapi::tbb::task_arena arena{\\n static_cast(options.max_threads)};\\n arena.execute([&] {\\n oneapi::tbb::parallel_for(\\n oneapi::tbb::blocked_range{\\n 0,\\n evaluations.size(),\\n options.grain_size,\\n },\\n [&](const oneapi::tbb::blocked_range& range) {\\n for (std::size_t index = range.begin();\\n index != range.end();\\n ++index) {\\n ElementEvaluation local = evaluate_element(\\n domain,\\n dofs,\\n domain.beam_elements()[index],\\n element_ids[index]);\\n evaluations[index] = std::move(local);\\n }\\n });\\n });\\n\\n std::vector contributions;\\n contributions.reserve(domain.beam_elements().size() * 78);\\n for (const std::size_t element_index : element_order) {\\n ElementEvaluation& evaluation = evaluations[element_index];\\n if (evaluation.error.has_value()) {\\n throw std::runtime_error{std::move(*evaluation.error)};\\n }\\n contributions.insert(\\n contributions.end(),\\n std::make_move_iterator(evaluation.contributions.begin()),\\n std::make_move_iterator(evaluation.contributions.end()));\\n }\\n\\n const std::vector canonical =\\n canonicalize_contributions(contributions);\\n return {\\n merge_contributions(dofs.full_dof_count(), canonical),\\n assemble_force(domain, dofs),\\n };\\n}\\n\\n} // namespace fesa\\n\\r\\n#include \\r\\n\\r\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n\\n#include \\n\\nnamespace fesa {\\nnamespace {\\n\\nstruct NumericContribution final {\\n std::size_t row;\\n std::size_t column;\\n const EntityOrigin* element_origin;\\n std::size_t local_order;\\n double value;\\n};\\n\\nstd::int32_t csr_index(const std::size_t value) {\\n if (value >\\n static_cast(\\n std::numeric_limits::max())) {\\n throw std::overflow_error{\\n \\\"Symmetric CSR exceeds the 32-bit index range.\\\"};\\n }\\n return static_cast(value);\\n}\\n\\nauto origin_key(const EntityOrigin& origin) {\\n return std::tie(\\n origin.instance_name,\\n origin.local_label,\\n origin.part_name);\\n}\\n\\nSymmetricCsr build_sparsity_pattern(\\n const Domain& domain,\\n const DofManager& dofs) {\\n using Coordinate = std::pair;\\n std::vector coordinates;\\n coordinates.reserve(\\n dofs.full_dof_count() +\\n domain.beam_elements().size() * 78);\\n\\n for (std::size_t full = 0; full < dofs.full_dof_count(); ++full) {\\n coordinates.emplace_back(full, full);\\n }\\n\\n for (const BeamElement& element : domain.beam_elements()) {\\n const std::array full_dofs =\\n dofs.element_full_dofs(element);\\n for (std::size_t local_row = 0; local_row < full_dofs.size();\\n ++local_row) {\\n for (std::size_t local_column = local_row;\\n local_column < full_dofs.size();\\n ++local_column) {\\n coordinates.emplace_back(\\n std::min(\\n full_dofs[local_row],\\n full_dofs[local_column]),\\n std::max(\\n full_dofs[local_row],\\n full_dofs[local_column]));\\n }\\n }\\n }\\n\\n std::ranges::sort(coordinates);\\n coordinates.erase(\\n std::ranges::unique(coordinates).begin(),\\n coordinates.end());\\n\\n SymmetricCsr pattern{\\n dofs.full_dof_count(),\\n std::vector(dofs.full_dof_count() + 1, 0),\\n {},\\n {},\\n };\\n pattern.column_indices.reserve(coordinates.size());\\n for (const auto [row, column] : coordinates) {\\n if (row >= pattern.order || column >= pattern.order) {\\n throw std::invalid_argument{\\n \\\"DofManager element mapping exceeds the full system order.\\\"};\\n }\\n ++pattern.row_offsets[row + 1];\\n pattern.column_indices.push_back(csr_index(column));\\n }\\n for (std::size_t row = 0; row < pattern.order; ++row) {\\n const std::size_t offset =\\n static_cast(pattern.row_offsets[row]) +\\n static_cast(pattern.row_offsets[row + 1]);\\n pattern.row_offsets[row + 1] = csr_index(offset);\\n }\\n pattern.values.resize(pattern.column_indices.size(), 0.0);\\n return pattern;\\n}\\n\\nstd::runtime_error kernel_error(\\n const BeamElement& element,\\r\\n const BeamKernelResult& result) {\\r\\n std::string message =\\r\\n \\\"Beam element \\\" + std::to_string(element.origin.local_label) +\\r\\n \\\" kernel failed\\\";\\r\\n for (const Diagnostic& diagnostic : result.diagnostics) {\\r\\n message += \\\": \\\" + diagnostic.code + \\\" - \\\" + diagnostic.message;\\r\\n }\\r\\n return std::runtime_error{std::move(message)};\\r\\n}\\r\\n\\r\\nstd::vector collect_numeric_contributions(\\n const Domain& domain,\\n const DofManager& dofs) {\\n std::vector contributions;\\n contributions.reserve(domain.beam_elements().size() * 78);\\r\\n\\r\\n for (const BeamElement& element : domain.beam_elements()) {\\r\\n const BeamKernelResult result = compute_beam3d2({\\r\\n {\\r\\n domain.node(element.nodes[0]).position,\\r\\n domain.node(element.nodes[1]).position,\\r\\n },\\r\\n domain.material(element.material),\\r\\n domain.section(element.section),\\r\\n });\\r\\n if (!result.contribution.has_value()) {\\r\\n throw kernel_error(element, result);\\r\\n }\\r\\n\\r\\n const std::array full_dofs =\\r\\n dofs.element_full_dofs(element);\\r\\n for (std::size_t local_row = 0; local_row < full_dofs.size();\\r\\n ++local_row) {\\r\\n for (std::size_t local_column = local_row;\\r\\n local_column < full_dofs.size();\\r\\n ++local_column) {\\r\\n contributions.push_back({\\r\\n std::min(\\r\\n full_dofs[local_row],\\r\\n full_dofs[local_column]),\\r\\n std::max(\\r\\n full_dofs[local_row],\\r\\n full_dofs[local_column]),\\r\\n &element.origin,\\n local_row * full_dofs.size() + local_column,\\n result.contribution\\n ->global_stiffness[local_row][local_column],\\n });\\n }\\r\\n }\\r\\n }\\r\\n\\r\\n std::ranges::sort(\\n contributions,\\n [](const NumericContribution& left,\\n const NumericContribution& right) {\\n return std::tuple{\\n left.row,\\n left.column,\\n origin_key(*left.element_origin),\\n left.local_order} <\\n std::tuple{\\n right.row,\\n right.column,\\n origin_key(*right.element_origin),\\n right.local_order};\\n });\\n return contributions;\\n}\\n\\nvoid merge_numeric_contributions(\\n SymmetricCsr& matrix,\\n const std::vector& contributions) {\\n std::size_t contribution_index = 0;\\n while (contribution_index < contributions.size()) {\\n const NumericContribution& first =\\n contributions[contribution_index];\\n double value = 0.0;\\n do {\\n value += contributions[contribution_index].value;\\n ++contribution_index;\\n } while (\\n contribution_index < contributions.size() &&\\n contributions[contribution_index].row == first.row &&\\n contributions[contribution_index].column == first.column);\\n\\n const auto row_begin =\\n matrix.column_indices.begin() +\\n matrix.row_offsets[first.row];\\n const auto row_end =\\n matrix.column_indices.begin() +\\n matrix.row_offsets[first.row + 1];\\n const auto entry = std::lower_bound(\\n row_begin,\\n row_end,\\n csr_index(first.column));\\n if (entry == row_end || *entry != csr_index(first.column)) {\\n throw std::logic_error{\\n \\\"Numeric contribution is absent from the CSR pattern.\\\"};\\n }\\n matrix.values[static_cast(\\n std::distance(matrix.column_indices.begin(), entry))] = value;\\n }\\n}\\n\\r\\nstd::vector assemble_force(\\r\\n const Domain& domain,\\r\\n const DofManager& dofs) {\\r\\n std::vector force(dofs.full_dof_count(), 0.0);\\r\\n for (const NodalLoad& load : domain.step().nodal_loads) {\\r\\n for (std::size_t component = 0; component < load.values.size();\\r\\n ++component) {\\r\\n const auto dof = static_cast(component);\\r\\n force[dofs.full_dof({load.node, dof})] +=\\r\\n load.values[component];\\r\\n }\\r\\n }\\r\\n return force;\\r\\n}\\r\\n\\r\\n} // namespace\\r\\n\\r\\nEquationSystem assemble_serial(\\n const Domain& domain,\\n const DofManager& dofs) {\\n SymmetricCsr stiffness = build_sparsity_pattern(domain, dofs);\\n const std::vector contributions =\\n collect_numeric_contributions(domain, dofs);\\n merge_numeric_contributions(stiffness, contributions);\\n return {\\r\\n std::move(stiffness),\\r\\n assemble_force(domain, dofs),\\r\\n };\\r\\n}\\r\\n\\r\\n} // namespace fesa\\r\\n\\r\\n#pragma once\\r\\n\\r\\n#include \\r\\n#include \\r\\n\\r\\n#include \\r\\n#include \\r\\n#include \\r\\n\\r\\nnamespace fesa {\\r\\n\\r\\nstruct AnalysisRunResult final {\\r\\n bool succeeded;\\r\\n std::optional results;\\r\\n std::vector diagnostics;\\r\\n};\\r\\n\\r\\nclass LinearStaticAnalysis final {\\r\\npublic:\\r\\n [[nodiscard]] AnalysisRunResult run(const Domain& domain) const;\\r\\n};\\r\\n\\r\\n} // namespace fesa\\r\\n\\r\\n#include \\r\\n\\r\\n#include \\r\\n#include \\r\\n#include \\r\\n#include \\r\\n#include