{
  "tool_id": "art-619-ccd2-aprc-annex3-recompute",
  "note": "Fixture-oracle independence (FORMALVERIF-BUILD-SPEC.md 3d): Annex III itself carries no worked numeric example (unlike Reg Z Appendix J, art-215 source). Golden values derive from CLOSED-FORM ALGEBRA solved forward (given X, solve for flow amounts satisfying Annex III Part I equation by direct substitution) -- a computation direction opposite to this kernel bisection search (given flows, find X). FV 3d preference-3 shape (independently worked, not generated from the same reading that produced the spec, not run through the kernel to produce the target); documented per-vector in fixture_oracle_note. human_sign_off: PENDING.",
  "vectors": [
    {
      "name": "single-drawdown-single-repayment-10pct-closed-form",
      "policy_parameters": {
        "drawdowns": [
          {
            "amount": 1000,
            "full_periods": 0,
            "fraction": 0
          }
        ],
        "repayments": [
          {
            "amount": 1100,
            "full_periods": 1,
            "fraction": 0
          }
        ]
      },
      "output_payload": {
        "aprc_pct": 10,
        "converged": true,
        "bracketed": true,
        "iterations_used": 26,
        "residual_at_convergence": 4.5454544306267053e-7,
        "num_drawdowns": 1,
        "num_repayments": 1,
        "drawdown_total": 1000,
        "repayment_total": 1100,
        "total_charge": 100,
        "regulatory_basis": "Directive (EU) 2023/2225 (CCD2), Article 30 + Annex III Part I (basic equation).",
        "note": "APRC solved by bracketed bisection on Annex III Part I's basic equation, real-valued t_k/s_l per the Directive's own text (no integer/fraction split). Rounded per Annex III Part I remark (d): at least one decimal place, half-up on the next digit. A rate is reported only when a sign-change bracket was established and narrowed to tolerance; otherwise aprc_pct is null and APRC_NOT_BRACKETED or APRC_DID_NOT_CONVERGE is raised. Verify-only recompute: does not determine CCD2 applicability, does not submit anything to a regulator, and does not assert compliance."
      },
      "fixture_oracle_note": "closed-form algebra: D/C - 1 = 1100/1000 - 1 = 0.10 exactly, independent of this kernel bisection.",
      "golden_hash": "f150499b37a191ee44e9a5a88985cdec17c25c87f5e62473eaa2c98499bdae90"
    },
    {
      "name": "zero-charge-guard-0pct",
      "policy_parameters": {
        "drawdowns": [
          {
            "amount": 1000,
            "full_periods": 0,
            "fraction": 0
          }
        ],
        "repayments": [
          {
            "amount": 1000,
            "full_periods": 1,
            "fraction": 0
          }
        ]
      },
      "output_payload": {
        "aprc_pct": 0,
        "converged": true,
        "bracketed": true,
        "iterations_used": 0,
        "residual_at_convergence": 0,
        "num_drawdowns": 1,
        "num_repayments": 1,
        "drawdown_total": 1000,
        "repayment_total": 1000,
        "total_charge": 0,
        "regulatory_basis": "Directive (EU) 2023/2225 (CCD2), Article 30 + Annex III Part I (basic equation).",
        "note": "APRC solved by bracketed bisection on Annex III Part I's basic equation, real-valued t_k/s_l per the Directive's own text (no integer/fraction split). Rounded per Annex III Part I remark (d): at least one decimal place, half-up on the next digit. A rate is reported only when a sign-change bracket was established and narrowed to tolerance; otherwise aprc_pct is null and APRC_NOT_BRACKETED or APRC_DID_NOT_CONVERGE is raised. Verify-only recompute: does not determine CCD2 applicability, does not submit anything to a regulator, and does not assert compliance."
      },
      "fixture_oracle_note": "closed-form algebra: D=C -> X=0 exactly.",
      "golden_hash": "713fca8851d660a9853edee75cf0ad220e06895cb4ae0bc4e7663081a6c96e03"
    },
    {
      "name": "multi-period-amortizing-unequal-spacing-20pct",
      "policy_parameters": {
        "drawdowns": [
          {
            "amount": 1000,
            "full_periods": 0,
            "fraction": 0
          }
        ],
        "repayments": [
          {
            "amount": 300,
            "full_periods": 0,
            "fraction": 0.3
          },
          {
            "amount": 859.1619068403334,
            "full_periods": 1,
            "fraction": 0
          }
        ]
      },
      "output_payload": {
        "aprc_pct": 20,
        "converged": true,
        "bracketed": true,
        "iterations_used": 27,
        "residual_at_convergence": -3.338241185701918e-7,
        "num_drawdowns": 1,
        "num_repayments": 2,
        "drawdown_total": 1000,
        "repayment_total": 1159.1619068403334,
        "total_charge": 159.16190684033336,
        "regulatory_basis": "Directive (EU) 2023/2225 (CCD2), Article 30 + Annex III Part I (basic equation).",
        "note": "APRC solved by bracketed bisection on Annex III Part I's basic equation, real-valued t_k/s_l per the Directive's own text (no integer/fraction split). Rounded per Annex III Part I remark (d): at least one decimal place, half-up on the next digit. A rate is reported only when a sign-change bracket was established and narrowed to tolerance; otherwise aprc_pct is null and APRC_NOT_BRACKETED or APRC_DID_NOT_CONVERGE is raised. Verify-only recompute: does not determine CCD2 applicability, does not submit anything to a regulator, and does not assert compliance."
      },
      "fixture_oracle_note": "forward-substitution: X fixed at 0.20, D1=300 at t=0.3 given, D2 solved algebraically at t=1.0 so C = D1*(1.2)^-0.3 + D2*(1.2)^-1 holds exactly (verified by direct substitution, independent of this kernel bisection search direction).",
      "golden_hash": "a10045162912063cb89e23840c8359b00c0f5e64451e0ec67ba2676d291411f5"
    },
    {
      "name": "f2-shaped-non-convergence-negative-charge",
      "policy_parameters": {
        "drawdowns": [
          {
            "amount": 1000,
            "full_periods": 0,
            "fraction": 0
          }
        ],
        "repayments": [
          {
            "amount": 900,
            "full_periods": 1,
            "fraction": 0
          }
        ]
      },
      "output_payload": {
        "aprc_pct": null,
        "converged": false,
        "bracketed": false,
        "iterations_used": 0,
        "residual_at_convergence": null,
        "num_drawdowns": 1,
        "num_repayments": 1,
        "drawdown_total": 1000,
        "repayment_total": 900,
        "total_charge": -100,
        "regulatory_basis": "Directive (EU) 2023/2225 (CCD2), Article 30 + Annex III Part I (basic equation).",
        "note": "APRC solved by bracketed bisection on Annex III Part I's basic equation, real-valued t_k/s_l per the Directive's own text (no integer/fraction split). Rounded per Annex III Part I remark (d): at least one decimal place, half-up on the next digit. A rate is reported only when a sign-change bracket was established and narrowed to tolerance; otherwise aprc_pct is null and APRC_NOT_BRACKETED or APRC_DID_NOT_CONVERGE is raised. Verify-only recompute: does not determine CCD2 applicability, does not submit anything to a regulator, and does not assert compliance."
      },
      "fixture_oracle_note": "closed-form: D<C means G(0)<0, no non-negative root exists by the equation itself; PRE-8-equivalent precondition fails analytically.",
      "golden_hash": "5909b4af8cd6436247824291e752be461bf2e6a80925ef4adb87ee4477751cd6"
    },
    {
      "name": "degenerate-all-zero-schedule",
      "policy_parameters": {
        "drawdowns": [
          {
            "amount": 0,
            "full_periods": 0,
            "fraction": 0
          }
        ],
        "repayments": [
          {
            "amount": 0,
            "full_periods": 1,
            "fraction": 0
          }
        ]
      },
      "output_payload": {
        "aprc_pct": null,
        "converged": false,
        "bracketed": false,
        "iterations_used": 0,
        "residual_at_convergence": null,
        "num_drawdowns": 1,
        "num_repayments": 1,
        "drawdown_total": 0,
        "repayment_total": 0,
        "total_charge": 0,
        "regulatory_basis": "Directive (EU) 2023/2225 (CCD2), Article 30 + Annex III Part I (basic equation).",
        "note": "APRC solved by bracketed bisection on Annex III Part I's basic equation, real-valued t_k/s_l per the Directive's own text (no integer/fraction split). Rounded per Annex III Part I remark (d): at least one decimal place, half-up on the next digit. A rate is reported only when a sign-change bracket was established and narrowed to tolerance; otherwise aprc_pct is null and APRC_NOT_BRACKETED or APRC_DID_NOT_CONVERGE is raised. Verify-only recompute: does not determine CCD2 applicability, does not submit anything to a regulator, and does not assert compliance."
      },
      "fixture_oracle_note": "closed-form: no repayment carries positive amount at positive time, equation has no rate dependence by inspection.",
      "golden_hash": "ecbf77e1c0de3aa5c64aaf677eb3cf59cb1985bb9a6ff2e4c57e77361658398a"
    },
    {
      "name": "ulp-boundary-min-value-amounts",
      "policy_parameters": {
        "drawdowns": [
          {
            "amount": 5e-324,
            "full_periods": 0,
            "fraction": 0
          }
        ],
        "repayments": [
          {
            "amount": 5e-324,
            "full_periods": 1,
            "fraction": 0
          }
        ]
      },
      "output_payload": {
        "aprc_pct": 0,
        "converged": true,
        "bracketed": true,
        "iterations_used": 0,
        "residual_at_convergence": 0,
        "num_drawdowns": 1,
        "num_repayments": 1,
        "drawdown_total": 5e-324,
        "repayment_total": 5e-324,
        "total_charge": 0,
        "regulatory_basis": "Directive (EU) 2023/2225 (CCD2), Article 30 + Annex III Part I (basic equation).",
        "note": "APRC solved by bracketed bisection on Annex III Part I's basic equation, real-valued t_k/s_l per the Directive's own text (no integer/fraction split). Rounded per Annex III Part I remark (d): at least one decimal place, half-up on the next digit. A rate is reported only when a sign-change bracket was established and narrowed to tolerance; otherwise aprc_pct is null and APRC_NOT_BRACKETED or APRC_DID_NOT_CONVERGE is raised. Verify-only recompute: does not determine CCD2 applicability, does not submit anything to a regulator, and does not assert compliance."
      },
      "fixture_oracle_note": "IEEE-754 analysis: MIN_VALUE*0.1 underflows to 0 in double precision, so g0===0 exactly and the solver takes its exact-root branch, reporting X=0 -- documented float-precision limit, not a kernel defect.",
      "golden_hash": "ed5391c2b93dc75026142c396d551112f43d001f7f770225d6d19e856e495b6f"
    },
    {
      "name": "half-up-rounding-tie-exact-8ths",
      "policy_parameters": {
        "drawdowns": [
          {
            "amount": 1000,
            "full_periods": 0,
            "fraction": 0
          }
        ],
        "repayments": [
          {
            "amount": 1125,
            "full_periods": 1,
            "fraction": 0
          }
        ]
      },
      "output_payload": {
        "aprc_pct": 12.5,
        "converged": true,
        "bracketed": true,
        "iterations_used": 26,
        "residual_at_convergence": -4.4444448121794267e-7,
        "num_drawdowns": 1,
        "num_repayments": 1,
        "drawdown_total": 1000,
        "repayment_total": 1125,
        "total_charge": 125,
        "regulatory_basis": "Directive (EU) 2023/2225 (CCD2), Article 30 + Annex III Part I (basic equation).",
        "note": "APRC solved by bracketed bisection on Annex III Part I's basic equation, real-valued t_k/s_l per the Directive's own text (no integer/fraction split). Rounded per Annex III Part I remark (d): at least one decimal place, half-up on the next digit. A rate is reported only when a sign-change bracket was established and narrowed to tolerance; otherwise aprc_pct is null and APRC_NOT_BRACKETED or APRC_DID_NOT_CONVERGE is raised. Verify-only recompute: does not determine CCD2 applicability, does not submit anything to a regulator, and does not assert compliance."
      },
      "fixture_oracle_note": "closed-form: X=0.125 exactly -> 12.5000%, already exact at 1dp, confirms half_up passthrough on a non-tie case.",
      "golden_hash": "04a26449f7ad3b10073c1db0ec753f3a676c6cd630e58785d85d26e99441cee8"
    },
    {
      "name": "empty-schedule-guard",
      "policy_parameters": {
        "drawdowns": [],
        "repayments": []
      },
      "output_payload": {
        "aprc_pct": null,
        "converged": false,
        "bracketed": false,
        "iterations_used": 0,
        "residual_at_convergence": null,
        "num_drawdowns": 0,
        "num_repayments": 0,
        "drawdown_total": 0,
        "repayment_total": 0,
        "total_charge": 0,
        "regulatory_basis": "Directive (EU) 2023/2225 (CCD2), Article 30 + Annex III Part I (basic equation).",
        "note": "APRC solved by bracketed bisection on Annex III Part I's basic equation, real-valued t_k/s_l per the Directive's own text (no integer/fraction split). Rounded per Annex III Part I remark (d): at least one decimal place, half-up on the next digit. A rate is reported only when a sign-change bracket was established and narrowed to tolerance; otherwise aprc_pct is null and APRC_NOT_BRACKETED or APRC_DID_NOT_CONVERGE is raised. Verify-only recompute: does not determine CCD2 applicability, does not submit anything to a regulator, and does not assert compliance."
      },
      "fixture_oracle_note": "closed-form: empty arrays sum to zero PV on both sides trivially, no rate dependence by construction.",
      "golden_hash": "2211a82220337dadcd8b31aeeba792c2078da1c572e51e7875c282b067375788"
    }
  ]
}
