Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 81 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# BodySimPy GitHub Copilot Instructions

## Project identity

BodySimPy is a Python-driven structural CAE workflow automation project built around a simplified automotive body structural surrogate.

The project is intended to demonstrate engineering software architecture, structural mechanics, finite-element workflow automation, validation, uncertainty analysis, fatigue methods, parameter studies, reporting, and machine-learning surrogate modelling.

Do not describe BodySimPy as a BMW project, proprietary body-in-white model, production vehicle model, or industrial validation study.

## Engineering modelling rules

- Use SI units internally unless a reporting layer explicitly converts units for presentation.
- Do not invent material properties, fatigue curves, manufacturing tolerances, load cases, geometry, experimental measurements, or solver results.
- Do not hardcode numerical FEA outputs that should come from CalculiX.
- Preserve the distinction between analytical reference solutions and finite-element results.
- Preserve the distinction between the simplified structural surrogate and a production automotive structure.
- Clearly state assumptions whenever a proposed implementation introduces a new physical assumption.

## Structural configuration rules

- Geometric dimensions must be physically positive.
- A rectangular hollow section is valid only when the wall thickness leaves a positive internal cavity.
- The physical constraint is:

`2 * thickness < min(width, height)`

- Do not silently clamp physically invalid geometry.
- Invalid geometry should be rejected explicitly.

## Loading rules

- `tip_force_n` is a signed quantity.
- A negative force is valid and represents the opposite loading direction.
- Do not add positivity validation to `tip_force_n` unless the project requirements explicitly change.

## Material rules

- Young's modulus and density must remain physically positive.
- Poisson's ratio must remain inside the limits already defined by the configuration model.
- Do not invent material-specific durability or fatigue data.

## FEA rules

- CalculiX solver outputs must be parsed from generated solver files.
- Do not replace real solver integration tests with mocked results when the test is specifically intended to validate CalculiX integration.
- Keep temporary/raw CalculiX outputs outside version control.
- Maintain isolated work directories when independent simulations execute concurrently.

## Software architecture

- Reusable production code belongs in `src/bodysimpy/`.
- Verification belongs in `tests/`.
- Exploratory notebooks belong in `notebooks/`.
- Scripts may orchestrate studies but should reuse package functionality rather than duplicate engineering equations.
- Keep solver-independent domain objects separate from solver-specific implementations.
- Prefer small, focused functions and dataclasses over monolithic workflows.

## Testing workflow

Prefer test-driven development for new behaviour:

1. Define expected behaviour with a focused test.
2. Confirm the new test fails for the expected reason.
3. Implement the minimum correct behaviour.
4. Run the focused test.
5. Run the complete project quality gate.

Do not change physically correct implementation behaviour merely to satisfy an AI-generated test.

If an AI-generated test assumes behaviour that is not part of the BodySimPy requirements, flag that assumption instead of silently implementing it.

## Quality gate

Before considering a change complete, the project should pass:

```bash
ruff format --check .
ruff check .
mypy src
python -m pytest
89 changes: 89 additions & 0 deletions .github/prompts/configuration-edge-cases.prompt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# BodySimPy Configuration Edge-Case Review

## Goal

Identify useful additional edge-case unit tests for BodySimPy configuration validation.

Do not modify any source or test files yet.

Your first response must only propose candidate tests for human engineering review.

## Relevant project files

Review:

- `src/bodysimpy/config/models.py`
- `tests/unit/test_config_models.py`
- `tests/unit/test_sweep_config.py`

## Engineering constraints

Preserve the existing BodySimPy requirements.

In particular:

- geometric dimensions must be physically positive;
- rectangular hollow-section geometry requires:

`2 * thickness < min(width, height)`

- `tip_force_n` is signed and negative force values are valid;
- do not invent a requirement that loads must be positive;
- configuration models intentionally reject unsupported extra fields;
- positive worker counts are required where parallel execution is configured;
- do not invent arbitrary maximum worker limits;
- do not silently clamp invalid engineering values;
- do not invent requirements for sorting parameter-sweep values unless existing code requires sorted values;
- preserve existing public behaviour unless a genuine defect is identified.

## Task

Inspect the existing models and tests.

Identify gaps in boundary-value and invalid-input coverage.

Consider categories such as:

- exact physical boundary conditions;
- empty collections;
- zero values;
- negative values where physically invalid;
- signed values where negative values are intentionally valid;
- unsupported extra configuration fields;
- duplicate values;
- non-finite floating-point values;
- invalid worker counts;
- material-property boundaries.

Do not assume every category necessarily requires a new test.

## Required response format

For every proposed candidate, provide:

### Candidate N — descriptive test name

**Target model/function:**
Name of the model or function.

**Input condition:**
Exact edge condition being tested.

**Expected behaviour:**
Pass or reject, including expected exception type when appropriate.

**Reason:**
Why the test is useful.

**Requirement support:**
State whether the expected behaviour is directly supported by existing BodySimPy code/requirements or requires a new engineering decision.

## Important

Do not edit files.

Do not provide implementation changes yet.

Do not invent physical requirements.

If you identify an ambiguous requirement, explicitly mark it as ambiguous and ask for human engineering review.
106 changes: 106 additions & 0 deletions docs/ai_assisted_development.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# AI-Assisted Development

## Purpose

BodySimPy uses AI-assisted development selectively to support software engineering tasks such as test generation, code review, documentation, refactoring suggestions, and workflow analysis.

AI output is treated as a candidate engineering suggestion rather than authoritative code or engineering truth.

The human developer remains responsible for validating physical assumptions, software behaviour, solver integration, tests, and final implementation decisions.

---

## AID-001 — Configuration Validation Edge Cases

### AI Output

GitHub Copilot proposed 40 candidate configuration-validation tests covering geometry boundaries, material properties, signed loading, modal settings, stochastic configuration, mesh configuration, parameter sweeps, project configuration, strict-model behavior, and non-finite numerical values.

The assistant distinguished between behavior already supported by the existing implementation and several ambiguous cases requiring a new engineering decision.

Notably, the assistant correctly identified that negative `tip_force_n` values are intentionally valid and must not be rejected.

The assistant also identified non-finite floating-point values (`NaN` and infinity) as an unresolved validation-policy question across multiple physical configuration fields.

### Engineering Validation

The candidate list was manually reviewed against BodySimPy's existing structural assumptions and software requirements.

The review deliberately rejected broad implementation of all AI-generated candidates. Redundant tests that merely repeated equivalent direct field constraints were not selected solely because they were suggested by the AI assistant.

Nine existing-contract tests were accepted for their boundary or regression value:

- exact rectangular-hollow-section thickness boundary rejection;
- acceptance immediately inside the valid thickness boundary;
- both exact Poisson-ratio boundary rejections;
- preservation of valid negative signed tip force;
- rejection of an empty thickness sweep;
- preservation of unsorted sweep input;
- rejection of zero worker count;
- rejection of unsupported extra fields in a nested geometry configuration.

Several suggestions were deferred because they would unnecessarily duplicate existing validation or would establish requirements not yet justified by the project.

The non-finite-number suggestions were treated separately because they exposed a genuine engineering-policy question rather than an existing implementation requirement.

A human engineering decision was made that physical numerical configuration values used by structural analysis and simulation workflows must be finite. `NaN`, positive infinity, and negative infinity are therefore considered invalid engineering configuration values.

This finite-number policy will be introduced test-first before any production implementation is changed.

## Validation Policy

Every significant AI-assisted change follows this workflow:

1. Define a bounded engineering or software task.
2. Provide relevant repository context and constraints.
3. Record the prompt used for the task.
4. Review the generated suggestions individually.
5. Reject suggestions that introduce unsupported physical or software assumptions.
6. Modify partially correct suggestions when necessary.
7. Implement only validated changes.
8. Run the complete BodySimPy quality gate.
9. Record the final accepted result.

The standard verification commands are:

### Final Result

The AI-assisted review produced two classes of improvements.

First, nine high-value regression and boundary tests were selected from the larger AI-generated candidate set after human engineering review. These tests protect existing requirements including signed loading, geometric boundary behaviour, parameter-sweep semantics, and strict nested configuration validation.

Second, the AI review surfaced ambiguity around non-finite floating-point values. A human engineering decision established that physical numerical configuration values must be finite.

Test-first validation showed that infinite Young's modulus, infinite signed load, infinite stochastic standard deviation, and infinite thickness-sweep entries were still accepted by the existing configuration layer, while some geometry cases were already rejected by existing constraints.

The production configuration policy was then changed centrally through the shared Pydantic model configuration rather than by adding duplicated field-specific validators.

The final policy preserves finite negative signed loads while rejecting NaN and positive/negative infinity.

### Human Validation Decisions

Accepted:
- preserve signed negative finite loads;
- enforce the exact rectangular-hollow-section geometric boundary;
- preserve unsorted sweep input;
- reject zero worker counts;
- reject unsupported nested fields;
- enforce finite numerical engineering configuration values.

Rejected or deferred:
- redundant tests that simply duplicated equivalent existing field constraints;
- arbitrary maximum worker limits;
- automatic sweep sorting;
- silent input clamping;
- unsupported material or physical assumptions;
- unrelated project-name policy changes.

### Verification

The accepted implementation was verified using:

```text
ruff format --check .
ruff check .
mypy src
python -m pytest
1 change: 1 addition & 0 deletions src/bodysimpy/config/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ class StrictModel(BaseModel):
model_config = ConfigDict(
extra="forbid",
frozen=True,
allow_inf_nan=False,
)


Expand Down
Loading