{
  "schemaVersion": "reqproof.evidence-package.v1",
  "canonicalizationVersion": "1",
  "packageIdentity": "epkg-c21fdacdbce894a0011fb3f984d7d614063a83686bc936b4f899d6d52fc8b11c",
  "canonicalDigest": "sha256:5585f9c1c4cd1ecbfc2e9aa5199975a36a3f35cac2d51b9a013526083f4ee615",
  "createdAt": "2026-10-03T09:32:04Z",
  "producerRunId": "run-1ec6d97caf7403e0898ebcbf75d3f4dd6f709596ddbf5fd09ceebd8c586fc54e",
  "subject": {
    "repo": "https://example.invalid/teaching/retained-obligation",
    "provider": "github",
    "prNumber": null,
    "headSha": "33e282532163634bb0137fc66fa6fa3fab00c8fe",
    "treeKind": "head",
    "forge": {
      "provider": "generic",
      "host": "example.invalid",
      "project": "teaching/retained-obligation"
    },
    "changeKind": "commit",
    "changeId": "33e282532163634bb0137fc66fa6fa3fab00c8fe",
    "changeKey": "commit/33e282532163634bb0137fc66fa6fa3fab00c8fe",
    "specRevision": "565502407126b1c07d0130db9eadacbd637f52ac",
    "engineVersion": "0.1.0-teaching-b845ff313bac",
    "assemblerVersion": "0.1.0-teaching-b845ff313bac"
  },
  "readiness": "not_assessed",
  "auditVerdictAtHead": "pass",
  "gates": [
    {
      "id": "tests_pass",
      "scope": "project",
      "outcome": "passed",
      "rawStatus": "pass",
      "severity": "error",
      "required": false,
      "requirednessSource": "unknown_no_trusted_policy",
      "applicable": true
    }
  ],
  "evidenceRecords": [],
  "review": {
    "baseBranch": "33e282532163634bb0137fc66fa6fa3fab00c8fe",
    "summary": {
      "added": 0,
      "modified": 0,
      "deleted": 0,
      "total": 0
    },
    "changes": [],
    "codeChanges": {
      "totalFiles": 0,
      "mappedFiles": 0,
      "unmappedFiles": [],
      "mappingGranularity": "file"
    },
    "diff": {
      "files": []
    },
    "diffCoverage": {
      "source": "none",
      "measured": false
    },
    "risk": {
      "level": "low",
      "reasons": [
        "No introduced gate failures, no untested or unmeasured changed decisions, and every changed function maps to a requirement at function level."
      ]
    },
    "scope": {
      "method": "changed units from review.diff (function-granular where a parser exists, else file-granular) traced against the requirements' implemented_by/verified_by targets and local annotations; touched requirements clustered in the intent graph (satisfies/parent incl. siblings under a parent with <= 20 children, shared component, interface contracts); uncodified connections from call-level impact paths (review.changes impactPath); removed-code traces from trace targets and removed diff lines",
      "intentGraph": {
        "available": true,
        "requirements": 1,
        "parentEdges": 0,
        "components": 1,
        "contracts": 0,
        "maxSiblingFanout": 20
      },
      "units": [],
      "clusters": [],
      "coherence": "no_requirements",
      "coherenceNote": "The PR touches no traced requirement (no spec change and no changed code traced to a requirement).",
      "specGapCandidates": [],
      "approximations": [
        "Units are function-granular only where a parser extracts function boundaries (tree-sitter languages, plus C/C++ function-like macros); other changed files are one file-granular unit, and hunks outside any function are attributed to the file only when no function of that file changed.",
        "Renamed/moved detection is best effort: a removed and an added function with the same name in different files are \"moved\"; a different name with >= 80% identical normalized body lines (>= 3 lines) is \"renamed\"; anything else is removed + added.",
        "Function-level mapping comes from trace targets `path:symbol` / line ranges (authored + derived) and function-local annotations; a whole-file trace is file-level (weak) and says nothing about which function a requirement needs.",
        "Intent relations: requirement level = satisfies/parent or siblings under a parent with <= 20 children; component level = shared component (incl. traces.components); contract level = an interface requirement naming both components. A missing spec edge can make a real dependency look uncodified, and a broad contract can make an uncodified dependency look related — every candidate is a question for a reviewer, not a verdict on the code or the spec.",
        "When a changed function is traced only at FILE level, every requirement of its file is a from-side seed: a relation through any of them counts as codified, so a coarse trace can MASK an uncodified connection (and inflate scope clusters — see coarse_trace).",
        "Scope clusters are seeded only by directly touched requirements (spec changes and code_changed); behavior_affected requirements are what the change reaches and are judged by the uncodified-connection rule instead.",
        "Removed-code traces: targets naming a removed/renamed/moved function or a deleted file, and requirement ids cited on removed diff lines that the evaluated file no longer cites. remainingTraces counts the requirement's other code targets at the evaluated revision without re-checking that each still resolves.",
        "Uncodified connections need call-level impact (review.effects — C/C++ only today): this package has none, so NO uncodified connection could be detected. Absence of such candidates proves nothing here."
      ]
    },
    "behaviorDiff": {
      "status": "not_checked",
      "reason": "no behaviour-diff harness is configured (project.review.behavior_diff)",
      "head": "33e282532163634bb0137fc66fa6fa3fab00c8fe",
      "harness": {
        "command": ""
      },
      "corpus": {
        "sources": [],
        "partitions": []
      },
      "inputsRun": 0,
      "inventory": [],
      "differences": []
    },
    "compat": {
      "state": "not_checked",
      "sources": [
        {
          "source": "test_diff",
          "status": "not_checked",
          "reason": "no base / head revision to compare tests between",
          "findings": 0
        },
        {
          "source": "mcdc_diff",
          "status": "not_applicable",
          "reason": "the project records no MC/DC evidence",
          "findings": 0
        },
        {
          "source": "removed_behavior",
          "status": "checked",
          "findings": 0
        },
        {
          "source": "differential",
          "status": "not_checked",
          "reason": "no behaviour-diff harness is configured (project.review.behavior_diff)",
          "findings": 0
        }
      ],
      "findings": []
    }
  },
  "policyBasis": {
    "source": "base_revision",
    "candidateRevision": "33e282532163634bb0137fc66fa6fa3fab00c8fe",
    "status": "unavailable",
    "reason": "the base revision is unknown (no subject.baseSha / mergeBaseSha)"
  },
  "testResults": {
    "status": "ingested",
    "reportPath": ".evidence/tests.xml",
    "format": "junit",
    "reportDigest": "sha256:4f01bf7b550d4e2caa3d6d863b3bba196703db66bad60a5ea763aa1af5c617f0",
    "currency": "current",
    "currencyDetail": "run record (full run at 2026-10-03T09:32:04Z) matches the current test inputs",
    "total": 5,
    "passed": 5,
    "failed": 0,
    "skipped": 0,
    "taggedTests": 0,
    "joinedTests": 0
  },
  "decisionSummary": {
    "schemaVersion": "reqproof.decision-summary.v1",
    "readiness": "not_assessed",
    "evaluatedRevision": {
      "evaluatedCommit": "33e282532163634bb0137fc66fa6fa3fab00c8fe",
      "headSha": "33e282532163634bb0137fc66fa6fa3fab00c8fe",
      "treeKind": "head",
      "producerRunId": "run-1ec6d97caf7403e0898ebcbf75d3f4dd6f709596ddbf5fd09ceebd8c586fc54e"
    },
    "intendedChange": {
      "status": "undeclared",
      "sources": [],
      "changedRequirements": []
    },
    "preservedBehaviour": {
      "requirements": [],
      "total": 0
    },
    "scope": {
      "coherence": "no_requirements",
      "directRequirements": 0,
      "reachedRequirements": 0,
      "clusters": 0,
      "changedFiles": 0,
      "unmappedFiles": 0,
      "mappingGranularity": "file",
      "approximations": [
        "Function-level mapping comes from trace targets `path:symbol` / line ranges (authored + derived) and function-local annotations; a whole-file trace is file-level (weak) and says nothing about which function a requirement needs.",
        "Intent relations: requirement level = satisfies/parent or siblings under a parent with <= 20 children; component level = shared component (incl. traces.components); contract level = an interface requirement naming both components. A missing spec edge can make a real dependency look uncodified, and a broad contract can make an uncodified dependency look related — every candidate is a question for a reviewer, not a verdict on the code or the spec.",
        "Removed-code traces: targets naming a removed/renamed/moved function or a deleted file, and requirement ids cited on removed diff lines that the evaluated file no longer cites. remainingTraces counts the requirement's other code targets at the evaluated revision without re-checking that each still resolves.",
        "Renamed/moved detection is best effort: a removed and an added function with the same name in different files are \"moved\"; a different name with >= 80% identical normalized body lines (>= 3 lines) is \"renamed\"; anything else is removed + added.",
        "Scope clusters are seeded only by directly touched requirements (spec changes and code_changed); behavior_affected requirements are what the change reaches and are judged by the uncodified-connection rule instead.",
        "Uncodified connections need call-level impact (review.effects — C/C++ only today): this package has none, so NO uncodified connection could be detected. Absence of such candidates proves nothing here.",
        "Units are function-granular only where a parser extracts function boundaries (tree-sitter languages, plus C/C++ function-like macros); other changed files are one file-granular unit, and hunks outside any function are attributed to the file only when no function of that file changed.",
        "When a changed function is traced only at FILE level, every requirement of its file is a from-side seed: a relation through any of them counts as codified, so a coarse trace can MASK an uncodified connection (and inflate scope clusters — see coarse_trace)."
      ],
      "uncertaintyDisclosures": [
        "intent_undeclared",
        "policy_unavailable"
      ]
    },
    "claimEvidence": [],
    "routineEvidence": {
      "gatesPassed": 1,
      "gatesAdvisory": 0,
      "gatesNotApplicable": 0,
      "testsPassed": 0,
      "claimsObservedPass": 0
    },
    "disclosures": [
      {
        "id": "policy_unavailable",
        "kind": "partial_input",
        "reason": "policy_unavailable",
        "severity": "high",
        "consequence": "prevents_ready",
        "summary": "The approved policy (the policy at the base revision) could not be read, so readiness cannot be evaluated against it: the base revision is unknown (no subject.baseSha / mergeBaseSha).",
        "sourceRecords": [
          "policyBasis"
        ],
        "actor": "change_author"
      },
      {
        "id": "intent_undeclared",
        "kind": "partial_input",
        "reason": "intent_undeclared",
        "severity": "medium",
        "consequence": "prevents_ready",
        "summary": "Neither the change request nor the specification states what this change intends, so its effects cannot be judged against an intent.",
        "sourceRecords": [
          "changeRequest",
          "review.changes"
        ],
        "actor": "change_author"
      },
      {
        "id": "no_verifying_test",
        "kind": "missing_evidence",
        "reason": "no_verifying_test",
        "severity": "medium",
        "consequence": "prevents_ready",
        "summary": "The change touches no traced requirement, so no behavioural claim could be checked against observed evidence.",
        "sourceRecords": [
          "review.changes"
        ],
        "actor": "change_author"
      },
      {
        "id": "compat_not_checked",
        "kind": "missing_evidence",
        "reason": "compat_not_checked",
        "severity": "info",
        "consequence": "informs",
        "summary": "Backward compatibility was not fully checked (test_diff not_checked: no base / head revision to compare tests between; differential not_checked: no behaviour-diff harness is configured (project.review.behavior_diff)), so a compatibility change can go unnoticed.",
        "sourceRecords": [
          "compat.source:differential",
          "compat.source:test_diff"
        ]
      }
    ],
    "disclosureCounts": {
      "blocks": 0,
      "preventsReady": 3,
      "requiresJudgement": 0,
      "informs": 1
    },
    "nextDecision": {
      "kind": "more_evidence",
      "reason": "partial_inputs",
      "question": "Supply the missing evaluation inputs (1 input) so readiness can be assessed.",
      "disclosureIds": [
        "policy_unavailable"
      ]
    },
    "requiredAuthority": {
      "role": "change_author",
      "basis": "no_approved_policy",
      "acceptedIdentitySources": [
        "github_login",
        "portal_user"
      ],
      "enforcement": "portal_or_forge"
    },
    "compatibility": {
      "state": "not_checked",
      "intended": 0,
      "undeclared": 0,
      "fixed": 0,
      "partitions": 0,
      "inputs": 0
    }
  }
}
