add skills
This commit is contained in:
@@ -0,0 +1,112 @@
|
|||||||
|
---
|
||||||
|
name: fesa-feature-definition
|
||||||
|
description: Use when defining or reviewing FESA solver feature requests, requirements, research questions, acceptance criteria, verification matrices, tolerance needs, or downstream handoffs before FEM formulation, I/O definition, reference modeling, implementation, or release.
|
||||||
|
---
|
||||||
|
|
||||||
|
# FESA Feature Definition
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
Use this skill to turn a FESA solver feature request into a verifiable Feature Definition Packet. Define what the solver feature must do, how it will be verified, what research is needed, and what downstream agents need as input.
|
||||||
|
|
||||||
|
This skill is shared by Requirement Agent, Research Agent, Coordinator Agent, and Release Agent. It is not a formulation, implementation, reference generation, or release approval workflow.
|
||||||
|
|
||||||
|
## Inputs
|
||||||
|
|
||||||
|
Read the smallest useful set of these inputs before drafting or reviewing the packet:
|
||||||
|
|
||||||
|
- `docs/SOLVER_SKILL_DESIGN.md`
|
||||||
|
- `docs/SOLVER_AGENT_DESIGN.md`
|
||||||
|
- `AGENTS.md`
|
||||||
|
- User feature request or Coordinator handoff
|
||||||
|
- Existing `docs/requirements/<feature-id>.md`
|
||||||
|
- Existing `docs/research/<feature-id>-research.md`
|
||||||
|
- Relevant coordination or release reports when reviewing traceability
|
||||||
|
|
||||||
|
## Workflow
|
||||||
|
|
||||||
|
1. Feature Intake: assign a stable `feature_id`, summarize the requested capability, and separate user-visible behavior from implementation detail.
|
||||||
|
2. Solver Context: classify analysis type, element family, DOFs, material model boundary, loads, boundary conditions, units, coordinates, and required result quantities.
|
||||||
|
3. Requirement Drafting: write singular `shall` requirements. Keep each requirement measurable, necessary, unambiguous, feasible, and traceable.
|
||||||
|
4. Verification Planning: create a Requirement Verification Matrix that maps each `must` requirement to a verification method, acceptance criterion, compared quantity, artifact need, and tolerance decision.
|
||||||
|
5. Research Framing: list Research Questions for missing theory, benchmark values, official solver manual details, source quality, or applicability limits.
|
||||||
|
6. Quality Check: mark unverifiable, ambiguous, or missing decisions as `needs-user-decision`; do not invent values.
|
||||||
|
7. Downstream Handoff: package only the facts needed by Research, Formulation, I/O Definition, Reference Model, Implementation Planning, Release, or Coordinator agents.
|
||||||
|
|
||||||
|
## Output Contract
|
||||||
|
|
||||||
|
The primary output is a `Feature Definition Packet`. The default save candidate is `docs/requirements/<feature-id>.md`; Research Agent may later create `docs/research/<feature-id>-research.md`.
|
||||||
|
|
||||||
|
Include these sections:
|
||||||
|
|
||||||
|
- Metadata: `feature_id`, `title`, `status`, `owner_agent`, `date`, source request
|
||||||
|
- Feature Summary: purpose and expected solver behavior
|
||||||
|
- Included Scope: analysis, element, material, load, boundary, I/O, and result scope
|
||||||
|
- Excluded Scope: explicitly deferred capabilities
|
||||||
|
- Solver Context: units, coordinate system, DOFs, sign conventions, output quantities
|
||||||
|
- Requirement Records: one record per `shall` requirement
|
||||||
|
- Requirement Verification Matrix: requirement id, method, acceptance criterion, artifact, tolerance
|
||||||
|
- Research Questions: source gaps and benchmark questions for Research Agent
|
||||||
|
- Reference Artifact Needs: expected `model.inp`, `metadata.json`, and required CSVs
|
||||||
|
- Tolerance Decisions: known tolerance policies and unresolved tolerance decisions
|
||||||
|
- Open Issues: `needs-user-decision`, `needs-research`, or `needs-reference-artifacts`
|
||||||
|
- Downstream Handoff: target agent, required inputs, expected output, stop condition
|
||||||
|
|
||||||
|
Requirement record format:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
id: FESA-REQ-<FEATURE>-###
|
||||||
|
statement: "The FESA solver shall ..."
|
||||||
|
category: functional | physics | numerical | input | output | verification | constraint
|
||||||
|
rationale: "<why this is needed>"
|
||||||
|
source: user | docs | standard | benchmark | derived
|
||||||
|
priority: must | should | could
|
||||||
|
verification_method: test | analysis | inspection | demonstration | reference-comparison
|
||||||
|
acceptance_criteria: "<measurable pass/fail rule>"
|
||||||
|
tolerance: "<absolute/relative/norm tolerance or N/A with reason>"
|
||||||
|
trace_to:
|
||||||
|
parent_need: "<need id or statement>"
|
||||||
|
downstream_agents: ["Research Agent", "Formulation Agent"]
|
||||||
|
status: draft | needs-user-decision | approved
|
||||||
|
```
|
||||||
|
|
||||||
|
## Verification Matrix Rules
|
||||||
|
|
||||||
|
- Use `test` for deterministic unit, parser, or integration behavior.
|
||||||
|
- Use `analysis` for checks proven by calculation, dimensional reasoning, or theoretical derivation.
|
||||||
|
- Use `inspection` for static documents, schemas, files, and artifact presence.
|
||||||
|
- Use `demonstration` only when pass/fail can be observed without reference comparison.
|
||||||
|
- Use `reference-comparison` for stored reference artifact comparisons against displacements, reactions, element internal forces, stresses, and optional strain, energy, or residual quantities.
|
||||||
|
- If a tolerance is missing, write the tolerance need as an open issue instead of choosing one.
|
||||||
|
- If a required CSV or `metadata.json` is missing, do not mark the feature definition ready for downstream implementation.
|
||||||
|
|
||||||
|
## Boundaries
|
||||||
|
|
||||||
|
- Do not finalize FEM formulations.
|
||||||
|
- Do not write weak forms, shape functions, element matrices, or C++ API decisions as approved requirements.
|
||||||
|
- Do not implement C++ code.
|
||||||
|
- Do not create implementation plans beyond downstream handoff notes.
|
||||||
|
- Do not run Abaqus, Nastran, or any reference solver.
|
||||||
|
- Do not generate reference CSVs.
|
||||||
|
- Do not change stored reference artifacts or tolerance policies.
|
||||||
|
- Do not approve release readiness.
|
||||||
|
|
||||||
|
## Quality Gate
|
||||||
|
|
||||||
|
Before marking the packet `approved` or ready for a downstream agent, verify:
|
||||||
|
|
||||||
|
- Included and excluded scope are explicit.
|
||||||
|
- Every `must` requirement has a verification method and measurable acceptance criteria.
|
||||||
|
- Numerical requirements include units, coordinate system, quantity, and tolerance status.
|
||||||
|
- Reference-comparison requirements name the physical quantities and required artifacts.
|
||||||
|
- Phrases such as "same as Abaqus", "accurate", or "fast" are converted into measurable criteria or open issues.
|
||||||
|
- Implementation details are separated from requirements and moved to downstream handoff.
|
||||||
|
- Open decisions are marked `needs-user-decision` or assigned to a downstream agent.
|
||||||
|
|
||||||
|
## Common Mistakes
|
||||||
|
|
||||||
|
- Treating "Abaqus-compatible" as a requirement without a supported keyword subset and verification evidence.
|
||||||
|
- Turning preferred implementation details into `shall` requirements.
|
||||||
|
- Advancing to formulation when tolerance, unit, coordinate, or output-location decisions are absent.
|
||||||
|
- Treating a reference artifact request as permission to run Abaqus or create CSVs.
|
||||||
|
- Declaring release readiness from requirement quality alone.
|
||||||
@@ -0,0 +1,156 @@
|
|||||||
|
---
|
||||||
|
name: fesa-fem-specification
|
||||||
|
description: Use when drafting or reviewing FESA FEM formulations, numerical review criteria, Abaqus .inp keyword subsets, internal model mappings, result CSV schemas, output recovery, numerical risks, or implementation-planning handoffs before C++ implementation or reference validation.
|
||||||
|
---
|
||||||
|
|
||||||
|
# FESA FEM Specification
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
Use this skill to convert approved FESA requirements and research briefs into an implementation-ready FEM specification package: mathematical formulation, independent numerical review criteria, and Abaqus `.inp`/CSV I/O contract.
|
||||||
|
|
||||||
|
This skill is shared by Formulation Agent, Numerical Review Agent, I/O Definition Agent, and Implementation Planning Agent. It prepares specifications only; implementation and reference validation are handled by other skills.
|
||||||
|
|
||||||
|
## Inputs
|
||||||
|
|
||||||
|
Read the smallest useful set of these inputs before drafting or reviewing a specification:
|
||||||
|
|
||||||
|
- `docs/SOLVER_SKILL_DESIGN.md`
|
||||||
|
- `docs/SOLVER_AGENT_DESIGN.md`
|
||||||
|
- `AGENTS.md`
|
||||||
|
- `docs/requirements/<feature-id>.md`
|
||||||
|
- `docs/research/<feature-id>-research.md`
|
||||||
|
- Existing `docs/formulations/<feature-id>-formulation.md`
|
||||||
|
- Existing `docs/numerical-reviews/<feature-id>-review.md`
|
||||||
|
- Existing `docs/io-definitions/<feature-id>-io.md`
|
||||||
|
|
||||||
|
## Workflow
|
||||||
|
|
||||||
|
1. INPUT CHECK: verify that requirements, research sources, analysis type, element type, material scope, output quantities, units, coordinate system, and tolerance status are available. Mark missing decisions as `needs-user-decision` or `needs-research`.
|
||||||
|
2. FORMULATION SPEC: draft the math-level contract: strong form, weak/variational form, discretization, shape functions, DOFs, kinematics, constitutive contract, element residual/internal force, stiffness/tangent, mapping/Jacobian, numerical integration, and output recovery.
|
||||||
|
3. NUMERICAL REVIEW CHECK: review dimensions, signs, DOF ordering, coordinate transforms, matrix/vector sizes, integration weights, tangent consistency, output locations, rigid body modes, patch test readiness, symmetry, positive definiteness, hourglass, locking, distortion, singular Jacobian, conditioning, and convergence expectations.
|
||||||
|
4. I/O CONTRACT: define the feature-specific Abaqus `.inp` supported keyword subset, unsupported/ignored/error policy, model data/history data mapping, internal semantic model mapping, output request mapping, and result CSV schema.
|
||||||
|
5. HANDOFF: pass math-level pseudocode, parser acceptance cases, CSV writer tests, numerical risk tests, and open issues to Implementation Planning Agent without prescribing C++ structure.
|
||||||
|
|
||||||
|
## Output Contract
|
||||||
|
|
||||||
|
Create or review one or more of these documents:
|
||||||
|
|
||||||
|
- `docs/formulations/<feature-id>-formulation.md`
|
||||||
|
- `docs/numerical-reviews/<feature-id>-review.md`
|
||||||
|
- `docs/io-definitions/<feature-id>-io.md`
|
||||||
|
|
||||||
|
Keep documents in Korean Markdown. Keep FEM symbols, Abaqus keywords, status values, schema keys, and requirement IDs in English.
|
||||||
|
|
||||||
|
## FORMULATION SPEC Checklist
|
||||||
|
|
||||||
|
Include these formulation sections when the feature requires a formulation document:
|
||||||
|
|
||||||
|
- Metadata: `feature_id`, source requirement, source research, `status`, owner agent, date.
|
||||||
|
- Scope and Assumptions: analysis type, element type, small/large deformation, linear/nonlinear, material model boundary, coordinate system, units.
|
||||||
|
- Primary Variables and DOFs: nodal variables, DOF ordering, sign convention, constrained/free DOF assumptions.
|
||||||
|
- Strong Form and Boundary Conditions: governing equation, Dirichlet boundary, Neumann boundary, natural boundary terms.
|
||||||
|
- Weak or Variational Form: test functions, integration by parts, internal virtual work, external virtual work.
|
||||||
|
- Discretization: interpolation, shape functions, nodal layout, partition of unity, Kronecker delta.
|
||||||
|
- Kinematics: strain-displacement relation, `B` matrix or kinematic operator, deformation gradient or strain measure when needed.
|
||||||
|
- Constitutive Contract: elasticity matrix or stress-update assumptions, material state variables, constraints; never C++ APIs.
|
||||||
|
- Element Equations: internal force or residual, external force, stiffness or tangent matrix, mass/damping only when required, vector/matrix dimensions.
|
||||||
|
- Mapping and Numerical Integration: reference coordinates, isoparametric mapping, Jacobian, determinant validity, derivative transform, Gauss points, weights, full/reduced/selective/analytical integration policy.
|
||||||
|
- Output Recovery: displacement, reaction, element force, strain, stress, output location, nodal/element/integration-point/centroidal/nodal extrapolation policy.
|
||||||
|
- Algorithm Pseudocode: math-level element routine and assembly flow only.
|
||||||
|
- Numerical Risks: rigid body modes, patch test, symmetry, positive definiteness, hourglass, shear locking, volumetric locking, distortion, singular Jacobian, conditioning, convergence risk.
|
||||||
|
|
||||||
|
## NUMERICAL REVIEW CHECK Rules
|
||||||
|
|
||||||
|
When reviewing a formulation, lead with findings and required revisions:
|
||||||
|
|
||||||
|
- Treat confirmed defects, numerical risks, open questions, and downstream test recommendations as separate categories.
|
||||||
|
- Check dimensions of equations, vectors, matrices, integration terms, residuals, and stiffness/tangent matrices.
|
||||||
|
- Check signs for loads, reactions, stresses, internal force, residual, and element force output.
|
||||||
|
- Check coordinate transforms, local/global conventions, output locations, and component naming.
|
||||||
|
- Check Jacobian rules, determinant validity, derivative transform, distortion policy, integration weights, and Gauss point counts.
|
||||||
|
- Check whether patch tests, rigid body mode checks, symmetry checks, positive definiteness expectations, locking/hourglass risks, and conditioning risks are documented.
|
||||||
|
- Use `pass-for-implementation-planning` only when the specification is complete enough for implementation planning; this is not release approval.
|
||||||
|
|
||||||
|
## I/O CONTRACT Checklist
|
||||||
|
|
||||||
|
Include these I/O sections when the feature requires an Abaqus input or result CSV contract:
|
||||||
|
|
||||||
|
- Abaqus Input Scope: input format is Abaqus `.inp`; define supported documentation source/version and state that FESA supports only this feature's keyword subset.
|
||||||
|
- Syntax Policy: case-insensitivity, comma-separated keyword/data lines, comments beginning with `**`, continuation, includes, labels, line-length limits, ASCII assumptions, empty data fields.
|
||||||
|
- Model Data Mapping: nodes, elements, node sets, element sets, material, section, coordinates, units.
|
||||||
|
- History Data Mapping: steps, analysis procedure keyword, boundary conditions, loads, output requests.
|
||||||
|
- Internal Model Contract: semantic fields for node label, element label, element type, connectivity, set membership, material, section, boundary condition, load, step, output request; never C++ classes or function signatures.
|
||||||
|
- Output and CSV Schemas: column names, ID fields, component naming, coordinate system, units, step/frame identity, and quantity location.
|
||||||
|
- Validation Rules: required fields, duplicate labels, missing references, unsupported keywords, set expansion, coordinate conventions, output quantity availability.
|
||||||
|
|
||||||
|
Default Abaqus keyword checklist:
|
||||||
|
|
||||||
|
- `*HEADING`
|
||||||
|
- `*INCLUDE`
|
||||||
|
- `*NODE`
|
||||||
|
- `*NSET`
|
||||||
|
- `*ELEMENT`
|
||||||
|
- `*ELSET`
|
||||||
|
- `*MATERIAL`
|
||||||
|
- `*ELASTIC`
|
||||||
|
- feature-specific section keyword such as `*SOLID SECTION`, `*BEAM SECTION`, or `*SHELL SECTION`
|
||||||
|
- `*BOUNDARY`
|
||||||
|
- `*CLOAD`
|
||||||
|
- `*DLOAD`
|
||||||
|
- `*STEP`
|
||||||
|
- feature-specific procedure keyword such as `*STATIC`
|
||||||
|
- `*OUTPUT`
|
||||||
|
- `*NODE OUTPUT`
|
||||||
|
- `*ELEMENT OUTPUT`
|
||||||
|
|
||||||
|
Default result CSV checklist:
|
||||||
|
|
||||||
|
- `displacements.csv`: step/frame, node id, displacement components, coordinate system, units.
|
||||||
|
- `reactions.csv`: step/frame, constrained node id, reaction force components, sign convention, units.
|
||||||
|
- `element_forces.csv`: step/frame, element id, location, component, value, sign convention, units.
|
||||||
|
- `stresses.csv`: step/frame, element id, integration point or recovery location, component, value, coordinate system, units.
|
||||||
|
- Optional `strains.csv` and `energy_or_residual.csv` only when upstream documents define schema and acceptance need.
|
||||||
|
|
||||||
|
## Handoff
|
||||||
|
|
||||||
|
Prepare downstream handoff without deciding implementation structure:
|
||||||
|
|
||||||
|
- Numerical Review Agent: derivations, assumptions, numerical risks, dimensions, open issues.
|
||||||
|
- I/O Definition Agent: required inputs, outputs, units, coordinates, output locations, Abaqus keyword needs.
|
||||||
|
- Reference Model Agent: benchmarkable quantities, patch test needs, expected invariants, singular or invalid-input cases.
|
||||||
|
- Implementation Planning Agent: math-level pseudocode, parser acceptance cases, CSV writer tests, numerical risk tests, acceptance-relevant quantities.
|
||||||
|
|
||||||
|
## Boundaries
|
||||||
|
|
||||||
|
- Do not implement C++ code.
|
||||||
|
- Do not design C++ APIs.
|
||||||
|
- Do not decide C++ file ownership or storage layout.
|
||||||
|
- Do not implement parsers.
|
||||||
|
- Do not run Abaqus, Nastran, or any reference solver.
|
||||||
|
- Do not generate reference CSVs.
|
||||||
|
- Do not create or modify reference artifacts.
|
||||||
|
- Do not change tolerance policies.
|
||||||
|
- Do not perform reference verification or physics validation.
|
||||||
|
- Do not approve release readiness.
|
||||||
|
|
||||||
|
## Quality Gate
|
||||||
|
|
||||||
|
Before marking a specification ready for implementation planning:
|
||||||
|
|
||||||
|
- Requirements and research sources are traceable, or missing source evidence is marked `needs-research`.
|
||||||
|
- Strong Form, Weak or Variational Form, Discretization, Kinematics, Element Equations, Mapping and Numerical Integration, Output Recovery, and Numerical Risks are complete enough for the feature scope.
|
||||||
|
- Shape functions include partition of unity and Kronecker delta expectations when applicable.
|
||||||
|
- Mapping includes reference coordinates, Jacobian, determinant validity, and derivative transform.
|
||||||
|
- Numerical review checks cover dimensions, signs, DOF ordering, coordinate transforms, integration weights, output locations, rigid body modes, patch tests, symmetry, positive definiteness, hourglass, locking, singular Jacobian, and conditioning.
|
||||||
|
- Abaqus Input Scope, Model Data Mapping, History Data Mapping, Internal Model Contract, Output and CSV Schemas, and Validation Rules are documented when I/O is in scope.
|
||||||
|
- Unsupported Abaqus keyword behavior is classified as `unsupported`, `ignored-with-warning`, or `requires-user-decision`.
|
||||||
|
- No C++ API, parser implementation, reference value, or tolerance policy is invented.
|
||||||
|
|
||||||
|
## Common Mistakes
|
||||||
|
|
||||||
|
- Advancing a formulation without dimensions, signs, coordinate system, or output location.
|
||||||
|
- Treating a feature as fully Abaqus-compatible when only a keyword subset is defined.
|
||||||
|
- Hiding uncertain derivations inside implementation pseudocode instead of recording open issues.
|
||||||
|
- Defining CSV columns without units, coordinate system, step/frame identity, or quantity location.
|
||||||
|
- Treating `pass-for-implementation-planning` as solver verification or release readiness.
|
||||||
@@ -11,6 +11,7 @@
|
|||||||
- CRITICAL: C++ 빌드는 CMake/MSVC/x64/Debug 기준으로 검증한다.
|
- CRITICAL: C++ 빌드는 CMake/MSVC/x64/Debug 기준으로 검증한다.
|
||||||
- CRITICAL: 새 기능 또는 동작 변경은 테스트를 먼저 작성하고 실패를 확인한 뒤 구현한다.
|
- CRITICAL: 새 기능 또는 동작 변경은 테스트를 먼저 작성하고 실패를 확인한 뒤 구현한다.
|
||||||
- CRITICAL: Abaqus reference artifact나 solver 코드 복원은 명시적으로 요청된 phase에서만 수행한다.
|
- CRITICAL: Abaqus reference artifact나 solver 코드 복원은 명시적으로 요청된 phase에서만 수행한다.
|
||||||
|
- Codex custom agent의 `model_reasoning_effort` 기본값은 `extra high`로 둔다.
|
||||||
- Harness runner는 `scripts/execute.py`에 둔다.
|
- Harness runner는 `scripts/execute.py`에 둔다.
|
||||||
- Codex hook 정책은 `.codex/hooks/`에 둔다.
|
- Codex hook 정책은 `.codex/hooks/`에 둔다.
|
||||||
- Harness planning/review instructions are stored in `.codex/skills/`.
|
- Harness planning/review instructions are stored in `.codex/skills/`.
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ class BuildTestExecutorAgentConfigTests(unittest.TestCase):
|
|||||||
self.assertEqual(data["name"], "build-test-executor-agent")
|
self.assertEqual(data["name"], "build-test-executor-agent")
|
||||||
self.assertIn("C++/MSVC/CMake/CTest validation", data["description"])
|
self.assertIn("C++/MSVC/CMake/CTest validation", data["description"])
|
||||||
self.assertEqual(data["sandbox_mode"], "workspace-write")
|
self.assertEqual(data["sandbox_mode"], "workspace-write")
|
||||||
self.assertEqual(data["model_reasoning_effort"], "high")
|
self.assertEqual(data["model_reasoning_effort"], "extra high")
|
||||||
self.assertIn("developer_instructions", data)
|
self.assertIn("developer_instructions", data)
|
||||||
|
|
||||||
def test_build_test_executor_agent_instructions_enforce_boundaries(self):
|
def test_build_test_executor_agent_instructions_enforce_boundaries(self):
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ class CoordinatorAgentConfigTests(unittest.TestCase):
|
|||||||
self.assertEqual(data["name"], "coordinator-agent")
|
self.assertEqual(data["name"], "coordinator-agent")
|
||||||
self.assertIn("workflow state", data["description"])
|
self.assertIn("workflow state", data["description"])
|
||||||
self.assertEqual(data["sandbox_mode"], "workspace-write")
|
self.assertEqual(data["sandbox_mode"], "workspace-write")
|
||||||
self.assertEqual(data["model_reasoning_effort"], "high")
|
self.assertEqual(data["model_reasoning_effort"], "extra high")
|
||||||
self.assertIn("developer_instructions", data)
|
self.assertIn("developer_instructions", data)
|
||||||
|
|
||||||
def test_coordinator_agent_instructions_enforce_boundaries(self):
|
def test_coordinator_agent_instructions_enforce_boundaries(self):
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ class CorrectionAgentConfigTests(unittest.TestCase):
|
|||||||
self.assertEqual(data["name"], "correction-agent")
|
self.assertEqual(data["name"], "correction-agent")
|
||||||
self.assertIn("C++/MSVC/CMake/CTest fixes", data["description"])
|
self.assertIn("C++/MSVC/CMake/CTest fixes", data["description"])
|
||||||
self.assertEqual(data["sandbox_mode"], "workspace-write")
|
self.assertEqual(data["sandbox_mode"], "workspace-write")
|
||||||
self.assertEqual(data["model_reasoning_effort"], "high")
|
self.assertEqual(data["model_reasoning_effort"], "extra high")
|
||||||
self.assertIn("developer_instructions", data)
|
self.assertIn("developer_instructions", data)
|
||||||
|
|
||||||
def test_correction_agent_instructions_enforce_boundaries(self):
|
def test_correction_agent_instructions_enforce_boundaries(self):
|
||||||
|
|||||||
@@ -0,0 +1,92 @@
|
|||||||
|
import unittest
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
|
ROOT = Path(__file__).resolve().parents[1]
|
||||||
|
SKILL_PATH = ROOT / ".codex" / "skills" / "fesa-feature-definition" / "SKILL.md"
|
||||||
|
|
||||||
|
|
||||||
|
def read_skill():
|
||||||
|
return SKILL_PATH.read_text(encoding="utf-8")
|
||||||
|
|
||||||
|
|
||||||
|
def parse_frontmatter(text):
|
||||||
|
lines = text.splitlines()
|
||||||
|
if not lines or lines[0] != "---":
|
||||||
|
raise AssertionError("SKILL.md must start with YAML frontmatter")
|
||||||
|
|
||||||
|
fields = {}
|
||||||
|
for line in lines[1:]:
|
||||||
|
if line == "---":
|
||||||
|
return fields
|
||||||
|
key, sep, value = line.partition(":")
|
||||||
|
if not sep:
|
||||||
|
raise AssertionError(f"Invalid frontmatter line: {line}")
|
||||||
|
fields[key.strip()] = value.strip()
|
||||||
|
|
||||||
|
raise AssertionError("SKILL.md frontmatter must be closed")
|
||||||
|
|
||||||
|
|
||||||
|
class FesaFeatureDefinitionSkillTests(unittest.TestCase):
|
||||||
|
def test_skill_file_exists_with_required_frontmatter(self):
|
||||||
|
self.assertTrue(SKILL_PATH.exists(), "fesa-feature-definition SKILL.md is missing")
|
||||||
|
|
||||||
|
fields = parse_frontmatter(read_skill())
|
||||||
|
|
||||||
|
self.assertEqual(set(fields), {"name", "description"})
|
||||||
|
self.assertEqual(fields["name"], "fesa-feature-definition")
|
||||||
|
self.assertIn("Use when", fields["description"])
|
||||||
|
self.assertIn("FESA solver feature requests", fields["description"])
|
||||||
|
self.assertIn("requirements", fields["description"])
|
||||||
|
self.assertIn("research questions", fields["description"])
|
||||||
|
self.assertIn("acceptance criteria", fields["description"])
|
||||||
|
self.assertIn("verification matrices", fields["description"])
|
||||||
|
|
||||||
|
def test_skill_body_defines_core_workflow_and_inputs(self):
|
||||||
|
body = read_skill()
|
||||||
|
|
||||||
|
for required_text in (
|
||||||
|
"## Inputs",
|
||||||
|
"## Workflow",
|
||||||
|
"## Output Contract",
|
||||||
|
"## Boundaries",
|
||||||
|
"## Quality Gate",
|
||||||
|
"docs/SOLVER_SKILL_DESIGN.md",
|
||||||
|
"docs/SOLVER_AGENT_DESIGN.md",
|
||||||
|
"AGENTS.md",
|
||||||
|
"docs/requirements/<feature-id>.md",
|
||||||
|
"docs/research/<feature-id>-research.md",
|
||||||
|
):
|
||||||
|
self.assertIn(required_text, body)
|
||||||
|
|
||||||
|
def test_skill_body_defines_requirement_and_verification_contract(self):
|
||||||
|
body = read_skill()
|
||||||
|
|
||||||
|
for required_text in (
|
||||||
|
"Feature Definition Packet",
|
||||||
|
"shall",
|
||||||
|
"Requirement Verification Matrix",
|
||||||
|
"Research Questions",
|
||||||
|
"Reference Artifact Needs",
|
||||||
|
"Tolerance Decisions",
|
||||||
|
"Downstream Handoff",
|
||||||
|
"FESA-REQ-<FEATURE>-###",
|
||||||
|
"needs-user-decision",
|
||||||
|
):
|
||||||
|
self.assertIn(required_text, body)
|
||||||
|
|
||||||
|
def test_skill_body_enforces_scope_boundaries(self):
|
||||||
|
body = read_skill()
|
||||||
|
|
||||||
|
for required_text in (
|
||||||
|
"Do not finalize FEM formulations.",
|
||||||
|
"Do not implement C++ code.",
|
||||||
|
"Do not run Abaqus, Nastran, or any reference solver.",
|
||||||
|
"Do not generate reference CSVs.",
|
||||||
|
"Do not approve release readiness.",
|
||||||
|
):
|
||||||
|
self.assertIn(required_text, body)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
unittest.main()
|
||||||
@@ -0,0 +1,124 @@
|
|||||||
|
import unittest
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
|
ROOT = Path(__file__).resolve().parents[1]
|
||||||
|
SKILL_PATH = ROOT / ".codex" / "skills" / "fesa-fem-specification" / "SKILL.md"
|
||||||
|
|
||||||
|
|
||||||
|
def read_skill():
|
||||||
|
return SKILL_PATH.read_text(encoding="utf-8")
|
||||||
|
|
||||||
|
|
||||||
|
def parse_frontmatter(text):
|
||||||
|
lines = text.splitlines()
|
||||||
|
if not lines or lines[0] != "---":
|
||||||
|
raise AssertionError("SKILL.md must start with YAML frontmatter")
|
||||||
|
|
||||||
|
fields = {}
|
||||||
|
for line in lines[1:]:
|
||||||
|
if line == "---":
|
||||||
|
return fields
|
||||||
|
key, sep, value = line.partition(":")
|
||||||
|
if not sep:
|
||||||
|
raise AssertionError(f"Invalid frontmatter line: {line}")
|
||||||
|
fields[key.strip()] = value.strip()
|
||||||
|
|
||||||
|
raise AssertionError("SKILL.md frontmatter must be closed")
|
||||||
|
|
||||||
|
|
||||||
|
class FesaFemSpecificationSkillTests(unittest.TestCase):
|
||||||
|
def test_skill_file_exists_with_required_frontmatter(self):
|
||||||
|
self.assertTrue(SKILL_PATH.exists(), "fesa-fem-specification SKILL.md is missing")
|
||||||
|
|
||||||
|
fields = parse_frontmatter(read_skill())
|
||||||
|
|
||||||
|
self.assertEqual(set(fields), {"name", "description"})
|
||||||
|
self.assertEqual(fields["name"], "fesa-fem-specification")
|
||||||
|
self.assertIn("Use when", fields["description"])
|
||||||
|
self.assertIn("FESA FEM formulations", fields["description"])
|
||||||
|
self.assertIn("numerical review", fields["description"])
|
||||||
|
self.assertIn("Abaqus .inp", fields["description"])
|
||||||
|
self.assertIn("CSV schemas", fields["description"])
|
||||||
|
self.assertIn("implementation-planning handoffs", fields["description"])
|
||||||
|
|
||||||
|
def test_skill_body_defines_workflow_and_inputs(self):
|
||||||
|
body = read_skill()
|
||||||
|
|
||||||
|
for required_text in (
|
||||||
|
"## Inputs",
|
||||||
|
"## Workflow",
|
||||||
|
"INPUT CHECK",
|
||||||
|
"FORMULATION SPEC",
|
||||||
|
"NUMERICAL REVIEW CHECK",
|
||||||
|
"I/O CONTRACT",
|
||||||
|
"HANDOFF",
|
||||||
|
"## Quality Gate",
|
||||||
|
"docs/SOLVER_SKILL_DESIGN.md",
|
||||||
|
"docs/SOLVER_AGENT_DESIGN.md",
|
||||||
|
"AGENTS.md",
|
||||||
|
"docs/requirements/<feature-id>.md",
|
||||||
|
"docs/research/<feature-id>-research.md",
|
||||||
|
):
|
||||||
|
self.assertIn(required_text, body)
|
||||||
|
|
||||||
|
def test_skill_body_defines_formulation_contract(self):
|
||||||
|
body = read_skill()
|
||||||
|
|
||||||
|
for required_text in (
|
||||||
|
"Strong Form",
|
||||||
|
"Weak or Variational Form",
|
||||||
|
"Discretization",
|
||||||
|
"Kinematics",
|
||||||
|
"Element Equations",
|
||||||
|
"Mapping and Numerical Integration",
|
||||||
|
"Output Recovery",
|
||||||
|
"Numerical Risks",
|
||||||
|
"partition of unity",
|
||||||
|
"Kronecker delta",
|
||||||
|
"Jacobian",
|
||||||
|
"derivative transform",
|
||||||
|
):
|
||||||
|
self.assertIn(required_text, body)
|
||||||
|
|
||||||
|
def test_skill_body_defines_io_contract(self):
|
||||||
|
body = read_skill()
|
||||||
|
|
||||||
|
for required_text in (
|
||||||
|
"Abaqus Input Scope",
|
||||||
|
"Model Data Mapping",
|
||||||
|
"History Data Mapping",
|
||||||
|
"Internal Model Contract",
|
||||||
|
"Output and CSV Schemas",
|
||||||
|
"*NODE",
|
||||||
|
"*ELEMENT",
|
||||||
|
"*MATERIAL",
|
||||||
|
"*ELASTIC",
|
||||||
|
"*BOUNDARY",
|
||||||
|
"*STEP",
|
||||||
|
"*OUTPUT",
|
||||||
|
"*NODE OUTPUT",
|
||||||
|
"*ELEMENT OUTPUT",
|
||||||
|
"displacements.csv",
|
||||||
|
"reactions.csv",
|
||||||
|
"element_forces.csv",
|
||||||
|
"stresses.csv",
|
||||||
|
):
|
||||||
|
self.assertIn(required_text, body)
|
||||||
|
|
||||||
|
def test_skill_body_enforces_scope_boundaries(self):
|
||||||
|
body = read_skill()
|
||||||
|
|
||||||
|
for required_text in (
|
||||||
|
"Do not implement C++ code.",
|
||||||
|
"Do not design C++ APIs.",
|
||||||
|
"Do not implement parsers.",
|
||||||
|
"Do not run Abaqus, Nastran, or any reference solver.",
|
||||||
|
"Do not generate reference CSVs.",
|
||||||
|
"Do not approve release readiness.",
|
||||||
|
):
|
||||||
|
self.assertIn(required_text, body)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
unittest.main()
|
||||||
@@ -19,7 +19,7 @@ class FormulationAgentConfigTests(unittest.TestCase):
|
|||||||
self.assertEqual(data["name"], "formulation-agent")
|
self.assertEqual(data["name"], "formulation-agent")
|
||||||
self.assertIn("FEM formulation", data["description"])
|
self.assertIn("FEM formulation", data["description"])
|
||||||
self.assertEqual(data["sandbox_mode"], "read-only")
|
self.assertEqual(data["sandbox_mode"], "read-only")
|
||||||
self.assertEqual(data["model_reasoning_effort"], "high")
|
self.assertEqual(data["model_reasoning_effort"], "extra high")
|
||||||
self.assertIn("developer_instructions", data)
|
self.assertIn("developer_instructions", data)
|
||||||
|
|
||||||
def test_formulation_agent_instructions_enforce_boundaries(self):
|
def test_formulation_agent_instructions_enforce_boundaries(self):
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ class ImplementationAgentConfigTests(unittest.TestCase):
|
|||||||
self.assertEqual(data["name"], "implementation-agent")
|
self.assertEqual(data["name"], "implementation-agent")
|
||||||
self.assertIn("C++17/MSVC", data["description"])
|
self.assertIn("C++17/MSVC", data["description"])
|
||||||
self.assertEqual(data["sandbox_mode"], "workspace-write")
|
self.assertEqual(data["sandbox_mode"], "workspace-write")
|
||||||
self.assertEqual(data["model_reasoning_effort"], "high")
|
self.assertEqual(data["model_reasoning_effort"], "extra high")
|
||||||
self.assertIn("developer_instructions", data)
|
self.assertIn("developer_instructions", data)
|
||||||
|
|
||||||
def test_implementation_agent_instructions_define_tdd_execution_contract(self):
|
def test_implementation_agent_instructions_define_tdd_execution_contract(self):
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ class ImplementationPlanningAgentConfigTests(unittest.TestCase):
|
|||||||
self.assertEqual(data["name"], "implementation-planning-agent")
|
self.assertEqual(data["name"], "implementation-planning-agent")
|
||||||
self.assertIn("TDD-first C++/MSVC implementation plans", data["description"])
|
self.assertIn("TDD-first C++/MSVC implementation plans", data["description"])
|
||||||
self.assertEqual(data["sandbox_mode"], "read-only")
|
self.assertEqual(data["sandbox_mode"], "read-only")
|
||||||
self.assertEqual(data["model_reasoning_effort"], "high")
|
self.assertEqual(data["model_reasoning_effort"], "extra high")
|
||||||
self.assertIn("developer_instructions", data)
|
self.assertIn("developer_instructions", data)
|
||||||
|
|
||||||
def test_implementation_planning_agent_instructions_enforce_boundaries(self):
|
def test_implementation_planning_agent_instructions_enforce_boundaries(self):
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ class IoDefinitionAgentConfigTests(unittest.TestCase):
|
|||||||
self.assertEqual(data["name"], "io-definition-agent")
|
self.assertEqual(data["name"], "io-definition-agent")
|
||||||
self.assertIn("Abaqus input-file subsets", data["description"])
|
self.assertIn("Abaqus input-file subsets", data["description"])
|
||||||
self.assertEqual(data["sandbox_mode"], "read-only")
|
self.assertEqual(data["sandbox_mode"], "read-only")
|
||||||
self.assertEqual(data["model_reasoning_effort"], "high")
|
self.assertEqual(data["model_reasoning_effort"], "extra high")
|
||||||
self.assertIn("developer_instructions", data)
|
self.assertIn("developer_instructions", data)
|
||||||
|
|
||||||
def test_io_definition_agent_instructions_enforce_boundaries(self):
|
def test_io_definition_agent_instructions_enforce_boundaries(self):
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ class NumericalReviewAgentConfigTests(unittest.TestCase):
|
|||||||
self.assertEqual(data["name"], "numerical-review-agent")
|
self.assertEqual(data["name"], "numerical-review-agent")
|
||||||
self.assertIn("numerical correctness", data["description"])
|
self.assertIn("numerical correctness", data["description"])
|
||||||
self.assertEqual(data["sandbox_mode"], "read-only")
|
self.assertEqual(data["sandbox_mode"], "read-only")
|
||||||
self.assertEqual(data["model_reasoning_effort"], "high")
|
self.assertEqual(data["model_reasoning_effort"], "extra high")
|
||||||
self.assertIn("developer_instructions", data)
|
self.assertIn("developer_instructions", data)
|
||||||
|
|
||||||
def test_numerical_review_agent_instructions_enforce_boundaries(self):
|
def test_numerical_review_agent_instructions_enforce_boundaries(self):
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ class PhysicsEvaluationAgentConfigTests(unittest.TestCase):
|
|||||||
self.assertEqual(data["name"], "physics-evaluation-agent")
|
self.assertEqual(data["name"], "physics-evaluation-agent")
|
||||||
self.assertIn("physical plausibility", data["description"])
|
self.assertIn("physical plausibility", data["description"])
|
||||||
self.assertEqual(data["sandbox_mode"], "workspace-write")
|
self.assertEqual(data["sandbox_mode"], "workspace-write")
|
||||||
self.assertEqual(data["model_reasoning_effort"], "high")
|
self.assertEqual(data["model_reasoning_effort"], "extra high")
|
||||||
self.assertIn("developer_instructions", data)
|
self.assertIn("developer_instructions", data)
|
||||||
|
|
||||||
def test_physics_evaluation_agent_instructions_enforce_boundaries(self):
|
def test_physics_evaluation_agent_instructions_enforce_boundaries(self):
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ class ReferenceModelAgentConfigTests(unittest.TestCase):
|
|||||||
self.assertEqual(data["name"], "reference-model-agent")
|
self.assertEqual(data["name"], "reference-model-agent")
|
||||||
self.assertIn("reference model packages", data["description"])
|
self.assertIn("reference model packages", data["description"])
|
||||||
self.assertEqual(data["sandbox_mode"], "read-only")
|
self.assertEqual(data["sandbox_mode"], "read-only")
|
||||||
self.assertEqual(data["model_reasoning_effort"], "high")
|
self.assertEqual(data["model_reasoning_effort"], "extra high")
|
||||||
self.assertIn("developer_instructions", data)
|
self.assertIn("developer_instructions", data)
|
||||||
|
|
||||||
def test_reference_model_agent_instructions_enforce_boundaries(self):
|
def test_reference_model_agent_instructions_enforce_boundaries(self):
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ class ReferenceVerificationAgentConfigTests(unittest.TestCase):
|
|||||||
self.assertEqual(data["name"], "reference-verification-agent")
|
self.assertEqual(data["name"], "reference-verification-agent")
|
||||||
self.assertIn("stored Abaqus reference CSV artifacts", data["description"])
|
self.assertIn("stored Abaqus reference CSV artifacts", data["description"])
|
||||||
self.assertEqual(data["sandbox_mode"], "workspace-write")
|
self.assertEqual(data["sandbox_mode"], "workspace-write")
|
||||||
self.assertEqual(data["model_reasoning_effort"], "high")
|
self.assertEqual(data["model_reasoning_effort"], "extra high")
|
||||||
self.assertIn("developer_instructions", data)
|
self.assertIn("developer_instructions", data)
|
||||||
|
|
||||||
def test_reference_verification_agent_instructions_enforce_boundaries(self):
|
def test_reference_verification_agent_instructions_enforce_boundaries(self):
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ class ReleaseAgentConfigTests(unittest.TestCase):
|
|||||||
self.assertEqual(data["name"], "release-agent")
|
self.assertEqual(data["name"], "release-agent")
|
||||||
self.assertIn("release readiness", data["description"])
|
self.assertIn("release readiness", data["description"])
|
||||||
self.assertEqual(data["sandbox_mode"], "workspace-write")
|
self.assertEqual(data["sandbox_mode"], "workspace-write")
|
||||||
self.assertEqual(data["model_reasoning_effort"], "high")
|
self.assertEqual(data["model_reasoning_effort"], "extra high")
|
||||||
self.assertIn("developer_instructions", data)
|
self.assertIn("developer_instructions", data)
|
||||||
|
|
||||||
def test_release_agent_instructions_enforce_boundaries(self):
|
def test_release_agent_instructions_enforce_boundaries(self):
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ class RequirementAgentConfigTests(unittest.TestCase):
|
|||||||
self.assertEqual(data["name"], "requirement-agent")
|
self.assertEqual(data["name"], "requirement-agent")
|
||||||
self.assertIn("verifiable requirements", data["description"])
|
self.assertIn("verifiable requirements", data["description"])
|
||||||
self.assertEqual(data["sandbox_mode"], "read-only")
|
self.assertEqual(data["sandbox_mode"], "read-only")
|
||||||
self.assertEqual(data["model_reasoning_effort"], "high")
|
self.assertEqual(data["model_reasoning_effort"], "extra high")
|
||||||
self.assertIn("developer_instructions", data)
|
self.assertIn("developer_instructions", data)
|
||||||
|
|
||||||
def test_requirement_agent_instructions_enforce_boundaries(self):
|
def test_requirement_agent_instructions_enforce_boundaries(self):
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ class ResearchAgentConfigTests(unittest.TestCase):
|
|||||||
self.assertEqual(data["name"], "research-agent")
|
self.assertEqual(data["name"], "research-agent")
|
||||||
self.assertIn("FEM theory", data["description"])
|
self.assertIn("FEM theory", data["description"])
|
||||||
self.assertEqual(data["sandbox_mode"], "read-only")
|
self.assertEqual(data["sandbox_mode"], "read-only")
|
||||||
self.assertEqual(data["model_reasoning_effort"], "high")
|
self.assertEqual(data["model_reasoning_effort"], "extra high")
|
||||||
self.assertIn("developer_instructions", data)
|
self.assertIn("developer_instructions", data)
|
||||||
|
|
||||||
def test_research_agent_instructions_enforce_boundaries(self):
|
def test_research_agent_instructions_enforce_boundaries(self):
|
||||||
|
|||||||
Reference in New Issue
Block a user