feat(nonlinear-static-newton-raphson): step 11 - equilibrium-projection-and-reference-gate
This commit is contained in:
@@ -134,6 +134,10 @@ Add tests first.
|
||||
- `NSNR-PROC-017`: failed nonlinear run preserves prior final HDF5 according to output lifecycle.
|
||||
- `NSNR-PROC-018`: deterministic repeat produces same sparse structure, nodal source-identity order, result row order, diagnostics, and log line ordering.
|
||||
|
||||
### USER-DECISION-003 option-1 revision addendum
|
||||
|
||||
Step 10의 completed status, summary, timestamps와 commits는 보존한다. Existing procedure는 same-trial free residual/internal/external vectors를 force와 moment channel별로 분리하여 `EvaluateNewtonConvergence`에 전달하고 fresh same-iteration correction을 별도로 전달한다. 따라서 option 1의 production correction은 Step 11의 `nonlinear_static_control.cpp`에 한정하며 `nonlinear_static_procedure.cpp`, prepared-analysis API와 log writer production 변경은 예상하지 않는다. Step 11의 shellNL copied-input run과 log assertions이 unloaded rotational external channel의 exact-zero branch, loaded force channel의 retained relative branch, four-channel AND 및 intended factors `0.1..1.0`을 integration 수준에서 검증한다.
|
||||
|
||||
Run:
|
||||
|
||||
```powershell
|
||||
@@ -171,3 +175,4 @@ Update only Step 10 status and one-line payload. Executor owns timestamps, commi
|
||||
- Do not insert nonlinear branches into `LinearStaticAnalysis` private lifecycle. 이유: new procedure owns its own lifecycle.
|
||||
- Do not replace final HDF5 on failed analysis, log failure, or HDF5 failure. 이유: asymmetric preservation contract requires prior valid final preservation.
|
||||
- Do not construct MKL/TBB/HDF5 backends inside procedure executors. 이유: dependencies are injected so tests can observe lifecycle and no backend type crosses analysis/core public boundaries.
|
||||
- Do not duplicate the option-1 selector in the procedure or log writer. 이유: the existing procedure already transports the three residual vectors separately and convergence ownership remains in `nonlinear_static_control`.
|
||||
|
||||
@@ -1,79 +1,143 @@
|
||||
# Step 11: reference-comparison-gate
|
||||
# Step 11: equilibrium-projection-and-reference-gate
|
||||
|
||||
## 목적
|
||||
|
||||
USER-DECISION-004 option 1과 `AUDIT-001`을 구현·검증한다. 같은 accepted factor-one state에서
|
||||
accepted free residual, constrained reaction resultant, global applied-plus-reaction balance error를
|
||||
서로 다른 quantity로 재구성하고, 기존 schema-v1 `/global/equilibrium`에는 balance error만 저장한다.
|
||||
Fine nonlinear case는 primary, coarse nonlinear case는 companion으로 검증한다. Local nodal
|
||||
`RF1/RF2/RF3`와 physical spatial `RM1/RM2`는 deterministic review-only evidence이고 blocking
|
||||
verdict를 바꾸지 않는다. Global force와 moment balance는 각각 fixed normalized `<=1e-8`
|
||||
comparator gate를 사용하며 runtime configuration 또는 product solver acceptance로 노출하지 않는다.
|
||||
|
||||
## 읽어야 할 파일
|
||||
|
||||
- `AGENTS.md`
|
||||
- `docs/PRD.md`
|
||||
- `docs/ARCHITECTURE.md`
|
||||
- `docs/ADR.md`
|
||||
- `docs/CODINGSTYLE.md`
|
||||
- `docs/TOLERANCE.md`
|
||||
- `docs/nonlinear-static-newton-raphson/reference-model.md`
|
||||
- `docs/nonlinear-static-newton-raphson/io.md`
|
||||
- `docs/nonlinear-static-newton-raphson/numerical-review.md`
|
||||
- `docs/nonlinear-static-newton-raphson/requirements.md`
|
||||
- `docs/nonlinear-static-newton-raphson/research.md`
|
||||
- `docs/nonlinear-static-newton-raphson/formulation.md` §§11.4, 13.1, 13.4, 14.1
|
||||
- `docs/nonlinear-static-newton-raphson/numerical-review.md` §§3.2, 6.2, 6.3
|
||||
- `docs/nonlinear-static-newton-raphson/reference-model.md` §§3–6
|
||||
- `docs/nonlinear-static-newton-raphson/io.md` §§7.3–7.5.1, 8.1–8.7
|
||||
- `docs/nonlinear-static-newton-raphson/implementation-plan.md`
|
||||
- `docs/nonlinear-static-newton-raphson/corrections.md` §13
|
||||
- `phases/nonlinear-static-newton-raphson/index.json`
|
||||
- `include/fesa/analysis/nonlinear_analysis_state.h`
|
||||
- `include/fesa/analysis/nonlinear_static_procedure.h`
|
||||
- `include/fesa/analysis/nonlinear_static_control.h`
|
||||
- `src/fesa/analysis/nonlinear_static_procedure.cpp`
|
||||
- `src/fesa/analysis/nonlinear_static_control.cpp`
|
||||
- `include/fesa/results/nonlinear_results_writer.h`
|
||||
- `include/fesa/io/hdf5/nonlinear_hdf5_results_writer.h`
|
||||
- `src/fesa/io/hdf5/nonlinear_hdf5_results_writer.cpp`
|
||||
- `tests/integration/analysis/nonlinear_static_procedure_test.cpp`
|
||||
- `tests/unit/io/hdf5/nonlinear_hdf5_results_writer_test.cpp`
|
||||
- `tests/unit/analysis/nonlinear_static_control_test.cpp`
|
||||
- `tests/unit/analysis/newton_iteration_log_test.cpp`
|
||||
- `tests/reference/reference_tolerance_policy.h`
|
||||
- `tests/reference/reference_tolerance_policy.cpp`
|
||||
- `tests/reference/reference_comparison.h`
|
||||
- `tests/reference/reference_comparison.cpp`
|
||||
- `tests/reference/mitc4_reference_comparison.h`
|
||||
- `tests/reference/mitc4_reference_comparison.cpp`
|
||||
- Step 9 files: `include/fesa/results/nonlinear_results_writer.h`, `include/fesa/io/hdf5/nonlinear_hdf5_results_writer.h`
|
||||
- Step 10 files: `include/fesa/analysis/prepared_analysis.h`, `src/fesa/app/fesa_application.cpp`
|
||||
- `tests/reference/nonlinear_static_reference_comparison.h`
|
||||
- `tests/reference/nonlinear_static_reference_comparison.cpp`
|
||||
- `tests/reference/nonlinear_static_reference_cases_test.cpp`
|
||||
- `tests/CMakeLists.txt`
|
||||
- `.harness/config.json`
|
||||
- `CMakePresets.json`
|
||||
|
||||
## 이전 Step 전제
|
||||
## 이전 Step과 보존 전제
|
||||
|
||||
Step 10 runs copied input files through FESA and writes authoritative HDF5 outputs after log close.
|
||||
- Steps 0–10은 completed다. 그 status, summary, timestamp, commit 또는 구현을 replay, amend,
|
||||
reset하거나 다시 작성하지 않는다.
|
||||
- 현재 worktree의 `NSNR-CTRL-018..021`, `NSNR-LOG-012`, `NSNR-PROC-019`,
|
||||
`NSNR-HDF5-014`, residual-selector GREEN과 `NSNR-REF-001..023` comparator/CMake 작업은
|
||||
이전 blocked Step 11에서 생성된 보존 대상이다. 삭제·재생성·reset하지 말고 현재 내용에서
|
||||
계속한다.
|
||||
- 현재 comparator의 shared `<=1e-10` global force/moment gate는 이전 blocker를 재현하는
|
||||
보존된 implementation state다. 새 RED가 approved between-threshold metric을 거부하는 것을
|
||||
증명한 뒤 comparator 내부 gate만 `<=1e-8`로 변경한다.
|
||||
- Selector RED는 이미 과거 실행 evidence에 속한다. 이 재실행에서 selector RED를 fabricate하거나
|
||||
다시 실패시키지 않는다. 기존 테스트가 계속 green인지 focused VERIFY에서 확인한다.
|
||||
- Step 12는 pending이며 이 Step에서 시작하지 않는다.
|
||||
|
||||
## 소유 파일
|
||||
|
||||
- Create: `tests/reference/nonlinear_static_reference_comparison.h`
|
||||
- Create: `tests/reference/nonlinear_static_reference_comparison.cpp`
|
||||
- Create: `tests/reference/nonlinear_static_reference_cases_test.cpp`
|
||||
- Modify: `tests/CMakeLists.txt`
|
||||
RED test를 먼저 추가한 뒤 필요한 production file만 최소 수정한다.
|
||||
|
||||
## 인터페이스
|
||||
- Modify test first: `tests/integration/analysis/nonlinear_static_procedure_test.cpp`
|
||||
- Modify test first: `tests/unit/io/hdf5/nonlinear_hdf5_results_writer_test.cpp`
|
||||
- Preserve and extend test-private comparator: `tests/reference/nonlinear_static_reference_comparison.h`
|
||||
- Preserve and extend test-private comparator: `tests/reference/nonlinear_static_reference_comparison.cpp`
|
||||
- Preserve and extend tests: `tests/reference/nonlinear_static_reference_cases_test.cpp`
|
||||
- Preserve existing registration; edit only if the current sources are not registered:
|
||||
`tests/CMakeLists.txt`
|
||||
- Minimal GREEN: `src/fesa/analysis/nonlinear_static_procedure.cpp`
|
||||
- Minimal GREEN: `src/fesa/io/hdf5/nonlinear_hdf5_results_writer.cpp`
|
||||
- Preserve existing partial GREEN/tests without redesign:
|
||||
`src/fesa/analysis/nonlinear_static_control.cpp`,
|
||||
`tests/unit/analysis/nonlinear_static_control_test.cpp`,
|
||||
`tests/unit/analysis/newton_iteration_log_test.cpp`
|
||||
|
||||
No public header, new CMake target, new HDF5 dataset, schema-version change or reference artifact is
|
||||
owned by this Step.
|
||||
|
||||
## Authoritative HDF5 입력과 test-private report 경계
|
||||
|
||||
Comparator는 아래 existing schema-v1 paths만 읽는다.
|
||||
|
||||
```text
|
||||
/model/nodes [node_count]
|
||||
/model/nodal_constraint_mask [node_count,6]
|
||||
/steps/Step-1/accepted_frames unique factor-one row
|
||||
/steps/Step-1/frames/<frame>/nodal/displacement [node_count,6]
|
||||
/steps/Step-1/frames/<frame>/nodal/generalized_internal_force [node_count,6]
|
||||
/steps/Step-1/frames/<frame>/nodal/generalized_external_force [node_count,6]
|
||||
/steps/Step-1/frames/<frame>/nodal/generalized_residual [node_count,6]
|
||||
/steps/Step-1/frames/<frame>/nodal/reaction [node_count,6]
|
||||
/steps/Step-1/frames/<frame>/global/equilibrium [6]
|
||||
```
|
||||
|
||||
`/global/equilibrium` component order is
|
||||
`FORCE_1,FORCE_2,FORCE_3,MOMENT_1,MOMENT_2,MOMENT_3` and its required
|
||||
`location` is `global-balance-error`.
|
||||
|
||||
Preserve the current test-private types and make only the extensions needed by the approved
|
||||
dispositions and distinct internal evidence. Add the required standard `<array>` and `<optional>`
|
||||
includes to the test-private header. Candidate signature-level shape:
|
||||
|
||||
```cpp
|
||||
namespace fesa::test {
|
||||
|
||||
struct NonlinearReferenceCase {
|
||||
std::string case_id;
|
||||
std::filesystem::path original_input_path;
|
||||
std::filesystem::path displacement_csv_path;
|
||||
std::filesystem::path reaction_csv_path;
|
||||
std::filesystem::path stress_inventory_path;
|
||||
std::filesystem::path execution_directory;
|
||||
};
|
||||
|
||||
struct ArtifactSnapshot {
|
||||
std::filesystem::path path;
|
||||
std::string sha256;
|
||||
std::uintmax_t byte_size;
|
||||
std::filesystem::file_time_type last_write_time;
|
||||
};
|
||||
|
||||
enum class NonlinearReferenceDisposition {
|
||||
kBlocking,
|
||||
kWarningOnly,
|
||||
kExcluded
|
||||
kReviewOnly,
|
||||
kExcluded,
|
||||
};
|
||||
|
||||
struct NonlinearReferenceRowKey {
|
||||
std::string case_id;
|
||||
std::string accepted_state;
|
||||
std::string instance_name;
|
||||
std::int64_t source_node_label;
|
||||
std::string component;
|
||||
};
|
||||
|
||||
struct NonlinearReferenceFamilyReport {
|
||||
struct NonlinearReferencePrecheckFinding {
|
||||
std::string family_identity;
|
||||
std::vector<std::string> components;
|
||||
NonlinearReferenceDisposition disposition;
|
||||
std::size_t row_count;
|
||||
ReferenceToleranceFamilyDecision tolerance;
|
||||
std::string diagnostic_code;
|
||||
std::vector<NonlinearReferenceRowKey> affected_keys;
|
||||
};
|
||||
|
||||
struct GeneratedRunArtifacts {
|
||||
std::filesystem::path copied_input_path;
|
||||
std::filesystem::path generated_results_hdf5;
|
||||
std::filesystem::path generated_log_path;
|
||||
struct NonlinearInternalEquilibriumReport {
|
||||
std::string family_identity;
|
||||
std::size_t row_count;
|
||||
double numerator;
|
||||
double scale;
|
||||
std::optional<double> normalized_metric;
|
||||
bool passed;
|
||||
std::string diagnostic_code;
|
||||
};
|
||||
|
||||
struct ConstrainedReactionResultantReport {
|
||||
std::array<double, 3> force;
|
||||
std::array<double, 3> moment;
|
||||
};
|
||||
|
||||
struct NonlinearReferenceComparisonReport {
|
||||
@@ -85,103 +149,257 @@ struct NonlinearReferenceComparisonReport {
|
||||
std::vector<ArtifactSnapshot> pre_run_artifacts;
|
||||
std::vector<ArtifactSnapshot> post_run_artifacts;
|
||||
std::vector<NonlinearReferenceFamilyReport> families;
|
||||
std::vector<NonlinearReferencePrecheckFinding> precheck_findings;
|
||||
std::vector<NonlinearInternalEquilibriumReport> internal_equilibrium;
|
||||
ConstrainedReactionResultantReport constrained_reaction_resultant;
|
||||
bool external_blocking_passed;
|
||||
bool internal_blocking_passed;
|
||||
bool blocking_passed;
|
||||
};
|
||||
|
||||
enum class NonlinearReferenceClassification {
|
||||
kPassed,
|
||||
kFailed,
|
||||
kWarningOnlyDifferences
|
||||
};
|
||||
|
||||
Result<std::vector<ArtifactSnapshot>> ArtifactCheck(
|
||||
const NonlinearReferenceCase& reference_case);
|
||||
Result<std::filesystem::path> CopyInputToExecutionDirectory(
|
||||
const NonlinearReferenceCase& reference_case);
|
||||
Result<GeneratedRunArtifacts> RunFesaApplicationOnCopiedInput(
|
||||
const NonlinearReferenceCase& reference_case,
|
||||
const std::filesystem::path& copied_input_path);
|
||||
Result<NonlinearReferenceComparisonReport> CompareHdf5ToReferenceCsv(
|
||||
const NonlinearReferenceCase& reference_case,
|
||||
const std::filesystem::path& hdf5_results_path);
|
||||
NonlinearReferenceClassification ClassifyReferenceComparison(
|
||||
const NonlinearReferenceComparisonReport& report);
|
||||
NonlinearReferenceComparisonReport BuildReferenceComparisonReport(
|
||||
const NonlinearReferenceCase& reference_case,
|
||||
const std::filesystem::path& hdf5_results_path);
|
||||
|
||||
} // namespace fesa::test
|
||||
```
|
||||
|
||||
These are test-support interfaces only. Match the existing aggregate/data style and avoid a public
|
||||
solver API. For an exact-zero internal scale, leave `normalized_metric` empty and use
|
||||
`diagnostic_code` plus the exact-zero numerator/pass rule instead of writing NaN or Inf.
|
||||
|
||||
## Required physical algorithm
|
||||
|
||||
For each node in stable Domain order at the accepted state:
|
||||
|
||||
1. Read `X` from Domain/model identity and `u, phi` from the accepted state. Set `x=X+u`.
|
||||
2. Read generalized applied force/covector from `generalized_external_force`.
|
||||
3. Build constrained generalized reaction by applying the exact component mask to
|
||||
`generalized_residual` before any rotational conversion.
|
||||
4. Convert applied and constrained-reaction rotational covectors independently with
|
||||
`InverseTransposeLeftJacobianSO3(phi)`. Do not convert their sum as a shortcut and do not mix
|
||||
free generalized residual into reaction.
|
||||
5. Accumulate, about global origin `[0,0,0]`:
|
||||
|
||||
```text
|
||||
F_applied += applied spatial force
|
||||
M_applied += x cross F_applied_node + applied spatial physical moment
|
||||
F_reaction += constrained reaction spatial force
|
||||
M_reaction += x cross F_reaction_node + reaction spatial physical moment
|
||||
global balance error = [F_applied + F_reaction,
|
||||
M_applied + M_reaction]
|
||||
```
|
||||
|
||||
Store only the six-component balance error in the existing accepted-frame
|
||||
`global_equilibrium` and existing `/global/equilibrium` dataset. Reconstruct the constrained
|
||||
reaction resultant and accepted free residual separately in the comparator; do not add summary
|
||||
datasets or a public header.
|
||||
|
||||
For internal blocking gates:
|
||||
|
||||
- Force scale is `max(sum(||F_applied_node||2), sum(||F_reaction_node||2))`.
|
||||
- Moment scale is
|
||||
`max(sum(||x cross F_applied_node + M_applied_node||2),
|
||||
sum(||x cross F_reaction_node + M_reaction_node||2))`.
|
||||
- Force and moment use separate `||balance_error||2/scale <= 1e-8` gates. If scale is exact zero,
|
||||
only exact-zero balance passes. No floor, `max(1,scale)` or clamp is allowed.
|
||||
- Accepted free translation-force and rotation-moment rows use the exact free mask and reproduce
|
||||
NSNR-069: nonzero matching external scale uses
|
||||
`||residual||inf/max(||internal||inf,||external||inf) <= 1e-2`; exact-zero external scale uses
|
||||
typed absolute `<=1e-3`. Finite checks occur first.
|
||||
- `docs/TOLERANCE.md` is not used for these internal gates.
|
||||
|
||||
## RED
|
||||
|
||||
Add tests first.
|
||||
기존 dirty `NSNR-PROC-019`, `NSNR-HDF5-014`, `NSNR-REF-020..023`은 재작성하지 않는다.
|
||||
먼저 existing `NSNR-REF-022`를 실행해 old shared gate failure를 다시 관찰·기록한 뒤,
|
||||
`NSNR-REF-024..025`를 comparator threshold 변경 전에 test-first로 추가한다. Procedure/HDF5
|
||||
behavior는 threshold rework를 위해 추가 변경하지 않는다.
|
||||
|
||||
- `NSNR-REF-001`: artifact check verifies exact pre-run SHA-256 for every declared input/CSV path.
|
||||
- `NSNR-REF-002`: original `reference/shellNL/shellNL.inp` bytes are copied unchanged into a unique build-local temp case directory and only the copied `.inp` is passed to `FesaApplication`.
|
||||
- `NSNR-REF-003`: original `reference/shell/shell.inp` bytes are copied unchanged into a unique build-local temp case directory and only the copied `.inp` is passed to `FesaApplication`.
|
||||
- `NSNR-REF-004`: copied shellNL run produces copied-sibling `shellNL_results.h5` and `shellNL_log.txt`; copied shell run produces copied-sibling `shell_results.h5` and `shell_log.txt`.
|
||||
- `NSNR-REF-005`: HDF5 source path identity matches the copied user-addressed input path, and source content identity matches the approved original input hash.
|
||||
- `NSNR-REF-006`: exact post-run SHA-256, byte size, timestamp, and inventory for all original declared reference artifacts match pre-run snapshots.
|
||||
- `NSNR-REF-007`: shellNL displacement/reaction rows require exact `Frame` value `Increment 10: Step Time = 1.000`.
|
||||
- `NSNR-REF-008`: required CSV wide rows expand to unique `(case_id, accepted_state, instance, source_node_label, component)` keys.
|
||||
- `NSNR-REF-009`: HDF5 rows and CSV rows reject missing, extra, duplicate, and nonfinite required rows before tolerance.
|
||||
- `NSNR-REF-010`: `linear.translation` has 147 blocking rows.
|
||||
- `NSNR-REF-011`: `linear.rotation` has 147 warning-only rows.
|
||||
- `NSNR-REF-012`: `nonlinear.translation` has 147 blocking rows.
|
||||
- `NSNR-REF-013`: `nonlinear.rotation` has 147 warning-only rows.
|
||||
- `NSNR-REF-014`: shellNL constrained nodes select only labels `1,3,4,5,6,7,8,9,14,15,16,17,22,23,24,25,26,27,28,29,30,31,32,33`.
|
||||
- `NSNR-REF-015`: `RF1/RF2` has 48 blocking rows, `RF3` has 24 blocking rows, and `RM1/RM2` has 48 blocking rows.
|
||||
- `NSNR-REF-016`: `RM3` and stress quantities create no numeric comparison family.
|
||||
- `NSNR-REF-017`: docs/TOLERANCE.md family policy is applied exactly and warning-only failures do not change blocking verdict.
|
||||
- `NSNR-REF-018`: stress CSV files are hash-audited as nonblocking inventory artifacts and their schema/order is not a blocking verdict.
|
||||
- Approved draft label `NSNR-PROC-011` collides with completed Step 10's historical
|
||||
`NSNR-PROC-011` increment-loop identity. Preserve that history and use collision-resolved test ID
|
||||
`NSNR-PROC-019` with exact GTest symbol
|
||||
`NonlinearStaticProcedure.NonzeroPrescribedMotionWritesCurrentArmSpatialAppliedPlusReactionBalance`.
|
||||
Use a supported nonlinear shell input with nonzero prescribed translation and rotation plus a
|
||||
resolved fixed-global load. Independently reconstruct the six balance components from accepted
|
||||
`X,u,phi`, external force and masked residual. Expected RED: the current helper uses initial
|
||||
coordinates, raw full-residual summation and raw rotational residual, so the current-arm/spatial
|
||||
expected vector or distinct constrained/free projection assertion fails.
|
||||
- `NSNR-HDF5-014`
|
||||
`NonlinearHdf5ResultsWriter.WritesSchemaV1GlobalBalanceErrorLocation` checks existing path/shape,
|
||||
exact component names, schema version 1 and `location=global-balance-error`. Expected RED: current
|
||||
writer emits `location=global-origin`.
|
||||
- `NSNR-REF-020`
|
||||
`NonlinearStaticReference.AuditsFinePrimaryAndCoarseCompanionArtifacts` checks all exact fine,
|
||||
coarse and linear input/CSV hashes, fine/coarse independent execution directories and case roles.
|
||||
Expected RED: current case inventory supports only coarse nonlinear and linear cases.
|
||||
- `NSNR-REF-021`
|
||||
`NonlinearStaticReference.ReviewOnlyLocalReactionsCannotChangeBlockingVerdict` injects or observes
|
||||
failing local RF/RM row/RMS decisions while U and internal blocking families pass. It requires
|
||||
deterministic local error/precheck reporting and an unchanged blocking pass. Expected RED:
|
||||
current local RF/RM dispositions are `kBlocking`.
|
||||
- `NSNR-REF-022`
|
||||
`NonlinearStaticReference.BlocksOnGlobalBalanceAndAcceptedFreeResidual` fails each coarse/fine
|
||||
global-force, global-moment, free-force-residual and free-moment-residual family one at a time,
|
||||
then passes all. It also asserts the constrained reaction resultant is a distinct review summary.
|
||||
Expected RED for this re-execution: the preserved comparator applies the old shared `<=1e-10`
|
||||
gate, so the approved coarse metric `1.413750912531167e-10` and fine metric
|
||||
`2.7454660159924086e-10` are rejected even though both are below `1e-8`.
|
||||
- `NSNR-REF-023`
|
||||
`NonlinearStaticReference.RejectsMissingExtraDuplicateAndNonfiniteRowsBeforeToleranceAndRecordsReviewOnlyFindings`
|
||||
covers blocking, warning-only and review-only families. Blocking precheck failure changes the
|
||||
blocking verdict; warning/review failures remain ordered findings. Expected RED: the current
|
||||
comparator cannot retain review-only precheck findings independently of the blocking verdict.
|
||||
- `NSNR-REF-024`
|
||||
`NonlinearStaticReference.GlobalForceAndMomentBalanceUseApprovedInclusiveOneEighthGate` uses a
|
||||
test-private balance evaluator for distinct force and moment family identities. It requires an
|
||||
approved between-threshold metric such as `5e-9` and exact `1e-8` to pass, and
|
||||
`nextafter(1e-8,+infinity)` to fail for both identities. Expected decisive RED: the preserved
|
||||
shared `<=1e-10` comparison rejects `5e-9` and `1e-8`.
|
||||
- `NSNR-REF-025`
|
||||
`NonlinearStaticReference.GlobalForceAndMomentExactZeroScaleRequiresExactZeroBalance` exercises
|
||||
force and moment identities independently and requires exact-zero scale plus exact-zero numerator
|
||||
to pass while any nonzero numerator fails without NaN/Inf or a fabricated normalized metric. This
|
||||
is an unchanged-contract regression and may already pass in the RED batch; it must be present
|
||||
before GREEN.
|
||||
|
||||
Run:
|
||||
Run and record the observed failures:
|
||||
|
||||
```powershell
|
||||
cmake --build --preset windows-msvc-ninja-debug
|
||||
ctest --preset windows-msvc-ninja-debug -R "NonlinearStaticReference|ReferenceTolerance|Mitc4Reference" --output-on-failure
|
||||
ctest --preset windows-msvc-ninja-debug -R "^(NonlinearStaticProcedure|NonlinearHdf5ResultsWriter|NonlinearStaticReference)\." --output-on-failure
|
||||
```
|
||||
|
||||
Expected: new tests fail. Unexpected pass stops.
|
||||
The new tests must fail for the stated reasons. A compile failure caused only by the test-first
|
||||
enum/report extension is valid RED when the diagnostic identifies the missing planned production/
|
||||
test-support behavior. An unexpected pass or unrelated failure stops the Step for classification.
|
||||
|
||||
## GREEN
|
||||
## Minimal GREEN
|
||||
|
||||
Implement `ARTIFACT CHECK -> COPY -> RUN -> COMPARE -> CLASSIFY -> REPORT` while preserving the required public gate wording `ARTIFACT CHECK -> COMPARE -> CLASSIFY -> REPORT` in reports. The runner never passes the original reference input path to `FesaApplication`; it copies input bytes unchanged into a unique build-local temp case directory, runs the copied `.inp`, consumes copied-sibling `_results.h5` and `_log.txt`, and compares HDF5 data to original read-only CSVs. Use exact declared paths and hashes:
|
||||
1. Replace the private raw-residual/initial-coordinate global helper in
|
||||
`src/fesa/analysis/nonlinear_static_procedure.cpp` with the Required physical algorithm above.
|
||||
Keep stable node order, mask-before-conversion, independent applied/reaction conversion and
|
||||
finite failure behavior. Do not change the public procedure header or accepted-state layout.
|
||||
2. In `src/fesa/io/hdf5/nonlinear_hdf5_results_writer.cpp`, preserve the path, shape, component
|
||||
names and schema version; change the exact `/global/equilibrium` location attribute to
|
||||
`global-balance-error` and keep writer validation finite/fail-closed.
|
||||
3. Extend the existing comparator without deleting its partial work:
|
||||
- add fine primary inventory and keep coarse companion/linear control independent;
|
||||
- add `kReviewOnly` and keep local RF/RM key/schema/inventory/finite/row/RMS evidence;
|
||||
- reconstruct the constrained reaction resultant and accepted free residual from the exact HDF5
|
||||
paths/mask; never use `/nodal/reaction` or `/global/equilibrium` as a substitute for all three;
|
||||
- apply internal gates exactly as specified above, using one test-private/internal shared
|
||||
`1.0e-8` constant for both distinct force and moment families;
|
||||
- keep U blocking, UR warning-only, local RF/RM review-only, RM3/stress excluded;
|
||||
- reject blocking missing/extra/duplicate/nonfinite rows before tolerance and retain ordered
|
||||
nonblocking findings;
|
||||
- set overall blocking verdict from blocking external U families AND all internal global/free
|
||||
families only.
|
||||
4. Preserve existing `NSNR-CTRL-018..021`, `NSNR-LOG-012`, Full Newton, fixed factors, iteration
|
||||
limit, 39-field log schema and the already corrected residual selector unchanged.
|
||||
5. Do not change production solver/configuration behavior for the balance threshold. No `fesa.env`,
|
||||
environment variable, CLI option, public API or HDF5 schema change is part of this GREEN.
|
||||
|
||||
| path | rows | SHA-256 |
|
||||
| --- | ---: | --- |
|
||||
| `reference/shellNL/shellNL.inp` | input | `4BF3ECB0F7F1E8462C573E993DBC97AC5D920C91CF6F23AD4C6891D77FFBADA2` |
|
||||
| `reference/shellNL/shellNL displacements.csv` | 49 | `4E0F99CA9372B1ADF7FAF102F43BC0B887DC743FDEDA378E4342D2CF8E0C0786` |
|
||||
| `reference/shellNL/shellNL reactions.csv` | 49 | `001CB1541A9E94424E5E650509D46BC8724970DF4DE47184D9DB09C7938AB069` |
|
||||
| `reference/shellNL/shellNL stresses.csv` | 288 | `5500E5114B1C44887528E30CEC054A1EB0F68BE3F4B8CE81FA59FC74A881483F` |
|
||||
| `reference/shell/shell.inp` | input | `4005851E1AB22FD3A16AC17A8D5DA3E051233F69F37419079F3553AD134ECFCF` |
|
||||
| `reference/shell/shell displacements.csv` | 49 | `C81D94E0B4A849F87AA0F79C83A79B94D5661AC79E44ED826919AB432C87746B` |
|
||||
| `reference/shell/shell reactions.csv` | 49 | `0E34EEC27E700C3C0C744C1DAFD8A3B95EFEF34B8616FE96665876586FE82D41` |
|
||||
| `reference/shell/shell stresses.csv` | 288 | `2B75A5B0DEB045A283C9BB7E9B1153B79F7537FF487214BF4A23316B59B660A7` |
|
||||
## Exact read-only artifact inventory
|
||||
|
||||
Use docs/TOLERANCE.md exactly: family scale `S=max(abs(reference))`, near-zero band `0.01*S`, non-near relative error `<=0.05`, family `RMS(error)/S<=0.01`, zero-scale exact zero only. Original reference directory inventory, bytes, timestamps, and hashes must be unchanged after the run.
|
||||
| case | exact path | rows | SHA-256 |
|
||||
| --- | --- | ---: | --- |
|
||||
| fine primary | `reference/shellNL-meshfine/shellNL-meshfine.inp` | input | `40DF1CE77311C8D799564A21A60F3BDEBB8148D52CAE22B7292FDFAD32018220` |
|
||||
| fine primary | `reference/shellNL-meshfine/shellNL-meshfine displacements.csv` | 729 | `740819FF8AED0E279961581F7CDBFA12784CFBA3A488C35A652E80103F64433F` |
|
||||
| fine primary | `reference/shellNL-meshfine/shellNL-meshfine reactions.csv` | 729 | `AEB01C98C596792B0E5F2B86A81945CAB0BEB0C6969CFC6738C6F81DF1F94363` |
|
||||
| fine optional | `reference/shellNL-meshfine/shellNL-meshfine stresses.csv` | 5,408 | `6D6213AB5DB9D6B1F5FBD641367D08BACC805967B6C5A95BCE0E1A5395377782` |
|
||||
| coarse companion | `reference/shellNL/shellNL.inp` | input | `4BF3ECB0F7F1E8462C573E993DBC97AC5D920C91CF6F23AD4C6891D77FFBADA2` |
|
||||
| coarse companion | `reference/shellNL/shellNL displacements.csv` | 49 | `4E0F99CA9372B1ADF7FAF102F43BC0B887DC743FDEDA378E4342D2CF8E0C0786` |
|
||||
| coarse companion | `reference/shellNL/shellNL reactions.csv` | 49 | `001CB1541A9E94424E5E650509D46BC8724970DF4DE47184D9DB09C7938AB069` |
|
||||
| coarse optional | `reference/shellNL/shellNL stresses.csv` | 288 | `5500E5114B1C44887528E30CEC054A1EB0F68BE3F4B8CE81FA59FC74A881483F` |
|
||||
| linear control | `reference/shell/shell.inp` | input | `4005851E1AB22FD3A16AC17A8D5DA3E051233F69F37419079F3553AD134ECFCF` |
|
||||
| linear control | `reference/shell/shell displacements.csv` | 49 | `C81D94E0B4A849F87AA0F79C83A79B94D5661AC79E44ED826919AB432C87746B` |
|
||||
| linear optional | `reference/shell/shell reactions.csv` | 49 | `0E34EEC27E700C3C0C744C1DAFD8A3B95EFEF34B8616FE96665876586FE82D41` |
|
||||
| linear optional | `reference/shell/shell stresses.csv` | 288 | `2B75A5B0DEB045A283C9BB7E9B1153B79F7537FF487214BF4A23316B59B660A7` |
|
||||
|
||||
## VERIFY
|
||||
For every case, snapshot original inventory, bytes, SHA-256, size and timestamp; copy only the `.inp`
|
||||
bytes to a unique build-local directory; run only the copy; consume copied-sibling `_results.h5` and
|
||||
`_log.txt`; compare against original read-only CSVs; then prove the original inventory is unchanged.
|
||||
|
||||
## External comparison and classification
|
||||
|
||||
- Fine and coarse `U1/U2/U3` are separate blocking families.
|
||||
- Linear `U1/U2/U3` is a blocking regression family.
|
||||
- All `UR1/UR2/UR3` families are warning-only.
|
||||
- Fine/coarse local `RF1/RF2`, `RF3`, spatial `RM1/RM2` are separate review-only families with exact
|
||||
mask-derived keys and complete common-policy error reports.
|
||||
- `RM3` and all stress values have no numerical family. Stress files remain hash-audited optional
|
||||
inventory; the known fine malformed optional stress key is not repaired.
|
||||
- External families use exactly `docs/TOLERANCE.md`: reference-only `S=max(abs(reference))`,
|
||||
`B=0.01*S`, near-zero row `abs(error)<=B`, other-row relative `<=0.05`, family
|
||||
`RMS(error)/S<=0.01`, exact-zero family exact-zero FESA only. No absolute floor, averaging,
|
||||
collapse, row-order identity, clamp or tolerance relaxation.
|
||||
|
||||
The final gate order is literally:
|
||||
|
||||
```text
|
||||
ARTIFACT CHECK -> COMPARE -> CLASSIFY -> REPORT
|
||||
```
|
||||
|
||||
## Focused and full VERIFY
|
||||
|
||||
After minimal GREEN, run in this order and retain command, exit code, duration and output tail for
|
||||
Step 12:
|
||||
|
||||
```powershell
|
||||
cmake --preset windows-msvc-ninja-debug
|
||||
cmake --build --preset windows-msvc-ninja-debug
|
||||
ctest --preset windows-msvc-ninja-debug -R "NonlinearStaticReference|ReferenceTolerance|Mitc4Reference" --output-on-failure
|
||||
ctest --preset windows-msvc-ninja-debug -R "^(NonlinearConvergence|NewtonIterationLog)\." --output-on-failure
|
||||
ctest --preset windows-msvc-ninja-debug -R "^(NonlinearStaticProcedure|NonlinearHdf5ResultsWriter)\." --output-on-failure
|
||||
ctest --preset windows-msvc-ninja-debug -R "^NonlinearStaticReference\." --output-on-failure
|
||||
ctest --preset windows-msvc-ninja-debug -R "^(NonlinearStaticReference|ReferenceTolerance|Mitc4Reference)\." --output-on-failure
|
||||
ctest --preset windows-msvc-ninja-debug --show-only=json-v1
|
||||
ctest --preset windows-msvc-ninja-debug --output-on-failure
|
||||
```
|
||||
|
||||
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.
|
||||
The Harness launch environment must be VsDevCmd x64 and inherit `FESA_GTEST_SOURCE_DIR`, `MKL_DIR`,
|
||||
`TBB_DIR`, and `HDF5_DIR`. Do not substitute the solution-only MSBuild path.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
- New RED tests fail first for their declared current behavior, then pass after minimal GREEN.
|
||||
- `/global/equilibrium` remains schema v1 `[6]` with the same component names and stores only the
|
||||
current-arm/spatial-moment applied-plus-reaction balance error with
|
||||
`location=global-balance-error`.
|
||||
- Fine/coarse global force and moment normalized metrics are each `<=1e-8`; exact-zero scale follows
|
||||
the exact-zero rule.
|
||||
- Fine/coarse accepted free force and moment residual gates pass NSNR-069 independently.
|
||||
- Fine/coarse U blocking and linear U regression pass `docs/TOLERANCE.md`.
|
||||
- UR differences remain warning-only. Local RF/RM findings remain review-only and cannot fail the
|
||||
blocking verdict. RM3/stress remain excluded.
|
||||
- Missing/extra/duplicate/nonfinite blocking rows fail before tolerance; warning/review findings are
|
||||
deterministic and nonblocking.
|
||||
- Original reference artifact content, inventory, size, timestamp and hash are unchanged.
|
||||
- Focused tests, test discovery and full CTest pass without new compiler warnings.
|
||||
|
||||
## 상태 기록
|
||||
|
||||
Update only Step 11 status and one-line payload. Executor owns timestamps, commits, retry, and advancement.
|
||||
On success, update only Step 11 to `completed` and add one concise `summary`. On an implementation,
|
||||
build, test or reference-comparison failure, classify it and update only the Executor-selected Step's
|
||||
allowed payload. Executor owns retry, timestamps, commits, advancement and top-level status. Do not
|
||||
start Step 12.
|
||||
|
||||
## 금지사항
|
||||
|
||||
- Do not rewrite, rename, normalize, or repair `.inp` or CSV artifacts. 이유: reference artifacts are immutable external evidence.
|
||||
- Do not run `FesaApplication` on original `reference/shellNL/shellNL.inp` or `reference/shell/shell.inp`. 이유: CLI derives sibling outputs and would mutate the reference directory.
|
||||
- Do not compare `RM3`. 이유: approved contract excludes stabilization-dependent drilling reaction.
|
||||
- Do not numerically compare stress CSV data. 이유: stress artifacts are nonblocking inventory only in this feature.
|
||||
- Do not average, omit, synthesize, or row-order match reference rows. 이유: source/component identity prechecks are mandatory.
|
||||
- Do not edit any reference artifact. 이유: exact stored files are immutable external evidence.
|
||||
- Do not run FESA on an original reference `.inp`. 이유: derived sibling outputs would mutate the
|
||||
reference directory.
|
||||
- Do not add HDF5 datasets, change schema version/path/shape/components or add public headers. 이유:
|
||||
Stage 5 requires reconstruction from existing schema-v1 datasets.
|
||||
- Do not use initial coordinates or raw rotational covectors for global physical moment. 이유:
|
||||
`AUDIT-001` requires accepted current arms and spatial moment conversion.
|
||||
- Do not apply the constraint mask after spatial conversion. 이유: partial rotational constraints
|
||||
would mix free residual into reaction.
|
||||
- Do not use `/global/equilibrium`, local `/nodal/reaction` or a raw full-residual sum as a substitute
|
||||
for all three equilibrium quantities. 이유: their physical identities differ.
|
||||
- Do not make local reaction rows blocking or omit their review evidence. 이유: USER-DECISION-004
|
||||
fixes review-only with deterministic findings.
|
||||
- Do not compare `RM3` or stress values, average/collapse rows, match by row order, clamp zero values,
|
||||
add `max(1,S)`, relax tolerance or repair CSVs. 이유: approved identity/tolerance contracts forbid it.
|
||||
- Do not add `fesa.env`, runtime configuration, product solver acceptance, CLI or public API behavior
|
||||
for the `1e-8` gate. 이유: this fixed threshold belongs only to comparator-owned internal verification.
|
||||
- Do not replay or fabricate selector RED, delete partial Step 11 work, reset history, commit, push,
|
||||
run a reference solver, start Step 12, or claim Physics/Release readiness.
|
||||
- Stop and return a classified blocker if the required behavior needs an upstream contract, public
|
||||
API, HDF5 schema, tolerance or reference-artifact change.
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# Step 12: execution-closure-and-evidence-docs
|
||||
|
||||
## 목적
|
||||
|
||||
Step 11이 실제로 통과한 뒤에만 fresh MSVC/CTest와 reference gate evidence를 수집하고 Stage 6
|
||||
canonical reports를 actual output으로 작성한다. 직접 superseded된 PRD/ARCHITECTURE/ADR 문장만
|
||||
최소 동기화한다. 이 Step은 solver 동작을 새로 구현하지 않는다.
|
||||
|
||||
## 읽어야 할 파일
|
||||
|
||||
- `AGENTS.md`
|
||||
@@ -8,85 +14,219 @@
|
||||
- `docs/ADR.md`
|
||||
- `docs/CODINGSTYLE.md`
|
||||
- `docs/TOLERANCE.md`
|
||||
- `docs/nonlinear-static-newton-raphson/implementation-plan.md`
|
||||
- `docs/SOLVER_AGENT_DESIGN.md`
|
||||
- `docs/HARNESS.md`
|
||||
- `docs/HARNESS_WORKFLOW.md`
|
||||
- `docs/nonlinear-static-newton-raphson/requirements.md`
|
||||
- `docs/nonlinear-static-newton-raphson/numerical-review.md`
|
||||
- `docs/nonlinear-static-newton-raphson/reference-model.md`
|
||||
- `docs/nonlinear-static-newton-raphson/io.md`
|
||||
- `docs/nonlinear-static-newton-raphson/formulation.md` §§11.4, 13.1, 13.4, 14.1
|
||||
- `docs/nonlinear-static-newton-raphson/numerical-review.md` §§3.2, 6.2, 6.3
|
||||
- `docs/nonlinear-static-newton-raphson/reference-model.md` §§3–6
|
||||
- `docs/nonlinear-static-newton-raphson/io.md` §§7.5.1, 8.1–8.7
|
||||
- `docs/nonlinear-static-newton-raphson/implementation-plan.md`
|
||||
- `docs/nonlinear-static-newton-raphson/corrections.md` §13
|
||||
- `phases/nonlinear-static-newton-raphson/index.json`
|
||||
- Step 0-11 modified source/test/CMake files
|
||||
- `phases/nonlinear-static-newton-raphson/step11.md`
|
||||
- All source/test/CMake files actually changed by Steps 0–11
|
||||
- `.harness/config.json`
|
||||
- `CMakePresets.json`
|
||||
|
||||
## 이전 Step 전제
|
||||
## 시작 전 hard gate
|
||||
|
||||
Steps 0-11 have implemented and verified CLI lifecycle, Domain contract, nonlinear MITC4, controls, tangent solver, log, state, HDF5 schema v1, full prepared procedure, and reference comparison tests.
|
||||
- Steps 0–10의 completed history를 그대로 유지한다.
|
||||
- Step 11 must be `completed` with an actual summary and passing RED/GREEN/VERIFY evidence.
|
||||
- If Step 11 is not completed, stop without creating/updating evidence docs or global docs.
|
||||
- Do not infer Step 11 success from a prior blocked run, diagnostic spike or translation-only report.
|
||||
|
||||
## 소유 파일
|
||||
|
||||
- Modify: `docs/PRD.md`
|
||||
- Modify: `docs/ARCHITECTURE.md`
|
||||
- Modify: `docs/ADR.md`
|
||||
- Create: `docs/nonlinear-static-newton-raphson/implementation-report.md`
|
||||
- Create: `docs/nonlinear-static-newton-raphson/build-test.md`
|
||||
- Create: `docs/nonlinear-static-newton-raphson/reference-comparison.md`
|
||||
- Modify only directly superseded statements: `docs/PRD.md`
|
||||
- Modify only directly superseded statements: `docs/ARCHITECTURE.md`
|
||||
- Modify only directly superseded decisions or add the minimum accepted decision record:
|
||||
`docs/ADR.md`
|
||||
- Create from actual outputs: `docs/nonlinear-static-newton-raphson/implementation-report.md`
|
||||
- Create from actual outputs: `docs/nonlinear-static-newton-raphson/build-test.md`
|
||||
- Create from actual outputs: `docs/nonlinear-static-newton-raphson/reference-comparison.md`
|
||||
|
||||
No C++ production file is owned by this Step.
|
||||
No C++ production, public header, test, CMake, Harness, reference or tolerance file is owned by this
|
||||
Step.
|
||||
|
||||
## 인터페이스
|
||||
## RED: evidence freshness audit
|
||||
|
||||
Evidence documents must record actual observed outputs:
|
||||
Perform this audit before writing reports. The expected initial result is failure because the three
|
||||
canonical reports are missing or do not contain this Step's fresh evidence.
|
||||
|
||||
```text
|
||||
implementation-report.md: RED/GREEN/VERIFY command log, Step summaries, diagnostics, implementation-owned decisions.
|
||||
build-test.md: fresh configure/build/discovery/full CTest commands, exit codes, duration, stdout/stderr tail, warning audit, failure classification.
|
||||
reference-comparison.md: exact artifact inventory, HDF5 paths, projection, row prechecks, tolerance, per-family decisions, classification, no-change assertion.
|
||||
```
|
||||
- `NSNR-EVID-001`: `implementation-report.md` is missing or stale unless it records every Step 11 new
|
||||
RED test, the observed reason, minimal GREEN diff, focused/full VERIFY and preserved
|
||||
`NSNR-CTRL-018..021`/`NSNR-LOG-012` evidence.
|
||||
- `NSNR-EVID-002`: `build-test.md` is missing or stale unless it records fresh configure, build,
|
||||
discovery, focused/full CTest commands with exit code, duration, output tail, MSVC x64 Debug
|
||||
environment, warning audit and failure classification.
|
||||
- `NSNR-EVID-003`: `reference-comparison.md` is missing or stale unless it records the literal
|
||||
`ARTIFACT CHECK -> COMPARE -> CLASSIFY -> REPORT` run with exact paths/hashes, generated HDF5/log
|
||||
paths, projection, row decisions, metrics, classification and no-change evidence.
|
||||
- `NSNR-EVID-004`: evidence or global docs are stale if they still classify local RF/RM as blocking,
|
||||
omit review-only findings, identify coarse shellNL as the only nonlinear case, or describe
|
||||
`/global/equilibrium` as raw full-residual/initial-arm evidence.
|
||||
- `NSNR-EVID-005`: reference evidence is stale if it lacks fine-primary/coarse-companion/linear-control
|
||||
inventory, separate U/UR/local reaction families, four coarse and four fine internal blocking
|
||||
equilibrium families, the inclusive `1e-8` force/moment boundary and exact-zero-scale regressions,
|
||||
and the distinct constrained-reaction summary.
|
||||
- `NSNR-EVID-006`: implementation evidence is stale unless it closes `AUDIT-001` with actual tests for
|
||||
nonzero prescribed translation/rotation, `x=X+u`, mask-before-conversion, independent
|
||||
`InverseTransposeLeftJacobianSO3(phi)` conversion, and `location=global-balance-error`.
|
||||
- `NSNR-EVID-007`: command evidence is stale if copied from an earlier run, omits artifact pre/post
|
||||
immutability, lacks command output/exit/duration, changes the required stage order, or claims a
|
||||
verdict before CLASSIFY.
|
||||
|
||||
## RED
|
||||
Record this expected failing freshness audit in `implementation-report.md` only after fresh evidence
|
||||
has been collected. If the audit unexpectedly passes before this Step's commands, stop and report the
|
||||
evidence provenance conflict.
|
||||
|
||||
Before writing evidence docs, run an evidence freshness audit by checking that the three evidence docs do not already contain current command outputs from this final Step.
|
||||
## GREEN: fresh evidence execution
|
||||
|
||||
- `NSNR-EVID-001`: missing or stale `implementation-report.md` is a failing precondition.
|
||||
- `NSNR-EVID-002`: missing or stale `build-test.md` is a failing precondition.
|
||||
- `NSNR-EVID-003`: missing or stale `reference-comparison.md` is a failing precondition.
|
||||
- `NSNR-EVID-004`: PRD/ARCHITECTURE/ADR still contain directly superseded global CLI/procedure/output statements.
|
||||
- `NSNR-EVID-005`: reference artifact pre-run SHA inventory must match Step 11 values.
|
||||
Use the ignored `.harness/config.json` and tracked `windows-msvc-ninja-debug` preset. The parent
|
||||
environment must be VsDevCmd x64 and contain `FESA_GTEST_SOURCE_DIR`, `MKL_DIR`, `TBB_DIR`, and
|
||||
`HDF5_DIR`.
|
||||
|
||||
Expected: evidence freshness audit fails before this Step writes docs. If it unexpectedly passes with current evidence already present, stop and report to Coordinator.
|
||||
|
||||
## GREEN
|
||||
|
||||
- Run fresh MSVC x64 Debug configure/build/discovery/full CTest.
|
||||
- Run focused nonlinear reference comparison repeat.
|
||||
- Run deterministic repeat/reference checks required by Step 11.
|
||||
- Run warning audit from build output.
|
||||
- Run `git diff --check` and `git status --short`.
|
||||
- Run reference artifact post-run SHA audit and compare to pre-run values.
|
||||
- Update only directly superseded PRD/ARCHITECTURE/ADR statements for CLI removal, prepared linear/nonlinear procedure boundary, output naming, log lifecycle, and nonlinear HDF5 schema.
|
||||
- Create the three Stage 6 evidence docs from actual command outputs only.
|
||||
|
||||
## VERIFY
|
||||
|
||||
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:
|
||||
### 1. Fresh build and regression evidence
|
||||
|
||||
```powershell
|
||||
cmake --preset windows-msvc-ninja-debug
|
||||
cmake --build --preset windows-msvc-ninja-debug
|
||||
ctest --preset windows-msvc-ninja-debug --show-only=json-v1
|
||||
ctest --preset windows-msvc-ninja-debug -R "^(NonlinearConvergence|NewtonIterationLog)\." --output-on-failure
|
||||
ctest --preset windows-msvc-ninja-debug -R "^(NonlinearStaticProcedure|NonlinearHdf5ResultsWriter)\." --output-on-failure
|
||||
ctest --preset windows-msvc-ninja-debug --output-on-failure
|
||||
ctest --preset windows-msvc-ninja-debug -R "NonlinearStaticReference" --output-on-failure
|
||||
```
|
||||
|
||||
Record command, working directory, exit code, duration, stdout/stderr tail and failed-test inventory.
|
||||
Audit new compiler warnings. Stop at the first decisive failure and classify it as
|
||||
`configure | compile | link | test | reference-comparison | harness | environment | upstream-contract`.
|
||||
|
||||
### 2. Final reference gate in literal order
|
||||
|
||||
#### ARTIFACT CHECK
|
||||
|
||||
- Verify every exact fine/coarse/linear input/CSV path and SHA-256 from `reference-model.md` and
|
||||
`step11.md`.
|
||||
- Verify readable headers, exact nonlinear factor-one Frame, source node/component inventories,
|
||||
uniqueness and finite required values.
|
||||
- Snapshot original inventory, size, timestamps and hashes before any copied-input run.
|
||||
- Verify generated results will be written only under unique build-local copied-input directories.
|
||||
|
||||
#### COMPARE
|
||||
|
||||
```powershell
|
||||
ctest --preset windows-msvc-ninja-debug -R "^NonlinearStaticReference\." --output-on-failure
|
||||
ctest --preset windows-msvc-ninja-debug -R "^(NonlinearStaticReference|ReferenceTolerance|Mitc4Reference)\." --output-on-failure
|
||||
```
|
||||
|
||||
Compare by `(case_id, accepted_state, canonical_instance_name, source_node_label, component)`, never
|
||||
by row order. Apply `docs/TOLERANCE.md` only to external U/UR/local-review families. Apply internal
|
||||
`1e-8` force/moment balance and NSNR-069 free-residual gates separately. Preserve the exact
|
||||
blocking/warning/review/excluded dispositions.
|
||||
|
||||
#### CLASSIFY
|
||||
|
||||
- Blocking pass requires fine/coarse U families, linear U regression and all eight fine/coarse
|
||||
internal equilibrium families to pass.
|
||||
- UR failure is warning-only.
|
||||
- Local RF/RM precheck/row/RMS failure is a deterministic review finding and cannot change blocking
|
||||
pass/fail.
|
||||
- RM3/stress values are excluded.
|
||||
- Any blocking missing/extra/duplicate/nonfinite row fails before tolerance.
|
||||
- Classify actual failures without relaxing tolerance, changing artifacts or claiming external solver
|
||||
internal equivalence.
|
||||
|
||||
#### REPORT
|
||||
|
||||
Only after CLASSIFY, write the three canonical reports from actual outputs.
|
||||
|
||||
## Report contracts
|
||||
|
||||
### `implementation-report.md`
|
||||
|
||||
Record metadata, approved upstream hashes, Steps 0–10 preserved summaries, Step 11 RED failures,
|
||||
minimal GREEN file/symbol changes, focused/full VERIFY commands and results, `AUDIT-001` closure,
|
||||
requirement/test traceability, no-change assertion, classification and open issues. Do not invent
|
||||
unobserved output.
|
||||
|
||||
### `build-test.md`
|
||||
|
||||
Use `owner_agent: implementation-agent`. Record execution environment, exact commands, working
|
||||
directories, exit codes, durations, output tails, discovered test inventory, focused/full results,
|
||||
new-warning audit, failure classification, failed tests, handoff recommendation, no-change assertion
|
||||
and open issues.
|
||||
|
||||
### `reference-comparison.md`
|
||||
|
||||
Record exact input/CSV SHA inventory, copied input and generated HDF5/log paths, accepted factor-one
|
||||
frame, every HDF5 projection/path/component, stable source-key matching, row prechecks, external
|
||||
common tolerance, internal gates, per-family/per-row decisions, max absolute error, applicable
|
||||
relative error, RMS/scale metric, constrained-reaction summary, warnings/review findings, final
|
||||
classification, original artifact post-run identity, no-change assertion and open issues.
|
||||
|
||||
The report must explicitly state that FESA HDF5 is authoritative, CSV is external comparison
|
||||
evidence, and numerical agreement does not imply Abaqus S4 internal formulation equivalence.
|
||||
|
||||
## Minimal PRD/ARCHITECTURE/ADR sync
|
||||
|
||||
After actual passing evidence exists, update only statements directly superseded by the implemented
|
||||
feature:
|
||||
|
||||
- repository-wide derived result/log names and removal of `--output`;
|
||||
- prepared parse-once linear/nonlinear procedure boundary and separate nonlinear state/solver/writer;
|
||||
- nonlinear HDF5 schema v1 accepted-frame meaning;
|
||||
- `/global/equilibrium` as current-arm/spatial-moment applied-plus-reaction balance error;
|
||||
- distinct accepted free residual and constrained reaction resultant projections;
|
||||
- fine primary/coarse companion, U blocking, UR warning-only, local RF/RM review-only and RM3/stress
|
||||
exclusion.
|
||||
|
||||
Do not rewrite unrelated V0 history, refactor architecture prose or add future scope.
|
||||
|
||||
## Final validation
|
||||
|
||||
```powershell
|
||||
git diff --check
|
||||
git status --short
|
||||
```
|
||||
|
||||
Record command, exit code, duration, stdout/stderr tail, and failure classification for every command in the evidence docs.
|
||||
Confirm the original reference pre/post hashes, sizes, timestamps and inventory are equal. Confirm
|
||||
that every required report statement is backed by a command or deterministic artifact observation.
|
||||
Harness Python validation is not required because this Step does not change Harness Python, hooks or
|
||||
agent configuration.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
- Evidence freshness audit initially fails for the declared stale/missing reason and is recorded.
|
||||
- Fresh configure/build/discovery/focused/full CTest all pass with MSVC x64 Debug and no new warnings.
|
||||
- Final gate executes in exact order `ARTIFACT CHECK -> COMPARE -> CLASSIFY -> REPORT`.
|
||||
- All blocking external and internal families pass; warnings and review findings remain
|
||||
nonblocking and are fully reported.
|
||||
- `AUDIT-001`, fine/coarse roles and reaction disposition have direct test/output evidence.
|
||||
- Three canonical Stage 6 reports contain reproducible commands, metrics, classifications and
|
||||
no-change assertions.
|
||||
- PRD/ARCHITECTURE/ADR edits are limited to directly superseded statements.
|
||||
- `git diff --check` passes and reference artifacts remain byte-for-byte unchanged.
|
||||
|
||||
## 상태 기록
|
||||
|
||||
Update only Step 12 status and one-line payload. Executor owns timestamps, commits, retry, top-level phase completion, and advancement.
|
||||
On success, update only Step 12 to `completed` and add one concise `summary`. Executor owns
|
||||
timestamps, commits, top-level completion and advancement. A passing Step 12 returns Stage 6 evidence
|
||||
to Coordinator; it does not itself dispatch Physics or Release.
|
||||
|
||||
## 금지사항
|
||||
|
||||
- Do not claim success before the commands above actually pass. 이유: Stage 6 evidence docs must be output-backed.
|
||||
- Do not broadly rewrite global docs. 이유: Step 12 only synchronizes directly superseded CLI/procedure/output statements.
|
||||
- Do not change reference artifact content. 이유: SHA pre/post immutability is part of the acceptance evidence.
|
||||
- Do not run `scripts/execute.py` from this Step. 이유: Executor already owns Harness execution.
|
||||
- Do not create or update evidence reports before actual fresh output exists. 이유: Stage 6 reports
|
||||
are execution evidence, not predictions.
|
||||
- Do not change C++ code, tests, CMake, Harness configuration, tolerance or reference artifacts.
|
||||
이유: Step 12 is evidence closure only.
|
||||
- Do not run `scripts/execute.py` from this Step. 이유: Executor already owns the active Step session.
|
||||
- Do not reorder or collapse `ARTIFACT CHECK -> COMPARE -> CLASSIFY -> REPORT`. 이유: schema and
|
||||
identity failures must precede tolerance and verdict.
|
||||
- Do not make local RF/RM blocking, omit their errors, or compare RM3/stress. 이유:
|
||||
USER-DECISION-004 fixes the disposition.
|
||||
- Do not use Abaqus CSV/tolerance for internal balance/free-residual gates or claim Abaqus internal
|
||||
equivalence. 이유: external comparison and internal physics evidence are distinct.
|
||||
- Do not broadly rewrite PRD/ARCHITECTURE/ADR, alter Steps 0–11 history, commit, push, run a reference
|
||||
solver, or claim Physics/Release readiness.
|
||||
|
||||
@@ -136,6 +136,15 @@ Add tests first.
|
||||
- `NSNR-CTRL-016`: empty free channels evaluate with `numerator_norm=0`, `denominator_scale=0`, branch `kZeroScale`, exact zero-scale threshold/unit, and pass.
|
||||
- `NSNR-CTRL-017`: iteration numbering remains `1..100` with no iteration `101`.
|
||||
|
||||
### USER-DECISION-003 option-1 revision addendum
|
||||
|
||||
Step 5의 completed status, summary, timestamps와 commits는 보존한다. 다음 correction tests와 minimal GREEN은 재실행된 Step 5가 아니라 Executor-selected Step 11 안에서 수행한다.
|
||||
|
||||
- `NSNR-CTRL-018`: force와 force-length residual channel 각각에서 matching external vector가 finite exact zero이고 internal/residual이 nonzero여도 `kZeroScale`을 선택한다. Numerator exact `1.0e-3`은 pass, `std::nextafter(1.0e-3, +infinity)`는 fail이며 decision denominator는 exact `0`, threshold unit은 각각 `kForce`, `kForceLength`다. Empty free channel pass도 유지한다.
|
||||
- `NSNR-CTRL-019`: matching external scale이 nonzero이면 internal-dominant와 external-dominant case 모두 denominator `max(||f_int||inf,||f_ext||inf)`를 쓴다. Ratio exact `1.0e-2`는 pass, 바로 위는 fail이다. Numerator가 typed `1.0e-3`보다 작아도 relative ratio가 실패하는 case를 포함하여 absolute/relative OR가 없음을 증명한다.
|
||||
- `NSNR-CTRL-020`: residual/internal/external vector 또는 derived norm의 NaN/Inf는 branch/tolerance acceptance 전에 fail하고 combined pass를 만들지 않는다. `std::nextafter(0.0,+infinity)`인 matching external scale은 tolerance band, zero clamp, `max(1,...)` 없이 nonzero relative branch를 선택한다.
|
||||
- `NSNR-CTRL-021`: force residual, moment residual, translation correction, rotation correction을 하나씩 실패시키는 truth table과 네 channel 모두 pass하는 case로 logical AND를 고정한다. NSNR-070 correction selector, denominators, thresholds와 units는 변경하지 않는다.
|
||||
|
||||
Run:
|
||||
|
||||
```powershell
|
||||
@@ -147,7 +156,7 @@ Expected: new tests fail. Unexpected pass stops.
|
||||
|
||||
## GREEN
|
||||
|
||||
Implement factor sequence derivation, load/BC scaling, global-once fixed-load external vector `f_ext` and external tangent `K_ext` assembly, moment admissibility, and typed convergence-channel evaluation. Residual denominator scale is derived from the provided free internal/external channel values, correction denominator scale from the provided current increment channel values, and zero-scale branches use only `kZeroScale`. Thresholds and threshold units are not caller inputs; `EvaluateNewtonConvergence` assigns the exact branch/channel constants from `requirements.md` and `io.md`. Return structured diagnostics for invalid nonlinear static data, unsupported drilling load, nonfinite Newton data, and nonconvergence readiness.
|
||||
Implement factor sequence derivation, load/BC scaling, global-once fixed-load external vector `f_ext` and external tangent `K_ext` assembly, moment admissibility, and typed convergence-channel evaluation. For the USER-DECISION-003 correction, validate the residual/internal/external values and norms first, select a residual branch from the matching external scale itself, emit denominator exact `0` and typed absolute `1.0e-3` when that scale is exact zero, and otherwise emit retained `max(internal,external)` with relative `1.0e-2`. Correction denominator selection remains derived from current increment values. Thresholds and threshold units are not caller inputs; `EvaluateNewtonConvergence` assigns the exact branch/channel constants from `requirements.md` and `io.md`. Return structured diagnostics for invalid nonlinear static data, unsupported drilling load, nonfinite Newton data, and nonconvergence readiness.
|
||||
|
||||
## VERIFY
|
||||
|
||||
@@ -173,3 +182,4 @@ Update only Step 5 status and one-line payload. Executor owns timestamps, commit
|
||||
- Do not distribute full source-node CLOAD into every incident element. 이유: this would multiply loads by incident element count and violate formulation §11.2.
|
||||
- Do not emit convergence branch labels outside `relative` and `zero-scale`. 이유: io.md exposes exactly those two branches.
|
||||
- Do not accept per-call convergence thresholds or units. 이유: NSNR-069/070 fix branch thresholds and typed units globally.
|
||||
- Do not use internal scale, tolerance bands, clamps, `max(1,...)`, or absolute/relative OR to select a residual branch. 이유: revised NSNR-069 selects only from the finite matching external scale's exact-zero identity.
|
||||
|
||||
@@ -91,6 +91,12 @@ Add tests first.
|
||||
- `NSNR-LOG-010`: write/flush/close failure returns `log-output-failure` and prevents success classification.
|
||||
- `NSNR-LOG-011`: non-Newton controlled failure path can leave a zero-byte log owned by app lifecycle.
|
||||
|
||||
### USER-DECISION-003 option-1 revision addendum
|
||||
|
||||
Step 7의 completed status, summary, timestamps와 commits는 보존한다. Executor-selected Step 11에서 `tests/unit/analysis/newton_iteration_log_test.cpp`에 다음 RED assertion을 추가한다.
|
||||
|
||||
- `NSNR-LOG-012`: synthetic `NewtonChannelDecision`이 아니라 `EvaluateNewtonConvergence`가 만든 residual decisions를 record에 넣는다. Exact-zero matching external channel은 denominator exact `0`, branch `zero-scale`, threshold `1.0e-3`, force 또는 force-length unit으로 직렬화하고, nonzero matching external channel은 retained denominator, branch `relative`, threshold `1.0e-2`, unit `1`로 직렬화한다. 같은 line이 기존 39 labels/order, TAB separation, LF termination을 그대로 유지해야 하므로 기존 selector에서는 RED가 된다.
|
||||
|
||||
Run:
|
||||
|
||||
```powershell
|
||||
@@ -102,7 +108,7 @@ Expected: new tests fail. Unexpected pass stops.
|
||||
|
||||
## GREEN
|
||||
|
||||
Implement a small log writer with explicit open/write/flush/close state, serializer-owned 39-field order, deterministic escaping, finite numeric formatting, `relative`/`zero-scale` convergence branch mapping, typed `not-evaluated(reason)` substitution, and structured `Status` failures.
|
||||
Implement a small log writer with explicit open/write/flush/close state, serializer-owned 39-field order, deterministic escaping, finite numeric formatting, `relative`/`zero-scale` convergence branch mapping, typed `not-evaluated(reason)` substitution, and structured `Status` failures. USER-DECISION-003는 evaluator-produced decision semantics만 바꾸므로 log writer production 또는 `nsnr-log-v1` schema 변경은 예상하지 않는다.
|
||||
|
||||
## VERIFY
|
||||
|
||||
@@ -126,3 +132,4 @@ Update only Step 7 status and one-line payload. Executor owns timestamps, commit
|
||||
- Do not accept arbitrary caller-provided field vectors. 이유: io.md requires an exact fixed schema and order.
|
||||
- Do not write HDF5 trial history. 이유: log is diagnostic and HDF5 stores accepted frames only.
|
||||
- Do not continue after log write/flush/close failure. 이유: log failure blocks result commit.
|
||||
- Do not add, remove, rename, reorder, or re-delimit any `nsnr-log-v1` field. 이유: option 1 changes only residual decision values, not the approved 39-field external log contract.
|
||||
|
||||
Reference in New Issue
Block a user