{
  "ok": true,
  "tool": "api_why",
  "artifactClass": "why-run",
  "schemaVersion": "why-run-1.0",
  "sources": {
    "hash": "4f3f6bbaaad2cd611e636f6b3254d9099b258a5178e044f6e9c95cd7f8df2cfa",
    "files": [
      {
        "name": "support_access_after",
        "sha256": "57c925c01d7a146d3cb2fc247f9ffe511830319dbd45081524b710da7f4ad488"
      }
    ]
  },
  "request": {
    "binding": "Yichus/Examples/SupportAccess::reply_to_case",
    "inputs": {
      "p": {
        "user_id": "alice",
        "roles": []
      },
      "request": {
        "case_id": "case-1042",
        "reply": "Photo uploaded"
      }
    },
    "rows": {
      "support_cases": {
        "case-1042": {
          "id": "case-1042",
          "customer_id": "alice",
          "subject": "Damaged delivery",
          "status": "open",
          "customer_reply": "The corner is crushed",
          "staff_note": "Offer replacement after photo review"
        }
      }
    },
    "seed": 41,
    "observe": false,
    "variations": 5
  },
  "binding": {
    "package": "Yichus/Examples/SupportAccess",
    "name": "reply_to_case",
    "id": "Yichus/Examples/SupportAccess::reply_to_case",
    "type": "(Yichus/Data::Db, Yichus/Access::Principal, Yichus/Examples/SupportAccess::ReplyRequest) -> Yichus/IO::IO[Yichus/Service::Response]",
    "isIO": true,
    "arity": 3
  },
  "seed": 41,
  "inputs": [
    {
      "param": "db",
      "type": "Yichus/Data::Db",
      "shape": {
        "kind": "enum",
        "name": "Db",
        "constructors": []
      },
      "origin": "world",
      "json": null,
      "rendered": null
    },
    {
      "param": "p",
      "type": "Yichus/Access::Principal",
      "shape": {
        "kind": "struct",
        "name": "Principal",
        "newtype": false,
        "fields": [
          {
            "name": "user_id",
            "shape": {
              "kind": "string"
            }
          },
          {
            "name": "roles",
            "shape": {
              "kind": "list",
              "elem": {
                "kind": "string"
              }
            }
          }
        ]
      },
      "origin": "provided",
      "json": {
        "user_id": "alice",
        "roles": []
      },
      "rendered": "Principal(user_id: \"alice\", roles: [])"
    },
    {
      "param": "request",
      "type": "Yichus/Examples/SupportAccess::ReplyRequest",
      "shape": {
        "kind": "struct",
        "name": "ReplyRequest",
        "newtype": false,
        "fields": [
          {
            "name": "case_id",
            "shape": {
              "kind": "string"
            }
          },
          {
            "name": "reply",
            "shape": {
              "kind": "string"
            }
          }
        ]
      },
      "origin": "provided",
      "json": {
        "case_id": "case-1042",
        "reply": "Photo uploaded"
      },
      "rendered": "ReplyRequest(case_id: \"case-1042\", reply: \"Photo uploaded\")"
    }
  ],
  "output": {
    "type": "Yichus/Service::Response",
    "json": {
      "status": 200,
      "body": "case-1042 | Damaged delivery | open | reply: Photo uploaded"
    },
    "jsonStatus": "encoded",
    "rendered": "Response(status: 200, body: \"case-1042 | Damaged delivery | open | reply: Photo uploaded\")"
  },
  "soundFacts": {
    "basis": "sound-static (holds for every input)",
    "paramInfluence": [
      {
        "param": "db",
        "kind": "return-data",
        "sentence": "parameter 'db' may reach the returned data (static dataflow; holds for every input); no observation can rule its influence out"
      },
      {
        "param": "found",
        "kind": "return-data",
        "sentence": "parameter 'found' may reach the returned data (static dataflow; holds for every input); no observation can rule its influence out"
      },
      {
        "param": "p",
        "kind": "return-data",
        "sentence": "parameter 'p' may reach the returned data (static dataflow; holds for every input); no observation can rule its influence out"
      },
      {
        "param": "request",
        "kind": "return-data",
        "sentence": "parameter 'request' may reach the returned data (static dataflow; holds for every input); no observation can rule its influence out"
      },
      {
        "param": "updated",
        "kind": "return-data",
        "sentence": "parameter 'updated' may reach the returned data (static dataflow; holds for every input); no observation can rule its influence out"
      }
    ],
    "deadInputs": [],
    "structFields": [
      {
        "param": "request",
        "struct": "ReplyRequest",
        "field": "case_id",
        "readSites": 1,
        "sentence": "field 'case_id' of ReplyRequest is read at 1 site(s) program-wide (static; holds for every input)"
      },
      {
        "param": "request",
        "struct": "ReplyRequest",
        "field": "reply",
        "readSites": 1,
        "sentence": "field 'reply' of ReplyRequest is read at 1 site(s) program-wide (static; holds for every input)"
      }
    ]
  },
  "observed": {
    "basis": "bounded-observation (seed 41, one recorded handler run; 5 variations per aspect, each on a fresh world from the same seeded rows)",
    "referenceBasis": "global-value-forcing",
    "touched": [
      "Yichus/Examples/SupportAccess::cases_table",
      "Yichus/Examples/SupportAccess::owns_case",
      "Yichus/Examples/SupportAccess::public_case"
    ],
    "differentials": [],
    "notReached": {
      "definitions": [
        "Yichus/Examples/SupportAccess::forbidden_case",
        "Yichus/Examples/SupportAccess::missing_case"
      ],
      "sentence": "global values for 2 of 5 definitions reachable from Yichus/Examples/SupportAccess::reply_to_case statically were not forced on this input (seed 41): Yichus/Examples/SupportAccess::forbidden_case, Yichus/Examples/SupportAccess::missing_case — an absence on this input, not a fault; another input may force them; forcing a function value does not establish that its body ran; bounded observation, not proof"
    }
  },
  "world": {
    "shape": {
      "tables": {
        "support_cases": {
          "rowType": "Case",
          "rowForm": "record: the row under an id is one record (a JSON object)",
          "rowIsList": false,
          "recordFields": {
            "id": "String",
            "customer_id": "String",
            "subject": "String",
            "status": "String",
            "customer_reply": "String",
            "staff_note": "String"
          },
          "recordShape": {
            "kind": "struct",
            "name": "Case",
            "newtype": false,
            "fields": [
              {
                "name": "id",
                "shape": {
                  "kind": "string"
                }
              },
              {
                "name": "customer_id",
                "shape": {
                  "kind": "string"
                }
              },
              {
                "name": "subject",
                "shape": {
                  "kind": "string"
                }
              },
              {
                "name": "status",
                "shape": {
                  "kind": "string"
                }
              },
              {
                "name": "customer_reply",
                "shape": {
                  "kind": "string"
                }
              },
              {
                "name": "staff_note",
                "shape": {
                  "kind": "string"
                }
              }
            ]
          }
        }
      },
      "rowKey": "rows are {table: {id: row}} (or {table: [row, ...]} numbering rows \"1\"..\"n\"); a handler that reads by the principal's user_id needs a row under that id",
      "principalForm": {
        "user_id": "<id>",
        "roles": [
          "<role>"
        ]
      },
      "enumForm": "an enum value is written {\"Ctor\": {fields}} -- {\"Backlog\": {}} for a nullary constructor, which is also the form this tool prints; the bare object of a constructor's fields is read too, and a bare {} is the first nullary constructor"
    },
    "misses": [],
    "seededRows": {
      "support_cases": [
        "Case(id: \"case-1042\", customer_id: \"alice\", subject: \"Damaged delivery\", status: \"open\", customer_reply: \"The corner is crushed\", staff_note: \"Offer replacement after photo review\")"
      ]
    },
    "rowsAfter": {
      "support_cases": [
        "Case(id: \"case-1042\", customer_id: \"alice\", subject: \"Damaged delivery\", status: \"open\", customer_reply: \"Photo uploaded\", staff_note: \"Offer replacement after photo review\")"
      ]
    }
  },
  "skipped": [
    {
      "aspect": "differentials",
      "reason": "observe=false"
    }
  ],
  "proposals": [
    {
      "name": "p = a principal who owns no row",
      "rationale": "the recorded run's principal is 'alice'; untried: the principal 'someone-else' with no roles, who appears in no seeded row, which tests whether the result depends on who asks",
      "request": {
        "binding": "Yichus/Examples/SupportAccess::reply_to_case",
        "inputs": {
          "p": {
            "user_id": "someone-else",
            "roles": []
          },
          "request": {
            "case_id": "case-1042",
            "reply": "Photo uploaded"
          }
        },
        "rows": {
          "support_cases": {
            "case-1042": {
              "id": "case-1042",
              "customer_id": "alice",
              "subject": "Damaged delivery",
              "status": "open",
              "customer_reply": "The corner is crushed",
              "staff_note": "Offer replacement after photo review"
            }
          }
        },
        "seed": 41,
        "observe": false,
        "variations": 5
      }
    },
    {
      "name": "every table empty",
      "rationale": "the recorded run was seeded with rows in support_cases; untried: an empty world, where every read misses",
      "request": {
        "binding": "Yichus/Examples/SupportAccess::reply_to_case",
        "inputs": {
          "p": {
            "user_id": "alice",
            "roles": []
          },
          "request": {
            "case_id": "case-1042",
            "reply": "Photo uploaded"
          }
        },
        "rows": {},
        "seed": 41,
        "observe": false,
        "variations": 5
      }
    }
  ],
  "epistemics": "soundFacts hold for every input (static dataflow). observed entries are bounded observations from seeded runs. Decision rule: output dependence is ruled OUT only by a sound unused fact. A guard-only fact rules out data flow, but control flow can still change the result. A concrete differing-output witness establishes dependence. A return-data (may-reach) fact combined with observed-constant runs stays UNRESOLVED — the reaching path may need input regions these runs never visited, so vary the OTHER parameters' regions to hunt a witness before concluding anything.",
  "narrative": "This run evaluated the handler 'reply_to_case' (package Yichus/Examples/SupportAccess) with 'db' (the world's database), 'p' = Principal(user_id: \"alice\", roles: []) (provided) and 'request' = ReplyRequest(case_id: \"case-1042\", reply: \"Photo uploaded\") (provided). It returned Response(status: 200, body: \"case-1042 | Damaged delivery | open | reply: Photo uploaded\").\n\nProven for every input, by static dataflow (no run needed): 'db' may reach the result, so no run can rule its influence out; 'p' may reach the result, so no run can rule its influence out; 'request' may reach the result, so no run can rule its influence out; every field of ReplyRequest is read somewhere in the program.\n\nObserved on this run, not proven (bounded-observation (seed 41, one recorded handler run; 5 variations per aspect, each on a fresh world from the same seeded rows)): No input was varied. The run forced global values for 3 definitions: cases_table, owns_case, public_case. Loading a function value does not establish that its body ran. Global values for 2 definitions this one can reach were not forced on this input: forbidden_case, missing_case (an absence on this input, not a fault; another input may force them).\n\nThe world was seeded with 1 row in 'support_cases'. Seeded rows, as rendered: 'support_cases': Case(id: \"case-1042\", customer_id: \"alice\", subject: \"Damaged delivery\", status: \"open\", customer_reply: \"The corner is crushed\", staff_note: \"Offer replacement after photo review\"). Every read found its row. After the run, 'support_cases' changed under 1 id (the same count, different rows).\n\nNot measured: differentials (observe=false).\n\n2 experiments are proposed from this run's facts, none of them run: p = a principal who owns no row; every table empty."
}
