{
  "tool_id": "art-663-apy-earned-recompute",
  "note": "Golden vectors for the APY-earned recompute (periodic-statement annual percentage yield earned). FIXTURE ORACLE: vectors 1-3 carry the cited rule text's OWN published worked examples (Appendix A Part II Examples (1), (2), (3)), whose stated APY-earned figures (6.58%, 5.40%, 4.28%) this kernel must reproduce to two decimals; vector 4 reuses Example (1)'s span construction for the balance-segment derivation the text itself states ($1,500 for 15 days + $500 for 15 days of a 30-day period = $1,000 average daily balance); vectors 5-8 are hand-computed by a second reading directly against the formula text (compound general formula, not the build spec's simple-annualization variant). Each vector carries an independent_oracle block recording the externally-derived expectation; the proptest floor asserts the recomputed output against THAT block, so the recorded payload can never become its own oracle. The recorded output_payload/compliance_flags on each vector are the full golden master for the regression oracle. human_sign_off: PENDING.",
  "vectors": [
    {
      "name": "ruletext-part-ii-example-1-30-day-period",
      "note": "Appendix A Part II Example (1): balance $1,500 for 15 days and $500 for the remaining 15 days of a 30-day statement period; average daily balance $1,000; interest earned $5.25; stated APY earned 6.58%.",
      "independent_oracle": {
        "source": "eCFR, 12 CFR part 1030 (Regulation DD), Appendix A, Part II, Example (1)",
        "source_digest": "sha256:a31899e46c5b515c6e5b69bc6ec15ca0a4fb67e4e89ad45c772872cc4dc0a8fc",
        "derivation": "Issuer-stated: average daily balance $1,000, interest earned $5.25, days in period 30. Formula check: 100*((1+5.25/1000)^(365/30)-1) = 6.5779...%, which the text itself reports as 6.58% at two decimals. ADB $1,000 is the text's own arithmetic (1500*15 + 500*15)/30.",
        "expect": {
          "average_daily_balance": 1000,
          "apy_earned_computed_rounded": 6.58,
          "verdict": "MATCHES",
          "within_accuracy_band": true,
          "manual_review_required": false
        }
      },
      "policy_parameters": {
        "interest_earned": 5.25,
        "days_in_period": 30,
        "average_daily_balance": 1000,
        "disclosed_apy_earned": 6.58,
        "accuracy_band_pp": {
          "value": 0.05,
          "effective_from": "2019-07-03",
          "effective_to": null,
          "source": "12 CFR 1030.3(f)(2) accuracy tolerance for the annual percentage yield earned",
          "source_digest": "sha256:a31899e46c5b515c6e5b69bc6ec15ca0a4fb67e4e89ad45c772872cc4dc0a8fc"
        }
      },
      "output_payload": {
        "interest_earned": 5.25,
        "days_in_period": 30,
        "annualization_days": 365,
        "average_daily_balance": 1000,
        "average_daily_balance_supplied_directly": 1000,
        "balance_segments_used": 0,
        "balance_segments_days_sum": null,
        "accuracy_band_pp": 0.05,
        "accuracy_band_provenance": {
          "effective_from": "2019-07-03",
          "effective_to": null,
          "source": "12 CFR 1030.3(f)(2) accuracy tolerance for the annual percentage yield earned",
          "source_digest": "sha256:a31899e46c5b515c6e5b69bc6ec15ca0a4fb67e4e89ad45c772872cc4dc0a8fc"
        },
        "disclosed_apy_earned": 6.58,
        "apy_earned_computed": 6.578105215748975,
        "apy_earned_computed_rounded": 6.58,
        "abs_difference_pp": 0.0018947842510250723,
        "within_accuracy_band": true,
        "verdict": "MATCHES",
        "special_formula_declared": false,
        "manual_review_required": false,
        "warnings": [],
        "notes": []
      },
      "compliance_flags": [
        "APY_EARNED_RECOMPUTE_MATCHES"
      ],
      "golden_hash": "cbff3ccc6cc884fb19bf9daf135fc996a1572756fdba18919063396b306e8aea"
    },
    {
      "name": "ruletext-part-ii-example-2-monthly-avg-daily-balance",
      "note": "Appendix A Part II Example (2): average daily balance method for calendar month; balance $2,000 September 1-15 and $1,000 for the remaining 15 days; average daily balance $1,500; interest earned $6.50; stated APY earned 5.40%.",
      "independent_oracle": {
        "source": "eCFR, 12 CFR part 1030 (Regulation DD), Appendix A, Part II, Example (2)",
        "source_digest": "sha256:a31899e46c5b515c6e5b69bc6ec15ca0a4fb67e4e89ad45c772872cc4dc0a8fc",
        "derivation": "Issuer-stated: average daily balance $1,500, interest earned $6.50, days in period 30. Formula check: 100*((1+6.50/1500)^(365/30)-1) = 5.4015...%, which the text itself reports as 5.40% at two decimals.",
        "expect": {
          "average_daily_balance": 1500,
          "apy_earned_computed_rounded": 5.4,
          "verdict": "MATCHES",
          "within_accuracy_band": true,
          "manual_review_required": false
        }
      },
      "policy_parameters": {
        "interest_earned": 6.5,
        "days_in_period": 30,
        "average_daily_balance": 1500,
        "disclosed_apy_earned": 5.4,
        "accuracy_band_pp": {
          "value": 0.05,
          "effective_from": "2019-07-03",
          "effective_to": null,
          "source": "12 CFR 1030.3(f)(2) accuracy tolerance for the annual percentage yield earned",
          "source_digest": "sha256:a31899e46c5b515c6e5b69bc6ec15ca0a4fb67e4e89ad45c772872cc4dc0a8fc"
        }
      },
      "output_payload": {
        "interest_earned": 6.5,
        "days_in_period": 30,
        "annualization_days": 365,
        "average_daily_balance": 1500,
        "average_daily_balance_supplied_directly": 1500,
        "balance_segments_used": 0,
        "balance_segments_days_sum": null,
        "accuracy_band_pp": 0.05,
        "accuracy_band_provenance": {
          "effective_from": "2019-07-03",
          "effective_to": null,
          "source": "12 CFR 1030.3(f)(2) accuracy tolerance for the annual percentage yield earned",
          "source_digest": "sha256:a31899e46c5b515c6e5b69bc6ec15ca0a4fb67e4e89ad45c772872cc4dc0a8fc"
        },
        "disclosed_apy_earned": 5.4,
        "apy_earned_computed": 5.401672664350765,
        "apy_earned_computed_rounded": 5.4,
        "abs_difference_pp": 0.001672664350764741,
        "within_accuracy_band": true,
        "verdict": "MATCHES",
        "special_formula_declared": false,
        "manual_review_required": false,
        "warnings": [],
        "notes": []
      },
      "compliance_flags": [
        "APY_EARNED_RECOMPUTE_MATCHES"
      ],
      "golden_hash": "7e056591f9ebf50c32e42f61460bd87baf37e9c5e1f0298a375bcb04b8ff66fc"
    },
    {
      "name": "ruletext-part-ii-example-3-quarterly-91-days",
      "note": "Appendix A Part II Example (3): average daily balance for a quarter; balances $1,000/$2,000/$3,000 across September (30d)/October (31d)/November (30d); average daily balance $2,000; interest earned $21 for the quarter; stated APY earned 4.28%.",
      "independent_oracle": {
        "source": "eCFR, 12 CFR part 1030 (Regulation DD), Appendix A, Part II, Example (3)",
        "source_digest": "sha256:a31899e46c5b515c6e5b69bc6ec15ca0a4fb67e4e89ad45c772872cc4dc0a8fc",
        "derivation": "Issuer-stated: average daily balance $2,000, interest earned $21, days in period 91. Formula check: 100*((1+21/2000)^(365/91)-1) = 4.2784...%, which the text itself reports as 4.28% at two decimals.",
        "expect": {
          "average_daily_balance": 2000,
          "apy_earned_computed_rounded": 4.28,
          "verdict": "MATCHES",
          "within_accuracy_band": true,
          "manual_review_required": false
        }
      },
      "policy_parameters": {
        "interest_earned": 21,
        "days_in_period": 91,
        "average_daily_balance": 2000,
        "disclosed_apy_earned": 4.28,
        "accuracy_band_pp": {
          "value": 0.05,
          "effective_from": "2019-07-03",
          "effective_to": null,
          "source": "12 CFR 1030.3(f)(2) accuracy tolerance for the annual percentage yield earned",
          "source_digest": "sha256:a31899e46c5b515c6e5b69bc6ec15ca0a4fb67e4e89ad45c772872cc4dc0a8fc"
        }
      },
      "output_payload": {
        "interest_earned": 21,
        "days_in_period": 91,
        "annualization_days": 365,
        "average_daily_balance": 2000,
        "average_daily_balance_supplied_directly": 2000,
        "balance_segments_used": 0,
        "balance_segments_days_sum": null,
        "accuracy_band_pp": 0.05,
        "accuracy_band_provenance": {
          "effective_from": "2019-07-03",
          "effective_to": null,
          "source": "12 CFR 1030.3(f)(2) accuracy tolerance for the annual percentage yield earned",
          "source_digest": "sha256:a31899e46c5b515c6e5b69bc6ec15ca0a4fb67e4e89ad45c772872cc4dc0a8fc"
        },
        "disclosed_apy_earned": 4.28,
        "apy_earned_computed": 4.278582992752145,
        "apy_earned_computed_rounded": 4.28,
        "abs_difference_pp": 0.0014170072478556506,
        "within_accuracy_band": true,
        "verdict": "MATCHES",
        "special_formula_declared": false,
        "manual_review_required": false,
        "warnings": [],
        "notes": []
      },
      "compliance_flags": [
        "APY_EARNED_RECOMPUTE_MATCHES"
      ],
      "golden_hash": "b59708662f119d325e4208d034530fd5e8f7e1a353e76ea19b1c621b8d9a72f4"
    },
    {
      "name": "ruletext-example-1-balance-spans-derive-adb-1000",
      "note": "The span construction of Example (1) supplied as balance_segments: $1,500 for 15 days and $500 for 15 days. The derived average daily balance must equal the $1,000 the text itself states, and the yield must reproduce 6.58%.",
      "independent_oracle": {
        "source": "eCFR, 12 CFR part 1030 (Regulation DD), Appendix A, Part II, Example (1) balance construction",
        "source_digest": "sha256:a31899e46c5b515c6e5b69bc6ec15ca0a4fb67e4e89ad45c772872cc4dc0a8fc",
        "derivation": "Issuer-stated ADB: (1500*15 + 500*15)/30 = 1000 exactly. Yield as in vector 1: 6.58% at two decimals. The derivation of average daily balance from spans is the text's own worked statement.",
        "expect": {
          "average_daily_balance": 1000,
          "balance_segments_used": 2,
          "balance_segments_days_sum": 30,
          "apy_earned_computed_rounded": 6.58,
          "verdict": "MATCHES",
          "manual_review_required": false
        }
      },
      "policy_parameters": {
        "interest_earned": 5.25,
        "days_in_period": 30,
        "balance_segments": [
          {
            "balance": 1500,
            "days": 15
          },
          {
            "balance": 500,
            "days": 15
          }
        ],
        "disclosed_apy_earned": 6.58,
        "accuracy_band_pp": 0.05
      },
      "output_payload": {
        "interest_earned": 5.25,
        "days_in_period": 30,
        "annualization_days": 365,
        "average_daily_balance": 1000,
        "average_daily_balance_supplied_directly": null,
        "balance_segments_used": 2,
        "balance_segments_days_sum": 30,
        "accuracy_band_pp": 0.05,
        "accuracy_band_provenance": null,
        "disclosed_apy_earned": 6.58,
        "apy_earned_computed": 6.578105215748975,
        "apy_earned_computed_rounded": 6.58,
        "abs_difference_pp": 0.0018947842510250723,
        "within_accuracy_band": true,
        "verdict": "MATCHES",
        "special_formula_declared": false,
        "manual_review_required": false,
        "warnings": [],
        "notes": []
      },
      "compliance_flags": [
        "APY_EARNED_RECOMPUTE_MATCHES"
      ],
      "golden_hash": "918d35cac44a70132db57cf28c2ced936f49f8331166500565ad46bcdc3c38e4"
    },
    {
      "name": "disclosed-outside-band-diverges",
      "note": "Example (1) inputs with a disclosed figure of 7.25%: the recomputed 6.58% differs by ~0.67pp, far outside the 0.05pp band. Hand-computed against the formula text.",
      "independent_oracle": {
        "source": "eCFR, 12 CFR part 1030 (Regulation DD), Appendix A, Part II, Part II.A general formula (second-reading computation)",
        "source_digest": "sha256:a31899e46c5b515c6e5b69bc6ec15ca0a4fb67e4e89ad45c772872cc4dc0a8fc",
        "derivation": "Computed 6.5779...% as in vector 1. |6.5779 - 7.25| = 0.6721pp > 0.05pp band, so the verdict is DIVERGES with within_accuracy_band false.",
        "expect": {
          "verdict": "DIVERGES",
          "within_accuracy_band": false,
          "manual_review_required": false,
          "apy_earned_computed_rounded": 6.58
        }
      },
      "policy_parameters": {
        "interest_earned": 5.25,
        "days_in_period": 30,
        "average_daily_balance": 1000,
        "disclosed_apy_earned": 7.25,
        "accuracy_band_pp": 0.05
      },
      "output_payload": {
        "interest_earned": 5.25,
        "days_in_period": 30,
        "annualization_days": 365,
        "average_daily_balance": 1000,
        "average_daily_balance_supplied_directly": 1000,
        "balance_segments_used": 0,
        "balance_segments_days_sum": null,
        "accuracy_band_pp": 0.05,
        "accuracy_band_provenance": null,
        "disclosed_apy_earned": 7.25,
        "apy_earned_computed": 6.578105215748975,
        "apy_earned_computed_rounded": 6.58,
        "abs_difference_pp": 0.671894784251025,
        "within_accuracy_band": false,
        "verdict": "DIVERGES",
        "special_formula_declared": false,
        "manual_review_required": false,
        "warnings": [],
        "notes": []
      },
      "compliance_flags": [
        "APY_EARNED_RECOMPUTE_DIVERGES"
      ],
      "golden_hash": "f60a98c3788dc23837b70922fe547517a9084e8a75f8cf16fba9301d88796511"
    },
    {
      "name": "no-disclosed-figure-indeterminate",
      "note": "Example (1) inputs with no disclosed figure: the recompute completes but the verdict is INDETERMINATE — there is nothing to diff against.",
      "independent_oracle": {
        "source": "eCFR, 12 CFR part 1030 (Regulation DD), Appendix A, Part II, Part II.A general formula (second-reading computation)",
        "source_digest": "sha256:a31899e46c5b515c6e5b69bc6ec15ca0a4fb67e4e89ad45c772872cc4dc0a8fc",
        "derivation": "With disclosed_apy_earned absent, no diff is defined. The kernel must still compute 6.5779...% (reported 6.58% at two decimals) and return verdict INDETERMINATE with within_accuracy_band null, without refusing the inputs.",
        "expect": {
          "verdict": "INDETERMINATE",
          "within_accuracy_band": null,
          "manual_review_required": false,
          "apy_earned_computed_rounded": 6.58
        }
      },
      "policy_parameters": {
        "interest_earned": 5.25,
        "days_in_period": 30,
        "average_daily_balance": 1000,
        "accuracy_band_pp": 0.05
      },
      "output_payload": {
        "interest_earned": 5.25,
        "days_in_period": 30,
        "annualization_days": 365,
        "average_daily_balance": 1000,
        "average_daily_balance_supplied_directly": 1000,
        "balance_segments_used": 0,
        "balance_segments_days_sum": null,
        "accuracy_band_pp": 0.05,
        "accuracy_band_provenance": null,
        "disclosed_apy_earned": null,
        "apy_earned_computed": 6.578105215748975,
        "apy_earned_computed_rounded": 6.58,
        "abs_difference_pp": null,
        "within_accuracy_band": null,
        "verdict": "INDETERMINATE",
        "special_formula_declared": false,
        "manual_review_required": false,
        "warnings": [
          "DISCLOSED_APY_ABSENT"
        ],
        "notes": [
          "policy_parameters.disclosed_apy_earned is absent or not a finite number. The recompute runs, but with no disclosed figure to diff against the verdict is INDETERMINATE rather than MATCHES or DIVERGES."
        ]
      },
      "compliance_flags": [
        "DISCLOSED_APY_ABSENT",
        "APY_EARNED_RECOMPUTE_INDETERMINATE"
      ],
      "golden_hash": "46a9f59355135885e9393743a32f5059d183ff5a57981a8d3d3e7d7b860e7cf6"
    },
    {
      "name": "inside-band-matches-at-0-04pp",
      "note": "Example (1) inputs with disclosed 6.62%: |6.5779 - 6.62| = 0.0421pp <= 0.05pp band, so MATCHES. Hand-computed against the formula text.",
      "independent_oracle": {
        "source": "eCFR, 12 CFR part 1030 (Regulation DD), Appendix A, Part II, Part II.A general formula; 1030.3(f)(2) accuracy statement",
        "source_digest": "sha256:a31899e46c5b515c6e5b69bc6ec15ca0a4fb67e4e89ad45c772872cc4dc0a8fc",
        "derivation": "Computed 6.5779...% as in vector 1; |6.5779 - 6.62| = 0.0421pp is within the 0.05pp accuracy tolerance, so the disclosed figure is treated as accurate and the verdict is MATCHES.",
        "expect": {
          "verdict": "MATCHES",
          "within_accuracy_band": true,
          "manual_review_required": false
        }
      },
      "policy_parameters": {
        "interest_earned": 5.25,
        "days_in_period": 30,
        "average_daily_balance": 1000,
        "disclosed_apy_earned": 6.62,
        "accuracy_band_pp": 0.05
      },
      "output_payload": {
        "interest_earned": 5.25,
        "days_in_period": 30,
        "annualization_days": 365,
        "average_daily_balance": 1000,
        "average_daily_balance_supplied_directly": 1000,
        "balance_segments_used": 0,
        "balance_segments_days_sum": null,
        "accuracy_band_pp": 0.05,
        "accuracy_band_provenance": null,
        "disclosed_apy_earned": 6.62,
        "apy_earned_computed": 6.578105215748975,
        "apy_earned_computed_rounded": 6.58,
        "abs_difference_pp": 0.04189478425102511,
        "within_accuracy_band": true,
        "verdict": "MATCHES",
        "special_formula_declared": false,
        "manual_review_required": false,
        "warnings": [],
        "notes": []
      },
      "compliance_flags": [
        "APY_EARNED_RECOMPUTE_MATCHES"
      ],
      "golden_hash": "6fc208a33abcf4a3843f5c3d09a14689bbf74c0582ed97924bdf8f113ce81337"
    },
    {
      "name": "zero-interest-zero-yield-matches-zero-disclosed",
      "note": "Interest earned 0.00 over 30 days on balance $1,000: the formula yields exactly 0 (1^k = 1), and a disclosed 0.00% MATCHES.",
      "independent_oracle": {
        "source": "eCFR, 12 CFR part 1030 (Regulation DD), Appendix A, Part II, Part II.A general formula (second-reading computation)",
        "source_digest": "sha256:a31899e46c5b515c6e5b69bc6ec15ca0a4fb67e4e89ad45c772872cc4dc0a8fc",
        "derivation": "100*((1+0/1000)^(365/30)-1) = 0 exactly for any positive days. |0 - 0.00| = 0 <= 0.05pp, verdict MATCHES.",
        "expect": {
          "apy_earned_computed": 0,
          "apy_earned_computed_rounded": 0,
          "verdict": "MATCHES",
          "manual_review_required": false
        }
      },
      "policy_parameters": {
        "interest_earned": 0,
        "days_in_period": 30,
        "average_daily_balance": 1000,
        "disclosed_apy_earned": 0,
        "accuracy_band_pp": 0.05
      },
      "output_payload": {
        "interest_earned": 0,
        "days_in_period": 30,
        "annualization_days": 365,
        "average_daily_balance": 1000,
        "average_daily_balance_supplied_directly": 1000,
        "balance_segments_used": 0,
        "balance_segments_days_sum": null,
        "accuracy_band_pp": 0.05,
        "accuracy_band_provenance": null,
        "disclosed_apy_earned": 0,
        "apy_earned_computed": 0,
        "apy_earned_computed_rounded": 0,
        "abs_difference_pp": 0,
        "within_accuracy_band": true,
        "verdict": "MATCHES",
        "special_formula_declared": false,
        "manual_review_required": false,
        "warnings": [],
        "notes": []
      },
      "compliance_flags": [
        "APY_EARNED_RECOMPUTE_MATCHES"
      ],
      "golden_hash": "93bda9db7393b74817a46eb9db6a629ad357d447eb8932541b7b068db7aaa92a"
    }
  ]
}
