{
  "schema": "niua.auto-sim-run/v1",
  "about": "An agent repairs a robot description from the NIUA gate's typed failures until it passes urdf.sim-ready@1, then the repaired file is loaded and simulated in MuJoCo. Recorded on production.",
  "session": "auto-sim-2026-10-15",
  "recorded_at": "2026-10-15T15:51:50.437Z",
  "agent": "Claude Code (an AI coding agent) using tools/auto-sim/apply_repairs.py (trimesh for mass and inertia)",
  "contract": "urdf.sim-ready@1",
  "input": {
    "file": "/auto-sim/input.zip",
    "note": "The playground robot arm as made: four seeded mistakes"
  },
  "output": {
    "file": "/auto-sim/output.zip",
    "tree": "/auto-sim/output/niua_arm/urdf/niua_arm.urdf",
    "diff": "/auto-sim/urdf.diff"
  },
  "rounds": [
    {
      "round": 1,
      "check_id": "b1f2006f-153f-461e-a12f-90ab1badbb57",
      "verdict": "fail",
      "artifact_sha256": "4671c7d1277219fb6e5453c6cf391eae2d23ff137f2fad17d0d2501931a528c0",
      "failures": [
        {
          "rule": "inertial.mass_positive",
          "path": "/robot/link[finger_left]/inertial",
          "subject": "finger_left",
          "expected": "mass >= 0.001 kg",
          "got": "0 kg",
          "fix": "Give the link its real mass in kg (from CAD, or density × volume). A missing or near-zero mass makes the simulator collapse or explode the link."
        },
        {
          "rule": "inertial.tensor_valid",
          "path": "/robot/link[forearm]/inertial/inertia",
          "subject": "forearm",
          "expected": "largest moment <= mass × d² = 0.9337 kg·m² (d = model diagonal 1.022 m)",
          "got": "principal moments [1.0000, 1.0000, 1.0000]",
          "fix": "This tensor needs a body larger than the whole robot (radius of gyration 1.06 m). It looks like a placeholder (identity inertia?); recompute it from the link geometry."
        },
        {
          "rule": "collision.on_visual_links",
          "path": "/robot/link[wrist]/collision",
          "subject": "wrist",
          "expected": "a <collision> on every link with a <visual>",
          "got": "a visual and no collision",
          "fix": "Add a <collision> with a primitive (box, cylinder, sphere) or a convex hull of the visual mesh."
        },
        {
          "rule": "joints.limits",
          "path": "/robot/joint[elbow]/limit",
          "subject": "elbow",
          "expected": "lower < upper",
          "got": "lower 2.4 >= upper -2.4",
          "fix": "Swap or correct the limits; lower must be below upper (radians for revolute, metres for prismatic)."
        },
        {
          "rule": "joints.limits",
          "path": "/robot/joint[elbow]/limit",
          "subject": "elbow",
          "expected": "velocity > 0",
          "got": "no velocity",
          "fix": "Set velocity from the actuator's datasheet (rad/s or m/s); 0 means the joint can never move."
        }
      ],
      "receipt_id": null,
      "edits": [
        {
          "rule": "inertial.mass_positive",
          "subject": "finger_left",
          "edit": "mass, centre of mass and inertia recomputed from meshes/finger_left.stl with trimesh",
          "values": {
            "mass_kg": 0.0144,
            "principal_moments": [
              4.8e-7,
              0.000004493,
              0.000004627
            ]
          },
          "assumption": "uniform density 1250 kg/m^3"
        },
        {
          "rule": "inertial.tensor_valid",
          "subject": "forearm",
          "edit": "mass, centre of mass and inertia recomputed from meshes/forearm.stl with trimesh",
          "values": {
            "mass_kg": 0.893569,
            "principal_moments": [
              0.000400007,
              0.007115325,
              0.007135105
            ]
          },
          "assumption": "uniform density 1250 kg/m^3"
        },
        {
          "rule": "collision.on_visual_links",
          "subject": "wrist",
          "edit": "added a box collider from the bounds of meshes/wrist.stl",
          "values": {
            "box_size_m": [
              0.064,
              0.064,
              0.07
            ],
            "origin_m": [
              0,
              0,
              0.035
            ]
          },
          "assumption": null
        },
        {
          "rule": "joints.limits",
          "subject": "elbow",
          "edit": "swapped inverted limits to lower -2.4, upper 2.4",
          "values": {
            "lower": -2.4,
            "upper": 2.4
          },
          "assumption": null
        },
        {
          "rule": "joints.limits",
          "subject": "elbow",
          "edit": "set velocity to 1.75",
          "values": {
            "velocity": 1.75
          },
          "assumption": "median velocity of the arm's other joints; no actuator datasheet exists for this arm"
        }
      ]
    },
    {
      "round": 2,
      "check_id": "f40e9b32-4425-4ee3-ae09-c768e74da1e7",
      "verdict": "pass",
      "artifact_sha256": "6f24db7ddfc7d99682b1f7eeca03f9548e39654516de1b92086ca384941cdde0",
      "failures": [],
      "receipt_id": "48e24d5c-3bb1-476d-8d1f-b5cd52bb7545",
      "edits": []
    }
  ],
  "receipt": {
    "id": "48e24d5c-3bb1-476d-8d1f-b5cd52bb7545",
    "valid": true,
    "page": "https://ohao.tech/niua/receipts/48e24d5c-3bb1-476d-8d1f-b5cd52bb7545"
  },
  "simulator": {
    "input": {
      "file": "niua_arm/urdf/niua_arm.urdf",
      "mujoco": "3.16.0",
      "seconds": 2,
      "compiles": false,
      "error": "Error: mass and inertia of moving bodies must be larger than mjMINVAL"
    },
    "output": {
      "file": "niua_arm/urdf/niua_arm.urdf",
      "mujoco": "3.16.0",
      "seconds": 2,
      "compiles": true,
      "bodies": 8,
      "joints": 7,
      "dof": 7,
      "geoms": 16,
      "total_mass_kg": 4.9372,
      "timestep_s": 0.002,
      "steps": 1000,
      "start_pose_rad": {
        "shoulder_lift": 0.6,
        "elbow": 0.9,
        "wrist_pitch": 0.6
      },
      "state_finite": true,
      "max_abs_qvel": 26.7953,
      "mujoco_warnings": 0
    },
    "script": "tools/auto-sim/simulate.py",
    "checks": "compiles, then 2 s under gravity from a bent pose with no actuation: the state stays finite. A loader and stability check, not a physics-fidelity or sim-to-real test."
  }
}
