{
  "capability_id": "mechanical.statics.incline_friction",
  "tool_id": "incline-friction",
  "engine": "incline-friction",
  "calculation_version": "1.0.0",
  "generated_at": "2026-09-23T10:57:00.183Z",
  "engine_build": "2026-09-23",
  "test_count": 7,
  "passed": 7,
  "failed": 0,
  "tests_summary": {
    "golden": {
      "total": 3,
      "passed": 3
    },
    "boundary": {
      "total": 4,
      "passed": 4
    },
    "property": {
      "total": 0,
      "passed": 0
    }
  },
  "engine_tested": true,
  "expert_reviewed": false,
  "internally_reviewed": false,
  "review_kind": null,
  "source_checked": true,
  "reviewed_by": null,
  "reviewer_role": null,
  "last_reviewed": null,
  "expert_review": {
    "status": "optional_not_performed",
    "reviewer": null,
    "scope": [
      "formula",
      "input semantics",
      "assumptions",
      "limitations",
      "sources",
      "tests"
    ],
    "note": "Domain expert review is optional under CVP (CVP-EXP-01). Absence does not block CVP Verified. See Review policy for supplemental domain assurance."
  },
  "internal_review": {
    "status": "not_applicable",
    "reviewer": null
  },
  "page": "https://www.calculatorx.com/calc/physics/incline-friction",
  "api": "https://www.calculatorx.com/api/v1/calc/incline-friction",
  "schema_input": "https://www.calculatorx.com/schemas/mechanical.statics.incline_friction.input.json",
  "schema_output": "https://www.calculatorx.com/schemas/mechanical.statics.incline_friction.output.json",
  "assumptions": [],
  "limitations": [
    "P is parallel to the plane and positive up the plane",
    "F is positive up the plane and opposes the impending motion",
    "μ is the coefficient at impending slip",
    "Not wedges, screws, belts, tipping, or kinetic friction as a separate coefficient"
  ],
  "boundary_conditions": [
    "missing W, θ, μ, or direction → MISSING_REQUIRED_INPUT",
    "W ≤ 0 → VALUE_MUST_BE_POSITIVE",
    "θ outside [0, 90) → VALUE_OUT_OF_RANGE",
    "μ < 0 → VALUE_OUT_OF_RANGE",
    "direction other than up or down → INVALID_INPUT"
  ],
  "sources": [
    {
      "title": "Hibbeler, Engineering Mechanics: Statics",
      "section": "Dry friction — impending motion",
      "supports": "On an incline, the force parallel to the plane at impending slip is W sinθ ± μ W cosθ",
      "kind": "reference"
    }
  ],
  "methods": [],
  "fingerprint": "sha256:8bfe172be8bdbba5155752742a366cc3fd78380049298fb0aadf68071e9b0a0f",
  "tests": [
    {
      "id": "golden-up",
      "ok": true,
      "kind": "golden",
      "inputs": {
        "W": 100,
        "theta_deg": 0,
        "mu": 0.25,
        "direction": "up"
      },
      "expect": {
        "P": 25,
        "N": 100,
        "F": -25,
        "direction": "up",
        "model": "incline_friction"
      },
      "expectWarning": null,
      "actual": {
        "model": "incline_friction",
        "W": 100,
        "theta_deg": 0,
        "mu": 0.25,
        "direction": "up",
        "P": 25,
        "N": 100,
        "F": -25,
        "phi_deg": 14.036243467926479,
        "solver": "friction + math.linear_algebra solve order 2",
        "convention": "P and F are positive up the plane. direction=up is impending motion up the plane, so friction acts down. N is compression against the surface. μ is the coefficient at impending slip."
      },
      "tol": 1e-12
    },
    {
      "id": "golden-down",
      "ok": true,
      "kind": "golden",
      "inputs": {
        "W": 100,
        "theta_deg": 0,
        "mu": 0.25,
        "direction": "down"
      },
      "expect": {
        "P": -25,
        "N": 100,
        "F": 25,
        "direction": "down"
      },
      "expectWarning": null,
      "actual": {
        "model": "incline_friction",
        "W": 100,
        "theta_deg": 0,
        "mu": 0.25,
        "direction": "down",
        "P": -25,
        "N": 100,
        "F": 25,
        "phi_deg": 14.036243467926479,
        "solver": "friction + math.linear_algebra solve order 2",
        "convention": "P and F are positive up the plane. direction=up is impending motion up the plane, so friction acts down. N is compression against the surface. μ is the coefficient at impending slip."
      },
      "tol": 1e-12
    },
    {
      "id": "golden-incline",
      "ok": true,
      "kind": "golden",
      "inputs": {
        "W": 100,
        "theta_deg": 30,
        "mu": 0,
        "direction": "up"
      },
      "expect": {
        "P": 50,
        "F": 0,
        "N": 86.60254037844386
      },
      "expectWarning": null,
      "actual": {
        "model": "incline_friction",
        "W": 100,
        "theta_deg": 30,
        "mu": 0,
        "direction": "up",
        "P": 50,
        "N": 86.6025403784,
        "F": 0,
        "phi_deg": 0,
        "solver": "friction + math.linear_algebra solve order 2",
        "convention": "P and F are positive up the plane. direction=up is impending motion up the plane, so friction acts down. N is compression against the surface. μ is the coefficient at impending slip."
      },
      "tol": 1e-9
    },
    {
      "id": "boundary-weight",
      "ok": true,
      "kind": "boundary",
      "inputs": {
        "W": 0,
        "theta_deg": 0,
        "mu": 0.25,
        "direction": "up"
      },
      "expectError": "VALUE_MUST_BE_POSITIVE",
      "code": "VALUE_MUST_BE_POSITIVE",
      "error": "Weight W must be positive."
    },
    {
      "id": "boundary-angle",
      "ok": true,
      "kind": "boundary",
      "inputs": {
        "W": 100,
        "theta_deg": 90,
        "mu": 0.25,
        "direction": "up"
      },
      "expectError": "VALUE_OUT_OF_RANGE",
      "code": "VALUE_OUT_OF_RANGE",
      "error": "theta_deg must lie in [0, 90)."
    },
    {
      "id": "boundary-mu",
      "ok": true,
      "kind": "boundary",
      "inputs": {
        "W": 100,
        "theta_deg": 0,
        "mu": -0.1,
        "direction": "up"
      },
      "expectError": "VALUE_OUT_OF_RANGE",
      "code": "VALUE_OUT_OF_RANGE",
      "error": "mu must be non-negative."
    },
    {
      "id": "boundary-direction",
      "ok": true,
      "kind": "boundary",
      "inputs": {
        "W": 100,
        "theta_deg": 0,
        "mu": 0.25
      },
      "expectError": "MISSING_REQUIRED_INPUT",
      "code": "MISSING_REQUIRED_INPUT",
      "error": "direction is required."
    }
  ],
  "tier": "engine_tested",
  "verification": {
    "tests": {
      "passed": 7,
      "total": 7,
      "golden": 3,
      "boundary": 4,
      "property": 0
    },
    "contract_checks": {
      "passed": 6,
      "total": 6
    }
  },
  "evidence_core_generated_at": "2026-09-23T10:34:21.178Z",
  "rendered_at": "2026-09-23T10:57:00.183Z",
  "release_integrity": {
    "status": "verified",
    "scope": "workspace",
    "production_attestation_required": true,
    "calculation_version": "1.0.0",
    "artifacts": {
      "engine": "1.0.0",
      "page": "1.0.0",
      "capability": "1.0.0",
      "evidence": "1.0.0",
      "input_schema": "1.0.0",
      "output_schema": "1.0.0",
      "mcp_contract": "1.0.0"
    },
    "digests": {
      "input_schema_sha256": "c9a87a5014dd69c3244ed88cb3a8e471a38068020f37be20589598ac6a68ab7d",
      "output_schema_sha256": "aaf5c4178077326ee390b5644ba15279cea0f946114a76f28a9bde402c12df00",
      "evidence_sha256": "f100abf790c16c2a19772f76d66ab57a6438046c71bca1c1488032b4a906f588",
      "evidence_core_sha256": "f100abf790c16c2a19772f76d66ab57a6438046c71bca1c1488032b4a906f588",
      "capability_sha256": "313e9c65055b987052e85a1083ad38c00343c5da65cce0c701076f90ccb800e7",
      "engine_sha256": "2834c6bc0e697b4d1e17766004f95cbfb57722d30aac4f3245109e79ef19ffae",
      "mcp_contract_sha256": "7015b0a59a475803dcfdfe80a660fa9d4d216cc36bd496d9466d1918d64ff186"
    },
    "contract_checks": {
      "total": 6,
      "passed": 6,
      "failed": 0,
      "items": [
        {
          "id": "release-artifacts-aligned",
          "status": "pass",
          "detail": "1.0.0"
        },
        {
          "id": "schema-output-required-declared",
          "status": "pass"
        },
        {
          "id": "schema-valid-input-executes",
          "status": "pass"
        },
        {
          "id": "engine-success-output-validates-schema",
          "status": "pass"
        },
        {
          "id": "schema-rejects-incomplete-input",
          "status": "pass"
        },
        {
          "id": "rest-success-payload-validates-schema",
          "status": "pass"
        }
      ]
    },
    "report": "https://www.calculatorx.com/.well-known/calculatorx-release-integrity.json"
  }
}
