{
  "schema": "MAKNOW_D3D001_LAB_VISIBLE_RULES_v1.2",
  "lesson_id": "D3D-001",
  "lab_id": "D3D-001-LAB1",
  "purpose": "Visible deterministic consistency rules for Production Mesh Modeling and Topology Evidence Pack v1; not an approval oracle.",
  "positive_states": [
    "READY",
    "TARGET_SPECIFIC"
  ],
  "allowed_states": [
    "READY",
    "TARGET_SPECIFIC",
    "REWORK_REQUIRED",
    "HOLD",
    "EVIDENCE_INCOMPLETE",
    "PROVENANCE_UNKNOWN",
    "METHOD_UNSUITABLE"
  ],
  "rules": [
    {
      "id": "R1",
      "text": "Positive states require all P8-critical dimensions: target/use+scope, units/reference scale, transform/topology/geometry, normals/manifold requirement, modifier stack plus destructive-step log, naming/origin, validation views, provenance, known limitations, interoperability evidence, and an explicit evidence_ref."
    },
    {
      "id": "R2",
      "text": "UNAPPLIED_NON_UNIFORM scale on a decisive object is incompatible with a positive state in this bounded lab unless the declared target evidence explicitly resolves it; shipped fixtures provide no such resolution."
    },
    {
      "id": "R3",
      "text": "INCONSISTENT_FLIPPED normals are incompatible with a positive state."
    },
    {
      "id": "R4",
      "text": "If the named geometry budget declares max_triangles, triangle_count above it is incompatible with a positive state."
    },
    {
      "id": "R5",
      "text": "If manifold_requirement is REQUIRED, positive state requires PASS_MANIFOLD_CHECK."
    },
    {
      "id": "R6",
      "text": "Positive state requires a visible modifier stack, an explicit destructive_step_log (which may be empty when no destructive step occurred), and no unreviewed destructive step."
    },
    {
      "id": "R7",
      "text": "Positive state requires a naming contract, decisive object names, and explicit origin/pivot state."
    },
    {
      "id": "R8",
      "text": "Export-only or beauty-render evidence is not interoperability proof."
    },
    {
      "id": "R9",
      "text": "READY requires STANDARD_DECLARED_TARGET; TARGET_SPECIFIC requires CONSTRAINED_NAMED_TARGET_ONLY."
    },
    {
      "id": "R10",
      "text": "Every chosen state requires at least one applicable learner-authored future trigger condition named review, migration, escalation, stop, or pivot. Do not require all five categories mechanically."
    },
    {
      "id": "R11",
      "text": "Missing decisive evidence may remain in typed non-success states; the checker never chooses the learner decision."
    },
    {
      "id": "R12",
      "text": "fixture_ref must resolve to a shipped visible baseline, mutation, or transfer fixture. Any submitted non-empty decisive evidence must match the resolved fixture/mutation evidence exactly. For positive states, every P8-critical/positive-required dimension and every target requirement explicitly present in the resolved fixture must be supplied and match that fixture; non-critical material_slot_count remains optional but is bound when supplied. The checker does not invent or infer fixture values."
    }
  ],
  "fixture_sources": {
    "D3D001-BASELINE-HS-01": "fixtures/baseline_fixture.json",
    "D3D001-MUT-MOBILE": "fixtures/mutation_mobile_target.json",
    "D3D001-MUT-SCALE": "fixtures/mutation_nonuniform_scale.json",
    "D3D001-MUT-NORMALS": "fixtures/mutation_flipped_normals.json",
    "D3D001-MUT-NAMING": "fixtures/mutation_missing_naming.json",
    "D3D001-TRANSFER-ORG-01": "transfer/transfer_fixture.json"
  },
  "fixture_binding_policy": "Visible CHECK_RULES.json maps fixture IDs to shipped files. The checker resolves baseline/transfer/mutations deterministically. For positive states it requires complete binding of P8-critical/positive-required evidence and explicit target requirements in the resolved fixture; non-critical material_slot_count is optional but must match if supplied. Decision values are never prefilled or used as an answer key.",
  "rule_source_contract": "pack_rules.py consumes rule IDs, allowed/positive states, and fixture_sources from this visible file."
}
