feat(nonlinear-static-newton-raphson): step 1 - nonlinear-static-domain-contract

This commit is contained in:
KOKO\Mimi
2026-08-24 13:17:17 +09:00
parent e7c6932d88
commit c00fb79b8f
28 changed files with 814 additions and 275 deletions
+1
View File
@@ -23,6 +23,7 @@ __pycache__/
# local Harness configuration and build outputs # local Harness configuration and build outputs
.harness/config.json .harness/config.json
.harness/build/ .harness/build/
.harness/build-ninja-msvc-debug/
.harness/doxygen/ .harness/doxygen/
# phase execution outputs # phase execution outputs
+7 -12
View File
@@ -1,16 +1,11 @@
{ {
"version": 1, "version": 1,
"projectType": "auto", "projectType": "cmake",
"tdd": { "cmake": {
"testRoots": [ "sourceDir": ".",
"tests", "binaryDir": ".harness/build-ninja-msvc-debug",
"test" "configurePreset": "windows-msvc-ninja-debug",
], "buildPreset": "windows-msvc-ninja-debug",
"testPatterns": [ "testPreset": "windows-msvc-ninja-debug"
"{stem}_test.cpp",
"{stem}_tests.cpp",
"test_{stem}.cpp",
"{stem}.test.cpp"
]
} }
} }
+30
View File
@@ -0,0 +1,30 @@
{
"version": 3,
"configurePresets": [
{
"name": "windows-msvc-ninja-debug",
"displayName": "Windows MSVC x64 Debug (Ninja)",
"generator": "Ninja",
"binaryDir": "${sourceDir}/.harness/build-ninja-msvc-debug",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug",
"FESA_GTEST_SOURCE_DIR": "$env{FESA_GTEST_SOURCE_DIR}",
"MKL_DIR": "$env{MKL_DIR}",
"TBB_DIR": "$env{TBB_DIR}",
"HDF5_DIR": "$env{HDF5_DIR}"
}
}
],
"buildPresets": [
{
"name": "windows-msvc-ninja-debug",
"configurePreset": "windows-msvc-ninja-debug"
}
],
"testPresets": [
{
"name": "windows-msvc-ninja-debug",
"configurePreset": "windows-msvc-ninja-debug"
}
]
}
@@ -6,13 +6,13 @@
- workflow_state: `needs-implementation` - workflow_state: `needs-implementation`
- owner_agent: `coordinator-agent` - owner_agent: `coordinator-agent`
- request_date: `2026-08-18` - request_date: `2026-08-18`
- last_updated: `2026-08-24` (REWORK-004 corrected; no-push Harness rerun authorized) - last_updated: `2026-08-24` (REWORK-006 passed; Step 1 no-push Harness rerun authorized)
- process_classification: `architectural` - process_classification: `architectural`
- requested_capability: Newton–Raphson 방법을 사용하는 새 nonlinear static analysis procedure - requested_capability: Newton–Raphson 방법을 사용하는 새 nonlinear static analysis procedure
- proposed_scope_boundary: 첫 release는 initial configuration 기준 Total Lagrangian, materially linear + geometrically nonlinear MITC4로 제한한다. 요구조건 인터뷰와 8단계 evidence gate를 먼저 완료하며, 승인 전에는 상세 수치·I/O·구현 범위를 확정하거나 기존 linear-static lifecycle을 변경하지 않는다. - proposed_scope_boundary: 첫 release는 initial configuration 기준 Total Lagrangian, materially linear + geometrically nonlinear MITC4로 제한한다. 요구조건 인터뷰와 8단계 evidence gate를 먼저 완료하며, 승인 전에는 상세 수치·I/O·구현 범위를 확정하거나 기존 linear-static lifecycle을 변경하지 않는다.
- naming_note: 사용자 표현 `Newton-Rhapson`은 표준 명칭 `Newton–Raphson`으로 정규화했다. - naming_note: 사용자 표현 `Newton-Rhapson`은 표준 명칭 `Newton–Raphson`으로 정규화했다.
- current_goal: Stage 6 no-push Harness/Implementation rerun is authorized for Executor-selected Step 0 and subsequent approved phase progression under the corrected `codex exec --disable unified_exec` runner envelope. - current_goal: REWORK-006 passed and Step 1 is reset to `pending`; authorize no-push Harness rerun from Step 1 under the approved Ninja/MSVC workspace-write envelope.
- constraints: 승인된 Stage 1-5 hashes, physics/scope/tolerance/authoritative output/public compatibility, `rho_M <= 1e-12`, fixed-global source identity, no drilling load channel과 Stage 6 materialization evidence를 보존한다. The authorized rerun envelope is Codex CLI `0.149.1`, `CODEX_HOME=C:\Users\baram\.codex`, child launch PATH filtering of `C:\Program Files\WindowsApps\Microsoft.PowerShell_*` and `C:\Users\baram\AppData\Local\Microsoft\WindowsApps`, `workspace-write`, implementation-agent `gpt-5.6-terra`/`xhigh`, hooks retained, no-push, no `danger-full-access`, and runner-retained `--disable unified_exec`. Do not edit feature contracts/reference artifacts/tolerance policies, run Abaqus/Nastran/reference solvers, or advance Physics/Release until `implementation-report.md`, `build-test.md`, `reference-comparison.md` and passing implementation evidence exist. - constraints: 승인된 Stage 1-5 hashes, physics/scope/tolerance/authoritative output/public compatibility, `rho_M <= 1e-12`, fixed-global source identity, no drilling load channel과 Stage 6 materialization evidence를 보존한다. Step 0 commits `fc16ef6` and `e7c6932`, Step 1 uncommitted implementation changes, phase block evidence and no-reference-artifact-change evidence must be preserved. The approved continuation envelope is MSVC/x64/Debug with Ninja generator, full CTest, `workspace-write`, Codex CLI `0.149.1`, `CODEX_HOME=C:\Users\baram\.codex`, child launch PATH filtering of `C:\Program Files\WindowsApps\Microsoft.PowerShell_*` and `C:\Users\baram\AppData\Local\Microsoft\WindowsApps`, implementation-agent `gpt-5.6-terra`/`xhigh`, hooks retained, no-push, no `danger-full-access`, and runner-retained `--disable unified_exec`. Do not edit feature contracts/reference artifacts/tolerance policies, run Abaqus/Nastran/reference solvers, clean/delete build artifacts, or advance Step 2/Physics/Release until `implementation-report.md`, `build-test.md`, `reference-comparison.md` and passing implementation evidence exist.
- repository_audit: 기존 worktree에는 `.codex/agents/*.toml`과 `AGENTS.md`의 사용자 변경이 있으며 이를 보존한다. - repository_audit: 기존 worktree에는 `.codex/agents/*.toml`과 `AGENTS.md`의 사용자 변경이 있으며 이를 보존한다.
## 2. Eight-Stage Worklist ## 2. Eight-Stage Worklist
@@ -24,7 +24,7 @@
| 3. Formulation | `formulation-agent` | `passed` | `docs/nonlinear-static-newton-raphson/formulation.md` | strong/weak form, kinematics, tangent/residual, integration, state/recovery가 구현 가능한 계약이며 O-ROT/O-MAP/O-DRILL/O-MOM/O-BC가 승인 scope 안에서 해소됨 | Rework attempt 2 owner/Coordinator pass와 사용자 명시 승인: reaction force/generalized moment/spatial moment symbols와 dimensions가 rotation matrix `R_I`와 분리됨; immutable fixed-global source, `rho_M <= 1e-12` admissibility, exact projected physical-work covector, `DP`/`DJ_l`/map-Hessian residual-tangent identity가 §§4.4/5/11.2–11.3/13.1/13.4/17에서 일치함; 18 sections와 7 closures 보존; SHA-256 `DFA629888041D5762FD0DF4271353464A692B325DC0C821A8D8689688C1EAFD0`. | 없음 | 2 | | 3. Formulation | `formulation-agent` | `passed` | `docs/nonlinear-static-newton-raphson/formulation.md` | strong/weak form, kinematics, tangent/residual, integration, state/recovery가 구현 가능한 계약이며 O-ROT/O-MAP/O-DRILL/O-MOM/O-BC가 승인 scope 안에서 해소됨 | Rework attempt 2 owner/Coordinator pass와 사용자 명시 승인: reaction force/generalized moment/spatial moment symbols와 dimensions가 rotation matrix `R_I`와 분리됨; immutable fixed-global source, `rho_M <= 1e-12` admissibility, exact projected physical-work covector, `DP`/`DJ_l`/map-Hessian residual-tangent identity가 §§4.4/5/11.2–11.3/13.1/13.4/17에서 일치함; 18 sections와 7 closures 보존; SHA-256 `DFA629888041D5762FD0DF4271353464A692B325DC0C821A8D8689688C1EAFD0`. | 없음 | 2 |
| 4. Numerical/reference review | `numerical-review-agent` | `passed` | `docs/nonlinear-static-newton-raphson/numerical-review.md`; `docs/nonlinear-static-newton-raphson/reference-model.md` | 두 문서가 함께 `pass-for-io-definition`이며 수치 안정성과 exact reference contract가 준비됨 | Corrected owner return, Coordinator audit pass and user explicit approval: status `pass-for-io-definition`; approved formulation hash matched; shellNL/shell artifacts inspected read-only with row counts `49/49/288`, duplicate required wide keys 0 and nonfinite required values 0; stress CSVs are optional read-only inspection/order evidence only; `RM3` excluded; required external comparison uses displacement, reaction force and physical spatial `RM1/RM2`; exact prechecks and `docs/TOLERANCE.md` policy retained. Current hashes: numerical-review `9517E11804C45A6F3822D18821D52EA493AE20353C8FFAD61E960F4315977D01`, reference-model `52D10B1D0C0500B295C5E48BCB3618B309D9696371B8070D4E3DCEE8D3D74CD3`. | 없음 | 2 | | 4. Numerical/reference review | `numerical-review-agent` | `passed` | `docs/nonlinear-static-newton-raphson/numerical-review.md`; `docs/nonlinear-static-newton-raphson/reference-model.md` | 두 문서가 함께 `pass-for-io-definition`이며 수치 안정성과 exact reference contract가 준비됨 | Corrected owner return, Coordinator audit pass and user explicit approval: status `pass-for-io-definition`; approved formulation hash matched; shellNL/shell artifacts inspected read-only with row counts `49/49/288`, duplicate required wide keys 0 and nonfinite required values 0; stress CSVs are optional read-only inspection/order evidence only; `RM3` excluded; required external comparison uses displacement, reaction force and physical spatial `RM1/RM2`; exact prechecks and `docs/TOLERANCE.md` policy retained. Current hashes: numerical-review `9517E11804C45A6F3822D18821D52EA493AE20353C8FFAD61E960F4315977D01`, reference-model `52D10B1D0C0500B295C5E48BCB3618B309D9696371B8070D4E3DCEE8D3D74CD3`. | 없음 | 2 |
| 5. I/O definition | `io-definition-agent` | `passed` | `docs/nonlinear-static-newton-raphson/io.md` | Abaqus subset, semantic mapping, HDF5 schema, diagnostics, CSV projection이 승인됨 | Bounded rework owner status `ready-for-coordinator-review`, SHA-256 `DBB959A68F17D67CA2B42569610B9C1B595A8BFB5502BC194B7E62B656031B28`; Coordinator audit passed and user explicitly approved the same hash. REWORK-002 defects are corrected: every argv token containing literal `--output` fails pre-input/pre-log/pre-output with one `cli-usage` diagnostic; `nsnr-log-v1` uses UTF-8 no BOM/LF/TAB fixed fields with four-channel gates, typed thresholds, branch identity, early-failure `not-evaluated(reason)`, round-trip numerics and escaping; log open/write/flush/close is fail-closed with zero-byte non-Newton success logs; exact `VARIABLE=PRESELECT` output requests are ignored-with-warning; lexical path/stem derivation, single-writer/candidate collision rules, HDF5 schema v1, reference projection, stress/RM3 exclusions and `docs/TOLERANCE.md` policy are preserved. | 없음 | 2 | | 5. I/O definition | `io-definition-agent` | `passed` | `docs/nonlinear-static-newton-raphson/io.md` | Abaqus subset, semantic mapping, HDF5 schema, diagnostics, CSV projection이 승인됨 | Bounded rework owner status `ready-for-coordinator-review`, SHA-256 `DBB959A68F17D67CA2B42569610B9C1B595A8BFB5502BC194B7E62B656031B28`; Coordinator audit passed and user explicitly approved the same hash. REWORK-002 defects are corrected: every argv token containing literal `--output` fails pre-input/pre-log/pre-output with one `cli-usage` diagnostic; `nsnr-log-v1` uses UTF-8 no BOM/LF/TAB fixed fields with four-channel gates, typed thresholds, branch identity, early-failure `not-evaluated(reason)`, round-trip numerics and escaping; log open/write/flush/close is fail-closed with zero-byte non-Newton success logs; exact `VARIABLE=PRESELECT` output requests are ignored-with-warning; lexical path/stem derivation, single-writer/candidate collision rules, HDF5 schema v1, reference projection, stress/RM3 exclusions and `docs/TOLERANCE.md` policy are preserved. | 없음 | 2 |
| 6. Implementation | `implementation-planning-agent`; `implementation-agent` | `in-progress` | `docs/nonlinear-static-newton-raphson/implementation-plan.md`; `docs/nonlinear-static-newton-raphson/implementation-report.md`; `docs/nonlinear-static-newton-raphson/build-test.md`; `docs/nonlinear-static-newton-raphson/reference-comparison.md`; `docs/nonlinear-static-newton-raphson/corrections.md` | 상세 인터뷰와 계획 승인 후 TDD, MSVC/x64/Debug CMake/CTest, blocking reference comparison이 통과함 | REWORK-004 Correction Agent returned `corrected-for-implementation-rerun`; `scripts/execute.py` now invokes `codex exec --disable unified_exec --json ...`, `tests/test_execute.py` asserts adjacent `("--disable", "unified_exec")` while preserving `gpt-5.6-terra`/`xhigh`, and `corrections.md` SHA-256 is `82572437689B41323B6533C2361F2F12BF07B5ED305825AA84C56AEEDC729930`. Owner/root evidence: RED targeted missing-pair assertion exit 1, GREEN targeted 1 passed, focused `tests/test_execute.py` 10/10, full pytest 23 passed/1 pre-existing `xhigh` vs `extra high`, MSVC Debug build exit 0, discovery 214, full CTest 214/214. | Stage 6 implementation evidence docs still absent; await no-push Harness rerun | 10 | | 6. Implementation | `implementation-planning-agent`; `implementation-agent` | `in-progress` | `docs/nonlinear-static-newton-raphson/implementation-plan.md`; `docs/nonlinear-static-newton-raphson/implementation-report.md`; `docs/nonlinear-static-newton-raphson/build-test.md`; `docs/nonlinear-static-newton-raphson/reference-comparison.md`; `docs/nonlinear-static-newton-raphson/corrections.md` | 상세 인터뷰와 계획 승인 후 TDD, MSVC/x64/Debug CMake/CTest, blocking reference comparison이 통과함 | REWORK-006 Correction returned `corrected-for-implementation-rerun`; `corrections.md` SHA-256 `7FA66A14E694D0451B4422BB5A233E117F2100231A9644771EFD428AF7AD6B81`. Evidence: nested `workspace-write` launched from VsDevCmd x64 plus dependency env; Ninja/Debug/MSVC Hostx64-x64 configure/build/discovery/full CTest all exit 0; 228 discovered/228 passed; Stop-hook `codex exec` exit 0; focused contract test 1/1; full Python 24 passed plus one pre-existing `xhigh`/`extra high` mismatch; reference hashes unchanged; top phase and Step 1 reset to `pending` only after pass, Step 2 remains pending. | Stage 6 implementation evidence docs still absent; no-push Harness rerun from Step 1 is authorized | 14 |
| 7. Physics evaluation | `physics-evaluation-agent` | `pending` | `docs/nonlinear-static-newton-raphson/physics-evaluation.md` | equilibrium, reaction, direction, path/history, energy, symmetry, model coverage가 `pass-for-release-agent`임 | 없음 | Stage 6 passing evidence 필요 | 0 | | 7. Physics evaluation | `physics-evaluation-agent` | `pending` | `docs/nonlinear-static-newton-raphson/physics-evaluation.md` | equilibrium, reaction, direction, path/history, energy, symmetry, model coverage가 `pass-for-release-agent`임 | 없음 | Stage 6 passing evidence 필요 | 0 |
| 8. Release readiness | `release-agent` | `pending` | `docs/nonlinear-static-newton-raphson/release.md` | `ready-for-release` recommendation과 acceptance traceability가 완전함 | 없음 | Stage 7 passing evidence 필요 | 0 | | 8. Release readiness | `release-agent` | `pending` | `docs/nonlinear-static-newton-raphson/release.md` | `ready-for-release` recommendation과 acceptance traceability가 완전함 | 없음 | Stage 7 passing evidence 필요 | 0 |
@@ -33,55 +33,46 @@
### Active Dispatch Package ### Active Dispatch Package
- feature_id: `nonlinear-static-newton-raphson` - feature_id: `nonlinear-static-newton-raphson`
- current_dispatch: `stage-6-no-push-harness-implementation-rerun` - current_dispatch: `stage-6-step1-no-push-harness-rerun`
- target_sub_agent: `implementation-agent` via Harness Executor (`python scripts/execute.py nonlinear-static-newton-raphson`; root launch required) - target_sub_agent: `implementation-agent` via Harness Executor (`python scripts/execute.py nonlinear-static-newton-raphson`; root launch required)
- required_inputs: - required_inputs:
- User explicit execution request on `2026-08-24`: `Harness/Implementation를 실행해주세요.` - REWORK-006 Correction return: status `corrected-for-implementation-rerun`, `docs/nonlinear-static-newton-raphson/corrections.md` SHA-256 `7FA66A14E694D0451B4422BB5A233E117F2100231A9644771EFD428AF7AD6B81`.
- Attempt 1 failure evidence: no-push Harness command `python scripts/execute.py nonlinear-static-newton-raphson`; `codex exec --json --sandbox workspace-write ...` timed out at `1800.7s`; `_invoke_codex` raised uncaught `subprocess.TimeoutExpired`; no Step 0 source/test edits, no `step0-output.json`, no `MAX_RETRIES` handling. - User explicitly approved USER-DECISION-002 option A / DECISION-039: Ninja/MSVC is the accepted Stage 6 validation contract for continuation.
- Bounded Harness repair evidence: Implementation Agent changed only `scripts/execute.py` and `tests/test_execute.py`; TDD RED 3 expected failures, GREEN 3 passed; focused `tests/test_execute.py` 10/10 passed; full pytest 23 passed/1 pre-existing HEAD contract failure `xhigh` actual vs `extra high` expected. - Current isolated worktree: `C:\git\FESADev\.worktrees\nonlinear-static-newton-raphson`; no push.
- Repair behavior now required: Codex timeout returns structured exit `124` and reaches `MAX_RETRIES`; runner reads `.codex/agents/implementation-agent.toml` and passes `gpt-5.6-terra` plus `xhigh` settings to `codex exec`. - Step 0 evidence: completed and committed as feature commit `fc16ef6` plus metadata commit `e7c6932`.
- Root independent review evidence: no new defect found; focused `tests/test_execute.py` 10/10 reproduced; full suite reproduced the same single pre-existing `xhigh` vs `extra high` mismatch. - Current Step 1 state: `pending` with historical `started_at`; existing uncommitted Domain/Abaqus mapping production and C++ test changes are preserved; Step 2..12 remain pending.
- Attempt 2 failure evidence: repaired Executor wrote `phases/nonlinear-static-newton-raphson/step0-output.json` with `exitCode` 124 and stderr `Codex timed out after 1800 seconds.`; stdout shows the Implementation Agent completed a turn but every nested command execution remained `status=in_progress`. - Current hashes: `phases/index.json` `307D8041537D73B579E53F96B052BA035774B65ABF071BB230AAE20CFCF966A7`; phase index `D3F30298EB728F4DECA948827900CF35989F47F009872B43DC4BD997B30C3950`.
- Runtime blocker evidence: nested commands hung for skill file reads, `Get-Date`, `cmd.exe /d /c echo test`, and `exit 0`; root classifies the cause as nested Codex Windows shell tool execution hang, not model delay, build, source, sandbox/auth, or the repaired Executor timeout/no-retry path. - Correction files/evidence: tracked `CMakePresets.json` SHA-256 `900EEE9EC564CEA09F2A73B8AC59865A7233E9480FAACD3CFEF60F2ABCDFFD43`; ignored `.harness/config.json` byte-identical to `.harness/config.example.json` SHA-256 `D07429860D472AE37D02D6CD638900FA46175085AF47F179E98601227F8D3C43`; contract test `tests/test_harness_preset_contract.py` SHA-256 `94433B65E155C90837724810A1E773BB990779AFB217268E557AE4E7662B8396`.
- Active process evidence from root: Executor auto-started another internal retry at `2026-08-24T02:58:35+09:00` under `python execute.py` PID 13820 / `codex` PID 7704; root terminated those unauthorized retry PIDs and verified none remain. - Correction validation: nested `workspace-write`/VsDevCmd x64/dependency env; Ninja/Debug/MSVC Hostx64-x64 configure/build/discovery/full all exit 0; 228 discovered/228 passed; Stop-hook `codex exec` exit 0; focused contract test 1/1; full Python 24 passed plus pre-existing `xhigh`/`extra high` mismatch 1.
- Root decision after blocked-no-auto-retry: authorize one bounded Correction Agent diagnostic/rework cycle because the repeated implementation failure is infrastructure/runtime, not physics/source/build. - Root independent review: no blocking finding; read AGENTS/ARCHITECTURE/ADR; focused contract test fresh pass 1/1; `cmake --list-presets` exposes only approved preset; `cmake --preset ... -N` exit 0; `git diff --check` pass; local config/build ignored as intended; `git diff -- reference` clean; no old VS/`.harness/build` commands remain in `implementation-plan.md` or `step0.md`..`step12.md`.
- Correction Agent return: status `blocked`, output `docs/nonlinear-static-newton-raphson/corrections.md` SHA-256 `C9F93AC99225725C88BB7F0BABC8F7D75D3E05082070090328203DB3776BEFE6`, no runner/test edits from correction, no safe documented CLI flag workaround proven. - Approved Stage 1-5 hashes remain unchanged: requirements `910E351F3F90FFA42F07D15206B55E62C05EAE821E250424430148337506EBF2`; research `C920A6B02381230D1DB419D73FE767D611B36720D27D6410507BA88C3CA28EEE`; formulation `DFA629888041D5762FD0DF4271353464A692B325DC0C821A8D8689688C1EAFD0`; numerical-review `9517E11804C45A6F3822D18821D52EA493AE20353C8FFAD61E960F4315977D01`; reference-model `52D10B1D0C0500B295C5E48BCB3618B309D9696371B8070D4E3DCEE8D3D74CD3`; io `DBB959A68F17D67CA2B42569610B9C1B595A8BFB5502BC194B7E62B656031B28`.
- User/root runtime update evidence: standalone Codex CLI updated `0.147.0 -> 0.149.1` under `CODEX_HOME=C:\Users\baram\.codex`; `codex doctor --json` reported current/consistent installation.
- User/root bounded smoke evidence: baseline still fails through inaccessible WindowsApps `pwsh`, direct `codex sandbox` elevated/unelevated `cmd echo` exits 0, and nested smoke passes only when launch env filters `C:\Program Files\WindowsApps\Microsoft.PowerShell_*` plus `C:\Users\baram\AppData\Local\Microsoft\WindowsApps`, aligns `CODEX_HOME`, retains `workspace-write` and hooks, uses implementation-agent `gpt-5.6-terra`/`xhigh`, and passes `--disable unified_exec`; output was exactly `CODEX_SHELL_SMOKE_OK\r\n`.
- REWORK-004 Correction Agent return: status `corrected-for-implementation-rerun`; changed only `scripts/execute.py`, `tests/test_execute.py`, `docs/nonlinear-static-newton-raphson/corrections.md`; no Harness phase, C++ source, CMake, reference solver, commit or push.
- Coordinator audit: current `scripts/execute.py` lines 300-315 pass exact adjacent args `--disable`, `unified_exec` immediately after `codex exec`; current test `test_invoke_codex_uses_implementation_agent_command_contract` asserts the pair while preserving `gpt-5.6-terra` and `model_reasoning_effort="xhigh"`.
- `AGENTS.md`, `docs/SOLVER_AGENT_DESIGN.md`, `docs/HARNESS.md`, `docs/HARNESS_WORKFLOW.md`, `.agents/skills/harness/SKILL.md`, `.codex/hooks.json`
- `docs/nonlinear-static-newton-raphson/implementation-plan.md` SHA-256 `BF4FC7A5CFDEEC19D62A36E1DF7CC34C0B9F614FA0A0FD8D0A321ADC73E69580`
- `phases/index.json` SHA-256 `F8BE89D579C303410BD1D2CD17AF33FCAD72BF68D9E10C3F644A39D1AA7331FB`
- `phases/nonlinear-static-newton-raphson/index.json` SHA-256 `439B67E1DED442D828EB5C31DAB35D28F32DBA6F66537512CAFFB5616956C137`
- Executor-selected initial current Step: `phases/nonlinear-static-newton-raphson/step0.md`, Step 0 `cli-output-lease-and-derived-names`, status `pending`
- Approved Stage 1-5 hashes: requirements `910E351F3F90FFA42F07D15206B55E62C05EAE821E250424430148337506EBF2`; research `C920A6B02381230D1DB419D73FE767D611B36720D27D6410507BA88C3CA28EEE`; formulation `DFA629888041D5762FD0DF4271353464A692B325DC0C821A8D8689688C1EAFD0`; numerical-review `9517E11804C45A6F3822D18821D52EA493AE20353C8FFAD61E960F4315977D01`; reference-model `52D10B1D0C0500B295C5E48BCB3618B309D9696371B8070D4E3DCEE8D3D74CD3`; io `DBB959A68F17D67CA2B42569610B9C1B595A8BFB5502BC194B7E62B656031B28`.
- Preserved materialization evidence: exactly one pending phase entry, 13/13 pending steps, Step 0 remains pending, no implementation evidence docs yet.
- expected_outputs: - expected_outputs:
- Executor-managed no-push phase execution from Step 0, with branch/pending selection/retry/timestamps/commits/advancement owned only by `scripts/execute.py`. - Executor-managed no-push Harness rerun beginning at Step 1. Executor owns branch state, pending selection, retries, timestamps, commits and advancement.
- Each Implementation Agent session performs only its Executor-selected current Step `RED -> observed failure -> minimal GREEN -> VERIFY`, updates only that Step status payload, and stops. - Implementation Agent owns only Executor-selected Step 1 `RED -> observed failure -> minimal GREEN -> VERIFY`, then Step 1 status/summary or blocker payload.
- Final Stage 6 evidence remains `docs/nonlinear-static-newton-raphson/implementation-report.md`, `docs/nonlinear-static-newton-raphson/build-test.md`, and `docs/nonlinear-static-newton-raphson/reference-comparison.md` after the approved phase reaches its final verification Step. - Final Stage 6 evidence remains `implementation-report.md`, `build-test.md`, and `reference-comparison.md` only after the approved phase reaches final verification.
- acceptance_gate: Root is explicitly authorized to run no-push `python scripts/execute.py nonlinear-static-newton-raphson` in the isolated worktree using Codex `0.149.1`, `CODEX_HOME=C:\Users\baram\.codex`, a child PATH filtered of `C:\Program Files\WindowsApps\Microsoft.PowerShell_*` and `C:\Users\baram\AppData\Local\Microsoft\WindowsApps`, `workspace-write`, hooks retained, implementation-agent `gpt-5.6-terra`/`xhigh`, and no `danger-full-access`. Passing Stage 6 still requires successful Implementation phase execution plus Coordinator audit of `implementation-report.md`, `build-test.md`, `reference-comparison.md`, full MSVC x64 Debug build/CTest, blocking reference comparison and no forbidden reference/upstream/tolerance mutation. - acceptance_gate: Root is authorized to rerun no-push `python scripts/execute.py nonlinear-static-newton-raphson` from the isolated worktree, launched from VsDevCmd x64 with `FESA_GTEST_SOURCE_DIR`, `MKL_DIR`, `TBB_DIR`, `HDF5_DIR`, Codex `0.149.1`, aligned `CODEX_HOME`, filtered WindowsApps PATH, `workspace-write`, hooks retained, `gpt-5.6-terra`/`xhigh`, `--disable unified_exec`, Ninja/MSVC presets, and no `danger-full-access`. Passing Stage 6 still requires successful Harness execution, MSVC/x64/Debug full CTest, required reference comparison, and Coordinator audit of implementation evidence docs.
- stop_condition: If nested shell execution hangs or cannot complete under the exact corrected runner and approved launch envelope, stop as `blocked` with the new evidence; do not broaden to `danger-full-access`, do not run Abaqus/Nastran/reference solvers, do not generate/modify reference CSVs, and do not advance Physics/Release. - stop_condition: Stop and report if Step 1 rerun blocks/errors, if the old Visual Studio/FileTracker path recurs, if the nested Codex shell hang recurs, if Ninja/MSVC validation fails, or if any unauthorized `danger-full-access`, push, reference solver/artifact mutation or Step 2 advance is attempted before Step 1 completion.
- missing_evidence: No-push Harness rerun result and Stage 6 implementation evidence docs remain absent. - missing_evidence: no-push Harness Step 1 rerun result and Stage 6 implementation evidence docs.
### Latest Sub-Agent Return ### Latest Sub-Agent Return
- target_sub_agent: `correction-agent` - target_sub_agent: `correction-agent`
- output_paths: - output_paths:
- `docs/nonlinear-static-newton-raphson/corrections.md` - `docs/nonlinear-static-newton-raphson/corrections.md`
- status: `corrected-for-implementation-rerun` (owner); Coordinator decision `passed-for-implementation-rerun` - status: `corrected-for-implementation-rerun` (owner); Coordinator decision `passed`
- evidence_summary: - evidence_summary:
- `corrections.md` SHA-256 is `82572437689B41323B6533C2361F2F12BF07B5ED305825AA84C56AEEDC729930`. - `corrections.md` SHA-256 `7FA66A14E694D0451B4422BB5A233E117F2100231A9644771EFD428AF7AD6B81`.
- `scripts/execute.py` SHA-256 is `E36A78E5C0AE7E91361B1AB6B995D2E8CF51569C0E0804D57F54711AFEFFB806`; `tests/test_execute.py` SHA-256 is `1E368382ABA21F5FBAC344E15E1E600B6BDAF4C4528431E4D1A757AA09D54CDE`. - Correction expressed DECISION-039 through tracked `CMakePresets.json`, ignored `.harness/config.json`, updated `.harness/config.example.json`, `.gitignore`, `implementation-plan.md`, and `step0.md`..`step12.md`, and added `tests/test_harness_preset_contract.py`; no Harness Python production change was required.
- Runner command contract now starts `codex exec --disable unified_exec --json ...` and still passes `--model gpt-5.6-terra`, `--config model_reasoning_effort="xhigh"`, `--sandbox workspace-write`, `--dangerously-bypass-hook-trust`, `--cd <repo>`. - Nested `workspace-write` with VsDevCmd x64 and dependency environment passed Ninja/Debug/MSVC Hostx64-x64 configure/build/discovery/full CTest, 228 discovered/228 passed, and Stop-hook `codex exec` exit 0.
- TDD evidence: targeted RED failed on missing adjacent pair with exit 1; targeted GREEN passed; focused `tests/test_execute.py` 10/10; full pytest remains 23 passed/1 pre-existing `xhigh` vs `extra high`; MSVC Debug build exit 0; CTest discovery 214; full CTest 214/214. - Focused contract test passed 1/1; full Python was 24 passed plus one pre-existing `xhigh`/`extra high` mismatch.
- Correction did not run Harness phase, edit C++/CMake/reference artifacts, run reference solvers, commit or push. - Top phase and Step 1 were reset to `pending` only after blocker-clear evidence; Step 2 remains pending.
- Reference artifact hashes match the approved inventory and `git diff -- reference` is clean.
- Correction did not run Harness phase, Step 2, reference solvers, cleanup, commit, push, or `danger-full-access`.
- blockers: - blockers:
- 없음 for runner-option correction; Stage 6 implementation evidence is still pending. - 없음 for REWORK-006; Stage 6 implementation evidence docs remain absent.
- self_audit_findings: Coordinator verified the correction report hash, audited current runner args and regression assertion, checked phase index pending statuses, did not run phase/build/tests/reference solvers, and updated only this isolated worktree `coordination.md`. - self_audit_findings: Coordinator accepted the Correction return, independently checked hashes, preset/config content, phase pending state, no reference/upstream contract diff, root independent review, and did not run Harness/build/tests/reference solvers.
- return_contract_check: output path, corrected status, evidence summary, blockers and changed-file assertion are present. - return_contract_check: output path, corrected status, evidence summary, blockers, no-change assertion and cleanup evidence are present.
- acceptance_evidence_check: REWORK-004 is closed; Stage 6 is eligible for no-push Harness rerun, but no implementation pass evidence exists yet. - acceptance_evidence_check: REWORK-006 is closed; no-push Harness rerun from Step 1 is eligible under the approved envelope.
### Compact Migration Evidence ### Compact Migration Evidence
@@ -192,10 +183,14 @@
| 2026-08-24 | Correction Agent return and Coordinator audit | `blocked` | Correction Agent returned `blocked` and created only `docs/nonlinear-static-newton-raphson/corrections.md` SHA-256 `C9F93AC99225725C88BB7F0BABC8F7D75D3E05082070090328203DB3776BEFE6`. Baseline smoke reproduced no nested shell completion; `--disable code_mode_host` failed closed; `--enable unified_exec` hung; combined flags failed closed. Root verified no nonlinear Harness/Codex processes remain, all 13 steps pending, Python 23 passed/1 pre-existing failure, MSVC build exit 0, discovery 214 and CTest 214/214. | `blocked` | No further Harness retry until external Codex runtime update/repair plus bounded shell smoke success | | 2026-08-24 | Correction Agent return and Coordinator audit | `blocked` | Correction Agent returned `blocked` and created only `docs/nonlinear-static-newton-raphson/corrections.md` SHA-256 `C9F93AC99225725C88BB7F0BABC8F7D75D3E05082070090328203DB3776BEFE6`. Baseline smoke reproduced no nested shell completion; `--disable code_mode_host` failed closed; `--enable unified_exec` hung; combined flags failed closed. Root verified no nonlinear Harness/Codex processes remain, all 13 steps pending, Python 23 passed/1 pre-existing failure, MSVC build exit 0, discovery 214 and CTest 214/214. | `blocked` | No further Harness retry until external Codex runtime update/repair plus bounded shell smoke success |
| 2026-08-24 | Codex `0.149.1` smoke pass and runner preflight | `needs-rework` | User/root authorized Codex CLI update, bounded smoke and Harness rerun. Smoke passed only with aligned `CODEX_HOME`, filtered WindowsApps PATH entries and `--disable unified_exec`; current `scripts/execute.py` does not pass that flag to nested `codex exec`, while local `codex exec --help` confirms `--disable <FEATURE>` support. | `needs-correction` | Dispatch bounded runner-option correction before any no-push Harness phase rerun | | 2026-08-24 | Codex `0.149.1` smoke pass and runner preflight | `needs-rework` | User/root authorized Codex CLI update, bounded smoke and Harness rerun. Smoke passed only with aligned `CODEX_HOME`, filtered WindowsApps PATH entries and `--disable unified_exec`; current `scripts/execute.py` does not pass that flag to nested `codex exec`, while local `codex exec --help` confirms `--disable <FEATURE>` support. | `needs-correction` | Dispatch bounded runner-option correction before any no-push Harness phase rerun |
| 2026-08-24 | REWORK-004 Correction return and Coordinator audit | `passed` | Correction returned `corrected-for-implementation-rerun`; runner now passes adjacent `--disable`, `unified_exec` after `codex exec`; regression test asserts the command contract; `corrections.md` SHA-256 `82572437689B41323B6533C2361F2F12BF07B5ED305825AA84C56AEEDC729930`; focused tests 10/10, full pytest only known pre-existing mismatch, MSVC build and 214/214 CTest pass per owner/root evidence. | `needs-implementation` | Root is authorized to run no-push `python scripts/execute.py nonlinear-static-newton-raphson` with Codex `0.149.1`, aligned `CODEX_HOME`, filtered child PATH, `workspace-write`, hooks retained and no `danger-full-access` | | 2026-08-24 | REWORK-004 Correction return and Coordinator audit | `passed` | Correction returned `corrected-for-implementation-rerun`; runner now passes adjacent `--disable`, `unified_exec` after `codex exec`; regression test asserts the command contract; `corrections.md` SHA-256 `82572437689B41323B6533C2361F2F12BF07B5ED305825AA84C56AEEDC729930`; focused tests 10/10, full pytest only known pre-existing mismatch, MSVC build and 214/214 CTest pass per owner/root evidence. | `needs-implementation` | Root is authorized to run no-push `python scripts/execute.py nonlinear-static-newton-raphson` with Codex `0.149.1`, aligned `CODEX_HOME`, filtered child PATH, `workspace-write`, hooks retained and no `danger-full-access` |
| 2026-08-24 | Harness rerun Step 1 safe block | `needs-rework` | No-push Harness rerun under the approved Codex `0.149.1` envelope exited 2 safely, not by nested shell hang. Step 0 completed and committed (`fc16ef6`, metadata `e7c6932`). Step 1 is `blocked` because Visual Studio 18 CMake configure hit MSBuild `FileTracker` `E_ACCESSDENIED` in `workspace-write`; root reports clean Ninja/MSVC build and all 228 CTest cases passed. Top phase hash `E5AB831A326AA361B1C3491DA2DA09AC2CA8D66D9A3BCEE8E771D78C6352EC45`, phase index hash `5CD3B4E2BD50BF03A105CAC645F7F48F5A1360414E085B08C9D75BF6D46317A8`, Step 1 output hash `B04B25E8C2D1E0CD54E712B086623E1741FC563A70F0582FD6DC813F660CD6D7`. | `needs-correction` | Root profile dispatch to bounded `correction-agent` for FileTracker diagnosis under `workspace-write`; `danger-full-access` requires explicit new user approval and is not authorized |
| 2026-08-24 | REWORK-005 FileTracker Correction return and Coordinator audit | `blocked` | Correction returned `blocked` / `needs-user-decision`, changed only `docs/nonlinear-static-newton-raphson/corrections.md` SHA-256 `BCA9DEE6F6F262A70FB5C7A49B2BF06CA3FF8BC6C6838FB20A8B48071CF9D420`. VS18/MSBuild `18.8.2` fails in FESA and gtest at `FileTracker..cctor()` -> `GetLongFilePath` with `E_ACCESSDENIED`; inherited `TEMP`/`TMP` is outside workspace; `/p:TrackFileAccess=false` and `:workspace` echo were not proven; exact process trees were cleaned; Ninja/MSVC 27/27 focused and 228/228 full evidence is preserved but not an approved substitute. | `needs-user-decision` | User must choose A Ninja/MSVC evidence substitution, B isolated `danger-full-access` fallback, or C stop pending external Codex sandbox Temp/FileTracker repair |
| 2026-08-24 | USER-DECISION-002 option A and REWORK-006 dispatch | `in-progress` | User explicitly approved option A: Ninja/MSVC is the accepted Stage 6 validation contract. Coordinator/root audit found `.harness/config.json` ignored/absent, CMake presets absent, and adapter preset triplets sufficient to route Stop hook to Ninja without Harness Python production changes. Root dispatched `correction-agent` for preset/config plumbing, preset-contract RED test, planning/phase command rewrite, blocker-clear evidence, and phase reset only after evidence. | `needs-correction` | Await REWORK-006 Correction return; no Harness rerun, Step 2, `danger-full-access`, push, reference solver or reference artifact change |
| 2026-08-24 | REWORK-006 Correction return and Coordinator audit | `passed` | Correction returned `corrected-for-implementation-rerun`; `corrections.md` SHA-256 `7FA66A14E694D0451B4422BB5A233E117F2100231A9644771EFD428AF7AD6B81`; Ninja/MSVC Debug configure/build/discovery/full CTest passed with 228/228, Stop-hook `codex exec` exit 0, focused contract test 1/1, full Python 24 passed plus pre-existing `xhigh`/`extra high`; reference hashes unchanged; top phase and Step 1 reset to `pending` only after evidence; root independent review found no blocking issue. | `needs-implementation` | Root is authorized to rerun no-push `python scripts/execute.py nonlinear-static-newton-raphson` from Step 1 under approved Ninja/MSVC workspace-write envelope |
- current_dispatch: `stage-6-no-push-harness-implementation-rerun` - current_dispatch: `stage-6-step1-no-push-harness-rerun`
- current_workflow_state: `needs-implementation` - current_workflow_state: `needs-implementation`
- next_gate_requires_user_approval: `false` (user/root already authorized Codex update, bounded smoke and Harness rerun) - next_gate_requires_user_approval: `false` for Step 1 no-push Harness rerun; `true` before any `danger-full-access`, Visual Studio fallback, reference solver, push, or manual Step 2 advancement
## 5. Risk, Blocker, and User-Decision Register ## 5. Risk, Blocker, and User-Decision Register
@@ -208,6 +203,9 @@
| BLOCKER-002 | harness-runtime | Nested Codex Windows shell tool execution hung inside Implementation/Correction Codex sessions. It is mitigated for the authorized rerun by Codex CLI `0.149.1`, aligned `CODEX_HOME`, filtered WindowsApps PATH entries, smoke success with exact `CODEX_SHELL_SMOKE_OK` output, and REWORK-004 runner retention of `--disable unified_exec`. Reopen only if the same hang recurs under the exact approved envelope. | external Codex runtime / user-root decision | mitigated | | BLOCKER-002 | harness-runtime | Nested Codex Windows shell tool execution hung inside Implementation/Correction Codex sessions. It is mitigated for the authorized rerun by Codex CLI `0.149.1`, aligned `CODEX_HOME`, filtered WindowsApps PATH entries, smoke success with exact `CODEX_SHELL_SMOKE_OK` output, and REWORK-004 runner retention of `--disable unified_exec`. Reopen only if the same hang recurs under the exact approved envelope. | external Codex runtime / user-root decision | mitigated |
| BLOCKER-003 | dispatch-runtime | This Coordinator runtime exposed no callable `spawn_agent` tool, but root successfully performed the required Correction Agent profile dispatch. | coordinator/root tooling | closed | | BLOCKER-003 | dispatch-runtime | This Coordinator runtime exposed no callable `spawn_agent` tool, but root successfully performed the required Correction Agent profile dispatch. | coordinator/root tooling | closed |
| REWORK-004 | harness | Corrected: `scripts/execute.py` now passes adjacent `--disable`, `unified_exec` immediately after `codex exec`; `tests/test_execute.py` asserts this while preserving terra/xhigh routing; `corrections.md` records RED/GREEN/VERIFY and no Harness phase/source C++/CMake/reference edits. | `correction-agent` | closed | | REWORK-004 | harness | Corrected: `scripts/execute.py` now passes adjacent `--disable`, `unified_exec` immediately after `codex exec`; `tests/test_execute.py` asserts this while preserving terra/xhigh routing; `corrections.md` records RED/GREEN/VERIFY and no Harness phase/source C++/CMake/reference edits. | `correction-agent` | closed |
| REWORK-005 | harness | FileTracker Correction returned `blocked`: VS18/MSBuild `FileTracker` `E_ACCESSDENIED` is classified as environment-owned sandbox/MSBuild interaction; no safe Visual Studio `workspace-write` workaround was proven. User resolved the route by approving option A Ninja/MSVC validation. | `correction-agent` | closed-by-USER-DECISION-002A |
| REWORK-006 | harness | Corrected: approved option A is expressed through tracked `CMakePresets.json`, ignored `.harness/config.json`, preset-based implementation-plan/step verification commands, RED-first contract test, workspace-write Ninja/MSVC blocker-clear evidence, and blocked-to-pending phase reset only after pass. | `correction-agent` | closed |
| USER-DECISION-002 | user decision | User explicitly chose option A: approve Ninja/MSVC evidence contract for Stage 6 continuation. Option B `danger-full-access` and option C external sandbox wait are not selected. | user via Coordinator | closed |
| RISK-001 | architecture | 기존 `LinearStaticAnalysis` private lifecycle은 단일 factorization/substitution과 final frame만 소유하므로 nonlinear increment/iteration/state commit을 삽입하면 ADR 경계를 위반한다. | `coordinator-agent` routing | open | | RISK-001 | architecture | 기존 `LinearStaticAnalysis` private lifecycle은 단일 factorization/substitution과 final frame만 소유하므로 nonlinear increment/iteration/state commit을 삽입하면 ADR 경계를 위반한다. | `coordinator-agent` routing | open |
| RISK-002 | scope | `Newton–Raphson`은 solution algorithm이고 geometric/material/contact nonlinearity 범위를 단독으로 결정하지 않는다. | `requirement-agent` | mitigated by DECISION-001 | | RISK-002 | scope | `Newton–Raphson`은 solution algorithm이고 geometric/material/contact nonlinearity 범위를 단독으로 결정하지 않는다. | `requirement-agent` | mitigated by DECISION-001 |
| RISK-003 | contract | 현재 `Element`는 displacement-dependent residual/consistent tangent/trial state 계약이 없고 `AnalysisState`는 nonlinear history를 소유하지 않는다. | downstream formulation/architecture gates | open | | RISK-003 | contract | 현재 `Element`는 displacement-dependent residual/consistent tangent/trial state 계약이 없고 `AnalysisState`는 nonlinear history를 소유하지 않는다. | downstream formulation/architecture gates | open |
@@ -251,15 +249,16 @@
| DECISION-036 | user approval | User explicitly approved the Stage 6 Implementation Planning 13-Step draft on `2026-08-24` and authorized creation of `implementation-plan.md` plus pending Harness phase files. | user via Coordinator | closed | | DECISION-036 | user approval | User explicitly approved the Stage 6 Implementation Planning 13-Step draft on `2026-08-24` and authorized creation of `implementation-plan.md` plus pending Harness phase files. | user via Coordinator | closed |
| DECISION-037 | user approval | User explicitly requested no-push Harness/Implementation execution for materialized phase `nonlinear-static-newton-raphson` on `2026-08-24`. | user via Coordinator | closed | | DECISION-037 | user approval | User explicitly requested no-push Harness/Implementation execution for materialized phase `nonlinear-static-newton-raphson` on `2026-08-24`. | user via Coordinator | closed |
| DECISION-038 | user/root runtime approval | User/root authorized Codex CLI update, shell smoke and no-push Harness rerun. Accepted runtime envelope is Codex CLI `0.149.1`, `CODEX_HOME=C:\Users\baram\.codex`, launch-env-only WindowsApps PATH filtering, `workspace-write`, hooks retained, implementation-agent `gpt-5.6-terra`/`xhigh`, no `danger-full-access`, and `--disable unified_exec`. | user/root via Coordinator | closed | | DECISION-038 | user/root runtime approval | User/root authorized Codex CLI update, shell smoke and no-push Harness rerun. Accepted runtime envelope is Codex CLI `0.149.1`, `CODEX_HOME=C:\Users\baram\.codex`, launch-env-only WindowsApps PATH filtering, `workspace-write`, hooks retained, implementation-agent `gpt-5.6-terra`/`xhigh`, no `danger-full-access`, and `--disable unified_exec`. | user/root via Coordinator | closed |
| DECISION-039 | user decision | Stage 6 FileTracker blocker route: user approved option A, making Ninja/MSVC x64 Debug with full CTest the accepted validation contract for continuation. `danger-full-access`, Visual Studio fallback, reference solver activity, push and Step 2 advancement remain unauthorized. | user via Coordinator | closed |
| USER-DECISION-001 | user decision | Stage 6 Implementation Planning draft Steps `0..12` were approved on `2026-08-24`; materialization is authorized for `implementation-planning-agent`. | user via Coordinator | closed | | USER-DECISION-001 | user decision | Stage 6 Implementation Planning draft Steps `0..12` were approved on `2026-08-24`; materialization is authorized for `implementation-planning-agent`. | user via Coordinator | closed |
## 6. Rework-Loop Control and Stop Condition ## 6. Rework-Loop Control and Stop Condition
- normalized_failure_attempts: `requirements-next-question-routing-mismatch`: 1; `requirements-output-failure-atomicity-scope-ambiguity`: 1; `requirements-compact-public-contract-omission`: 1; `formulation-equilibrium-reaction-symbol-collision`: 1; `formulation-moment-admissibility-work-inconsistency`: 1; `numerical-review-cross-report-disposition-contradiction`: 1; `io-contract-public-cli-log-output-request-gap`: 1; `harness-nested-codex-windows-shell-tool-execution-hang`: 2 - normalized_failure_attempts: `requirements-next-question-routing-mismatch`: 1; `requirements-output-failure-atomicity-scope-ambiguity`: 1; `requirements-compact-public-contract-omission`: 1; `formulation-equilibrium-reaction-symbol-collision`: 1; `formulation-moment-admissibility-work-inconsistency`: 1; `numerical-review-cross-report-disposition-contradiction`: 1; `io-contract-public-cli-log-output-request-gap`: 1; `harness-nested-codex-windows-shell-tool-execution-hang`: 2; `harness-msbuild-filetracker-eaccessdenied-workspace-write`: 2
- automatic_rework_limit: 동일 normalized failure classification `2`회 - automatic_rework_limit: 동일 normalized failure classification `2`회
- correction_agent_policy: 명확한 implementation failure는 먼저 `implementation-agent`에 반환하고, 반복되거나 원인이 불명확할 때만 `correction-agent`를 dispatch한다. - correction_agent_policy: 명확한 implementation failure는 먼저 `implementation-agent`에 반환하고, 반복되거나 원인이 불명확할 때만 `correction-agent`를 dispatch한다.
- stop_condition: 동일 classification이 두 번이면 자동 rework를 중단하고 workflow를 `needs-user-decision` 또는 `blocked`로 전환한다. - stop_condition: 동일 classification이 두 번이면 자동 rework를 중단하고 workflow를 `needs-user-decision` 또는 `blocked`로 전환한다.
- correction_cycle_authorization: Root-authorized REWORK-004 correction returned `corrected-for-implementation-rerun`; no further correction is active. If the same nested shell hang recurs under the exact corrected runner and approved launch envelope, stop as `blocked` rather than broadening privileges. - correction_cycle_authorization: REWORK-006 is closed and no correction dispatch is active. Step 1 no-push Harness rerun is authorized under the approved Ninja/MSVC workspace-write envelope; no Step 2 advancement, push, `danger-full-access`, Visual Studio fallback, or reference solver/artifact action is authorized outside Executor-owned progression.
## 7. Final Workflow Closure ## 7. Final Workflow Closure
@@ -269,11 +268,11 @@
## 8. No-Change Assertion ## 8. No-Change Assertion
- source_code: production solver source 변경 없음; earlier Harness repair and REWORK-004 owners modified only `scripts/execute.py` within runner scope. - source_code: Step 1 Implementation Agent left uncommitted production changes in `include/fesa/model/domain.h`, `include/fesa/model/model_types.h`, `src/fesa/io/abaqus/domain_mapping_context.cpp`, and `src/fesa/model/domain.cpp`; Coordinator did not edit source code.
- tests: production C++ tests 변경 없음; earlier Harness repair and REWORK-004 owners modified only `tests/test_execute.py` within Harness Python test scope. - tests: Step 1 Implementation Agent left uncommitted C++ test changes in `tests/unit/io/abaqus/domain_mapper_test.cpp`, `tests/unit/io/abaqus/domain_mapping_components_test.cpp`, `tests/unit/model/domain_test.cpp`, and `tests/unit/model/model_types_test.cpp`; Coordinator did not edit tests.
- CMake: 변경 없음 - CMake: `CMakeLists.txt` 변경 없음; REWORK-006 Correction added tracked `CMakePresets.json` for DECISION-039 Ninja/MSVC validation; Coordinator did not edit CMake configuration.
- reference_artifacts: 생성·수정·rename 없음 - reference_artifacts: 생성·수정·rename 없음
- tolerance_policies: 변경 없음 - tolerance_policies: 변경 없음
- phase_files: user-approved planning owner가 `phases/index.json` pending entry와 `phases/nonlinear-static-newton-raphson/index.json`, `step0.md`..`step12.md`를 materialize함; Executor attempt 2 generated `phases/nonlinear-static-newton-raphson/step0-output.json`; Step 0 remains pending and Coordinator did not edit phase files. - phase_files: Executor/Correction updated `phases/index.json` and `phases/nonlinear-static-newton-raphson/index.json`; Step 0 is completed and committed, Step 1 is reset to `pending` after REWORK-006 blocker-clear evidence, and Steps 2..12 are pending. Coordinator did not edit phase files.
- Harness: Implementation Agent bounded repair와 REWORK-004는 `scripts/execute.py`와 `tests/test_execute.py`에 한정됨; REWORK-004 did not run nonlinear Harness phase, commit or push. Coordinator did not run Harness/phase/build/test; root no-push rerun is now authorized under the approved corrected envelope. - Harness: REWORK-006 Correction updated `.gitignore`, `.harness/config.example.json`, and created ignored `.harness/config.json` for Ninja/MSVC preset selection; no Harness Python production change was required. Coordinator did not run Harness/phase/build/test, advance Step 2, use `danger-full-access`, clean build outputs, commit or push.
- feature_documents: 이번 coordinator update에서는 isolated worktree의 `coordination.md`만 갱신함; Correction Agent가 `docs/nonlinear-static-newton-raphson/corrections.md`를 갱신했고 `implementation-report.md`, `build-test.md`, `reference-comparison.md`는 아직 생성되지 않음 - feature_documents: REWORK-006 Correction updated `docs/nonlinear-static-newton-raphson/corrections.md` SHA-256 `7FA66A14E694D0451B4422BB5A233E117F2100231A9644771EFD428AF7AD6B81` and `implementation-plan.md`; this coordinator update changed only isolated `coordination.md`; `implementation-report.md`, `build-test.md`, `reference-comparison.md` are still absent.
@@ -5,15 +5,15 @@
| key | value | | key | value |
| --- | --- | | --- | --- |
| feature_id | `nonlinear-static-newton-raphson` | | feature_id | `nonlinear-static-newton-raphson` |
| source failure report | `docs/nonlinear-static-newton-raphson/coordination.md`; `phases/nonlinear-static-newton-raphson/step0-output.json` | | source failure report | `docs/nonlinear-static-newton-raphson/coordination.md`; `phases/nonlinear-static-newton-raphson/step0-output.json`; `phases/nonlinear-static-newton-raphson/step1-output.json` |
| source implementation plan | `docs/nonlinear-static-newton-raphson/implementation-plan.md` | | source implementation plan | `docs/nonlinear-static-newton-raphson/implementation-plan.md` |
| status | `corrected-for-implementation-rerun` | | status | `corrected-for-implementation-rerun` |
| owner_agent | `correction-agent` | | owner_agent | `correction-agent` |
| date | `2026-08-24` | | date | `2026-08-24` |
`implementation-report.md`, `build-test.md`, `reference-comparison.md`는 아직 생성되지 않았으므로 현재 Coordinator failure evidence와 Executor의 `step0-output.json`을 source failure report로 사용했다. `implementation-report.md`, `build-test.md`, `reference-comparison.md`는 아직 생성되지 않았으므로 현재 Coordinator failure evidence와 Executor의 `step0-output.json` 및 `step1-output.json`을 source failure report로 사용했다.
Sections 2-6의 Codex `0.147.0` 내용은 initial correction history이며, current REWORK-004 status와 증거는 Sections 7-9가 supersede한다. Sections 2-6의 Codex `0.147.0` 내용은 initial correction history이고 Sections 7-9는 REWORK-004 history다. Section 10은 FileTracker diagnosis history이며 USER-DECISION-002 option A 이후 current correction과 status는 Section 11이 supersede한다.
## 2. Failure Triage ## 2. Failure Triage
@@ -129,3 +129,192 @@ Full Python failure는 기존 `test_agent_toml_and_limited_skill_yaml_schemas_ar
| requirement id | task id | test id | corrected files | acceptance criterion | | requirement id | task id | test id | corrected files | acceptance criterion |
| --- | --- | --- | --- | --- | | --- | --- | --- | --- | --- |
| `FESA-REQ-NSNR-083` | Harness runner correction `REWORK-004`; blocks Step 0 `cli-output-lease-and-derived-names` | `test_invoke_codex_uses_implementation_agent_command_contract` | `scripts/execute.py`; `tests/test_execute.py` | nested Codex argv가 adjacent `--disable`, `unified_exec`를 포함하면서 Terra/xhigh routing을 보존함; passed | | `FESA-REQ-NSNR-083` | Harness runner correction `REWORK-004`; blocks Step 0 `cli-output-lease-and-derived-names` | `test_invoke_codex_uses_implementation_agent_command_contract` | `scripts/execute.py`; `tests/test_execute.py` | nested Codex argv가 adjacent `--disable`, `unified_exec`를 포함하면서 Terra/xhigh routing을 보존함; passed |
## 10. FileTracker Workspace-Write Diagnosis
### 10.1 Metadata
| key | value |
| --- | --- |
| feature_id | `nonlinear-static-newton-raphson` |
| source failure report | `phases/nonlinear-static-newton-raphson/step1-output.json`; `docs/nonlinear-static-newton-raphson/coordination.md` |
| source implementation plan | `docs/nonlinear-static-newton-raphson/implementation-plan.md`; `phases/nonlinear-static-newton-raphson/step1.md` |
| status | `blocked` |
| owner_agent | `correction-agent` |
| date | `2026-08-24` |
### 10.2 Failure Triage
- classification: `harness`
- normalized classification: `harness-msbuild-filetracker-eaccessdenied-workspace-write`
- attempt: `1`
- first failed stage command:
```powershell
cmake --build .harness/build --config Debug
```
- failed target or test: Visual Studio 18 generator의 `fesa_solver.vcxproj`와 GoogleTest `gtest.vcxproj` CL task
- evidence tail: MSBuild `18.8.2`가 `Microsoft.CppCommon.targets(790,5)`에서 `MSB4018`을 냈다. Inner exception은 `System.UnauthorizedAccessException`, HRESULT `0x80070005 (E_ACCESSDENIED)`이며 stack은 `NativeMethods.GetLongFilePath` -> `FileTracker..cctor()` -> `FileTracker.FileIsExcludedFromDependencies` -> `CanonicalTrackedInputFiles.ConstructDependencyTable` -> `CL.ComputeOutOfDateSources`다.
- command-result caveat: `step1-output.json`의 item 25는 build와 CTest를 세미콜론으로 연결해 aggregate exit `0`을 기록했지만, 그 내부 `cmake --build`는 exit `1`로 실패했다. 뒤따른 stale-build CTest 성공은 Visual Studio build 성공 evidence가 아니다.
- configure boundary: 보존된 `.harness/build/CMakeCache.txt`는 `CMAKE_GENERATOR=Visual Studio 18 2026`, platform `x64`다. CMake generation 자체가 아니라 생성된 MSBuild project의 CL dependency-tracking 단계가 실패했다.
### 10.3 Root Cause Summary
FESA source, Step 1 test 또는 CMake registration이 원인이 아니다. 서로 독립적인 FESA와 GoogleTest project가 동일한 `FileTracker` static initializer에서 실패하므로 project-local input보다 sandbox/environment boundary다.
Microsoft의 `FileTracker.cs`는 static initialization에서 `Path.GetTempPath()`를 구한 뒤 그 경로에 `GetShortFilePath`와 `GetLongFilePath`를 적용한다. 관찰 stack의 첫 failing native call과 정확히 일치한다. 현재 inherited `TEMP`/`TMP`는 `C:\Users\baram\AppData\Local\Temp`이고 runner는 이를 재지정하지 않는다. 따라서 Codex Windows `workspace-write` restricted token이 workspace 밖 user Temp의 long-path normalization을 거부한 것이 가장 좁은 root-cause inference다.
- boundary confidence: `high` — 두 project에서 같은 FileTracker initializer/`E_ACCESSDENIED`가 재현됨.
- exact denied-path confidence: `medium-high` — Microsoft source의 static field order와 inherited Temp가 일치하지만 failing API가 path argument를 log하지는 않음.
- implementation classification: environment-owned sandbox/MSBuild interaction; implementation defect, test defect, CMake registration issue가 아님.
검토한 primary vendor evidence:
- Microsoft MSBuild source: `https://github.com/dotnet/msbuild/blob/main/src/Utilities/TrackedDependencies/FileTracker.cs`
- Microsoft CL task documentation: `https://learn.microsoft.com/en-us/visualstudio/msbuild/cl-task?view=visualstudio`
- installed Visual Studio target: `C:\Program Files\Microsoft Visual Studio\18\Community\MSBuild\Microsoft\VC\v180\Microsoft.CppCommon.targets` lines 48-49 and 764-771
- OpenAI Codex sandbox CLI source: `https://github.com/openai/codex/blob/main/codex-rs/cli/src/lib.rs`; built-in writable profile name은 `:workspace`
### 10.4 Correction Scope
- changed report files: `docs/nonlinear-static-newton-raphson/corrections.md`
- changed source/header/test/CMake/runner files: 없음
- preserved dirty Step 1 files: `include/fesa/model/domain.h`, `include/fesa/model/model_types.h`, `src/fesa/io/abaqus/domain_mapping_context.cpp`, `src/fesa/model/domain.cpp`와 관련 unit tests
- preserved workflow files: `docs/nonlinear-static-newton-raphson/coordination.md`, `phases/index.json`, `phases/nonlinear-static-newton-raphson/index.json`
- excluded files: C++/CMake, phase definition/index, coordination, runner, upstream contracts, reference/tolerance artifacts
- prohibited actions not performed: Harness phase rerun, Step 2, build cleanup/deletion, Abaqus/Nastran/reference solver, `danger-full-access`, commit, push
### 10.5 Workaround Evaluation And Verification Evidence
| purpose | exact command/evidence | result |
| --- | --- | --- |
| preserved failure | `cmake --build .harness/build --config Debug` in `step1-output.json` | internal build exit `1`; `FileTracker..cctor()` `E_ACCESSDENIED` in both FESA and gtest |
| supported property inspection | installed `Microsoft.CppCommon.targets`; Microsoft CL task docs | `TrackFileAccess` defaults to `true` and is passed to CL; property is vendor-defined for incremental file-access tracking |
| narrow property smoke | nested `codex exec --sandbox workspace-write ...` requesting exactly `cmake --build .harness/build --config Debug -- /p:TrackFileAccess=false` | 60-second diagnostic timeout before a command completion event; no pass/fail conclusion; exact root PID `13720` and descendants cleaned, then absent |
| direct sandbox launcher check | `codex sandbox -P :workspace -C C:\git\FESADev\.worktrees\nonlinear-static-newton-raphson cmd.exe /d /c echo SANDBOX_OK` | 10-second timeout; no `SANDBOX_OK`; exact root PID `16708` tree cleaned, then absent |
| workspace-write alternative evidence | Visual Studio-bundled Ninja/MSVC build in `step1-output.json` | focused CTest 27/27 and full CTest 228/228 passed |
`/p:TrackFileAccess=false`는 vendor-defined 후보지만 동일 `workspace-write`에서 build completion이 관찰되지 않아 safe workaround로 채택할 수 없다. `TEMP`/`TMP`를 worktree로 재지정하는 후보도 FileTracker가 system-wide Temp를 dependency exclusion 기준으로 사용한다는 Microsoft source comment 때문에 tracking semantics 보존을 입증하지 않고 자동 적용하지 않았다.
Ninja/MSVC는 같은 sandbox에서 implementation/test 건전성을 입증하지만 Step 1 VERIFY가 명시한 `Visual Studio 18 2026` generator acceptance criterion을 대체하지 않는다. 따라서 correction-agent가 phase/upstream contract 변경 없이 자동 채택할 수 없다. `danger-full-access`는 지시대로 실행하거나 시험하지 않았다.
### 10.6 Traceability
| requirement id | task id | test id | failing command | corrected file | acceptance criterion |
| --- | --- | --- | --- | --- | --- |
| `FESA-REQ-NSNR-083` | Step 1 `nonlinear-static-domain-contract`; FileTracker correction attempt 1 | `CORR-HARNESS-FILETRACKER-001` | `cmake --build .harness/build --config Debug` | report only | approved `workspace-write`에서 Visual Studio 18/MSBuild build completion; not met |
| `FESA-REQ-NSNR-083` | same | `CORR-HARNESS-FILETRACKER-002` | same build with `/p:TrackFileAccess=false` | 없음 | vendor-defined property가 FileTracker denial을 제거하고 build를 완료함; completion evidence 없음 |
### 10.7 Handoff Recommendation
- recommendation: `needs-user-decision`; Coordinator Agent에 `blocked` 반환.
- safe automatic correction: 없음. Runner/CMake/Step 1 source를 변경하지 않는다.
- decision option 1: approved implementation plan/phase owner가 Ninja+MSVC를 Visual Studio generator 대체 evidence로 명시적으로 승인한다. 이는 correction-agent 범위 밖의 upstream acceptance 변경이다.
- decision option 2: 사용자가 `docs/HARNESS.md`의 isolated clean-worktree `danger-full-access` fallback을 명시적으로 승인한다. 이번 진단에서는 broader privilege를 사용하거나 시험하지 않았다.
- decision option 3: Codex/Windows sandbox 환경 소유자가 direct `:workspace` launcher와 user Temp long-path access 문제를 수정한 뒤 동일 Visual Studio build를 재검증한다.
### 10.8 Stop Condition
- repeated failure: normalized classification attempt `1`; 같은 classification의 두 번째 자동 rework는 아직 수행하지 않았다.
- environment blocker: direct `:workspace` no-op도 bounded completion을 내지 않아 workspace-only workaround를 신뢰성 있게 검증할 수 없다.
- upstream ambiguity: Ninja acceptance 또는 broader sandbox 권한은 사용자/Coordinator 결정이 필요하다.
- reference artifact gap: 없음; reference artifact는 읽기/수정/생성하지 않았다.
- final stop: safe, vendor-supported, contract-preserving `workspace-write` workaround가 입증되지 않아 code change 없이 `blocked`로 중단한다.
## 11. REWORK-006 Ninja/MSVC Validation Contract Correction
### 11.1 Metadata
| key | value |
| --- | --- |
| feature_id | `nonlinear-static-newton-raphson` |
| source failure report | `phases/nonlinear-static-newton-raphson/step1-output.json`; `docs/nonlinear-static-newton-raphson/coordination.md` USER-DECISION-002 option A / REWORK-006 |
| source implementation plan | `docs/nonlinear-static-newton-raphson/implementation-plan.md`; `phases/nonlinear-static-newton-raphson/step0.md`..`step12.md` |
| status | `corrected-for-implementation-rerun` |
| owner_agent | `correction-agent` |
| date | `2026-08-24` |
### 11.2 Failure Triage
- classification: `harness`
- normalized classification: `harness-msbuild-filetracker-eaccessdenied-workspace-write`
- attempt: `2`, resolved by USER-DECISION-002 option A의 approved validation-contract change
- first failed command: `cmake --build .harness/build --config Debug`
- failed target: Visual Studio generator/MSBuild `FileTracker..cctor()`; Section 10의 `E_ACCESSDENIED`
- replacement acceptance: `workspace-write` 안에서 VsDevCmd x64를 상속한 Ninja/MSVC Debug configure/build, CTest discovery, full CTest가 모두 통과해야 한다.
### 11.3 Root Cause Summary
FESA C++/test/CMake target defect가 아니라 Visual Studio generator의 MSBuild FileTracker와 `workspace-write` sandbox 사이 environment failure였다. User가 option A를 승인했으므로 tracked root `CMakePresets.json`과 existing Harness preset adapter를 사용해 동일 MSVC x64 Debug compiler를 Ninja로 구동한다. Harness Python은 이미 complete preset triplet과 parent environment copy를 지원하므로 production Python 변경은 필요하지 않았다.
### 11.4 Correction Scope
- validation plumbing: `CMakePresets.json`, `.harness/config.example.json`, `.gitignore`, ignored local `.harness/config.json`, `tests/test_harness_preset_contract.py`
- approved validation commands: `docs/nonlinear-static-newton-raphson/implementation-plan.md`, `phases/nonlinear-static-newton-raphson/step0.md`..`step12.md`
- report/status: `docs/nonlinear-static-newton-raphson/corrections.md`, `phases/nonlinear-static-newton-raphson/index.json`; top `phases/index.json`은 blocked payload 제거 후 HEAD와 같은 `pending` 의미로 복원됨
- generated/ignored build output: `.harness/build-ninja-msvc-debug/`; 삭제하거나 cleanup하지 않았다.
- production Harness Python, runner, C++, CMakeLists, upstream physics/I/O/reference/tolerance contract: 변경 없음
- preserved others' dirty files: Step 1 C++/unit tests와 Coordinator-owned `coordination.md`를 되돌리거나 덮어쓰지 않았다.
### 11.5 RED -> GREEN Evidence
| stage | command | result |
| --- | --- | --- |
| RED-1 | `uv run --with pytest python -m pytest -v -rs tests/test_harness_preset_contract.py` | exit `1`; `CMakePresets.json` `FileNotFoundError` |
| GREEN-1 | same focused command after preset/example/local config | exit `0`; 1 passed |
| RED-2 | `uv run --with pytest python -m pytest -q tests/test_harness_preset_contract.py` after adding generated-build ignore assertion | exit `1`; `.harness/build-ninja-msvc-debug/` rule absent |
| GREEN-2 | focused verbose command after `.gitignore` update | exit `0`; 1 passed; `git check-ignore` confirms config and build output |
Contract details:
- preset: `windows-msvc-ninja-debug`
- generator/configuration: `Ninja`, `CMAKE_BUILD_TYPE=Debug`
- binary directory: `.harness/build-ninja-msvc-debug`
- cache variables: `FESA_GTEST_SOURCE_DIR`, `MKL_DIR`, `TBB_DIR`, `HDF5_DIR` use `$env{...}` and therefore fail closed when the parent launch envelope is incomplete.
- `.harness/config.json` is ignored and byte-identical to `.harness/config.example.json`; both SHA-256 `D07429860D472AE37D02D6CD638900FA46175085AF47F179E98601227F8D3C43` at verification.
### 11.6 Verification Evidence
Exact nested launch envelope:
```powershell
VsDevCmd.bat -arch=x64 -host_arch=x64
$env:FESA_GTEST_SOURCE_DIR='C:/git/googletest'
$env:MKL_DIR='C:/Program Files (x86)/Intel/oneAPI/mkl/2026.1/lib/cmake/mkl'
$env:TBB_DIR='C:/Program Files (x86)/Intel/oneAPI/tbb/2023.1/lib/cmake/tbb'
$env:HDF5_DIR='C:/Program Files/HDF_Group/HDF5/2.1.1/cmake'
codex exec --ephemeral --json --sandbox workspace-write --disable unified_exec --dangerously-bypass-hook-trust -m gpt-5.6-terra -c 'model_reasoning_effort="xhigh"' -C C:\git\FESADev\.worktrees\nonlinear-static-newton-raphson <bounded-validation-prompt>
```
`CODEX_HOME=C:\Users\baram\.codex`를 상속하고 approved WindowsApps PATH entries를 child launch에서만 제거했다. `danger-full-access`와 sandbox bypass option은 사용하지 않았고 project hooks는 유지했다.
| verify item | exact command/evidence | result |
| --- | --- | --- |
| environment preflight | nested shell prints architecture, four variables, `cl.exe`, `ninja.exe` | exit `0`; target/host `x64`; `cl.exe` Hostx64/x64; VS-bundled Ninja; all dependency paths exist |
| configure | `cmake --preset windows-msvc-ninja-debug` | exit `0` |
| build | `cmake --build --preset windows-msvc-ninja-debug` | exit `0` |
| discovery | `ctest --preset windows-msvc-ninja-debug --show-only=json-v1` | exit `0`; 228 tests |
| full CTest | `ctest --preset windows-msvc-ninja-debug --output-on-failure` | exit `0`; 228/228 passed; 10.69초 |
| generated metadata | `.harness/build-ninja-msvc-debug/CMakeCache.txt`와 `CMakeCXXCompiler.cmake` | `Ninja`; `Debug`; compiler ID `MSVC`; Hostx64/x64 `cl.exe` |
| Stop | hooks-retained nested `codex exec` completion | overall exit `0`; no Stop blocking response; automatic Stop uses ignored config's same preset plan |
| full Harness Python | `uv run --with pytest python -m pytest -v -rs` | 24 passed, 1 pre-existing out-of-scope failure: actual `xhigh` vs expected `extra high` |
첫 cold workspace run은 full CTest에서 temporary `fesa_reference_tests_NOT_BUILT`로 207/208만 통과해 blocker-clear로 사용하지 않았고 phase도 reset하지 않았다. Automatic hooks가 missing target build를 완료한 뒤 두 번째 independent nested `workspace-write` run에서 위 228/228 evidence를 확보한 다음에만 phase를 reset했다.
Reference artifact no-change evidence: `git diff --name-only -- reference`는 empty였다. `shellNL.inp`, shellNL displacement/reaction/stress CSV와 shell input/displacement/reaction/stress CSV의 SHA-256은 implementation-plan inventory와 모두 일치한다. Reference solver와 feature Harness phase는 실행하지 않았다.
### 11.7 Traceability
| requirement id | task id | test id | failing command | corrected file | acceptance criterion |
| --- | --- | --- | --- | --- | --- |
| `FESA-REQ-NSNR-083` | `REWORK-006`; Steps 0..12 validation contract | `CORR-HARNESS-PRESET-001` | Visual Studio/MSBuild build | `CMakePresets.json`; `.harness/config.example.json`; `.gitignore`; `tests/test_harness_preset_contract.py` | tracked Ninja/MSVC preset and Harness plan select MSVC/x64/Debug under `workspace-write` |
| `FESA-REQ-NSNR-083` | same | `CORR-HARNESS-PRESET-VERIFY-001` | preset configure/build/discovery/full CTest | implementation plan and `step0.md`..`step12.md` | nested env preflight plus 228/228 CTest pass |
### 11.8 Handoff Recommendation And Stop Condition
- recommendation: Coordinator를 통해 Implementation Agent에 Step 1 no-push rerun을 요청한다; Step 2로 advance하지 않는다.
- phase state after evidence: top phase `pending`; Step 1 `pending`, historical `started_at` 보존; `blocked_reason`과 `blocked_at`만 제거; Steps 2..12 remain `pending`.
- status: `corrected-for-implementation-rerun`.
- blockers: 이 correction 범위에는 없음. Existing Python `xhigh`/`extra high` mismatch는 명시된 out-of-scope pre-existing failure다.
- prohibited actions not performed: Harness phase rerun, Step 2, `danger-full-access`, push, commit, reference solver/artifact mutation, build cleanup/deletion.
@@ -43,7 +43,7 @@
- Missing decisions: none. - Missing decisions: none.
- Missing required comparison files: none for declared blocking/reference families. - Missing required comparison files: none for declared blocking/reference families.
- Planning can proceed: yes. - Planning can proceed: yes.
- `.harness/config.json`: absent during planning inspection. Each Step must recheck at execution time and use it first if it appears. - `CMakePresets.json` tracks the approved `windows-msvc-ninja-debug` contract. The ignored `.harness/config.json` selects the matching configure/build/test presets and `.harness/build-ninja-msvc-debug` binary directory.
## Global Constraints ## Global Constraints
@@ -56,6 +56,7 @@
- Implementation and Harness execution remain unauthorized by this materialized plan until the user separately requests Executor execution. - Implementation and Harness execution remain unauthorized by this materialized plan until the user separately requests Executor execution.
- Preserve source label/instance identity, deterministic row order, deterministic diagnostics, finite checks, and docs/TOLERANCE.md exactly. - Preserve source label/instance identity, deterministic row order, deterministic diagnostics, finite checks, and docs/TOLERANCE.md exactly.
- Preserve `U1/U2/U3` blocking and `UR1/UR2/UR3` warning-only. For shellNL, preserve constrained `RF1/RF2`, `RF3`, physical spatial `RM1/RM2` blocking, and exclude `RM3` plus stress from numeric comparison. - Preserve `U1/U2/U3` blocking and `UR1/UR2/UR3` warning-only. For shellNL, preserve constrained `RF1/RF2`, `RF3`, physical spatial `RM1/RM2` blocking, and exclude `RM3` plus stress from numeric comparison.
- Launch every Harness process from VsDevCmd with `-arch=x64 -host_arch=x64` and inherit `FESA_GTEST_SOURCE_DIR`, `MKL_DIR`, `TBB_DIR`, and `HDF5_DIR`. The tracked preset selects Ninja and MSVC Debug without hard-coding machine-local dependency paths.
## Repository Seam Map ## Repository Seam Map
@@ -113,19 +114,15 @@
- Add C++ sources to `src/fesa/CMakeLists.txt` under existing `fesa_solver`. - Add C++ sources to `src/fesa/CMakeLists.txt` under existing `fesa_solver`.
- Add unit tests to `fesa_unit_tests`, integration tests to `fesa_integration_tests`, reference tests to `fesa_reference_tests`. - Add unit tests to `fesa_unit_tests`, integration tests to `fesa_integration_tests`, reference tests to `fesa_reference_tests`.
- Preserve current executable-wide labels. Use focused regex such as `ctest --test-dir .harness/build -C Debug -R "NonlinearStaticReference|ReferenceTolerance|Mitc4Reference" --output-on-failure`. - Preserve current executable-wide labels. Use focused regex such as `ctest --preset windows-msvc-ninja-debug -R "NonlinearStaticReference|ReferenceTolerance|Mitc4Reference" --output-on-failure`.
- If scoped per-test labels are introduced, the Step that introduces the mechanism must test it and avoid changing labels for unrelated discovered tests. - If scoped per-test labels are introduced, the Step that introduces the mechanism must test it and avoid changing labels for unrelated discovered tests.
- Configure/build/test commands: - Configure/build/test commands:
```powershell ```powershell
cmake --fresh -S . -B .harness/build -G "Visual Studio 18 2026" -A x64 ` cmake --preset windows-msvc-ninja-debug
"-DFESA_GTEST_SOURCE_DIR=$gtestSource" ` cmake --build --preset windows-msvc-ninja-debug
"-DMKL_DIR=$mklDir" ` ctest --preset windows-msvc-ninja-debug --show-only=json-v1
"-DTBB_DIR=$tbbDir" ` ctest --preset windows-msvc-ninja-debug --output-on-failure
"-DHDF5_DIR=$hdf5Dir"
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure
``` ```
## Data Flow Contract ## Data Flow Contract
@@ -218,18 +215,15 @@ Step 11 must not run original reference input paths directly. It snapshots exact
Each Step must: Each Step must:
1. Recheck `.harness/config.json`. If present, use the configured Harness build/test commands. 1. Use the ignored `.harness/config.json` preset contract and tracked `CMakePresets.json`.
2. If absent, use: 2. Confirm the Harness parent environment was initialized by VsDevCmd x64 and contains `FESA_GTEST_SOURCE_DIR`, `MKL_DIR`, `TBB_DIR`, and `HDF5_DIR`.
3. Run:
```powershell ```powershell
cmake --fresh -S . -B .harness/build -G "Visual Studio 18 2026" -A x64 ` cmake --preset windows-msvc-ninja-debug
"-DFESA_GTEST_SOURCE_DIR=$gtestSource" ` cmake --build --preset windows-msvc-ninja-debug
"-DMKL_DIR=$mklDir" ` ctest --preset windows-msvc-ninja-debug --show-only=json-v1
"-DTBB_DIR=$tbbDir" ` ctest --preset windows-msvc-ninja-debug --output-on-failure
"-DHDF5_DIR=$hdf5Dir"
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure
``` ```
Focused CTest commands are written explicitly in each `stepN.md`. Focused CTest commands are written explicitly in each `stepN.md`.
+8
View File
@@ -74,6 +74,12 @@ class StepDefinition {
const DomainCollectionView<ConcentratedNodalLoad>& ConcentratedLoads() const DomainCollectionView<ConcentratedNodalLoad>& ConcentratedLoads()
const noexcept; const noexcept;
/// @brief Returns the approved static procedure identity.
StaticProcedureKind ProcedureKind() const noexcept;
/// @brief Reports whether this step uses the nonlinear static procedure.
bool IsNonlinearStatic() const noexcept;
/// @brief Returns the static initial increment provenance value. /// @brief Returns the static initial increment provenance value.
double InitialIncrement() const noexcept; double InitialIncrement() const noexcept;
@@ -103,6 +109,8 @@ class StepDefinition {
std::vector<std::unique_ptr<Load>> loads_; std::vector<std::unique_ptr<Load>> loads_;
LoadView loads_view_; LoadView loads_view_;
DomainCollectionView<ConcentratedNodalLoad> concentrated_loads_view_; DomainCollectionView<ConcentratedNodalLoad> concentrated_loads_view_;
StaticProcedureKind procedure_kind_;
bool nlgeom_;
double initial_increment_; double initial_increment_;
double time_period_; double time_period_;
double minimum_increment_; double minimum_increment_;
+50 -1
View File
@@ -7,6 +7,7 @@
#include <optional> #include <optional>
#include <string> #include <string>
#include <string_view> #include <string_view>
#include <utility>
#include <vector> #include <vector>
#include "fesa/core/diagnostic.h" #include "fesa/core/diagnostic.h"
@@ -52,11 +53,59 @@ struct NodalLoad {
SourceLocation location; SourceLocation location;
}; };
/// @brief Stores the approved single linear-static step definition. /// @brief Identifies the approved static procedure semantics for one step.
enum class StaticProcedureKind {
kLinearSmallDisplacement,
kNonlinearFullNewton
};
/// @brief Stores the approved single static step definition.
struct StaticStepDefinition { struct StaticStepDefinition {
/// @brief Creates a static step with its mapped procedure identity.
StaticStepDefinition(
std::string step_name,
std::vector<PrescribedDisplacementDefinition> step_boundaries,
std::vector<NodalLoad> step_loads,
StaticProcedureKind step_procedure_kind,
bool step_nlgeom,
double step_initial_increment,
double step_time_period,
double step_minimum_increment,
double step_maximum_increment,
SourceLocation step_location)
: name{std::move(step_name)},
boundaries{std::move(step_boundaries)},
loads{std::move(step_loads)},
procedure_kind{step_procedure_kind},
nlgeom{step_nlgeom},
initial_increment{step_initial_increment},
time_period{step_time_period},
minimum_increment{step_minimum_increment},
maximum_increment{step_maximum_increment},
location{std::move(step_location)} {}
/// @brief Creates a legacy linear static step definition.
StaticStepDefinition(
std::string step_name,
std::vector<PrescribedDisplacementDefinition> step_boundaries,
std::vector<NodalLoad> step_loads,
double step_initial_increment,
double step_time_period,
double step_minimum_increment,
double step_maximum_increment,
SourceLocation step_location)
: StaticStepDefinition(
std::move(step_name), std::move(step_boundaries),
std::move(step_loads),
StaticProcedureKind::kLinearSmallDisplacement, false,
step_initial_increment, step_time_period, step_minimum_increment,
step_maximum_increment, std::move(step_location)) {}
std::string name; std::string name;
std::vector<PrescribedDisplacementDefinition> boundaries; std::vector<PrescribedDisplacementDefinition> boundaries;
std::vector<NodalLoad> loads; std::vector<NodalLoad> loads;
StaticProcedureKind procedure_kind;
bool nlgeom;
double initial_increment; double initial_increment;
double time_period; double time_period;
double minimum_increment; double minimum_increment;
@@ -95,8 +95,8 @@ struct AnalysisRequest {
실행: 실행:
```powershell ```powershell
cmake --build .harness/build --config Debug cmake --build --preset windows-msvc-ninja-debug
ctest --test-dir .harness/build -C Debug -R "FesaApplication|OutputPath" --output-on-failure ctest --preset windows-msvc-ninja-debug -R "FesaApplication|OutputPath" --output-on-failure
``` ```
기대: 새 테스트가 컴파일 실패 또는 assertion 실패로 실패한다. 새 테스트가 예상 없이 통과하면 구현을 중단하고 Coordinator에게 보고한다. 기대: 새 테스트가 컴파일 실패 또는 assertion 실패로 실패한다. 새 테스트가 예상 없이 통과하면 구현을 중단하고 Coordinator에게 보고한다.
@@ -110,18 +110,14 @@ ctest --test-dir .harness/build -C Debug -R "FesaApplication|OutputPath" --outpu
## VERIFY ## VERIFY
실행 전 `Test-Path .harness\config.json`으로 Harness config를 재확인한다. 있으면 그 설정을 우선한다. 없으면 다음 순서로 실행한다. Use the ignored `.harness/config.json` preset contract. The Harness process must inherit VsDevCmd x64 and `FESA_GTEST_SOURCE_DIR`, `MKL_DIR`, `TBB_DIR`, and `HDF5_DIR` from its parent launch environment. Run:
```powershell ```powershell
cmake --fresh -S . -B .harness/build -G "Visual Studio 18 2026" -A x64 ` cmake --preset windows-msvc-ninja-debug
"-DFESA_GTEST_SOURCE_DIR=$gtestSource" ` cmake --build --preset windows-msvc-ninja-debug
"-DMKL_DIR=$mklDir" ` ctest --preset windows-msvc-ninja-debug -R "FesaApplication|OutputPath" --output-on-failure
"-DTBB_DIR=$tbbDir" ` ctest --preset windows-msvc-ninja-debug --show-only=json-v1
"-DHDF5_DIR=$hdf5Dir" ctest --preset windows-msvc-ninja-debug --output-on-failure
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug -R "FesaApplication|OutputPath" --output-on-failure
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure
``` ```
## 상태 기록 ## 상태 기록
@@ -95,8 +95,8 @@ Add tests first.
Run: Run:
```powershell ```powershell
cmake --build .harness/build --config Debug cmake --build --preset windows-msvc-ninja-debug
ctest --test-dir .harness/build -C Debug -R "Domain|DomainMapping|Abaqus" --output-on-failure ctest --preset windows-msvc-ninja-debug -R "Domain|DomainMapping|Abaqus" --output-on-failure
``` ```
Expected: new tests fail. Unexpected pass stops the Step. Expected: new tests fail. Unexpected pass stops the Step.
@@ -111,18 +111,14 @@ Expected: new tests fail. Unexpected pass stops the Step.
## VERIFY ## VERIFY
```powershell ```powershell
cmake --fresh -S . -B .harness/build -G "Visual Studio 18 2026" -A x64 ` cmake --preset windows-msvc-ninja-debug
"-DFESA_GTEST_SOURCE_DIR=$gtestSource" ` cmake --build --preset windows-msvc-ninja-debug
"-DMKL_DIR=$mklDir" ` ctest --preset windows-msvc-ninja-debug -R "Domain|DomainMapping|Abaqus" --output-on-failure
"-DTBB_DIR=$tbbDir" ` ctest --preset windows-msvc-ninja-debug --show-only=json-v1
"-DHDF5_DIR=$hdf5Dir" ctest --preset windows-msvc-ninja-debug --output-on-failure
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug -R "Domain|DomainMapping|Abaqus" --output-on-failure
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure
``` ```
Recheck `.harness/config.json` before using these defaults. Use the ignored `.harness/config.json` preset contract. The Harness process must inherit VsDevCmd x64 and `FESA_GTEST_SOURCE_DIR`, `MKL_DIR`, `TBB_DIR`, and `HDF5_DIR` from its parent launch environment.
## 상태 기록 ## 상태 기록
@@ -137,8 +137,8 @@ Add tests first.
Run: Run:
```powershell ```powershell
cmake --build .harness/build --config Debug cmake --build --preset windows-msvc-ninja-debug
ctest --test-dir .harness/build -C Debug -R "LinearStaticAnalysis|NonlinearStaticProcedure|FesaApplication" --output-on-failure ctest --preset windows-msvc-ninja-debug -R "LinearStaticAnalysis|NonlinearStaticProcedure|FesaApplication" --output-on-failure
``` ```
Expected: new tests fail. Unexpected pass stops. Expected: new tests fail. Unexpected pass stops.
@@ -150,18 +150,14 @@ Refactor current parse/map and linear compute/recovery out of `LinearStaticAnaly
## VERIFY ## VERIFY
```powershell ```powershell
cmake --fresh -S . -B .harness/build -G "Visual Studio 18 2026" -A x64 ` cmake --preset windows-msvc-ninja-debug
"-DFESA_GTEST_SOURCE_DIR=$gtestSource" ` cmake --build --preset windows-msvc-ninja-debug
"-DMKL_DIR=$mklDir" ` ctest --preset windows-msvc-ninja-debug -R "LinearStaticAnalysis|NonlinearStaticProcedure|FesaApplication" --output-on-failure
"-DTBB_DIR=$tbbDir" ` ctest --preset windows-msvc-ninja-debug --show-only=json-v1
"-DHDF5_DIR=$hdf5Dir" ctest --preset windows-msvc-ninja-debug --output-on-failure
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug -R "LinearStaticAnalysis|NonlinearStaticProcedure|FesaApplication" --output-on-failure
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure
``` ```
Recheck `.harness/config.json` before default commands. Use the ignored `.harness/config.json` preset contract. The Harness process must inherit VsDevCmd x64 and `FESA_GTEST_SOURCE_DIR`, `MKL_DIR`, `TBB_DIR`, and `HDF5_DIR` from its parent launch environment.
## 상태 기록 ## 상태 기록
@@ -139,8 +139,8 @@ Add tests first.
Run: Run:
```powershell ```powershell
cmake --build .harness/build --config Debug cmake --build --preset windows-msvc-ninja-debug
ctest --test-dir .harness/build -C Debug -R "NonlinearStaticReference|ReferenceTolerance|Mitc4Reference" --output-on-failure ctest --preset windows-msvc-ninja-debug -R "NonlinearStaticReference|ReferenceTolerance|Mitc4Reference" --output-on-failure
``` ```
Expected: new tests fail. Unexpected pass stops. Expected: new tests fail. Unexpected pass stops.
@@ -165,18 +165,14 @@ Use docs/TOLERANCE.md exactly: family scale `S=max(abs(reference))`, near-zero b
## VERIFY ## VERIFY
```powershell ```powershell
cmake --fresh -S . -B .harness/build -G "Visual Studio 18 2026" -A x64 ` cmake --preset windows-msvc-ninja-debug
"-DFESA_GTEST_SOURCE_DIR=$gtestSource" ` cmake --build --preset windows-msvc-ninja-debug
"-DMKL_DIR=$mklDir" ` ctest --preset windows-msvc-ninja-debug -R "NonlinearStaticReference|ReferenceTolerance|Mitc4Reference" --output-on-failure
"-DTBB_DIR=$tbbDir" ` ctest --preset windows-msvc-ninja-debug --show-only=json-v1
"-DHDF5_DIR=$hdf5Dir" ctest --preset windows-msvc-ninja-debug --output-on-failure
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug -R "NonlinearStaticReference|ReferenceTolerance|Mitc4Reference" --output-on-failure
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure
``` ```
Recheck `.harness/config.json` before default commands. Use the ignored `.harness/config.json` preset contract. The Harness process must inherit VsDevCmd x64 and `FESA_GTEST_SOURCE_DIR`, `MKL_DIR`, `TBB_DIR`, and `HDF5_DIR` from its parent launch environment.
## 상태 기록 ## 상태 기록
@@ -66,18 +66,14 @@ Expected: evidence freshness audit fails before this Step writes docs. If it une
## VERIFY ## VERIFY
Recheck `.harness/config.json`. If absent, use: Use the ignored `.harness/config.json` preset contract. The Harness process must inherit VsDevCmd x64 and `FESA_GTEST_SOURCE_DIR`, `MKL_DIR`, `TBB_DIR`, and `HDF5_DIR` from its parent launch environment. Run:
```powershell ```powershell
cmake --fresh -S . -B .harness/build -G "Visual Studio 18 2026" -A x64 ` cmake --preset windows-msvc-ninja-debug
"-DFESA_GTEST_SOURCE_DIR=$gtestSource" ` cmake --build --preset windows-msvc-ninja-debug
"-DMKL_DIR=$mklDir" ` ctest --preset windows-msvc-ninja-debug --show-only=json-v1
"-DTBB_DIR=$tbbDir" ` ctest --preset windows-msvc-ninja-debug --output-on-failure
"-DHDF5_DIR=$hdf5Dir" ctest --preset windows-msvc-ninja-debug -R "NonlinearStaticReference" --output-on-failure
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure
ctest --test-dir .harness/build -C Debug -R "NonlinearStaticReference" --output-on-failure
git diff --check git diff --check
git status --short git status --short
``` ```
@@ -64,8 +64,8 @@ Add tests first.
Run: Run:
```powershell ```powershell
cmake --build .harness/build --config Debug cmake --build --preset windows-msvc-ninja-debug
ctest --test-dir .harness/build -C Debug -R "FiniteRotation" --output-on-failure ctest --preset windows-msvc-ninja-debug -R "FiniteRotation" --output-on-failure
``` ```
Expected: tests fail because the rotation module does not exist. Unexpected pass stops. Expected: tests fail because the rotation module does not exist. Unexpected pass stops.
@@ -77,18 +77,14 @@ Implement the SO(3) helper functions with finite checks and principal-branch val
## VERIFY ## VERIFY
```powershell ```powershell
cmake --fresh -S . -B .harness/build -G "Visual Studio 18 2026" -A x64 ` cmake --preset windows-msvc-ninja-debug
"-DFESA_GTEST_SOURCE_DIR=$gtestSource" ` cmake --build --preset windows-msvc-ninja-debug
"-DMKL_DIR=$mklDir" ` ctest --preset windows-msvc-ninja-debug -R "FiniteRotation" --output-on-failure
"-DTBB_DIR=$tbbDir" ` ctest --preset windows-msvc-ninja-debug --show-only=json-v1
"-DHDF5_DIR=$hdf5Dir" ctest --preset windows-msvc-ninja-debug --output-on-failure
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug -R "FiniteRotation" --output-on-failure
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure
``` ```
Recheck `.harness/config.json` before using default commands. Use the ignored `.harness/config.json` preset contract. The Harness process must inherit VsDevCmd x64 and `FESA_GTEST_SOURCE_DIR`, `MKL_DIR`, `TBB_DIR`, and `HDF5_DIR` from its parent launch environment.
## 상태 기록 ## 상태 기록
@@ -87,8 +87,8 @@ Add tests first.
Run: Run:
```powershell ```powershell
cmake --build .harness/build --config Debug cmake --build --preset windows-msvc-ninja-debug
ctest --test-dir .harness/build -C Debug -R "NonlinearMitc4Shell|NonlinearMitc4Recovery" --output-on-failure ctest --preset windows-msvc-ninja-debug -R "NonlinearMitc4Shell|NonlinearMitc4Recovery" --output-on-failure
``` ```
Expected: compile or test failure because nonlinear MITC4 files do not exist. Unexpected pass stops. Expected: compile or test failure because nonlinear MITC4 files do not exist. Unexpected pass stops.
@@ -100,18 +100,14 @@ Implement nonlinear MITC4 creation, kinematics, and recovery using approved 2x2x
## VERIFY ## VERIFY
```powershell ```powershell
cmake --fresh -S . -B .harness/build -G "Visual Studio 18 2026" -A x64 ` cmake --preset windows-msvc-ninja-debug
"-DFESA_GTEST_SOURCE_DIR=$gtestSource" ` cmake --build --preset windows-msvc-ninja-debug
"-DMKL_DIR=$mklDir" ` ctest --preset windows-msvc-ninja-debug -R "NonlinearMitc4Shell|NonlinearMitc4Recovery" --output-on-failure
"-DTBB_DIR=$tbbDir" ` ctest --preset windows-msvc-ninja-debug --show-only=json-v1
"-DHDF5_DIR=$hdf5Dir" ctest --preset windows-msvc-ninja-debug --output-on-failure
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug -R "NonlinearMitc4Shell|NonlinearMitc4Recovery" --output-on-failure
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure
``` ```
Recheck `.harness/config.json` before default commands. Use the ignored `.harness/config.json` preset contract. The Harness process must inherit VsDevCmd x64 and `FESA_GTEST_SOURCE_DIR`, `MKL_DIR`, `TBB_DIR`, and `HDF5_DIR` from its parent launch environment.
## 상태 기록 ## 상태 기록
@@ -61,8 +61,8 @@ Add tests first.
Run: Run:
```powershell ```powershell
cmake --build .harness/build --config Debug cmake --build --preset windows-msvc-ninja-debug
ctest --test-dir .harness/build -C Debug -R "NonlinearMitc4Residual|NonlinearMitc4Tangent|NonlinearMitc4Objectivity|NonlinearMitc4Patch" --output-on-failure ctest --preset windows-msvc-ninja-debug -R "NonlinearMitc4Residual|NonlinearMitc4Tangent|NonlinearMitc4Objectivity|NonlinearMitc4Patch" --output-on-failure
``` ```
Expected: new tests fail. Unexpected pass stops. Expected: new tests fail. Unexpected pass stops.
@@ -74,18 +74,14 @@ Implement same-trial internal residual/tangent, exact rotation derivative terms
## VERIFY ## VERIFY
```powershell ```powershell
cmake --fresh -S . -B .harness/build -G "Visual Studio 18 2026" -A x64 ` cmake --preset windows-msvc-ninja-debug
"-DFESA_GTEST_SOURCE_DIR=$gtestSource" ` cmake --build --preset windows-msvc-ninja-debug
"-DMKL_DIR=$mklDir" ` ctest --preset windows-msvc-ninja-debug -R "NonlinearMitc4Residual|NonlinearMitc4Tangent|NonlinearMitc4Objectivity|NonlinearMitc4Patch" --output-on-failure
"-DTBB_DIR=$tbbDir" ` ctest --preset windows-msvc-ninja-debug --show-only=json-v1
"-DHDF5_DIR=$hdf5Dir" ctest --preset windows-msvc-ninja-debug --output-on-failure
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug -R "NonlinearMitc4Residual|NonlinearMitc4Tangent|NonlinearMitc4Objectivity|NonlinearMitc4Patch" --output-on-failure
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure
``` ```
Recheck `.harness/config.json` before default commands. Use the ignored `.harness/config.json` preset contract. The Harness process must inherit VsDevCmd x64 and `FESA_GTEST_SOURCE_DIR`, `MKL_DIR`, `TBB_DIR`, and `HDF5_DIR` from its parent launch environment.
## 상태 기록 ## 상태 기록
@@ -139,8 +139,8 @@ Add tests first.
Run: Run:
```powershell ```powershell
cmake --build .harness/build --config Debug cmake --build --preset windows-msvc-ninja-debug
ctest --test-dir .harness/build -C Debug -R "NonlinearStaticControl|NonlinearConvergence|NonlinearLoadBoundary" --output-on-failure ctest --preset windows-msvc-ninja-debug -R "NonlinearStaticControl|NonlinearConvergence|NonlinearLoadBoundary" --output-on-failure
``` ```
Expected: new tests fail. Unexpected pass stops. Expected: new tests fail. Unexpected pass stops.
@@ -152,18 +152,14 @@ Implement factor sequence derivation, load/BC scaling, global-once fixed-load ex
## VERIFY ## VERIFY
```powershell ```powershell
cmake --fresh -S . -B .harness/build -G "Visual Studio 18 2026" -A x64 ` cmake --preset windows-msvc-ninja-debug
"-DFESA_GTEST_SOURCE_DIR=$gtestSource" ` cmake --build --preset windows-msvc-ninja-debug
"-DMKL_DIR=$mklDir" ` ctest --preset windows-msvc-ninja-debug -R "NonlinearStaticControl|NonlinearConvergence|NonlinearLoadBoundary" --output-on-failure
"-DTBB_DIR=$tbbDir" ` ctest --preset windows-msvc-ninja-debug --show-only=json-v1
"-DHDF5_DIR=$hdf5Dir" ctest --preset windows-msvc-ninja-debug --output-on-failure
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug -R "NonlinearStaticControl|NonlinearConvergence|NonlinearLoadBoundary" --output-on-failure
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure
``` ```
Recheck `.harness/config.json` before default commands. Use the ignored `.harness/config.json` preset contract. The Harness process must inherit VsDevCmd x64 and `FESA_GTEST_SOURCE_DIR`, `MKL_DIR`, `TBB_DIR`, and `HDF5_DIR` from its parent launch environment.
## 상태 기록 ## 상태 기록
@@ -68,8 +68,8 @@ Add tests first.
Run: Run:
```powershell ```powershell
cmake --build .harness/build --config Debug cmake --build --preset windows-msvc-ninja-debug
ctest --test-dir .harness/build -C Debug -R "TangentSolver|MklPardiso" --output-on-failure ctest --preset windows-msvc-ninja-debug -R "TangentSolver|MklPardiso" --output-on-failure
``` ```
Expected: new tests fail. Unexpected pass stops. Expected: new tests fail. Unexpected pass stops.
@@ -81,18 +81,14 @@ Implement backend-neutral tangent solver boundary and MKL full-CSR adapter. Fact
## VERIFY ## VERIFY
```powershell ```powershell
cmake --fresh -S . -B .harness/build -G "Visual Studio 18 2026" -A x64 ` cmake --preset windows-msvc-ninja-debug
"-DFESA_GTEST_SOURCE_DIR=$gtestSource" ` cmake --build --preset windows-msvc-ninja-debug
"-DMKL_DIR=$mklDir" ` ctest --preset windows-msvc-ninja-debug -R "TangentSolver|MklPardiso" --output-on-failure
"-DTBB_DIR=$tbbDir" ` ctest --preset windows-msvc-ninja-debug --show-only=json-v1
"-DHDF5_DIR=$hdf5Dir" ctest --preset windows-msvc-ninja-debug --output-on-failure
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug -R "TangentSolver|MklPardiso" --output-on-failure
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure
``` ```
Recheck `.harness/config.json` before default commands. Use the ignored `.harness/config.json` preset contract. The Harness process must inherit VsDevCmd x64 and `FESA_GTEST_SOURCE_DIR`, `MKL_DIR`, `TBB_DIR`, and `HDF5_DIR` from its parent launch environment.
## 상태 기록 ## 상태 기록
@@ -94,8 +94,8 @@ Add tests first.
Run: Run:
```powershell ```powershell
cmake --build .harness/build --config Debug cmake --build --preset windows-msvc-ninja-debug
ctest --test-dir .harness/build -C Debug -R "NewtonIterationLog" --output-on-failure ctest --preset windows-msvc-ninja-debug -R "NewtonIterationLog" --output-on-failure
``` ```
Expected: new tests fail. Unexpected pass stops. Expected: new tests fail. Unexpected pass stops.
@@ -107,18 +107,14 @@ Implement a small log writer with explicit open/write/flush/close state, seriali
## VERIFY ## VERIFY
```powershell ```powershell
cmake --fresh -S . -B .harness/build -G "Visual Studio 18 2026" -A x64 ` cmake --preset windows-msvc-ninja-debug
"-DFESA_GTEST_SOURCE_DIR=$gtestSource" ` cmake --build --preset windows-msvc-ninja-debug
"-DMKL_DIR=$mklDir" ` ctest --preset windows-msvc-ninja-debug -R "NewtonIterationLog" --output-on-failure
"-DTBB_DIR=$tbbDir" ` ctest --preset windows-msvc-ninja-debug --show-only=json-v1
"-DHDF5_DIR=$hdf5Dir" ctest --preset windows-msvc-ninja-debug --output-on-failure
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug -R "NewtonIterationLog" --output-on-failure
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure
``` ```
Recheck `.harness/config.json` before default commands. Use the ignored `.harness/config.json` preset contract. The Harness process must inherit VsDevCmd x64 and `FESA_GTEST_SOURCE_DIR`, `MKL_DIR`, `TBB_DIR`, and `HDF5_DIR` from its parent launch environment.
## 상태 기록 ## 상태 기록
@@ -130,8 +130,8 @@ Add tests first.
Run: Run:
```powershell ```powershell
cmake --build .harness/build --config Debug cmake --build --preset windows-msvc-ninja-debug
ctest --test-dir .harness/build -C Debug -R "NonlinearAnalysisState|CommitRollback" --output-on-failure ctest --preset windows-msvc-ninja-debug -R "NonlinearAnalysisState|CommitRollback" --output-on-failure
``` ```
Expected: new tests fail. Unexpected pass stops. Expected: new tests fail. Unexpected pass stops.
@@ -143,18 +143,14 @@ Implement `NonlinearAnalysisState::Create` as the only construction seam for a v
## VERIFY ## VERIFY
```powershell ```powershell
cmake --fresh -S . -B .harness/build -G "Visual Studio 18 2026" -A x64 ` cmake --preset windows-msvc-ninja-debug
"-DFESA_GTEST_SOURCE_DIR=$gtestSource" ` cmake --build --preset windows-msvc-ninja-debug
"-DMKL_DIR=$mklDir" ` ctest --preset windows-msvc-ninja-debug -R "NonlinearAnalysisState|CommitRollback" --output-on-failure
"-DTBB_DIR=$tbbDir" ` ctest --preset windows-msvc-ninja-debug --show-only=json-v1
"-DHDF5_DIR=$hdf5Dir" ctest --preset windows-msvc-ninja-debug --output-on-failure
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug -R "NonlinearAnalysisState|CommitRollback" --output-on-failure
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure
``` ```
Recheck `.harness/config.json` before default commands. Use the ignored `.harness/config.json` preset contract. The Harness process must inherit VsDevCmd x64 and `FESA_GTEST_SOURCE_DIR`, `MKL_DIR`, `TBB_DIR`, and `HDF5_DIR` from its parent launch environment.
## 상태 기록 ## 상태 기록
@@ -80,8 +80,8 @@ Add tests first.
Run: Run:
```powershell ```powershell
cmake --build .harness/build --config Debug cmake --build --preset windows-msvc-ninja-debug
ctest --test-dir .harness/build -C Debug -R "NonlinearHdf5|Hdf5ResultsWriter" --output-on-failure ctest --preset windows-msvc-ninja-debug -R "NonlinearHdf5|Hdf5ResultsWriter" --output-on-failure
``` ```
Expected: new tests fail. Unexpected pass stops. Expected: new tests fail. Unexpected pass stops.
@@ -93,18 +93,14 @@ Implement `include/fesa/results/nonlinear_results_writer.h` as the backend-neutr
## VERIFY ## VERIFY
```powershell ```powershell
cmake --fresh -S . -B .harness/build -G "Visual Studio 18 2026" -A x64 ` cmake --preset windows-msvc-ninja-debug
"-DFESA_GTEST_SOURCE_DIR=$gtestSource" ` cmake --build --preset windows-msvc-ninja-debug
"-DMKL_DIR=$mklDir" ` ctest --preset windows-msvc-ninja-debug -R "NonlinearHdf5|Hdf5ResultsWriter" --output-on-failure
"-DTBB_DIR=$tbbDir" ` ctest --preset windows-msvc-ninja-debug --show-only=json-v1
"-DHDF5_DIR=$hdf5Dir" ctest --preset windows-msvc-ninja-debug --output-on-failure
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug -R "NonlinearHdf5|Hdf5ResultsWriter" --output-on-failure
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure
``` ```
Recheck `.harness/config.json` before default commands. Use the ignored `.harness/config.json` preset contract. The Harness process must inherit VsDevCmd x64 and `FESA_GTEST_SOURCE_DIR`, `MKL_DIR`, `TBB_DIR`, and `HDF5_DIR` from its parent launch environment.
## 상태 기록 ## 상태 기록
+112 -28
View File
@@ -107,6 +107,9 @@ struct RawMaterial {
struct RawStep { struct RawStep {
SourceLocation location; SourceLocation location;
bool has_static{false}; bool has_static{false};
StaticProcedureKind procedure_kind{
StaticProcedureKind::kLinearSmallDisplacement};
bool nlgeom{false};
std::array<double, 4> static_values{}; std::array<double, 4> static_values{};
std::vector<PrescribedDisplacementDefinition> boundaries; std::vector<PrescribedDisplacementDefinition> boundaries;
std::vector<NodalLoad> loads; std::vector<NodalLoad> loads;
@@ -343,6 +346,27 @@ class DomainMappingContext::Impl {
return true; return true;
} }
bool ParseNonlinearStaticDouble(const std::string& text, double& value,
const SourceLocation& location,
const std::string& keyword) {
if (text.empty()) {
return InputFailure("invalid-nonlinear-static-data", location, keyword,
text,
"A nonlinear STATIC field cannot be empty.");
}
char* end = nullptr;
errno = 0;
const double parsed = std::strtod(text.c_str(), &end);
if (errno == ERANGE || end != text.c_str() + text.size() ||
!std::isfinite(parsed)) {
return InputFailure("invalid-nonlinear-static-data", location, keyword,
text,
"All four nonlinear STATIC fields must be finite.");
}
value = parsed;
return true;
}
bool ParseModelDouble(const std::string& text, double& value, bool ParseModelDouble(const std::string& text, double& value,
const SourceLocation& location, const SourceLocation& location,
const std::string& keyword, const std::string& keyword,
@@ -1367,9 +1391,20 @@ class DomainMappingContext::Impl {
void ParseStepStart(const KeywordBlock& block) { void ParseStepStart(const KeywordBlock& block) {
if (step_seen_) { if (step_seen_) {
InputFailure("unsupported-multiple-step", block.location, const auto* nlgeom = Parameter(block, "NLGEOM");
block.canonical_name, "", const bool nonlinear_second_step =
"V0 accepts exactly one analysis step."); nlgeom != nullptr && nlgeom->value &&
AsciiCaseInsensitiveEquals(*nlgeom->value, "YES");
if (step_.nlgeom || nonlinear_second_step) {
InputFailure("unsupported-analysis-procedure", block.location,
block.canonical_name, "",
"The nonlinear static subset accepts exactly one "
"procedure step.");
} else {
InputFailure("unsupported-multiple-step", block.location,
block.canonical_name, "",
"V0 accepts exactly one analysis step.");
}
return; return;
} }
if (!assembly_seen_ || materials_.empty()) { if (!assembly_seen_ || materials_.empty()) {
@@ -1382,30 +1417,37 @@ class DomainMappingContext::Impl {
!RequireNoData(block)) { !RequireNoData(block)) {
return; return;
} }
const auto* nlgeom = Parameter(block, "NLGEOM"); StaticProcedureKind procedure_kind =
if (nlgeom != nullptr) { StaticProcedureKind::kLinearSmallDisplacement;
if (!nlgeom->value || nlgeom->value->empty()) { bool nlgeom = false;
const auto* nlgeom_parameter = Parameter(block, "NLGEOM");
if (nlgeom_parameter != nullptr) {
if (!nlgeom_parameter->value || nlgeom_parameter->value->empty()) {
InputFailure("invalid-keyword-parameter", block.location, InputFailure("invalid-keyword-parameter", block.location,
block.canonical_name, "NLGEOM", block.canonical_name, "NLGEOM",
"NLGEOM requires NO in the approved subset."); "NLGEOM requires YES or NO in the approved subset.");
return; return;
} }
if (!AsciiCaseInsensitiveEquals(*nlgeom->value, "NO")) { if (AsciiCaseInsensitiveEquals(*nlgeom_parameter->value, "YES")) {
if (model_element_family_ == ElementFamily::kShell) { if (model_element_family_ != ElementFamily::kShell) {
InputFailure("unsupported-nonlinear-geometry", block.location, InputFailure("unsupported-analysis-procedure", block.location,
block.canonical_name, *nlgeom->value, block.canonical_name, *nlgeom_parameter->value,
"Only absent NLGEOM or NLGEOM=NO is supported."); "NLGEOM=YES requires an S4 or S4R shell model.");
} else { return;
ModelFailure("unsupported-nonlinear-geometry", block.location,
block.canonical_name, *nlgeom->value,
"Only absent NLGEOM or NLGEOM=NO is supported.");
} }
procedure_kind = StaticProcedureKind::kNonlinearFullNewton;
nlgeom = true;
} else if (!AsciiCaseInsensitiveEquals(*nlgeom_parameter->value, "NO")) {
InputFailure("unsupported-analysis-procedure", block.location,
block.canonical_name, *nlgeom_parameter->value,
"NLGEOM must select YES or NO.");
return; return;
} }
} }
step_seen_ = true; step_seen_ = true;
in_step_ = true; in_step_ = true;
step_ = RawStep{block.location, false, {}, {}, {}}; step_ = RawStep{block.location, false, procedure_kind, nlgeom, {}, {},
{}};
step_load_seen_ = false; step_load_seen_ = false;
step_no_op_seen_ = false; step_no_op_seen_ = false;
} }
@@ -1485,6 +1527,14 @@ class DomainMappingContext::Impl {
ParseOutputChild(block); ParseOutputChild(block);
} else { } else {
active_output_ = false; active_output_ = false;
if (step_.procedure_kind ==
StaticProcedureKind::kNonlinearFullNewton &&
!step_.has_static) {
InputFailure("unsupported-analysis-procedure", block.location,
block.canonical_name, "",
"The nonlinear step supports only the STATIC procedure.");
return;
}
RejectUnknown(block); RejectUnknown(block);
} }
} }
@@ -1493,41 +1543,75 @@ class DomainMappingContext::Impl {
if (step_.has_static || !ValidateParameters(block, {}) || if (step_.has_static || !ValidateParameters(block, {}) ||
block.data.size() != 1U || block.data[0].fields.size() != 4U) { block.data.size() != 1U || block.data[0].fields.size() != 4U) {
if (!failure_) { if (!failure_) {
InputFailure("invalid-static-data", block.location, InputFailure(step_.nlgeom ? "invalid-nonlinear-static-data"
: "invalid-static-data",
block.location,
block.canonical_name, "", block.canonical_name, "",
"STATIC requires exactly one row of four values."); "STATIC requires exactly one row of four values.");
} }
return; return;
} }
for (std::size_t field = 0U; field < 4U; ++field) { for (std::size_t field = 0U; field < 4U; ++field) {
if (!ParseDouble(block.data[0].fields[field], step_.static_values[field], const std::string& text = block.data[0].fields[field];
block.data[0].location, block.canonical_name)) { const bool parsed = step_.nlgeom
? ParseNonlinearStaticDouble(
text, step_.static_values[field],
block.data[0].location,
block.canonical_name)
: ParseDouble(text, step_.static_values[field],
block.data[0].location,
block.canonical_name);
if (!parsed) {
return; return;
} }
if (step_.static_values[field] <= 0.0) { if (step_.static_values[field] <= 0.0) {
InputFailure("invalid-static-data", block.data[0].location, InputFailure(step_.nlgeom ? "invalid-nonlinear-static-data"
: "invalid-static-data",
block.data[0].location,
block.canonical_name, "", block.canonical_name, "",
"All four STATIC fields must be positive."); "All four STATIC fields must be positive.");
return; return;
} }
} }
if (step_.static_values[2] > step_.static_values[3]) { if (step_.static_values[2] > step_.static_values[3]) {
InputFailure("invalid-static-data", block.data[0].location, InputFailure(step_.nlgeom ? "invalid-nonlinear-static-data"
: "invalid-static-data",
block.data[0].location,
block.canonical_name, "", block.canonical_name, "",
"STATIC minimum increment cannot exceed maximum increment."); "STATIC minimum increment cannot exceed maximum increment.");
return; return;
} }
if (step_.nlgeom && step_.static_values[1] != 1.0) {
InputFailure("invalid-nonlinear-static-data", block.data[0].location,
block.canonical_name, "",
"The nonlinear STATIC time period must be exactly 1.0.");
return;
}
step_.has_static = true; step_.has_static = true;
} }
void ParseOutputRoot(const KeywordBlock& block) { void ParseOutputRoot(const KeywordBlock& block) {
if (!ValidateParameters(block, {"FIELD", "HISTORY", "VARIABLE"})) {
return;
}
const auto* field = Parameter(block, "FIELD"); const auto* field = Parameter(block, "FIELD");
const auto* history = Parameter(block, "HISTORY"); const auto* history = Parameter(block, "HISTORY");
const auto* variable = Parameter(block, "VARIABLE");
if ((field == nullptr) == (history == nullptr) || if ((field == nullptr) == (history == nullptr) ||
(field != nullptr && field->value) || (field != nullptr && field->value) ||
(history != nullptr && history->value)) { (history != nullptr && history->value)) {
InputFailure("unsupported-keyword", block.location, block.canonical_name, InputFailure(step_.nlgeom ? "invalid-keyword-parameter"
"", "OUTPUT must select exactly FIELD or HISTORY."); : "unsupported-keyword",
block.location, block.canonical_name, "",
"OUTPUT must select exactly FIELD or HISTORY.");
return;
}
if (step_.nlgeom &&
(variable == nullptr || !variable->value ||
!AsciiCaseInsensitiveEquals(*variable->value, "PRESELECT"))) {
InputFailure("invalid-keyword-parameter", block.location,
block.canonical_name, "VARIABLE",
"Nonlinear OUTPUT requires VARIABLE=PRESELECT.");
return; return;
} }
active_output_ = true; active_output_ = true;
@@ -2176,10 +2260,10 @@ class DomainMappingContext::Impl {
// Static time-control values are provenance only: V0 creates exactly // Static time-control values are provenance only: V0 creates exactly
// the canonical final frame 0 and performs no increment loop here. // the canonical final frame 0 and performs no increment loop here.
definition_.steps.push_back({"Step-1", std::move(boundaries), step_.loads, definition_.steps.push_back(
step_.static_values[0], step_.static_values[1], {"Step-1", std::move(boundaries), step_.loads, step_.procedure_kind,
step_.static_values[2], step_.static_values[3], step_.nlgeom, step_.static_values[0], step_.static_values[1],
step_.location}); step_.static_values[2], step_.static_values[3], step_.location});
} }
const ParsedInput& input_; const ParsedInput& input_;
+10
View File
@@ -9,6 +9,8 @@ namespace fesa {
StepDefinition::StepDefinition(StaticStepDefinition definition) StepDefinition::StepDefinition(StaticStepDefinition definition)
: name_{std::move(definition.name)}, : name_{std::move(definition.name)},
procedure_kind_{definition.procedure_kind},
nlgeom_{definition.nlgeom},
initial_increment_{definition.initial_increment}, initial_increment_{definition.initial_increment},
time_period_{definition.time_period}, time_period_{definition.time_period},
minimum_increment_{definition.minimum_increment}, minimum_increment_{definition.minimum_increment},
@@ -60,6 +62,14 @@ StepDefinition::ConcentratedLoads() const noexcept {
return concentrated_loads_view_; return concentrated_loads_view_;
} }
StaticProcedureKind StepDefinition::ProcedureKind() const noexcept {
return procedure_kind_;
}
bool StepDefinition::IsNonlinearStatic() const noexcept {
return procedure_kind_ == StaticProcedureKind::kNonlinearFullNewton;
}
double StepDefinition::InitialIncrement() const noexcept { double StepDefinition::InitialIncrement() const noexcept {
return initial_increment_; return initial_increment_;
} }
+80
View File
@@ -0,0 +1,80 @@
import json
from pathlib import Path
import sys
ROOT = Path(__file__).resolve().parents[1]
SCRIPTS = ROOT / "scripts"
sys.path.insert(0, str(SCRIPTS))
from msvc_harness.adapters.cmake import CMakeAdapter
from msvc_harness.config import load_config
from msvc_harness.models import ProjectKind, ProjectSelection, Toolchain
PRESET_NAME = "windows-msvc-ninja-debug"
BINARY_DIR = ".harness/build-ninja-msvc-debug"
def test_harness_uses_tracked_ninja_msvc_presets(tmp_path):
presets = json.loads((ROOT / "CMakePresets.json").read_text(encoding="utf-8"))
configure = presets["configurePresets"][0]
assert configure == {
"name": PRESET_NAME,
"displayName": "Windows MSVC x64 Debug (Ninja)",
"generator": "Ninja",
"binaryDir": f"${{sourceDir}}/{BINARY_DIR}",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug",
"FESA_GTEST_SOURCE_DIR": "$env{FESA_GTEST_SOURCE_DIR}",
"MKL_DIR": "$env{MKL_DIR}",
"TBB_DIR": "$env{TBB_DIR}",
"HDF5_DIR": "$env{HDF5_DIR}",
},
}
assert presets["buildPresets"] == [
{"name": PRESET_NAME, "configurePreset": PRESET_NAME}
]
assert presets["testPresets"] == [
{"name": PRESET_NAME, "configurePreset": PRESET_NAME}
]
example = json.loads(
(ROOT / ".harness" / "config.example.json").read_text(encoding="utf-8")
)
assert example == {
"version": 1,
"projectType": "cmake",
"cmake": {
"sourceDir": ".",
"binaryDir": BINARY_DIR,
"configurePreset": PRESET_NAME,
"buildPreset": PRESET_NAME,
"testPreset": PRESET_NAME,
},
}
assert ".harness/build-ninja-msvc-debug/" in (
ROOT / ".gitignore"
).read_text(encoding="utf-8").splitlines()
harness_dir = tmp_path / ".harness"
harness_dir.mkdir()
(harness_dir / "config.json").write_text(
json.dumps(example), encoding="utf-8"
)
config = load_config(tmp_path)
tools = Toolchain(
installation=tmp_path / "vs",
msbuild=tmp_path / "msbuild.exe",
cmake=tmp_path / "cmake.exe",
ctest=tmp_path / "ctest.exe",
)
selection = ProjectSelection(ProjectKind.CMAKE, ROOT / "CMakePresets.json")
plan = CMakeAdapter().create_plan(tmp_path, selection, config, tools)
assert [step.command.argv[1:] for step in plan.steps] == [
("--preset", PRESET_NAME),
("--build", "--preset", PRESET_NAME),
("--preset", PRESET_NAME, "--show-only=json-v1"),
("--preset", PRESET_NAME, "--output-on-failure"),
]
+143 -3
View File
@@ -174,6 +174,12 @@ TipSecond, 6, 1.
)inp"; )inp";
} }
std::string NonlinearShellDeck() {
return ReplaceOnce(
ReplaceOnce(ShellDeck(), "nlgeom=NO", "nlgeom=YES"),
"0.1, 1., 0.01, 1.", "0.1, 1., 0.001, 0.1");
}
std::string SupportedInventoryDeck(bool include_no_ops) { std::string SupportedInventoryDeck(bool include_no_ops) {
const std::string preprint = const std::string preprint =
include_no_ops ? "*Preprint, echo=NO, model=NO, history=NO, contact=NO\n" include_no_ops ? "*Preprint, echo=NO, model=NO, history=NO, contact=NO\n"
@@ -570,6 +576,142 @@ TEST(InpDomainMapping, NoOpAllowlistWarnsWithoutSemanticEffect) {
plain.Value().Steps()[0].Loads().size()); plain.Value().Steps()[0].Loads().size());
} }
// NSNR-IO-001, NSNR-IO-005, NSNR-IO-007
TEST(InpDomainMapping, MapsNonlinearStaticShellProcedureAndRawControls) {
auto result = MapText("nonlinear-static-shell", NonlinearShellDeck());
ASSERT_TRUE(result.HasValue());
const fesa::Domain& domain = result.Value();
ASSERT_EQ(domain.Steps().Size(), 1U);
const auto& step = domain.Steps()[0U];
EXPECT_EQ(step.ProcedureKind(),
fesa::StaticProcedureKind::kNonlinearFullNewton);
EXPECT_TRUE(step.IsNonlinearStatic());
EXPECT_DOUBLE_EQ(step.InitialIncrement(), 0.1);
EXPECT_DOUBLE_EQ(step.TimePeriod(), 1.0);
EXPECT_DOUBLE_EQ(step.MinimumIncrement(), 0.001);
EXPECT_DOUBLE_EQ(step.MaximumIncrement(), 0.1);
EXPECT_TRUE(domain.BeamElements().Empty());
ASSERT_EQ(domain.ShellElements().Size(), 4U);
EXPECT_EQ(domain.ShellElements()[0U].source_type,
fesa::ShellSourceElementType::kS4);
EXPECT_EQ(domain.ShellElements()[1U].source_type,
fesa::ShellSourceElementType::kS4r);
}
// NSNR-IO-002, NSNR-IO-003
TEST(InpDomainMapping, KeepsExplicitAndImplicitLinearStaticProcedures) {
const std::vector<std::string> decks{
ShellDeck(), ReplaceOnce(ShellDeck(), ", nlgeom=NO", "")};
for (std::size_t index = 0U; index < decks.size(); ++index) {
SCOPED_TRACE(index);
auto result = MapText("linear-static-procedure-" + std::to_string(index),
decks[index]);
ASSERT_TRUE(result.HasValue());
ASSERT_EQ(result.Value().Steps().Size(), 1U);
EXPECT_EQ(result.Value().Steps()[0U].ProcedureKind(),
fesa::StaticProcedureKind::kLinearSmallDisplacement);
EXPECT_FALSE(result.Value().Steps()[0U].IsNonlinearStatic());
}
}
// NSNR-IO-004
TEST(InpDomainMapping, RejectsInvalidNonlinearStaticControlValues) {
struct InvalidCase {
std::string name;
std::string controls;
};
const std::vector<InvalidCase> cases{
{"zero", "0., 1., 0.001, 0.1"},
{"nonfinite", "nan, 1., 0.001, 0.1"},
{"nonunit-period", "0.1, 0.5, 0.001, 0.1"},
{"reversed-bounds", "0.1, 1., 0.2, 0.1"}};
for (const auto& test_case : cases) {
SCOPED_TRACE(test_case.name);
auto result = MapText(
"invalid-nonlinear-static-" + test_case.name,
ReplaceOnce(NonlinearShellDeck(), "0.1, 1., 0.001, 0.1",
test_case.controls));
ASSERT_FALSE(result.HasValue());
EXPECT_EQ(result.GetStatus().Category(), fesa::FailureCategory::kInput);
ASSERT_NE(FindDiagnostic(result.GetStatus(), "invalid-nonlinear-static-data"),
nullptr);
}
}
// NSNR-IO-006, NSNR-IO-008
TEST(InpDomainMapping, RejectsUnsupportedNonlinearProceduresAndMixedModels) {
const std::string nonlinear = NonlinearShellDeck();
const std::vector<std::pair<std::string, std::string>> procedure_cases{
{"dynamic",
ReplaceOnce(nonlinear, "*Static\n0.1, 1., 0.001, 0.1",
"*Dynamic\n0.1, 1., 0.001, 0.1")},
{"mixed-steps",
nonlinear + "*Step, name=Linear, nlgeom=NO\n*Static\n0.1, 1., 0.01, "
"1.\n*End Step\n"},
{"beam-nlgeom",
ReplaceOnce(MinimalDeck(), "nlgeom=NO", "nlgeom=YES")}};
for (const auto& test_case : procedure_cases) {
SCOPED_TRACE(test_case.first);
auto result = MapText("unsupported-nonlinear-" + test_case.first,
test_case.second);
ASSERT_FALSE(result.HasValue());
EXPECT_EQ(result.GetStatus().Category(), fesa::FailureCategory::kInput);
ASSERT_NE(FindDiagnostic(result.GetStatus(), "unsupported-analysis-procedure"),
nullptr);
}
const std::string mixed_model = ReplaceOnce(
nonlinear, "0020, 2, 5, 6, 3\n*Elset",
"0020, 2, 5, 6, 3\n*Element, type=B33\n30, 1, 2\n*Elset");
auto mixed_result = MapText("mixed-nonlinear-model", mixed_model);
ASSERT_FALSE(mixed_result.HasValue());
EXPECT_EQ(mixed_result.GetStatus().Category(), fesa::FailureCategory::kInput);
ASSERT_NE(FindDiagnostic(mixed_result.GetStatus(),
"unsupported-mixed-element-model"),
nullptr);
}
// NSNR-IO-009, NSNR-IO-010, NSNR-IO-011
TEST(InpDomainMapping, AcceptsOnlyNonlinearPreselectOutputNoOps) {
auto plain = MapText("nonlinear-output-plain", NonlinearShellDeck());
ASSERT_TRUE(plain.HasValue());
for (const std::string_view request : {"field", "history"}) {
const std::string deck = ReplaceOnce(
NonlinearShellDeck(), "*End Step\n",
"*Output, " + std::string{request} + ", variable=PRESELECT\n*End Step\n");
auto result = MapText("nonlinear-output-" + std::string{request}, deck);
ASSERT_TRUE(result.HasValue());
EXPECT_EQ(result.Value().Nodes().size(), plain.Value().Nodes().size());
EXPECT_EQ(result.Value().Steps().Size(), plain.Value().Steps().Size());
EXPECT_EQ(result.Value().Steps()[0U].BoundaryConditions().size(),
plain.Value().Steps()[0U].BoundaryConditions().size());
EXPECT_EQ(result.Value().Steps()[0U].Loads().size(),
plain.Value().Steps()[0U].Loads().size());
ASSERT_EQ(result.Value().Warnings().size(), 1U);
EXPECT_EQ(result.Value().Warnings()[0U].keyword, "OUTPUT");
}
const std::vector<std::string> malformed_requests{
"*Output, field\n", "*Output, field, history, variable=PRESELECT\n",
"*Output, field, variable=ALL\n"};
for (std::size_t index = 0U; index < malformed_requests.size(); ++index) {
SCOPED_TRACE(index);
auto result = MapText(
"malformed-nonlinear-output-" + std::to_string(index),
ReplaceOnce(NonlinearShellDeck(), "*End Step\n",
malformed_requests[index] + "*End Step\n"));
ASSERT_FALSE(result.HasValue());
EXPECT_EQ(result.GetStatus().Category(), fesa::FailureCategory::kInput);
ASSERT_NE(FindDiagnostic(result.GetStatus(), "invalid-keyword-parameter"),
nullptr);
}
}
// MITC4-MAP-001 // MITC4-MAP-001
// C-MODEL-002 // C-MODEL-002
TEST(InpDomainMapping, MapsS4AndS4rThroughOneMitc4Identity) { TEST(InpDomainMapping, MapsS4AndS4rThroughOneMitc4Identity) {
@@ -738,8 +880,6 @@ TEST(InpDomainMapping,
const std::vector<InvalidCase> cases{ const std::vector<InvalidCase> cases{
{"second-step", base + "*Step\n*Static\n1., 1., 1., 1.\n*End Step\n", {"second-step", base + "*Step\n*Static\n1., 1., 1., 1.\n*End Step\n",
"unsupported-multiple-step"}, "unsupported-multiple-step"},
{"nonlinear-step", ReplaceOnce(base, "nlgeom=NO", "nlgeom=YES"),
"unsupported-nonlinear-geometry"},
{"other-procedure", {"other-procedure",
ReplaceOnce(base, "*Static\n0.1, 1., 0.01, 1.", ReplaceOnce(base, "*Static\n0.1, 1., 0.01, 1.",
"*Dynamic\n0.1, 1., 0.01, 1."), "*Dynamic\n0.1, 1., 0.01, 1."),
@@ -898,7 +1038,7 @@ TEST(InpDomainMapping, RejectsUnsupportedAndInvalidPortfolio) {
{"malformed-node-arity", ReplaceOnce(base, "1, 0., 0., 0.", "1, 0., 0."), {"malformed-node-arity", ReplaceOnce(base, "1, 0., 0., 0.", "1, 0., 0."),
"invalid-data-arity", fesa::FailureCategory::kInput}, "invalid-data-arity", fesa::FailureCategory::kInput},
{"nlgeom", ReplaceOnce(base, "nlgeom=NO", "nlgeom=YES"), {"nlgeom", ReplaceOnce(base, "nlgeom=NO", "nlgeom=YES"),
"unsupported-nonlinear-geometry", fesa::FailureCategory::kModel}, "unsupported-analysis-procedure", fesa::FailureCategory::kInput},
{"unknown-keyword", {"unknown-keyword",
ReplaceOnce(base, "*Assembly, name=Assembly", ReplaceOnce(base, "*Assembly, name=Assembly",
"*Density\n1.\n*Assembly, name=Assembly"), "*Density\n1.\n*Assembly, name=Assembly"),
@@ -150,6 +150,9 @@ TEST(DomainMappingComponents,
EXPECT_EQ(domain.Materials().Size(), 1U); EXPECT_EQ(domain.Materials().Size(), 1U);
EXPECT_EQ(domain.Properties().Size(), 1U); EXPECT_EQ(domain.Properties().Size(), 1U);
ASSERT_EQ(domain.Steps().Size(), 1U); ASSERT_EQ(domain.Steps().Size(), 1U);
EXPECT_EQ(domain.Steps()[0].ProcedureKind(),
StaticProcedureKind::kLinearSmallDisplacement);
EXPECT_FALSE(domain.Steps()[0].IsNonlinearStatic());
EXPECT_EQ(domain.Steps()[0].BoundaryConditions().size(), 7U); EXPECT_EQ(domain.Steps()[0].BoundaryConditions().size(), 7U);
EXPECT_EQ(domain.Steps()[0].Loads().size(), 1U); EXPECT_EQ(domain.Steps()[0].Loads().size(), 1U);
ASSERT_EQ(domain.Warnings().size(), 3U); ASSERT_EQ(domain.Warnings().size(), 3U);
+5
View File
@@ -49,6 +49,8 @@ fesa::ModelDefinition MakeOwnedDefinition() {
definition.steps = {{"Step-1", definition.steps = {{"Step-1",
{{"Root", 1, 6, 0.0, {"models/owned.inp", 60U}}}, {{"Root", 1, 6, 0.0, {"models/owned.inp", 60U}}},
{{"Tip", 3, -1000.0, {"models/owned.inp", 61U}}}, {{"Tip", 3, -1000.0, {"models/owned.inp", 61U}}},
fesa::StaticProcedureKind::kLinearSmallDisplacement,
false,
0.1, 0.1,
1.0, 1.0,
1.0e-5, 1.0e-5,
@@ -197,6 +199,9 @@ TEST(DomainModel, ImmutableOwnershipPreservesStableOrder) {
EXPECT_DOUBLE_EQ(domain.Steps()[0].TimePeriod(), 1.0); EXPECT_DOUBLE_EQ(domain.Steps()[0].TimePeriod(), 1.0);
EXPECT_DOUBLE_EQ(domain.Steps()[0].MinimumIncrement(), 1.0e-5); EXPECT_DOUBLE_EQ(domain.Steps()[0].MinimumIncrement(), 1.0e-5);
EXPECT_DOUBLE_EQ(domain.Steps()[0].MaximumIncrement(), 1.0); EXPECT_DOUBLE_EQ(domain.Steps()[0].MaximumIncrement(), 1.0);
EXPECT_EQ(domain.Steps()[0].ProcedureKind(),
fesa::StaticProcedureKind::kLinearSmallDisplacement);
EXPECT_FALSE(domain.Steps()[0].IsNonlinearStatic());
ASSERT_EQ(domain.Steps()[0].BoundaryConditions().size(), 6U); ASSERT_EQ(domain.Steps()[0].BoundaryConditions().size(), 6U);
ASSERT_EQ(domain.Steps()[0].Loads().size(), 1U); ASSERT_EQ(domain.Steps()[0].Loads().size(), 1U);
ASSERT_EQ(domain.Steps()[0].ConcentratedLoads().Size(), 1U); ASSERT_EQ(domain.Steps()[0].ConcentratedLoads().Size(), 1U);
+6 -2
View File
@@ -70,8 +70,9 @@ TEST(DomainModel, SourceAndInternalIdentityRemainDistinct) {
"Root", 1, 6, 0.0, {"models/beam.inp", 60U}}; "Root", 1, 6, 0.0, {"models/beam.inp", 60U}};
const fesa::NodalLoad load{"Tip", 3, -1000.0, {"models/beam.inp", 70U}}; const fesa::NodalLoad load{"Tip", 3, -1000.0, {"models/beam.inp", 70U}};
const fesa::StaticStepDefinition step{ const fesa::StaticStepDefinition step{
"Step-1", {boundary}, {load}, 0.1, "Step-1", {boundary}, {load},
1.0, 1.0e-5, 1.0, {"models/beam.inp", 50U}}; fesa::StaticProcedureKind::kLinearSmallDisplacement, false, 0.1,
1.0, 1.0e-5, 1.0, {"models/beam.inp", 50U}};
const fesa::NodeSet node_set{ const fesa::NodeSet node_set{
"Root", std::string{"Instance-A"}, {5U}, {"models/beam.inp", 25U}}; "Root", std::string{"Instance-A"}, {5U}, {"models/beam.inp", 25U}};
const fesa::ElementSet element_set{ const fesa::ElementSet element_set{
@@ -118,6 +119,9 @@ TEST(DomainModel, SourceAndInternalIdentityRemainDistinct) {
EXPECT_EQ(definition.steps[0].time_period, 1.0); EXPECT_EQ(definition.steps[0].time_period, 1.0);
EXPECT_EQ(definition.steps[0].minimum_increment, 1.0e-5); EXPECT_EQ(definition.steps[0].minimum_increment, 1.0e-5);
EXPECT_EQ(definition.steps[0].maximum_increment, 1.0); EXPECT_EQ(definition.steps[0].maximum_increment, 1.0);
EXPECT_EQ(definition.steps[0].procedure_kind,
fesa::StaticProcedureKind::kLinearSmallDisplacement);
EXPECT_FALSE(definition.steps[0].nlgeom);
ASSERT_EQ(definition.warnings.size(), 1U); ASSERT_EQ(definition.warnings.size(), 1U);
EXPECT_EQ(definition.warnings[0].location.line, 75U); EXPECT_EQ(definition.warnings[0].location.line, 75U);