FR register¶
All functional requirements with their satisfying module. FRs are the build contract for each module — testable statements that define exactly what the system must do.
FR-001 to FR-043 are deprecated and no longer in use. Module-specific functional requirements begin at FR-044.
SD01 — Core Banking (bank-core)¶
MOD-001 — Double-entry posting engine¶
| Code | Requirement |
|---|---|
| FR-045 | System shall post every debit and credit as matching double-entry ledger entries in a single atomic Postgres transaction, rejecting any posting where the sum of debits does not equal the sum of credits. |
| FR-046 | System shall reject any posting that would result in a negative available balance on an account not explicitly authorised for overdraft, returning a machine-readable error code to the caller. |
| FR-047 | System shall assign a globally unique, monotonically increasing posting ID (UUIDv7 via Postgres 17 uuidv7()) to every accepted transaction before committing, enabling deterministic replay ordering by ID sort. |
| FR-048 | System shall support idempotent posting by accepting a client-supplied idempotency key and returning the original posting result for any duplicate submission within a 24-hour window. |
| FR-421 | System shall publish a bank.core.posting_completed domain event (per the event catalogue) to the bank-core EventBridge bus after every successful atomic commit, carrying posting ID, account_id, optional counterparty_account_id (present on internal transfers), debit/credit amounts, ISO 4217 currency code, and jurisdiction, delivered within 500 ms of commit. |
| FR-422 | System shall support cancellation postings that reference an original posting ID; the cancellation shall mirror the original legs with reversed signs, enforce exact amount equivalence, and populate reverses_posting_id on the cancellation row (pointing to the original) in the same atomic transaction. Reverse lookup (find the cancellation of a given posting) is provided by idx_postings_reverses_posting_id. The original posting row is immutable — no column is added to it. |
| FR-423 | System shall return a structured error response for every rejected posting, including a machine-readable error_code drawn from a fixed enumeration (UNBALANCED_LEGS, INSUFFICIENT_FUNDS, ACCOUNT_NOT_ACTIVE, DUPLICATE_POSTING, INVALID_CURRENCY, JURISDICTION_MISMATCH), a human-readable message, and the idempotency key if one was supplied. |
| FR-424 | System shall enforce that every posting carries a jurisdiction field matching the destination (credit-leg) account's registered jurisdiction column in accounts.accounts, rejecting with JURISDICTION_MISMATCH any posting where the stated jurisdiction does not match. For two-leg internal transfers, the jurisdiction of the credit-leg account is authoritative. Cross-jurisdiction transfers (NZ account crediting AU account) must use the SD04 international payments path, not this endpoint. |
MOD-002 — Immutable transaction log¶
| Code | Requirement |
|---|---|
| FR-049 | System shall store every committed posting record with an append-only constraint enforced at the database layer, rejecting any UPDATE or DELETE statement issued against the transaction log table. |
| FR-050 | System shall record the originating system, operator identity, timestamp (UTC), and posting amount on every log entry, with no nullable fields permitted on these four columns. |
| FR-051 | System shall expose a paginated read-only query endpoint that returns an ordered log of all postings for a given account, filtered by date range, within the p99 latency budget. |
| FR-052 | System shall detect and alert within 60 seconds if any row-level hash in the transaction log fails integrity verification against its stored checksum. |
| FR-425 | System shall record jurisdiction, source_module, and trace_id as non-nullable columns on every transaction log entry, rejecting inserts that omit any of these three fields. |
| FR-426 | System shall enforce append-only semantics via a Postgres trigger on core.transaction_log that raises an exception on any UPDATE or DELETE statement regardless of the role issuing it, including roles with table ownership. |
| FR-427 | System shall compute and store a SHA-256 hash of each log row's immutable fields at insert time and expose a batch verification endpoint that re-computes hashes for a requested date range, returning a list of any rows where the stored hash does not match the recomputed value. |
| FR-428 | System shall enforce transaction log record retention for a minimum of 7 years from the posting date via a row-level policy that prevents deletion of any record within the retention window by any database role. |
MOD-003 — Real-time balance engine¶
| Code | Requirement |
|---|---|
| FR-053 | System shall maintain a real-time available balance per account, updated synchronously on every accepted posting before returning a success response to the caller. |
| FR-054 | System shall distinguish between ledger balance (posted) and available balance (ledger minus pending holds) and surface both values on every balance query response. |
| FR-055 | System shall respond to a point-in-time balance query for any account within p99 ≤5 ms, reading from the primary replica without requiring a full ledger scan. |
| FR-056 | System shall support balance reconstruction from the immutable transaction log, producing a result that matches the stored balance for any account at any historical timestamp. |
| FR-429 | System shall support balance holds: reserve a specified amount against an account for a pending payment, deducting it from available balance immediately upon hold creation, with automatic hold expiry and balance restoration after a configurable maximum hold duration (default 24 hours). |
| FR-430 | System shall handle concurrent posting events against the same account using optimistic locking (version counter), detecting write conflicts and retrying up to 3 times before returning a CONCURRENT_MODIFICATION error — ensuring no balance update is silently discarded. |
| FR-431 | System shall produce a daily end-of-day balance snapshot for every account, tagged with jurisdiction and snapshot timestamp, retained for 7 years to support regulatory point-in-time balance queries. |
| FR-432 | System shall expose a multi-account balance endpoint that returns ledger and available balances for up to 50 accounts belonging to the same party_id in a single response, within p99 ≤ 20 ms. |
MOD-004 — Multi-currency ledger (NZD/AUD)¶
| Code | Requirement |
|---|---|
| FR-057 | System shall maintain separate ledger accounts for NZD and AUD denominations, preventing any posting that mixes currency in a single ledger entry without an explicit FX conversion record. |
| FR-058 | System shall record the ISO 4217 currency code on every posting and reject postings that reference a currency code not listed in the platform's active currency register. |
| FR-059 | System shall store and display monetary amounts using fixed-point arithmetic to two decimal places for NZD and AUD, with no floating-point representation permitted in the ledger schema. |
| FR-060 | System shall produce a daily multi-currency trial balance report showing debits, credits, and net position for each supported currency, reconciled to zero for balanced accounts. |
| FR-433 | System shall maintain a currency register listing active ISO 4217 codes with activation and deactivation dates, and reject any posting referencing a currency code not currently active in the register. |
| FR-434 | System shall record an FX conversion entry pair for every cross-currency transaction, linking the debit leg (source currency) and credit leg (target currency) via a shared fx_conversion_id, and storing the applied exchange rate and rate timestamp on both legs. |
| FR-435 | System shall compute and post daily FX revaluation entries for any open multi-currency position when a new mid-market rate is received, writing the resulting gain or loss to the FX P&L ledger account with a reference to the source rate event. |
| FR-436 | System shall expose a cross-currency balance endpoint that returns the combined NZD-equivalent value of all currency sub-accounts for a given party_id, applying the most recently recorded mid-market rate for each non-NZD position. |
MOD-005 — Daily accrual calculator¶
| Code | Requirement |
|---|---|
| FR-061 | System shall calculate and post daily interest accrual for every active interest-bearing account by 23:59 local time each calendar day, with no account omitted from the run. |
| FR-062 | System shall apply the accrual rate in effect at the start of each accrual period, sourced from MOD-006 rate records, and reject accrual if no valid rate is found for that period. |
| FR-063 | System shall generate a reconciliation summary after each accrual run, listing total interest posted per product tier and flagging any account where accrual deviated from the expected formula by more than 0.01 cents. |
| FR-064 | System shall support retroactive accrual correction postings when a rate change is applied retrospectively, creating an adjustment entry referencing the original accrual posting ID. |
| FR-514 | System shall recalculate the loan repayment schedule via MOD-112 within 5 minutes of receiving a rate change event from MOD-006, applying the new rate to the outstanding principal from the next scheduled payment date, and delivering the updated schedule to the customer via MOD-063 within 24 hours. |
| FR-515 | System shall compute daily interest on the net balance for offset account relationships — deducting the linked offset account balance from the loan principal before applying the daily rate — reading the offset balance from MOD-003 at the time of each accrual run. |
MOD-006 — Rate change propagation¶
| Code | Requirement |
|---|---|
| FR-065 | System shall propagate an approved interest or fee rate change to all affected account types within 5 minutes of the change being committed to the rate register. |
| FR-066 | System shall maintain a versioned history of every rate change, recording the effective date, previous rate, new rate, and authorising user ID, with no record deletable after commitment. |
| FR-067 | System shall validate that any rate change effective date is not in the past at the time of submission, rejecting backdated rate changes without an explicit retroactive-correction flag and supervisor approval. |
| FR-068 | System shall notify MOD-005 and any downstream accrual consumers via an internal domain event within 30 seconds of a rate record becoming active. |
| FR-516 | System shall enforce a minimum advance notice period (configurable per product type and jurisdiction, minimum 14 days for NZ and AU retail customers) before any interest rate increase on variable rate products takes effect, publishing a rate.change_notified event to MOD-063 at the point the change is committed to the register. |
| FR-517 | System shall distinguish between rate increases (subject to advance notice gate) and rate decreases (effective immediately upon activation), applying the appropriate effective date logic to each. |
MOD-007 — Account state machine¶
| Code | Requirement |
|---|---|
| FR-069 | System shall enforce account state transitions through a defined state machine (Pending → Active → Restricted → Dormant → Closed), rejecting any transition not present in the transition table. |
| FR-070 | System shall record the timestamp, initiating actor (system or user ID), reason code, and previous state on every state transition event in an append-only state history log. |
| FR-071 | System shall block all debit postings to an account in Restricted or Closed state, returning a machine-readable error code indicating the blocking state. |
| FR-072 | System shall emit a bank.core.account_status_changed EventBridge event within 10 seconds of a state transition being committed. |
| FR-437 | System shall enforce a KYC gate on every Pending → Active state transition by reading the party's KYC status from a local accounts.kyc_status_mirror table (populated by EventBridge consumer of bank.kyc.identity_verified), rejecting the transition with error_code: KYC_NOT_VERIFIED if the status is not VERIFIED. |
| FR-438 | System shall transition an account to Restricted state upon receiving a bank.kyc.sanctions_match_found event from MOD-013, blocking all outbound postings immediately and recording the triggering event reference and timestamp in the account state history. |
| FR-439 | System shall enforce that a transition to Closed state requires the account's available balance to be exactly zero, rejecting the request with error_code: BALANCE_NOT_ZERO if any funds remain. |
| FR-440 | System shall support a Restricted → Active reinstatement path requiring a compliance officer action — with staff_id, rationale, and approval timestamp recorded in the state history — before the account resumes normal operations. |
| FR-441 | System shall apply jurisdiction-specific dormancy thresholds when evaluating dormancy eligibility — NZ: 12 months with no customer-initiated transaction (Unclaimed Money Act 1971); AU: 7 years (Banking Act 1959) — sourcing the applicable threshold from the account's jurisdiction column. |
| FR-518 | System shall enforce a MATURING state for term deposit accounts from 30 days before the maturity date through to the maturity date, during which the account accepts credits but blocks new term re-fixes until the maturity instruction is captured or the existing term expires. |
| FR-519 | System shall block withdrawal from a term deposit account in Active state unless a break cost disclosure has been accepted by the account holder within the current session, returning error_code BREAK_COST_ACCEPTANCE_REQUIRED to the caller. |
MOD-008 — Dormancy & escheatment engine¶
| Code | Requirement |
|---|---|
| FR-073 | System shall identify accounts with no customer-initiated transaction for a configurable dormancy threshold (default 12 months) and transition them to Dormant state automatically within the nightly batch window. |
| FR-074 | System shall generate a pre-escheatment notice to the account holder at 90, 30, and 7 days before the statutory escheatment date, delivered via the notification orchestration module. |
| FR-075 | System shall produce a machine-readable escheatment submission file in the format specified by the relevant jurisdiction regulator (RBNZ for NZ, ASIC for AU) and deliver it to the regulatory submission endpoint by the statutory deadline. |
| FR-076 | System shall reverse a dormancy classification within one business day of confirmed customer-initiated activity, restoring the account to Active state and cancelling any pending escheatment submission. |
SD02 — KYC Platform (bank-kyc)¶
MOD-009 — eIDV & document verification¶
| Code | Requirement |
|---|---|
| FR-077 | System shall verify a customer's identity document (passport, driver licence, or national ID) against an authorised biographic data provider within p99 ≤8 seconds of submission. |
| FR-078 | System shall perform liveness detection on selfie captures and reject any submission where liveness confidence score is below the configured threshold (default 0.92). |
| FR-079 | System shall record the verification provider response, match score, document type, expiry date, and outcome on every eIDV attempt in the KYC audit trail store. |
| FR-080 | System shall block account activation for any customer whose eIDV result is Failed or Refer until an operator manually reviews and overrides the result with a documented reason. |
| FR-442 | System shall route document verification requests to the jurisdiction-appropriate service: DIA API for NZ passports and NZTA for NZ driver licences; DVS gateway (Department of Home Affairs) for AU documents — determined by the jurisdiction value in the customer's onboarding context at the time of the request. |
| FR-443 | System shall compute a composite identity confidence score from the weighted combination of document verification result, liveness detection score, and credit bureau name/DOB match, applying the routing thresholds: ≥ 0.90 → VERIFIED (Standard CDD), 0.70–0.89 → VERIFIED (Standard CDD, flagged for periodic review), 0.50–0.69 → PENDING_EDD, < 0.50 → FAILED. |
| FR-444 | System shall publish a kyc.identity_verified or kyc.identity_failed event to the bank-kyc EventBridge bus within 2 seconds of writing a verification outcome, carrying party_id, jurisdiction, kyc_status, and cdd_tier for consumption by MOD-010 and MOD-007. |
| FR-445 | System shall implement a provider fallback policy: retry the primary provider up to 3 times with exponential backoff; fall back to an alternative liveness provider if the primary is unavailable; set outcome to PENDING_EDD (not FAILED) if all retries are exhausted due to provider-side failure — preserving the customer's ability to complete verification once the provider recovers. |
MOD-010 — CDD tier assignment engine¶
| Code | Requirement |
|---|---|
| FR-081 | System shall assign a CDD tier (Standard, Enhanced, or Simplified) to every verified customer based on a configurable risk scoring model evaluated at onboarding completion. |
| FR-082 | System shall re-evaluate CDD tier assignment whenever a customer's risk profile changes (new product, jurisdiction flag, PEP/sanctions match, or manual trigger) and update the tier within 60 seconds. |
| FR-083 | System shall enforce Enhanced Due Diligence controls (source of funds, senior management approval) before activating accounts assigned to the Enhanced tier. |
| FR-084 | System shall log every CDD tier assignment and change event, including the input risk factors, computed score, resulting tier, and timestamp, in the KYC audit trail store. |
| FR-446 | System shall derive CDD tier from a configurable risk scoring model evaluating: document type and jurisdiction, credit bureau match quality, PEP indicator from MOD-013 screening, declared source of funds, and account product type — each factor carrying a configurable weight, summed to a risk score that maps to Standard / Enhanced / Simplified tier thresholds. |
| FR-447 | System shall subscribe to the kyc.identity_verified event from MOD-009, complete CDD tier assignment within 10 seconds of receiving the event, and publish a cdd.tier_assigned event carrying party_id, tier, and effective_date. |
| FR-448 | System shall enforce jurisdiction-specific EDD requirements before activating an Enhanced tier account: for NZ, source of funds declaration and evidence of origin of wealth; for AU, beneficial ownership verification for business accounts — rejecting activation until all jurisdiction-specific EDD items are collected and approved by an authorised officer. |
| FR-449 | System shall support manual tier override by a compliance officer, recording the overriding officer's staff_id, written justification, and a mandatory review date not exceeding 90 days from the override date, after which the system automatically re-evaluates the tier using the standard scoring model. |
MOD-011 — KYC periodic review scheduler¶
| Code | Requirement |
|---|---|
| FR-085 | System shall schedule a KYC periodic review for every customer at an interval determined by their CDD tier (Standard: 24 months, Enhanced: 12 months, Simplified: 36 months). |
| FR-086 | System shall generate a review task in the operations work queue at 60, 30, and 7 days before the review due date, escalating to the compliance team if not actioned by due date. |
| FR-087 | System shall restrict account activity (block new product origination) for any customer whose KYC review is overdue by more than 14 days, until the review is completed. |
| FR-088 | System shall record the completion date, reviewer ID, outcome, and any updated risk factors for every completed periodic review in the KYC audit trail store. |
MOD-012 — KYC audit trail store¶
| Code | Requirement |
|---|---|
| FR-089 | System shall record every KYC action (identity check, document upload, tier assignment, review completion, manual override) as an immutable audit event within 1 second of the action being committed. |
| FR-090 | System shall retain KYC audit records for a minimum of 7 years from the date of the most recent KYC action on the associated customer account, in line with NZ and AU statutory retention periods. |
| FR-091 | System shall allow authorised compliance officers to query the audit trail by customer ID, date range, and event type, returning results within p99 ≤3 seconds for any query spanning up to 12 months. |
| FR-092 | System shall produce a tamper-evidence hash chain across all audit records for each customer, enabling verification that no record has been inserted, modified, or deleted. |
MOD-013 — Real-time sanctions screener¶
| Code | Requirement |
|---|---|
| FR-093 | System shall screen every new customer name and every payment counterparty name against all active sanctions lists (UNSC, OFAC, AU DFAT, NZ MFAT) within p99 ≤500 ms of submission. |
| FR-094 | System shall block transaction processing and flag the customer record for compliance review whenever a screening result returns a confirmed sanctions match, with no bypass path available without operator override. |
| FR-095 | System shall re-screen all active customers within 4 hours of receiving a sanctions list update, prioritising customers with existing Refer results before processing the full population. |
| FR-096 | System shall record every screening attempt with the matched list name, match score, entity name queried, and outcome in the KYC audit trail store. |
| FR-450 | System shall apply transliteration-normalised fuzzy name matching with a configurable similarity threshold (default 0.85), screening against full entity name, all registered aliases, and AKA entries in each list, and returning the match score and matched list entry for every result at or above the alert threshold. |
| FR-451 | System shall screen for both sanctions exposure (UNSC, OFAC, AU DFAT, NZ MFAT) and PEP status (domestic and foreign politically exposed persons) as distinct screening dimensions, returning separate result fields for each, with PEP matches routing to Enhanced CDD rather than immediate account blocking. |
| FR-452 | System shall expose a false positive adjudication API allowing a compliance officer to record a CONFIRMED_FALSE_POSITIVE decision on a REFER result, requiring mandatory rationale and decided_by fields, and publishing a bank.kyc.false_positive_recorded event to unblock the affected party. |
| FR-453 | System shall publish a bank.kyc.sanctions_match_found event to the bank-kyc EventBridge bus within 60 seconds of a confirmed match being adjudicated, carrying screening_id, entity_type, entity_id, list_source, match_score, and match_type for consumption by MOD-007 (account restriction) and MOD-018 (AML case creation). |
MOD-014 — List change propagation¶
| Code | Requirement |
|---|---|
| FR-097 | System shall detect publication of a new or updated sanctions or PEP list within 15 minutes of the list provider making it available and initiate an automated ingestion pipeline. |
| FR-098 | System shall validate the structural integrity and digital signature of every ingested list file before activating it in the screening engine, rejecting any file that fails validation. |
| FR-099 | System shall maintain the previous list version as a rollback target for a minimum of 48 hours after a new list becomes active, enabling reversion without data loss. |
| FR-100 | System shall emit a domain event to MOD-013 within 60 seconds of a new list version being activated, triggering the re-screening of all active customers. |
MOD-015 — False positive management¶
| Code | Requirement |
|---|---|
| FR-101 | System shall present every sanctions screening Refer result to an authorised analyst in a structured review queue, including the matched entity name, list source, match score, and customer context. |
| FR-102 | System shall allow an analyst to mark a Refer result as a confirmed false positive, recording their user ID, decision rationale, and timestamp, and suppressing future alerts for the same name-entity pair. |
| FR-103 | System shall escalate any Refer result not actioned within 24 hours to a senior compliance officer, updating the case status to Escalated in the audit trail. |
| FR-104 | System shall measure and report the false positive rate per list and per screening rule monthly, enabling tuning of match thresholds to reduce analyst workload without increasing miss rate. |
SD03 — AML Monitoring (bank-aml)¶
MOD-016 — Rule-based typology engine¶
| Code | Requirement |
|---|---|
| FR-105 | System shall evaluate every committed transaction against a library of configurable typology rules (structuring, rapid round-trip, high-risk jurisdiction, cash threshold) within p99 ≤1 second of posting. |
| FR-106 | System shall generate an alert case in MOD-018 for every rule breach, including the rule ID, triggered threshold, transaction reference, and customer ID. |
| FR-107 | System shall allow compliance administrators to enable, disable, or modify rule parameters (thresholds, lookback windows) without a code deployment, taking effect within 5 minutes of configuration save. |
| FR-108 | System shall maintain a complete audit log of every rule execution result (pass or alert), retaining records for a minimum of 7 years in line with AML/CFT obligations. |
MOD-017 — ML behavioural scoring model¶
| Code | Requirement |
|---|---|
| FR-109 | System shall generate a behavioural risk score (0–1000) for every customer account on each transaction event, using a trained ML model that incorporates transaction velocity, amount distributions, counterparty diversity, and time-of-day patterns. |
| FR-110 | System shall trigger an alert in MOD-018 when a customer's behavioural score exceeds a configurable threshold (default 750) on any transaction event. |
| FR-111 | System shall record the model version, feature vector hash, and output score for every scoring event, enabling retrospective model performance analysis without reprocessing raw data. |
| FR-112 | System shall support model version rollback to the previous production model within 30 minutes of a new model being identified as underperforming, without interrupting the real-time scoring pipeline. |
MOD-018 — Alert case management system¶
| Code | Requirement |
|---|---|
| FR-113 | System shall create a structured alert case for every input from MOD-016 and MOD-017, de-duplicating alerts from multiple sources against the same customer within the same 24-hour window into a single case. |
| FR-114 | System shall assign each case to an available analyst based on workload balancing rules, escalating to a supervisor if no analyst accepts the case within 4 business hours. |
| FR-115 | System shall record every case action (assignment, note addition, status change, SAR decision) as an immutable event in the case audit trail, with operator ID and timestamp. |
| FR-116 | System shall enforce a mandatory supervisor approval step before a case is closed as No Action Taken when the originating alert score exceeded the SAR consideration threshold. |
MOD-019 — Regulatory report submission module¶
| Code | Requirement |
|---|---|
| FR-117 | System shall compile and submit a Suspicious Activity Report (SAR) to the relevant regulator (AUSTRAC or RBNZ/Police FIU) within 3 business days of the SAR decision being approved in MOD-018. |
| FR-118 | System shall generate a transaction monitoring report in the regulator-mandated XML or structured format, validating the report against the published schema before submission. |
| FR-119 | System shall record the submission timestamp, submission reference number, and report content hash for every regulatory report filed, retaining records for a minimum of 7 years. |
| FR-120 | System shall alert the compliance team within 1 hour if a regulatory submission endpoint returns an error or acknowledgement timeout, providing the error payload for remediation. |
SD04 — Payments (bank-payments)¶
MOD-020 — Pre-payment validation suite¶
| Code | Requirement |
|---|---|
| FR-121 | System shall validate every payment instruction against a configurable rule set (account existence, currency support, BIC/BSB format, daily limit, sanctions status) before passing it to the execution layer, rejecting non-compliant instructions with a machine-readable error code. |
| FR-122 | System shall complete the full pre-payment validation pipeline within p99 ≤200 ms, measured from instruction receipt to validation outcome. |
| FR-123 | System shall log every validation outcome (pass/fail) with the rule(s) applied, result, instruction ID, and timestamp, retaining records for a minimum of 7 years. |
| FR-124 | System shall support dry-run validation mode, returning the validation result without initiating payment execution, for use by the payment initiation UI before submission. |
| FR-520 | System shall validate every direct debit presentation against the mandate registry (MOD-114) before posting — returning return code MANDATE_NOT_FOUND or MANDATE_CANCELLED if no valid active mandate exists for the biller and account combination. |
MOD-021 — Payment limit & velocity controller¶
| Code | Requirement |
|---|---|
| FR-125 | System shall enforce per-transaction, daily, and rolling-30-day payment limits per customer and per channel, rejecting payments that would breach any active limit. |
| FR-126 | System shall allow authorised operators to adjust limit values for individual customers, recording the operator ID, previous limit, new limit, reason code, and timestamp on every change. |
| FR-127 | System shall count all payment attempts (including failed and reversed) toward velocity calculations within the relevant rolling window, not just successful transactions. |
| FR-128 | System shall notify the customer via the notification module when a payment is blocked by a limit control, providing the applicable limit type and current utilisation. |
MOD-022 — Payment audit trail¶
| Code | Requirement |
|---|---|
| FR-129 | System shall record every payment event (initiated, validated, authorised, settled, rejected, reversed) as an immutable audit record within 1 second of the event occurring. |
| FR-130 | System shall retain payment audit records for a minimum of 7 years, with records for cross-border payments retained for a minimum of 10 years per AML/CFT obligations. |
| FR-131 | System shall provide a query interface returning the full event history for any payment instruction by instruction ID, within p99 ≤3 seconds for any instruction with up to 50 events. |
| FR-132 | System shall include the authorising operator or system identity, IP address (for operator-initiated payments), and channel on every audit record. |
MOD-023 — Transaction fraud scorer¶
| Code | Requirement |
|---|---|
| FR-133 | System shall generate a fraud risk score (0–1000) for every payment instruction within p99 ≤200 ms, using a real-time model that incorporates device fingerprint, transaction amount, counterparty history, and velocity signals. |
| FR-134 | System shall block payment execution and route the instruction to the manual review queue when the fraud score exceeds the configured block threshold (default 850). |
| FR-135 | System shall apply step-up authentication (push notification confirmation) for payments with a fraud score between the warn threshold (default 600) and the block threshold. |
| FR-136 | System shall log the model version, score, and contributing feature weights for every scored payment, enabling retrospective investigation of fraud decisions. |
MOD-024 — Device & session intelligence¶
| Code | Requirement |
|---|---|
| FR-137 | System shall collect and store a device fingerprint (device ID, OS version, app version, screen resolution, network type) for every payment session initiated from the mobile or web app. |
| FR-138 | System shall flag and alert the fraud team when a payment is initiated from a device not previously associated with the customer, or from a device associated with a known fraudulent session. |
| FR-139 | System shall detect session anomalies (geolocation mismatch >500 km from prior session within 30 minutes, emulator fingerprint, rooted device) and apply step-up authentication or block the session. |
| FR-140 | System shall record device and session metadata on every payment audit record, linked by session ID, retaining data for a minimum of 7 years. |
MOD-025 — FX rate lock & conversion¶
| Code | Requirement |
|---|---|
| FR-141 | System shall lock the FX rate for a cross-currency payment at the time of customer confirmation and hold that rate for a configurable lock window (default 30 seconds), guaranteeing the locked rate if settlement instruction is submitted within the window. |
| FR-142 | System shall apply the locked rate to the settlement instruction and post the FX conversion entry to the multi-currency ledger as an atomic operation with the payment posting. |
| FR-143 | System shall expire the locked rate after the lock window and notify the customer to re-confirm, recording the expiry event in the payment audit trail. |
| FR-144 | System shall record every FX rate lock, including the rate source, locked rate, lock timestamp, expiry timestamp, and whether the rate was consumed or expired, in an immutable FX lock log. |
MOD-026 — IFTI / CMIR reporting trigger¶
| Code | Requirement |
|---|---|
| FR-145 | System shall identify every cross-border electronic funds transfer that triggers an IFTI reporting obligation (IFTI-E has no minimum threshold — every cross-border electronic transfer is reportable) and every physical cash movement that meets the CMIR threshold (AUD 10,000 equivalent), evaluate each against configurable per-jurisdiction thresholds, and insert a record into payments.ifti_cmir_queue within 1 minute of the triggering transaction being committed. Reporting thresholds are operator-configurable via SSM/AppConfig; production defaults are: IFTI — every cross-border electronic transfer; CMIR — AUD 10,000 equivalent. |
| FR-146 | System shall submit the report to AUSTRAC (Australia) or RBNZ (New Zealand) in the regulator-specified format within the statutory timeframe (IFTI: next business day; CMIR: 10 business days). |
| FR-147 | System shall validate every report against the regulator's published schema before submission and reject invalid reports with a detailed error log, triggering a compliance team alert. |
| FR-148 | System shall record the report reference number, submission timestamp, and acknowledgement receipt for every submitted report, retaining records for a minimum of 7 years. |
MOD-061 — Open Banking API gateway & CDR adapter¶
| Code | Requirement |
|---|---|
| FR-149 | System shall expose Open Banking API endpoints conforming to the NZ API Centre and CDR (AU) standards, returning well-formed responses for all mandatory resource types (accounts, transactions, balances, payees). |
| FR-150 | System shall authenticate third-party providers (TPP) using OAuth 2.0 with PKCE and validate the TPP's accreditation status against the CDR/API Centre register before processing any request. |
| FR-151 | System shall enforce customer consent scope on every TPP data request, returning only the data attributes explicitly consented to, and returning HTTP 403 for out-of-scope attribute access. |
| FR-152 | System shall log every TPP API request with the TPP identifier, consent ID, resource accessed, and response status, retaining records for a minimum of 7 years. |
MOD-067 — Trade finance operations¶
| Code | Requirement |
|---|---|
| FR-153 | System shall create and track trade finance instruments (letters of credit, bank guarantees, documentary collections) with a full lifecycle state machine from issuance to settlement or expiry. |
| FR-154 | System shall validate document presentation against instrument terms (amount, expiry, required documents) before authorising payment, flagging discrepancies for manual review. |
| FR-155 | System shall record every trade finance event (creation, amendment, presentation, payment, expiry) as an immutable audit record with the authorising operator identity and timestamp. |
| FR-156 | System shall generate SWIFT MT700/MT740/MT750 message payloads for all applicable trade finance instructions, validated against SWIFT formatting rules before transmission. |
MOD-081 — Payment reconciliation engine¶
| Code | Requirement |
|---|---|
| FR-157 | System shall reconcile every outbound and inbound payment instruction against the corresponding settlement confirmation from the payment scheme or nostro account within 4 business hours of the settlement timestamp. |
| FR-158 | System shall automatically identify and categorise reconciliation breaks as unmatched, timing difference, or amount discrepancy, and route each category to the appropriate resolution queue. |
| FR-159 | System shall produce a daily reconciliation report for each payment rail (domestic, international, card), showing total matched, total unmatched, and net difference in each currency. |
| FR-160 | System shall escalate any reconciliation break unresolved for more than 2 business days to the finance operations manager, recording the escalation event in the audit trail. |
MOD-082 — Nostro & FX treasury management¶
| Code | Requirement |
|---|---|
| FR-161 | System shall maintain real-time positions for all nostro accounts and FX exposure across all active currency pairs, updating positions within 1 minute of each settlement or FX conversion event. |
| FR-162 | System shall enforce configurable nostro balance thresholds and alert the treasury team when any nostro balance falls below the minimum or exceeds the maximum operational limit. |
| FR-163 | System shall produce an end-of-day FX position report showing open positions, settlement obligations, and unrealised P&L in the base currency, by 18:00 local time. |
| FR-164 | System shall record every manual nostro adjustment with the authorising senior treasury officer identity, reason code, and full before/after position state in an immutable adjustment log. |
MOD-084 — Inbound CDR data retrieval¶
| Code | Requirement |
|---|---|
| FR-165 | System shall retrieve consented customer financial data from accredited CDR data holders via the CDR consumer data standards API, using the customer's active consent token and scope. |
| FR-166 | System shall validate the data holder's CDR accreditation status before initiating any data retrieval and abort the retrieval if accreditation has lapsed. |
| FR-167 | System shall store retrieved CDR data with the consent ID, data holder identifier, retrieval timestamp, and data expiry date, deleting data automatically at expiry if no explicit renewal is in place. |
| FR-168 | System shall surface retrieved CDR account and transaction data to authorised internal consumers (affordability engine, categorisation model) only within the scope of the customer's consent, returning HTTP 403 for out-of-scope access. |
SD05 — Credit (bank-credit)¶
MOD-027 — Affordability calculator¶
| Code | Requirement |
|---|---|
| FR-169 | System shall calculate net monthly disposable income for every credit application by subtracting validated committed expenditure from verified income, using open banking transaction data (CDR) or bank statement analysis where available. |
| FR-170 | System shall apply jurisdiction-specific responsible lending buffers (NZ: CCCFA stress rate; AU: NCCP buffer rate) to calculate the maximum supportable repayment amount for each application. |
| FR-171 | System shall reject any credit application where the calculated debt-to-income ratio exceeds the product policy maximum, returning a decline reason code without operator override capability. |
| FR-172 | System shall record every affordability calculation input, calculated values, applied buffers, and outcome in the credit application audit record, retaining for a minimum of 7 years. |
MOD-028 — Credit score & risk rating¶
| Code | Requirement |
|---|---|
| FR-173 | System shall retrieve a credit bureau report from a configured bureau (Centrix NZ, Equifax AU, or both) for every credit applicant and ingest the structured data within p99 ≤10 seconds of the bureau call being initiated. |
| FR-174 | System shall calculate an internal credit risk rating (1–10 scale) for each applicant by combining bureau score, internal behavioural data, and product risk parameters. |
| FR-175 | System shall store the bureau report reference, raw score, internal rating, and rating model version on the credit application record, enabling retrospective model validation. |
| FR-176 | System shall re-run the credit risk rating on any application where the bureau report is older than 30 days at the time of credit decision, triggering a fresh bureau pull. |
MOD-029 — Pre-approval engine¶
| Code | Requirement |
|---|---|
| FR-177 | System shall generate a pre-approval decision (Approved, Conditionally Approved, or Declined) for eligible customers within p99 ≤10 seconds of a pre-approval request being received. |
| FR-178 | System shall cap the pre-approved limit at the lower of the affordability-calculated maximum and the product policy maximum, without operator override capability. |
| FR-179 | System shall expire pre-approval offers after a configurable validity period (default 30 days) and remove them from the customer's active offers without requiring manual intervention. |
| FR-180 | System shall record every pre-approval run with the input data snapshot, decision, limit offered, validity period, and model version, retaining records for a minimum of 7 years. |
MOD-030 — Stage allocation model¶
| Code | Requirement |
|---|---|
| FR-181 | System shall assign a provisioning stage (Stage 1, 2, or 3 per IFRS 9) to every credit exposure based on the configured staging criteria (days past due, SICR indicators, credit-impaired status) evaluated at least daily. |
| FR-182 | System shall detect significant increases in credit risk (SICR) using a combination of days-past-due triggers and lifetime PD movement thresholds, and migrate exposures from Stage 1 to Stage 2 automatically. |
| FR-183 | System shall record every stage allocation change with the previous stage, new stage, triggering criteria met, and effective date, in an immutable stage history log. |
| FR-184 | System shall prevent manual override of a Stage 3 classification without documented credit committee approval, recording the approver identity and rationale in the audit trail. |
MOD-031 — ECL calculation & GL posting¶
| Code | Requirement |
|---|---|
| FR-185 | System shall calculate Expected Credit Loss (ECL) for every credit exposure daily, applying PD, LGD, and EAD parameters sourced from the approved model, and post the resulting provision movement to the general ledger via MOD-001. |
| FR-186 | System shall generate a portfolio-level ECL report showing collective and individual provisions by product, stage, and jurisdiction, available by 07:00 on the following business day. |
| FR-187 | System shall record the model version, parameter set version, and individual exposure calculation inputs for every ECL run, retaining data for a minimum of 7 years to support regulatory and audit review. |
| FR-188 | System shall flag and alert the finance team when the total provision movement in a single run exceeds a configurable materiality threshold (default ±5% of prior balance), requiring senior finance approval before GL posting. |
MOD-059 — Credit bureau submission engine¶
| Code | Requirement |
|---|---|
| FR-189 | System shall submit credit enquiry and credit account opening notifications to the required credit bureaus (Centrix NZ, Equifax AU) within 1 business day of the triggering credit event. |
| FR-190 | System shall submit monthly account performance data (balance, repayment status, days past due) to each bureau within 5 business days of the reporting month end. |
| FR-191 | System shall validate every bureau submission file against the bureau's published submission schema before transmission and halt submission if validation fails, alerting the credit operations team. |
| FR-192 | System shall record the submission file hash, submission timestamp, bureau acknowledgement, and any rejection reason for every bureau submission, retaining records for 7 years. |
MOD-065 — Credit servicing & collections¶
| Code | Requirement |
|---|---|
| FR-193 | System shall initiate the collections workflow for any credit account that becomes 1 day past due, assigning an initial soft-touch contact strategy and escalating to hardship review at 30 days past due. |
| FR-194 | System shall record all customer contact attempts, outcomes, payment arrangements, and hardship assessments in the collections case record, linked to the credit account, retaining for 7 years. |
| FR-195 | System shall enforce the NZ Credit Contracts and Consumer Finance Act (CCCFA) and AU National Consumer Credit Protection Act (NCCP) hardship obligations, blocking collections escalation until a hardship assessment is completed for eligible accounts. |
| FR-196 | System shall produce a weekly collections portfolio report showing accounts by days-past-due bucket, total exposure, and projected loss by product tier. |
MOD-066 — Collateral & security management¶
| Code | Requirement |
|---|---|
| FR-197 | System shall record every security interest (mortgage, PPSR charge, guarantee) linked to a credit exposure with the security type, registered value, registration reference, and registration expiry date. |
| FR-198 | System shall alert the credit operations team 90, 30, and 7 days before any security registration expiry date, triggering a renewal task in the operations work queue. |
| FR-199 | System shall recalculate the loan-to-value ratio for every secured exposure when collateral values are updated and flag any exposure where the recalculated LTV breaches the product policy maximum. |
| FR-200 | System shall prevent write-off of a secured exposure until the security realisation process is completed or explicitly waived by an authorised credit officer with a documented rationale. |
SD06 — Risk Platform (bank-risk-platform)¶
MOD-032 — LCR / NSFR calculator¶
| Code | Requirement |
|---|---|
| FR-201 | System shall calculate the Liquidity Coverage Ratio (LCR) and Net Stable Funding Ratio (NSFR) for every applicable reporting entity daily, using the HQLA and funding data sourced from the core ledger. |
| FR-202 | System shall complete the LCR/NSFR calculation and make results available in the prudential dashboard within 5 minutes of the end-of-day ledger snapshot being available. |
| FR-203 | System shall alert the treasury and finance teams when the LCR or NSFR breaches the internal management action trigger (MAT) level, within 5 minutes of the breach being detected. |
| FR-204 | System shall record the input data snapshot, calculation methodology version, and results for every LCR/NSFR run, retaining records for a minimum of 7 years. |
MOD-033 — RWA & capital ratio engine¶
| Code | Requirement |
|---|---|
| FR-205 | System shall calculate Risk-Weighted Assets (RWA) and all capital adequacy ratios (CET1, Tier 1, Total Capital) in accordance with the applicable Basel III framework (RBNZ BS2A/BS2B for NZ; APRA APS 110/112/113 for AU) daily. |
| FR-206 | System shall make capital ratio results available within 5 minutes of the daily ledger snapshot, enabling intraday capital monitoring. |
| FR-207 | System shall alert the CFO and CRO when any capital ratio falls below the internal management buffer, distinguishing between the management trigger and the regulatory minimum. |
| FR-208 | System shall produce capital adequacy output in the RBNZ and APRA return formats, ready for ingestion by MOD-036, with no manual reformatting required. |
MOD-034 — Stress testing scenario engine¶
| Code | Requirement |
|---|---|
| FR-209 | System shall execute a library of configurable stress scenarios (macroeconomic shock, liquidity crisis, credit concentration) against the current balance sheet, producing impact estimates for capital, liquidity, and earnings. |
| FR-210 | System shall complete a full stress test run across all active scenarios within 30 minutes of a run being initiated, for a portfolio of up to 500,000 exposures. |
| FR-211 | System shall allow risk officers to define custom scenarios by specifying parameter shocks (interest rate, FX rate, PD multiplier, LGD multiplier) through a structured configuration interface without code changes. |
| FR-212 | System shall retain all scenario definitions, run inputs, and output results for a minimum of 7 years to support regulatory review and internal model validation. |
MOD-035 — IRRBB / EVE / NII model¶
| Code | Requirement |
|---|---|
| FR-213 | System shall calculate Interest Rate Risk in the Banking Book (IRRBB) metrics — Economic Value of Equity (EVE) and Net Interest Income (NII) sensitivity — for each of the six BCBS 239 parallel and twist interest rate shock scenarios daily. |
| FR-214 | System shall apply the RBNZ and APRA IRRBB supervisory shock rates to the current repricing cash flow schedule, producing EVE and NII sensitivity output within 5 minutes of the daily rate curve update. |
| FR-215 | System shall alert the treasury risk team when EVE sensitivity to any scenario exceeds 15% of Tier 1 capital, the BCBS supervisory outlier threshold. |
| FR-216 | System shall produce IRRBB output in the format required by RBNZ and APRA prudential returns, retaining calculation records for a minimum of 7 years. |
MOD-036 — Prudential return builder (RBNZ / APRA)¶
| Code | Requirement |
|---|---|
| FR-217 | System shall compile and submit all RBNZ and APRA prudential returns (capital adequacy, liquidity, lending, statistical) by their respective statutory due dates, with no return submitted past the deadline. |
| FR-218 | System shall validate every return against the regulator-published validation rules before submission, blocking submission of any return that fails validation and alerting the finance team. |
| FR-219 | System shall maintain a submission calendar showing all return codes, due dates, and submission status, updated within 1 hour of any submission or acknowledgement event. |
| FR-220 | System shall record the submission reference, transmission timestamp, regulator acknowledgement, and return content hash for every submitted prudential return, retaining records for 7 years. |
| FR-807 | System shall require a valid REGULATORY.RETURN_APPROVALS record for the current (run_id, return_code) pair before the submission orchestrator may post to a regulator endpoint — see MOD-170 for the approval gate specification. |
MOD-037 — AUSTRAC / RBNZ AML reporting pipeline¶
| Code | Requirement |
|---|---|
| FR-221 | System shall aggregate transaction monitoring data from MOD-016 and MOD-017 and produce AUSTRAC and RBNZ AML compliance reports in the required format within the statutory reporting timeframes. |
| FR-222 | System shall validate every AML report payload against the published regulator schema and halt submission if validation fails, escalating to the compliance team within 1 hour. |
| FR-223 | System shall maintain a complete audit trail of every report produced, submitted, and acknowledged, with report content hashes, retaining records for a minimum of 7 years. |
| FR-224 | System shall support ad-hoc report generation on request from compliance officers without requiring a code deployment, parameterised by date range and reporting entity. |
MOD-038 — Data quality & reconciliation monitor¶
| Code | Requirement |
|---|---|
| FR-225 | System shall run automated data quality checks (completeness, referential integrity, value range, format conformance) across all risk platform input data sets on each batch cycle, producing a quality score per data set. |
| FR-226 | System shall halt any risk calculation run that depends on a data set with a quality score below the configured minimum threshold (default 98%) and alert the data engineering team. |
| FR-227 | System shall reconcile risk platform aggregates against source system ledger totals daily, flagging any discrepancy exceeding 0.01% of the aggregate as a reconciliation break. |
| FR-228 | System shall produce a daily data quality report for the CRO, showing quality scores, reconciliation status, and unresolved breaks by data domain. |
MOD-039 — Customer risk score model¶
| Code | Requirement |
|---|---|
| FR-229 | System shall calculate a composite customer risk score (0–100) for every active customer daily, combining AML risk signals, credit risk grade, sanctions screening status, and behavioural analytics. |
| FR-230 | System shall update a customer's risk score within 60 seconds of any significant risk event (sanctions hit, fraud flag, CDD tier change, large unusual transaction) without waiting for the nightly batch. |
| FR-231 | System shall expose the current risk score and score history via an internal API, available to MOD-010, MOD-016, and MOD-017 with p99 read latency ≤5 ms. |
| FR-232 | System shall record every score change with the previous score, new score, triggering event, and model version in an immutable score history log retained for 7 years. |
MOD-040 — Churn & health score engine¶
| Code | Requirement |
|---|---|
| FR-233 | System shall calculate a churn probability score (0–1) and a customer health score (0–100) for every active customer weekly, using product engagement, balance trends, transaction frequency, and support contact data. |
| FR-234 | System shall flag customers with a churn probability above 0.7 for proactive retention outreach, generating a task in the operations work queue within 24 hours of the score being produced. |
| FR-235 | System shall make scores available to the app insights module and back-office customer 360 view within 60 seconds of the weekly calculation completing. |
| FR-236 | System shall retain score history for every customer for a minimum of 3 years, enabling cohort analysis and model performance validation. |
MOD-041 — Categorisation & merchant enrichment model¶
| Code | Requirement |
|---|---|
| FR-237 | System shall categorise at least 85% of incoming transactions by merchant category (food, transport, utilities, etc.) within 60 seconds of each transaction being posted, using a trained ML categorisation model. |
| FR-238 | System shall enrich transaction records with normalised merchant name, merchant category code (MCC), and logo URL where available, storing enriched data linked to the transaction ID. |
| FR-239 | System shall allow customers to re-categorise any transaction via the app, recording the override as a labelled training signal for model improvement. |
| FR-240 | System shall surface aggregated category spending data to the account dashboard insight feed within 60 seconds of a new transaction being categorised. |
MOD-055 — Onboarding fraud scoring engine¶
| Code | Requirement |
|---|---|
| FR-241 | System shall score every onboarding application for fraud risk within p99 ≤500 ms of eIDV completion, using a model that incorporates device fingerprint, identity document risk, email/phone tenure, and application velocity signals. |
| FR-242 | System shall block account provisioning when the onboarding fraud score exceeds the configured block threshold (default 800) and route the application to the compliance review queue. |
| FR-243 | System shall apply step-up verification (video call or additional document) for onboarding applications with scores between the warn and block thresholds. |
| FR-244 | System shall log every onboarding fraud score with the model version, feature vector hash, score, threshold applied, and decision in an immutable fraud decision log retained for 7 years. |
MOD-056 — Regulatory change register & obligation tracker¶
| Code | Requirement |
|---|---|
| FR-245 | System shall maintain a register of all regulatory obligations applicable to the bank across NZ and AU jurisdictions, each linked to its source regulation, obligation type, owner, due date, and compliance control. |
| FR-246 | System shall ingest regulatory change notifications from subscribed regulator feeds (RBNZ, APRA, FMA, AUSTRAC) and create a new obligation or change record within 1 business day of publication. |
| FR-247 | System shall alert the obligation owner and the CCO when any obligation's due date is within 90 days and no compliance evidence has been recorded against it. |
| FR-248 | System shall generate a traceability matrix on demand showing every obligation, its linked policy, responsible system module, and current compliance status, exportable as structured data. |
MOD-057 — Statistical returns & survey engine¶
| Code | Requirement |
|---|---|
| FR-249 | System shall compile and submit statistical returns and surveys required by RBNZ (e.g., Bank Balance Sheet survey, Interest Rate survey) and ABS (AU) by their published due dates, sourcing data from the core ledger and risk platform. |
| FR-250 | System shall validate every statistical return against the regulator's published validation rules before submission, blocking and alerting on any return that fails validation. |
| FR-251 | System shall maintain a complete submission log for every statistical return, recording the return code, reporting period, submission timestamp, and regulator acknowledgement. |
| FR-252 | System shall support parameterised re-submission for returns where the regulator requests a correction, recording the original and corrected submissions linked by return code and reporting period. |
MOD-058 — Regulatory incident & breach notification engine¶
| Code | Requirement |
|---|---|
| FR-253 | System shall capture regulatory incident and breach notifications from all source systems and create a structured incident record within 1 business hour of the triggering event being reported. |
| FR-254 | System shall determine the statutory notification obligation (RBNZ, APRA, FMA, AUSTRAC) and due date for every incident based on its type and severity, alerting the CCO immediately for incidents with a due date within 24 hours. |
| FR-255 | System shall track the status of every regulatory notification (Draft, Submitted, Acknowledged, Closed) and escalate overdue submissions to the CEO and Board within 2 hours of the statutory deadline being missed. |
| FR-256 | System shall retain all incident records and regulatory correspondence for a minimum of 10 years, with access restricted to authorised compliance and legal personnel. |
MOD-060 — FATCA/CRS/AEOI reporting engine¶
| Code | Requirement |
|---|---|
| FR-257 | System shall identify every reportable account for FATCA (US persons), CRS (OECD participating jurisdictions), and AEOI obligations by evaluating customer tax residency, self-certification, and indicia data. |
| FR-258 | System shall generate FATCA XML reports for the IRS (via IRD/ATO) and CRS XML reports for the relevant competent authority in the OECD common schema format, validated before submission. |
| FR-259 | System shall complete report generation and submission by the statutory due date for each jurisdiction (FATCA: 31 July; CRS: 30 June) with no manual reformatting required. |
| FR-260 | System shall record every reportable account, the report year, submission reference, and the self-certification document reference for each included account, retained for 7 years. |
MOD-080 — Statutory financial reporting & ERP integration¶
| Code | Requirement |
|---|---|
| FR-261 | System shall produce statutory financial statements (balance sheet, income statement, cash flow statement) in IFRS format for every reporting period (monthly management accounts, quarterly, annual statutory), sourcing data from the core ledger. |
| FR-262 | System shall integrate with the bank's ERP system (NetSuite or equivalent) via a structured GL export, transmitting all journal entries within 2 hours of period-end close. |
| FR-263 | System shall reconcile the financial statement output to the core ledger trial balance with zero unexplained variance before the report is released for sign-off. |
| FR-264 | System shall retain all financial report outputs and ERP integration logs for a minimum of 7 years, with immutable storage for auditor access. |
SD07 — Data Platform (bank-platform)¶
MOD-042 — CDC pipeline — Neon logical replication to S3 Iceberg¶
| Code | Requirement |
|---|---|
| FR-265 | System shall replicate every committed change from the Neon Postgres primary database to the S3 Iceberg table store via logical replication, with end-to-end p99 latency ≤5 minutes from commit to availability in the data lake. |
| FR-266 | System shall maintain schema evolution records in the Iceberg table metadata, ensuring backward compatibility for downstream consumers when source schema changes are applied. |
| FR-267 | System shall detect and alert within 5 minutes if the replication lag exceeds 5 minutes or if the logical replication slot falls behind by more than 10,000 WAL records. |
| FR-268 | System shall support replay from any WAL position within the retention window (default 7 days), enabling full reprocessing of the Iceberg tables without data loss in the event of a pipeline failure. |
| FR-454 | System shall configure one Postgres logical replication slot per source database using the pgoutput plugin, and manage slot lifecycle (creation, health monitoring, drop on decommission) without manual operator intervention. |
| FR-455 | System shall write replicated data to Snowflake Iceberg tables partitioned by jurisdiction and event_date, preserving source column names and types, and applying the Snowflake PII_CLASSIFICATION object tag to any column whose source table is tagged PII_HIGH or PII_MEDIUM — triggering Dynamic Data Masking policies automatically in lower environments. |
| FR-456 | System shall publish replication metrics (lag_seconds, wal_records_behind, rows_replicated_per_minute, last_successful_sync_at) to MOD-076 every 60 seconds, and emit a cdc.lag_breach alert event if lag exceeds 5 minutes for any source database. |
| FR-457 | System shall enforce schema compatibility at pipeline startup by comparing the source Postgres schema against the target Snowflake Iceberg schema, and refuse to start replication if any non-nullable source column has no corresponding target column — preventing silent data loss on schema drift. |
MOD-043 — EventBridge domain event governance¶
| Code | Requirement |
|---|---|
| FR-269 | System shall publish every domain event to EventBridge with a schema validated against the domain event registry before delivery, rejecting events that do not conform to the registered schema. |
| FR-270 | System shall maintain a central event schema registry accessible to all consuming services, updated within 1 business day of any schema change being approved. |
| FR-271 | System shall deliver events to all registered subscribers with at-least-once delivery semantics, with dead-letter queue (DLQ) routing for events that fail delivery after 3 retry attempts. |
| FR-272 | System shall log every event publication with the event ID, schema version, source domain, publication timestamp, and delivery status to all subscribers, retaining records for 90 days. |
MOD-044 — JWT role-based access control¶
| Code | Requirement |
|---|---|
| FR-273 | System shall issue JWT access tokens scoped to the requesting service's defined role, rejecting token requests that claim permissions beyond the service's registered role definition. |
| FR-274 | System shall validate the JWT signature, expiry, issuer, and audience on every inbound API request, returning HTTP 401 for expired tokens and HTTP 403 for insufficient role scope. |
| FR-275 | System shall rotate JWT signing keys on a configurable schedule (default 90 days), supporting graceful rollover with a 24-hour dual-key validation window. |
| FR-276 | System shall log every token issuance and validation failure with the requesting service identity, requested scope, and outcome, retaining records for a minimum of 7 years. |
| FR-458 | System shall cache the Cognito JWKS public keys in-memory per Lambda instance for 24 hours, refreshing on cache miss or on receipt of a kid value not present in the cached key set — the JWKS endpoint must not be called on every API request. |
| FR-459 | System shall route JWT validation to the correct Cognito user pool based on the token's iss claim: the bank-customers-{env} pool for customer API requests, the bank-staff-{env} pool for admin API requests — rejecting any token whose iss does not match a known pool URL for the current environment. |
| FR-460 | System shall inject validated JWT claims into the Lambda event context under requestContext.authorizer.claims, including at minimum custom:user_id, custom:party_id, and custom:jurisdiction for customer tokens, and custom:staff_id and cognito:groups for staff tokens. |
| FR-461 | System shall enforce a scope-to-endpoint permission map maintained as configuration (not hardcoded), returning HTTP 403 with error_code: INSUFFICIENT_SCOPE for any request to an endpoint not covered by at least one scope present in the token's scope claim. |
MOD-045 — Secrets & key management¶
| Code | Requirement |
|---|---|
| FR-277 | System shall store all application secrets, API keys, and database credentials in AWS Secrets Manager exclusively, with no secret persisted in application configuration files, environment variables, or any alternative secrets store. |
| FR-278 | System shall enforce automatic secret rotation for all database credentials and API keys on a configurable schedule (default 90 days), with zero-downtime rotation that propagates the new secret to all consuming services before expiring the old one. |
| FR-279 | System shall alert the platform security team within 5 minutes of detecting a secret access from an unregistered service identity or outside of normal access patterns. |
| FR-280 | System shall record every secret access event (read, write, rotate, delete) with the requesting service identity, secret reference (not value), and timestamp in an immutable access log retained for 7 years. |
MOD-046 — Privileged access management (PAM)¶
| Code | Requirement |
|---|---|
| FR-281 | System shall require multi-factor authentication for all privileged access sessions to production systems, blocking access if MFA is not completed within 60 seconds. |
| FR-282 | System shall enforce just-in-time (JIT) access provisioning for all production privileged roles, granting access for a configurable maximum session duration (default 4 hours) and automatically revoking it at expiry. |
| FR-283 | System shall record every privileged access session with the user identity, role assumed, systems accessed, commands executed (via session recording), session start/end timestamps, and approval reference, in an immutable PAM audit log. |
| FR-284 | System shall alert the security team within 5 minutes of any privileged access attempt outside approved maintenance windows or without a linked change ticket reference. |
MOD-047 — Agent action logger¶
| Code | Requirement |
|---|---|
| FR-285 | System shall record every action taken by an AI agent (tool call, data read, data write, decision output) as an immutable log event within 1 second of the action occurring, including the agent ID, action type, input parameters, and output. |
| FR-286 | System shall prevent any agent action log record from being modified or deleted by any system process, enforcing append-only storage at the infrastructure layer. |
| FR-287 | System shall expose a query interface for authorised auditors to retrieve all agent actions for a given session or customer context, returning results within p99 ≤5 seconds for queries spanning up to 30 days. |
| FR-288 | System shall retain agent action logs for a minimum of 7 years, meeting the same retention standards as human operator audit logs. |
| FR-462 | System shall record the following fields on every agent action log entry: trace_id, correlation_id, module_id, jurisdiction, event_type, party_id (where applicable), agent_id or staff_id, action_type, input_summary, output_summary, duration_ms, level, and timestamp — rejecting inserts that omit any required field. |
| FR-463 | System shall propagate trace_id and correlation_id from the inbound request context into every log entry written during that request's handling, enabling end-to-end trace reconstruction across all modules that processed the same originating event. |
| FR-464 | System shall publish a daily summary of agent action counts by agent_id, module_id, and action_type to MOD-076, enabling detection of anomalous activity patterns such as unusually high data read volume by a single agent within a session. |
| FR-465 | System shall enforce that every write-type action log entry (data modification, decision output) carries either a party_id or account_id reference, rejecting write-type entries that have neither field set — preventing unattributable agent modifications. |
MOD-048 — System decision log¶
| Code | Requirement |
|---|---|
| FR-289 | System shall record every automated system decision (credit approval, fraud block, AML alert, KYC tier assignment) as an immutable decision log event, capturing the decision type, input features, model version, output decision, and applicable rule or model ID. |
| FR-290 | System shall retain decision log records for a minimum of 7 years to support regulatory review, customer disputes, and model performance audits. |
| FR-291 | System shall expose a decision explanation endpoint that returns the key features and their contribution to any logged decision by decision ID, within p99 ≤2 seconds. |
| FR-292 | System shall prevent any modification or deletion of committed decision log records, enforcing the append-only constraint at the database layer. |
MOD-062 — Workflow orchestration engine¶
| Code | Requirement |
|---|---|
| FR-293 | System shall orchestrate multi-step business workflows (onboarding, credit origination, dispute resolution) by executing tasks in a configured DAG, retrying failed tasks up to 3 times before routing to the manual exception queue. |
| FR-294 | System shall provide a real-time workflow status API returning current step, elapsed time, next step, and any error details for every active workflow instance, within p99 ≤200 ms. |
| FR-295 | System shall support approval steps within workflows that pause execution until an authorised operator records a decision; the paused state shall be durable across infrastructure restarts; only authorised approvers may advance or reject an approval step; the pause-resume mechanism shall use AWS Step Functions task tokens. |
| FR-296 | System shall record every workflow step transition (start, complete, fail, retry, cancel) with the workflow instance ID, step ID, timestamp, and actor (system or operator) in an immutable workflow event log. |
| FR-740 | System shall support workflow versioning, allowing in-flight workflow instances to complete on the version that was active at instantiation while new instances start on the latest version; a workflow definition shall be immutable once deployed and a new version shall require an explicit version increment. |
MOD-063 — Notification orchestration¶
| Code | Requirement |
|---|---|
| FR-297 | System shall deliver notifications to the customer's preferred channel (push notification, email, SMS) within 60 seconds of a notification trigger event being received from any source system. |
| FR-298 | System shall enforce the customer's active notification preferences (channel, frequency, opt-out) before dispatching any notification, suppressing delivery to opted-out channels. |
| FR-299 | System shall retry failed notification deliveries up to 3 times with exponential backoff, routing to a fallback channel after all retries are exhausted, and logging the failure for operations review. |
| FR-300 | System shall record every notification event (triggered, dispatched, delivered, failed) with the trigger source, channel, template ID, and customer ID, retaining records for 2 years. |
MOD-075 — Internal API gateway¶
| Code | Requirement |
|---|---|
| FR-301 | System shall route every internal API request to the correct backend service based on the request path and service registry, adding JWT propagation headers without modifying the request body. |
| FR-302 | System shall enforce per-service rate limits, rejecting requests that exceed the configured rate with HTTP 429 and recording the breach in the gateway access log. |
| FR-303 | System shall add API gateway overhead of ≤5 ms p99 for request routing and authentication checks, measured end-to-end at the gateway layer. |
| FR-304 | System shall log every request with the source service, target service, HTTP method, path, response status, and latency, retaining logs for 90 days for operational analysis. |
MOD-076 — Observability platform¶
| Code | Requirement |
|---|---|
| FR-305 | System shall collect metrics, logs, and distributed traces from all platform services and make them queryable in the observability platform within 60 seconds of ingestion. |
| FR-306 | System shall trigger automated alerts for any service where error rate exceeds 1% over a 5-minute window, or p99 latency exceeds the defined SLO threshold, notifying the on-call engineer within 2 minutes of threshold breach. |
| FR-307 | System shall retain metrics and log data for a minimum of 90 days and traces for 30 days, with automated archival to cold storage beyond these periods. |
| FR-308 | System shall expose a service health dashboard accessible to all engineering teams, showing real-time SLO adherence, error budgets, and top error contributors for every service. |
MOD-079 — Snowflake decision publication service¶
| Code | Requirement |
|---|---|
| FR-309 | System shall apply every approved decision result received from Snowflake to the relevant operational store within 60 seconds of the result being available on the decision inbox (see ADR-036). |
| FR-310 | System shall validate each decision result received from Snowflake against the ADR-036 data contract before applying it to the operational store, rejecting non-conformant records with a reason logged to the immutable delivery log and DLQ. |
| FR-311 | System shall support idempotent re-delivery of any decision result from Snowflake; re-publishing the same (decision_id, idempotency_key) shall be silently deduplicated without modifying the operational target. |
| FR-312 | System shall record every delivery event with the decision ID, apply target, delivery timestamp, and outcome status in an immutable delivery log retained for 90 days (GOV-006 LOG). |
SD08 — App (bank-app)¶
MOD-049 — Consent capture module¶
| Code | Requirement |
|---|---|
| FR-313 | System shall present consent requests to the customer in plain language, describing the specific data access or processing purpose, the consenting entity, and the withdrawal mechanism, before capturing consent. |
| FR-314 | System shall record every consent grant, amendment, and withdrawal with the customer ID, consent type, scope, channel, timestamp, and IP address or device ID, in an immutable consent audit log. |
| FR-315 | System shall enforce consent expiry, automatically invalidating access to consented data after the consent period ends and notifying the relevant system via a consent-expired event. |
| FR-316 | System shall allow the customer to withdraw any consent at any time through the app settings, propagating the withdrawal to all dependent systems within 60 seconds. |
MOD-050 — Disclosure enforcement module¶
| Code | Requirement |
|---|---|
| FR-317 | System shall present all mandatory regulatory disclosures (key facts sheet, credit disclosure, fees and charges) to the customer before any product application is submitted, blocking submission until acknowledgement is recorded. |
| FR-318 | System shall version all disclosure documents and present the version in effect at the time of disclosure, retaining a copy of the disclosed version linked to the customer interaction record for 7 years. |
| FR-319 | System shall detect and block any product application where the required disclosure has not been acknowledged within the same session, returning a machine-readable error to the calling workflow. |
| FR-320 | System shall record every disclosure event (presented, acknowledged, declined) with the customer ID, disclosure document ID, version, channel, and timestamp in the consent audit store. |
MOD-051 — Financial automation rules engine¶
| Code | Requirement |
|---|---|
| FR-321 | System shall allow customers to create financial automation rules (round-up, auto-save, scheduled transfer, spend category budget alert) through a structured rule builder interface, with rules activated within 60 seconds of creation. |
| FR-322 | System shall evaluate every relevant transaction event against active rules within p99 ≤2 seconds of the transaction being posted, triggering the configured action if conditions are met. |
| FR-323 | System shall record every rule evaluation (condition met/not met) and every rule-triggered action in an immutable automation log, linked to the originating transaction and rule ID. |
| FR-324 | System shall notify the customer via the notification module within 60 seconds of any rule-triggered action being executed, including the rule name, action taken, and resulting balance. |
MOD-052 — Role-scoped data access¶
| Code | Requirement |
|---|---|
| FR-325 | System shall enforce data access restrictions at the API layer so that each operator role (customer-facing, compliance, operations, senior) receives only the data attributes defined in their role specification, with no attribute returned outside the role's scope. |
| FR-326 | System shall evaluate role-scoped access rules on every data query, returning HTTP 403 with a reason code for any out-of-scope attribute request. |
| FR-327 | System shall log every data access request with the requesting user ID, role, data entity accessed, and any denied attributes, retaining records for 7 years. |
| FR-328 | System shall propagate role changes to the access control layer within 60 seconds of the change being committed in the identity management system, without requiring a service restart. |
MOD-053 — Case & complaint management module¶
| Code | Requirement |
|---|---|
| FR-329 | System shall create a structured case record for every customer complaint received via any channel (app, phone, email, chat), assigning a unique case ID and sending an acknowledgement to the customer within 1 business hour of receipt. |
| FR-330 | System shall track case resolution against the statutory timeframes (NZ FSCL: 40 days; AU AFCA: 45 days for most complaints) and escalate to the complaints manager when a case is within 5 days of the deadline with no resolution. |
| FR-331 | System shall record every case action (note, status change, customer contact, resolution) as an immutable event in the case audit trail, with operator ID and timestamp. |
| FR-332 | System shall generate a monthly complaints report for the Board showing case volumes by type, resolution rates, average resolution time, and cases escalated to external schemes. |
MOD-054 — Call recording & transcript attachment¶
| Code | Requirement |
|---|---|
| FR-333 | System shall record all customer service calls and attach the audio recording to the associated case or interaction record within 5 minutes of call completion. |
| FR-334 | System shall generate a structured transcript of each recorded call using an approved speech-to-text service and attach it to the interaction record within 15 minutes of call completion. |
| FR-335 | System shall restrict playback and transcript access to authorised roles (compliance, legal, quality assurance, senior management) enforced at the API layer. |
| FR-336 | System shall retain all call recordings and transcripts for a minimum of 7 years, with automated purge of recordings beyond the retention window only after compliance sign-off. |
MOD-064 — Operations work queue¶
| Code | Requirement |
|---|---|
| FR-337 | System shall maintain a prioritised work queue for all operations tasks (KYC reviews, fraud reviews, complaint actions, collections calls), surfacing tasks to operators based on priority, SLA proximity, and operator skill assignment. |
| FR-338 | System shall alert the operations manager when any task in the queue is within 2 hours of breaching its SLA, including the task type, assigned operator, and current status. |
| FR-339 | System shall record every task assignment, reassignment, action taken, and completion event with the operator ID and timestamp in an immutable task audit log. |
| FR-340 | System shall produce a daily operations throughput report showing task volumes by type, average handle time, SLA breach rate, and open backlog by priority tier. |
MOD-068 — Authentication & session management¶
| Code | Requirement |
|---|---|
| FR-341 | System shall authenticate customers using biometric (Face ID / Touch ID) or passkey as the primary method, falling back to PIN only after a configurable number of biometric failures (default 3), with no password-only path available. |
| FR-342 | System shall enforce session token expiry at 15 minutes of inactivity for sensitive operations (payment initiation, profile changes) and 60 minutes for read-only sessions, requiring re-authentication on expiry. |
| FR-343 | System shall detect and block concurrent active sessions from different device classes (e.g., two simultaneous mobile sessions) and notify the customer of the concurrent session termination. |
| FR-344 | System shall log every authentication event (success, failure, step-up, session expiry) with device ID, authentication method, timestamp, and IP address, retaining records for 7 years. |
| FR-466 | System shall maintain a device registry per customer, recording device fingerprint, platform (iOS / Android / Web), first-seen timestamp, trust level (Trusted / Unrecognised), and last-active timestamp; a new or unrecognised device must complete a full MFA ceremony before receiving Trusted status. |
| FR-467 | System shall store FIDO2/WebAuthn credential records (credential ID, public key, signature counter, AAGUID) bound to user_id in access.device_credentials, and enforce that the signature counter on each authentication assertion is strictly greater than the stored counter — rejecting replayed credential assertions. |
| FR-468 | System shall implement step-up authentication by exposing a /auth/step-up endpoint that downstream modules redirect to for high-risk actions; on successful biometric or passkey re-challenge, issue a step-up assertion token with a 5-minute TTL and a stepup:completed claim that the requesting module validates before executing the action. |
| FR-469 | System shall invalidate all active session tokens for a customer on explicit logout, password change, or on receipt of a fraud.suspicious_activity event from MOD-023, calling Cognito GlobalSignOut to revoke all refresh tokens and writing a session.revoked audit event recording the revocation reason and timestamp. |
MOD-069 — Customer app shell¶
| Code | Requirement |
|---|---|
| FR-345 | System shall deliver the initial app shell to the customer's device with a Time to Interactive (TTI) ≤2 seconds on a median mobile connection (10 Mbps), measured at the p75 percentile of user sessions. |
| FR-346 | System shall deliver the compiled app bundle with a total size ≤500 KB (gzipped), enforced as a CI build gate that fails the pipeline if the budget is exceeded. |
| FR-347 | System shall render all UI components using the approved design system tokens and reject any PR where Storybook visual regression tests detect a UI divergence above the 0.1% pixel difference threshold. |
| FR-348 | System shall support offline read access to the last-fetched account balance, last 20 transactions, and card controls, with a clear UI indicator distinguishing cached from live data. |
MOD-070 — Transaction history & search¶
| Code | Requirement |
|---|---|
| FR-349 | System shall display the full transaction history for any account, returning the first page of 25 transactions within p99 ≤500 ms of the customer navigating to the history view. |
| FR-350 | System shall support full-text search across transaction descriptions, merchant names, and amounts, returning results within p99 ≤1 second for queries spanning up to 12 months of history. |
| FR-351 | System shall display enriched transaction data (merchant name, category icon, enriched description) sourced from MOD-041 alongside the raw transaction record, with a fallback to raw data when enrichment is unavailable. |
| FR-352 | System shall support CSV and PDF export of transaction history for a customer-selected date range, generating and delivering the file within 30 seconds for ranges up to 12 months. |
MOD-071 — Payment initiation¶
| Code | Requirement |
|---|---|
| FR-353 | System shall submit a payment instruction to MOD-020 within p99 ≤500 ms of the customer confirming the payment in the app, and display confirmation or rejection feedback to the customer within p99 ≤5 seconds of confirmation. |
| FR-354 | System shall present a pre-submission summary screen showing recipient, amount, currency, fees, and FX rate (where applicable) and require an explicit customer confirmation tap before submitting the instruction. |
| FR-355 | System shall apply step-up authentication (biometric re-confirmation) for all payments above the customer's configured low-risk threshold (default NZD/AUD 500) and for all first-time payees. |
| FR-356 | System shall record every payment initiation event (customer confirmation, instruction submitted, result received) with the session ID, device fingerprint, and timestamps in the payment audit trail. |
MOD-072 — Customer profile & settings¶
| Code | Requirement |
|---|---|
| FR-357 | System shall allow customers to update their contact details (email, phone, address), notification preferences, and linked external accounts through the app, with changes effective within 60 seconds of submission. |
| FR-358 | System shall require re-authentication (biometric or step-up PIN) before processing any sensitive profile change (email, phone, address, linked account), blocking the change if re-authentication fails. |
| FR-359 | System shall propagate profile changes to all dependent systems (notifications, KYC, statements) within 60 seconds of the change being committed, via a profile-updated domain event. |
| FR-360 | System shall record every profile change with the field modified, previous value hash, new value hash, operator/customer identity, and timestamp in an immutable profile audit log retained for 7 years. |
MOD-073 — Document vault¶
| Code | Requirement |
|---|---|
| FR-361 | System shall store customer-uploaded documents (statements, identification, contracts) with end-to-end encryption at rest and in transit, enforcing a maximum single-file upload size of 25 MB. |
| FR-362 | System shall enforce document access controls so that customers can only retrieve their own documents, and operators can only access documents within their role's permitted document category. |
| FR-363 | System shall generate and return a pre-signed, time-limited (default 5-minute expiry) download URL for every document access request, with no permanent public URL available for any document. |
| FR-364 | System shall record every document upload and access event with the customer ID, document type, operator/customer identity, and timestamp in an immutable vault audit log retained for 7 years. |
MOD-074 — Back-office customer 360¶
| Code | Requirement |
|---|---|
| FR-365 | System shall present an authorised back-office operator with a unified customer 360 view showing identity summary, account balances, transaction history, KYC status, open cases, compliance flags, and risk scores on a single screen, loading within p99 ≤2 seconds. |
| FR-366 | System shall enforce role-scoped data access on every customer 360 data element, displaying only the attributes permitted for the operator's role and masking restricted fields with a clear indicator. |
| FR-367 | System shall record every customer 360 view access event with the operator ID, customer ID, role, and timestamp in an immutable access log retained for 7 years. |
| FR-368 | System shall surface AI-generated customer context summaries on the customer 360 view, clearly labelled as AI-generated and sourced from MOD-083, with a link to the underlying data. |
MOD-077 — Account dashboard & insight feed¶
| Code | Requirement |
|---|---|
| FR-369 | System shall display the customer's account balance, spending summary, and personalised financial insights on the dashboard, refreshing all data within 60 seconds of the customer opening the app. |
| FR-370 | System shall surface categorised spending insights sourced from MOD-041, showing the top 3 spending categories for the current month alongside the prior month comparison, updated within 60 seconds of a new transaction being categorised. |
| FR-371 | System shall personalise the insight feed using the customer health score from MOD-040, prioritising insights most relevant to the customer's financial behaviour, updating the feed within 60 seconds of a health score change. |
| FR-372 | System shall render the dashboard with a TTI ≤2 seconds on a median mobile connection, using optimistic UI patterns to display cached data immediately while fetching live updates. |
MOD-078 — Card & account controls¶
| Code | Requirement |
|---|---|
| FR-373 | System shall allow customers to freeze and unfreeze their debit and credit cards in real time, with the control taking effect within 5 seconds of the customer's confirmation and applying to all subsequent authorisation requests. |
| FR-374 | System shall allow customers to set per-transaction and daily spending limits on their cards, with changes effective within 60 seconds of submission and enforced by the payment validation module. |
| FR-375 | System shall allow customers to enable or disable specific transaction types (online, international, contactless) per card, with changes propagating to the authorisation engine within 60 seconds. |
| FR-376 | System shall record every card control change (freeze, limit update, channel toggle) with the customer ID, card ID, previous setting, new setting, and timestamp in an immutable controls audit log retained for 7 years. |
MOD-083 — Agent assist & compliance coaching panel¶
| Code | Requirement |
|---|---|
| FR-377 | System shall generate a real-time compliance coaching prompt for the agent during a customer interaction whenever a compliance risk keyword or regulated product topic is detected in the interaction transcript, within p99 ≤3 seconds of detection. |
| FR-378 | System shall display suggested next-best-action prompts sourced from the customer 360 profile, surfacing the top 3 contextually relevant actions for the agent on every new customer interaction. |
| FR-379 | System shall log every AI-generated coaching prompt and agent assist suggestion displayed, with the session ID, trigger event, suggestion content hash, and whether the suggestion was acted on, retaining records for 7 years. |
| FR-380 | System shall enforce a human-in-the-loop constraint on all AI-generated suggestions in the compliance coaching panel — no AI-suggested action shall be submitted to a downstream system without explicit agent confirmation. |
MOD-085 — Market rates ingestion & normalisation¶
| Code | Requirement |
|---|---|
| FR-381 | System shall ingest FX spot rates for all supported currency pairs (NZD, AUD, USD, EUR, GBP, SGD, JPY and their cross rates), FX forward curve tenor points (ON, TN, 1W, 1M, 3M, 6M, 1Y), swap/OIS curves (3M to 10Y), and central bank benchmark rates (RBA OCR, RBNZ OCR, BBSW) from one or more Snowflake Marketplace provider shares on a configurable refresh schedule. |
| FR-382 | System shall normalise all Marketplace-sourced market data into a canonical market.* Snowflake schema via Dynamic Tables, ensuring analytical consumers are decoupled from provider-specific field names, decimal precision conventions, and timestamp formats — provider swap requires no consumer code changes. |
| FR-383 | System shall write the latest FX spot mid-rate for each supported currency pair to the SD04 Postgres fx_rates table within 10 minutes of each Marketplace data refresh, and emit a bank-platform.market_rates_updated EventBridge event on each successful upsert. |
| FR-384 | System shall fetch BKBM (NZ Bank Bill Benchmark Rate) from the NZFMA HTTPS endpoint on each New Zealand business day, load the rate into market.benchmark_rates, carry the previous business day's rate forward with a data quality flag when the feed is unavailable, and fire an alert if the carry-forward persists beyond one business day. |
MOD-086 — Funds transfer pricing engine¶
| Code | Requirement |
|---|---|
| FR-385 | System shall compute a daily funds transfer pricing (FTP) rate grid covering tenor buckets ON, 1M, 3M, 6M, 1Y, 2Y, 3Y, 5Y, and 10Y, derived from the prevailing market.swap_curve and market.ois_curve Snowflake tables plus a Treasury-configured liquidity premium overlay, after end-of-day curve publication. |
| FR-386 | System shall write the computed daily TP rate grid to the ftp.transfer_prices Snowflake Dynamic Table and to the SD01 Postgres treasury.tp_rates table via write-back Lambda, completing both writes within 30 minutes of end-of-day curve availability. |
| FR-387 | System shall calculate NIM attribution by product segment and business line daily, allocating the TP cost (loans) or TP benefit (deposits) of each active balance to its originating product code, and publish results to the ftp.nim_attribution Snowflake Dynamic Table for use in management accounts and product P&L reporting. |
| FR-388 | System shall retain a full version history of all TP rate grids with effective date, curve source version identifier, and liquidity premium basis points applied, maintaining at least seven years of history to support product P&L audit and regulatory review. |
MOD-161 — Transfer pricing¶
SD01 co-owner of FR-386 and FR-388. treasury.tp_rates is the Postgres write target provisioned by MOD-161; MOD-086 performs the computation and the write. MOD-161 owns the schema, the row-level retention enforcement, and the bank-core cost-of-funds read service.
| Code | SD01 responsibility |
|---|---|
| FR-386 | Provisions and owns treasury.tp_rates — the SD01 Postgres write target for the daily TP rate grid published by MOD-086's write-back Lambda. Table schema, indexes, and tp_writeback_user GRANT are owned here. |
| FR-388 | Row-level delete prevention on treasury.tp_rates enforces the seven-year TP rate version history in Postgres. The Snowflake-side history is owned by MOD-086. |
MOD-097 — Usage event collector¶
| Code | Requirement |
|---|---|
| FR-389 | System shall emit a structured bank-platform.usage_event EventBridge event on every billable operation across all platform modules, including at minimum: API calls, ML inferences, Snowflake queries, enrichment API calls, notification sends, document storage operations, CDC events, and decision publication writes. |
| FR-390 | System shall tag every usage event with tenant_id, module_id, facility_id, event_type, quantity, resource_unit_type, environment, timestamp, and a correlation_id linking back to the originating request. |
| FR-391 | System shall stream all usage events via Kinesis Data Firehose to S3 and into Snowflake metering.usage_events within 5 minutes of the originating operation, with no event loss tolerance (Kinesis retry + DLQ required). |
| FR-392 | System shall enforce AWS resource tag compliance (tenant_id, module_id, environment) at IaC synthesis time, preventing deployment of any resource missing required billing tags to the production environment. |
MOD-098 — Cost attribution engine¶
| Code | Requirement |
|---|---|
| FR-393 | System shall pull AWS Cost Explorer cost and usage data daily, grouped by tenant_id and module_id tags, and write results to metering.aws_cost_daily in Snowflake within 2 hours of the Cost Explorer data becoming available (24–48h AWS lag). |
| FR-394 | System shall attribute Snowflake compute costs per tenant using dedicated warehouse credit consumption for high-volume tenants, and proportional query-credit attribution from snowflake.account_usage.query_history for tenants on shared warehouses. |
| FR-395 | System shall compute the three-part billing period summary per licensee tenant (customer levy, facility fees, variable consumption by resource type) using the rate card version active at billing period start, and publish results to metering.billing_period_summary, refreshed every 4 hours. |
| FR-396 | System shall maintain metering.unattributed_costs as a Dynamic Table containing all AWS cost records with no tenant_id tag, and fire a bank-platform.unattributed_cost_threshold_exceeded alert if unattributed costs exceed 2% of total daily AWS spend. |
MOD-099 — Infrastructure cost reports¶
| Code | Requirement |
|---|---|
| FR-400 | System shall provide Snowflake views and Dynamic Tables in BANK_{ENV}PLATFORM.REPORTS that surface MOD-098's metering data as a standalone cost-reporting data product: (a) daily AWS costs by service and environment; (b) daily Snowflake credit consumption by warehouse and database; (c) monthly infrastructure cost totals across AWS and Snowflake as a daily-refreshed Dynamic Table; (d) a rolling 90-day cost trend view; (e) a per-tenant attributed cost summary from metering.billing_period_summary and metering.unit_economics — all objects queryable directly from Snowsight or Streamlit without requiring access to the BANK_RISK database. |
MOD-100 — External asset connector¶
| Code | Requirement |
|---|---|
| FR-401 | System shall connect to the Akahu API using OAuth 2.0 and retrieve external asset data (KiwiSaver balance, fund type, provider name, last contribution date) for each consenting customer on a daily schedule during off-peak hours (02:00–04:00 NZST), with retry logic (3 attempts, exponential backoff) and a bank-platform.external_asset_retrieval_failed alert if retrieval fails for a customer on 3 consecutive days. |
| FR-402 | System shall normalise retrieved external asset data with asset_type of KIWISAVER (NZ) or SUPERANNUATION (AU), writing to a module-owned staging table and firing a bank-platform.external_asset_updated EventBridge event within 5 minutes of a successful provider response; the SD01 assets write-back is the responsibility of the bank-core asset-aggregator module subscribing to that event. |
| FR-403 | System shall store the customer's Akahu consent token, scope, and expiry in operating_contexts.akahu_consent, cease asset retrieval immediately upon consent revocation, and delete all cached external asset records belonging to the customer within 24 hours of revocation. |
| FR-404 | System shall implement a provider normalisation layer such that adding a new Akahu-connected KiwiSaver provider or a direct AU superannuation fund API requires only a mapping configuration addition — no changes to the assets schema, write-back Lambda, or downstream consumers. |
MOD-101 — Wealth intelligence engine¶
| Code | Requirement |
|---|---|
| FR-405 | System shall compute a daily net worth snapshot per customer by aggregating SD01 deposit account balances, outstanding loan balances, property equity estimates (properties.estimated_value minus secured loan balances), and external asset balances from the assets table, and publish results to the wealth.net_worth_daily Snowflake Dynamic Table within 2 hours of the daily MOD-100 external asset refresh completing. |
| FR-406 | System shall stratify net worth into four liquidity tiers — instant access (transaction and savings), short-term locked (term deposits and notice accounts), illiquid (property equity), and retirement-locked (KiwiSaver and AU superannuation) — as distinct columns in wealth.net_worth_daily for use in the app net worth dashboard (CAP-142). |
| FR-407 | System shall compute a KiwiSaver member tax credit utilisation indicator per NZ customer with a linked KiwiSaver account: calculate year-to-date observed contributions from transaction credits, compare against the $1,042.86 annual threshold, derive the weekly top-up required to reach the threshold before 30 June, and publish mtc_gap_nzd, mtc_shortfall_per_week, and mtc_full_credit_achievable to wealth.kiwisaver_health daily. |
| FR-408 | System shall infer each NZ customer's applicable PIR band by summing gross salary credits from the trailing 12 months of transaction history, map this to the 10.5% / 17.5% / 28% bands under Income Tax Act 2007 s HL 21, and set pir_mismatch_risk: true in wealth.kiwisaver_health if the inferred band differs from the PIR reported by the KiwiSaver provider via Akahu — surfacing this as an in-app insight only, with no product recommendation. |
MOD-102 — Snowflake account configuration & governance¶
| Code | Requirement |
|---|---|
| FR-409 | System shall provision named Snowflake warehouses for each workload class (ETL_WH, ANALYTICS_WH, RISK_WH, DECISIONS_WH, METERING_WH) with sizes, auto-suspend after 60 seconds, auto-resume, and a resource monitor per warehouse that alerts at 75% of daily credit limit and hard-stops at 100% — preventing uncontrolled cost escalation. |
| FR-410 | System shall provision a custom RBAC role hierarchy with one functional role per system domain (BANK_CORE_ROLE through BANK_APP_ROLE), each granted least-privilege access to its own Snowflake database and schemas only, plus read-only cross-domain roles (BANK_ANALYTICS_ROLE, BANK_REPORTING_ROLE) for approved consumers — no system domain role shall have access to another domain's raw tables without an explicit data governance board approval. |
| FR-411 | System shall configure a Snowflake S3 storage integration for the Iceberg data lake and Firehose landing buckets, a SQS notification integration for Snowpipe auto-ingest, and a network policy restricting Snowflake access to the bank's approved IP ranges — no public unrestricted access permitted. |
| FR-412 | System shall provide a CI/CD schema migration and transformation pipeline using dbt core with Snowflake's native Git integration, applying versioned SQL migrations and dbt model changes in order during each system domain's deployment pipeline, recording every applied migration with timestamp and commit SHA, and requiring a rollback script for every forward migration deployed to production. |
MOD-103 — Neon database platform bootstrap¶
| Code | Requirement |
|---|---|
| FR-413 | System shall provision a single Neon project in AWS region ap-southeast-2 with three persistent branches (prod, uat, dev) and automated ephemeral preview branch creation (zero-copy clone of dev) on pull request open and deletion on pull request close — preview branches must not contain production customer data. |
| FR-414 | System shall provision one Postgres database per system domain (bank_core, bank_kyc, bank_aml, bank_payments, bank_credit, bank_app) within each Neon project, with three roles per database: an application role (read/write on domain schema), a migration role (DDL only, direct connection), and a read-only role (SELECT only) — application role credentials stored in Secrets Manager and rotated every 90 days. |
| FR-415 | System shall configure Neon's PgBouncer connection pooler in transaction pooling mode for each application database, with pool size set to match Lambda concurrency ceiling per domain, and direct non-pooled connection strings reserved exclusively for migration operations and CDC replication source connections. |
| FR-416 | System shall provide a schema migration pipeline (Flyway) integrated into each system domain repository's CI/CD workflow, running migrations before Lambda code deployment, enforcing a migration lock to prevent concurrent runs, and requiring a corresponding undo migration script for every versioned forward migration deployed to the production environment. |
MOD-104 — AWS shared infrastructure bootstrap¶
| Code | Requirement |
|---|---|
| FR-417 | System shall provision one Amazon EventBridge custom event bus per system domain (bank-core, bank-kyc, bank-aml, bank-payments, bank-credit, bank-risk-platform, bank-platform, bank-app), each with a cross-account resource policy, a 30-day event archive rule for replay capability, and a dead-letter SQS queue for undeliverable events. |
| FR-418 | System shall provision named S3 buckets for Iceberg data lake, Firehose landing zone, document store, deployment artefacts, and regulatory report output — each with KMS encryption using the appropriate CMK per data classification, SSL-only access policy, public access blocked, versioning enabled, and lifecycle rules archiving to Glacier and enforcing 7-year retention for customer and financial data. |
| FR-419 | System shall provision three AWS KMS customer-managed keys (bank/pii, bank/financial, bank/operational), each with usage rights granted only to the Lambda execution roles of modules handling that data classification, automatic annual rotation enabled, and key ARNs exported to SSM Parameter Store at /bank/{env}/kms/{alias}/arn for consumption by all downstream IaC modules. |
| FR-420 | System shall provision two Amazon Cognito user pools per environment — one customer pool (bank-customers-{env}) with custom attributes custom:user_id, custom:party_id, and custom:jurisdiction, and one staff pool (bank-staff-{env}) per ADR-026, ADR-027, and ADR-042 — plus Kinesis Data Firehose delivery streams for CDC and usage event ingestion, one IAM Lambda execution role per system domain with least-privilege policies and mandatory module_id tagging conditions, and CloudTrail enabled across all accounts from first deploy with 90-day hot and 7-year cold retention. |
SD06 — Risk Platform: product intelligence modules¶
MOD-105 — Product eligibility engine¶
| Code | Requirement |
|---|---|
| FR-470 | System shall evaluate product eligibility for every active customer against every product in the product register on a nightly batch run, writing results to product_eligibility.eligibility_results with a structured reason code for every INELIGIBLE result, completing the full population run within 2 hours of batch start. |
| FR-471 | System shall expose a real-time eligibility API that, given a party_id and product_id, returns an ELIGIBLE or INELIGIBLE result with reason code within p99 ≤ 100 ms, reading from cached rules and live KYC/credit state — this endpoint is the mandatory pre-condition gate for MOD-108 offer generation and all product application entry points. |
| FR-472 | System shall enforce seven eligibility dimensions at evaluation time: CDD tier minimum, credit risk rating floor, jurisdiction match, existing product holdings (required products, mutual exclusions, per-customer maximum), total credit exposure ceiling, customer tenure minimum, and ROTE hurdle (where MOD-106 data is available) — returning a separate reason code for each failed dimension. |
| FR-473 | System shall log every eligibility evaluation with the input values used for each dimension, the result, the model version, and the evaluation timestamp, retaining records for 7 years to support fair treatment audits and regulatory enquiries. |
MOD-106 — ROTE engine¶
| Code | Requirement |
|---|---|
| FR-474 | System shall compute daily ROTE for every active credit and deposit facility using the formula: (NIM revenue − ECL provision − operating cost allocation) ÷ (exposure × RWA risk weight × CET1 floor), sourcing inputs from MOD-086 (NIM), MOD-031 (ECL), and MOD-033 (RWA), and writing results to rote.facility_rote by 06:00 each business day. |
| FR-475 | System shall compute a daily customer-level ROTE roll-up for every customer with at least one active facility, aggregating facility-level returns and capital allocations to produce a single customer ROTE figure written to rote.customer_rote. |
| FR-476 | System shall flag any facility where the annualised ROTE has been below the product's configured hurdle rate for 90 or more consecutive calendar days, publishing a rote.below_hurdle_breach alert to MOD-076 carrying the product_id, count of affected facilities, and cumulative days below hurdle — triggering product governance board notification. |
| FR-477 | System shall retain full ROTE calculation history (all inputs, intermediate values, and outputs) for every facility for a minimum of 7 years, with model version and parameter version recorded on every row to support retrospective audit of pricing and product governance decisions. |
MOD-107 — Next best product engine¶
| Code | Requirement |
|---|---|
| FR-478 | System shall produce a ranked list of up to 3 next best products per active customer on a weekly Snowflake run, scoped exclusively to the eligible product set from MOD-105, with each ranked product carrying a composite score (0.0–1.0), the primary contributing signal, and the model version. |
| FR-479 | System shall apply a 90-day cooling-off suppression to any product that was presented as an offer (MOD-108) and rejected by the customer — suppressed products must not appear in the NBP ranking for the cooling-off period regardless of their score. |
| FR-480 | System shall write the current week's top 3 NBP per customer to product_intelligence.nbp_current in Postgres within 1 hour of the Snowflake run completing, replacing the previous week's results, for consumption by MOD-083 (agent assist) and MOD-077 (app dashboard). |
| FR-481 | System shall compute a weekly fairness report comparing NBP recommendation rates across jurisdiction, customer segment, and account tenure band; if any product shows a recommendation rate difference greater than 10 percentage points across any demographic grouping, the system shall emit a nbp.fairness_breach alert to MOD-076 carrying the product_id, affected dimension, and disparity magnitude. |
SD08 — App: product commercial modules¶
MOD-108 — Product offer engine¶
| Code | Requirement |
|---|---|
| FR-482 | System shall generate personalised product offers only for products that MOD-105 has returned ELIGIBLE for the customer within the past 24 hours — the eligibility check must be re-run at offer generation time if the last result is older than 24 hours, blocking offer creation if the re-check returns INELIGIBLE. |
| FR-483 | System shall derive offer terms (interest rate, credit limit, fee structure, promotional bonus) within the floor and ceiling configured in the product rate card, applying behavioural personalisation only when a valid consent record for data-driven marketing exists in MOD-049 — generating a standard rate-card offer when consent is absent. |
| FR-484 | System shall enforce a financial advice licensing gate before generating an offer for any product flagged requires_advice_review = true in the product register, suppressing the offer and raising an offer.advice_review_required event if no authorised adviser review exists for the customer within the past 12 months. |
| FR-485 | System shall record every offer lifecycle event (GENERATED, PRESENTED, ACCEPTED, REJECTED, EXPIRED, SUPPRESSED) as an immutable append to app.offer_events with the actor, timestamp, and relevant detail, and shall retain all offer records for a minimum of 7 years to satisfy CON-006 audit trail requirements. |
MOD-109 — Product deal engine¶
| Code | Requirement |
|---|---|
| FR-486 | System shall verify product eligibility via MOD-105 at deal creation time and reject the deal proposal with a structured error if the customer is not eligible for the product — no deal may be proposed for a product the customer cannot obtain. |
| FR-487 | System shall evaluate proposed deal terms against the three-tier authorisation matrix at deal creation time: terms within Tier 1 tolerance are self-approved immediately; terms within Tier 2 tolerance are routed to the team manager approval queue; terms exceeding Tier 2 tolerance are routed to the product/pricing committee — the routing logic is driven by configurable tolerance band values in deal_authorisation_config. |
| FR-488 | System shall enforce that no deal is presented to a customer until it has reached APPROVED status — a deal in PROPOSED or PENDING_APPROVAL state must not be visible to the customer in any channel, and any attempt to present an unapproved deal must return an error. |
| FR-489 | System shall log every deal event (PROPOSED, PENDING_APPROVAL, APPROVED, DECLINED, PRESENTED, ACCEPTED, REJECTED, EXPIRED) as an immutable append to app.deal_events with the actor ID (agent or system), timestamp, and detail, and shall retain all deal records for a minimum of 7 years — the audit trail must support reconstruction of: who proposed what terms, who approved or declined, and what the customer's response was. |
MOD-110 — Fee engine¶
| Code | Requirement |
|---|---|
| FR-490 | System shall evaluate fee waiver conditions for every fee assessment before posting — checking minimum average daily balance, minimum transaction count, linked product holdings, introductory period, and promotional waiver codes against the tenant-configured fee schedule — and record the waiver reason on the fee event when a waiver applies. |
| FR-491 | System shall enforce an advance notice gate that prevents posting of any fee under a new or increased fee schedule until the configured notice period has elapsed since the change notification was published (minimum 14 days for NZ and AU retail customers per CON-005), while applying fee reductions immediately upon the new schedule's effective date. |
| FR-492 | System shall post every assessed fee as a double-entry ledger entry via MOD-001 — debit customer account, credit fee income GL account — in a single atomic transaction, recording the fee_type, schedule_version, and assessed_amount on the posting metadata. |
| FR-493 | System shall support fee reversal by an authorised agent, posting a compensating double-entry via MOD-001, recording the reversing staff_id and reason in the fee event log, and applying the same approval tier rules as MOD-109 deal authorisation for reversals above configured thresholds. |
MOD-111 — Term deposit maturity engine¶
| Code | Requirement |
|---|---|
| FR-494 | System shall send pre-maturity notifications to the customer via MOD-063 at exactly 30, 14, and 7 calendar days before the maturity date, including current balance, projected maturity proceeds (principal plus accrued interest at the current rate), and prevailing rollover rates for the same term — with no notification missed regardless of the number of maturing accounts on a given day. |
| FR-495 | System shall capture and store the customer's maturity instruction (rollover same term, rollover different term, withdraw all, partial rollover) against the account, applying the account's default instruction (auto-rollover to same term at prevailing rate) if no instruction is received by close of business two business days before maturity. |
| FR-496 | System shall calculate early withdrawal break cost using the formula: (contract_rate − current_reinvestment_rate) × outstanding_balance × (days_remaining / 365), flooring at zero (no negative break cost), and enforce that break cost disclosure is accepted by the customer before any funds are released from a term deposit prior to maturity. |
| FR-497 | System shall execute maturity proceeds disbursement atomically on the maturity date — posting accrued interest credit, executing rollover or withdrawal per the standing instruction, and updating the account state via MOD-007 — with the full sequence idempotent so that a replay produces no duplicate postings. |
MOD-112 — Amortisation schedule engine¶
| Code | Requirement |
|---|---|
| FR-498 | System shall generate a full amortisation schedule at loan origination using the declining balance method, producing payment date, total payment amount, principal component, interest component, and closing balance for every instalment in the loan term, and deliver the schedule to the customer via MOD-063 and MOD-113 within 60 seconds of loan settlement. |
| FR-499 | System shall recalculate the amortisation schedule within 5 minutes of any schedule-changing event — variable rate change, extra repayment above the scheduled instalment, interest-only period expiry, or hardship restructure — storing the new schedule as a new version and retaining all prior versions for audit, and delivering the updated schedule to the customer within 24 hours. |
| FR-500 | System shall offer two recalculation options to the customer when an extra repayment is received: (a) reduce the remaining term with the same instalment amount, or (b) reduce the instalment amount with the same remaining term — storing the customer's selection and applying it to the recalculated schedule. |
| FR-501 | System shall calculate the minimum monthly repayment for revolving credit facilities as max(configured_floor_amount, outstanding_balance × configured_percentage), auto-post the minimum repayment on the due date if no payment has been received, and assess a late payment fee via MOD-110 if a payment has been received but falls below the minimum. |
MOD-113 — Statement generation¶
| Code | Requirement |
|---|---|
| FR-502 | System shall generate a statement for every active account at the close of each statement period (monthly for transactional, savings, and credit accounts; at maturity for term deposits) containing: opening balance, all transactions with merchant name and timestamp, closing balance, interest earned or charged for the period with rate basis, and all fees with itemisation. |
| FR-503 | System shall deliver every generated statement to the customer's in-app document vault (MOD-073) and send a push notification via MOD-063 on the day after statement period close, retaining all statements for 7 years in S3 regardless of account closure. |
| FR-504 | System shall produce statements in both on-screen format (rendered in the app) and downloadable PDF format, with the PDF meeting WCAG 2.1 AA accessibility standards and containing all regulatory required disclosures for the product type and jurisdiction. |
| FR-505 | System shall support supplementary statement generation for any period where a post-statement correction occurs (fee reversal, interest adjustment), issuing the supplementary statement to the customer and retaining both the original and supplementary statement — not replacing the original. |
MOD-114 — Direct debit mandate management¶
| Code | Requirement |
|---|---|
| FR-506 | System shall maintain a mandate registry per account, storing biller ID, biller name, scheme reference, customer-set maximum debit amount (if configured), frequency, status, and full creation-to-cancellation event history — and validate each incoming direct debit presentation against this registry before authorising the debit. |
| FR-507 | System shall process a customer-initiated mandate cancellation within 60 seconds of the request being confirmed, updating the mandate status to CANCELLED and returning any subsequent debit presentation from that biller with the appropriate scheme return code (MANDATE_CANCELLED) regardless of the debit's processing time in the external rail. |
| FR-508 | System shall process a direct debit dishonour — when a debit cannot be posted due to insufficient funds or account restriction — by returning the debit with the correct scheme return code, assessing a dishonour fee via MOD-110 if configured in the tenant fee schedule, and notifying the customer via MOD-063 with the biller name and reason within 60 seconds of the return decision. |
| FR-509 | System shall support a customer dispute workflow for unauthorised direct debits, creating a case in MOD-053 within 60 seconds of dispute submission, placing a query hold that suspends further debits from the same biller pending investigation, and resolving the dispute within the jurisdiction's maximum dispute resolution period (NZ: 12 months; AU: 12 months from debit date). |
MOD-115 — Property security and LVR management¶
| Code | Requirement |
|---|---|
| FR-521 | System shall register a property security instrument against a loan at settlement, recording title reference, property address, property type, and registration number, and shall not allow a mortgage loan to advance to settled status until a security record with status active is present and the initial LVR calculation confirms the loan falls within the approved LVR band for the product. |
| FR-522 | System shall calculate current LVR for every secured loan daily using the formula lvr = outstanding_balance / current_valuation, store the result in credit.lvr_snapshots with an LVR band classification, and make the result available to the capital ratio engine (MOD-033) and the prudential return builder (MOD-036) within 60 minutes of the daily calculation run completing. |
| FR-523 | System shall emit a bank.credit.lvr_breach_detected event and trigger a back-office alert via MOD-063 within 5 minutes of detecting that a loan's current LVR exceeds the configured breach threshold, including the loan ID, current LVR percentage, and breach threshold in the event payload. |
| FR-524 | System shall process a security discharge — setting the security record status to discharged, recording the discharge date, and emitting a bank.credit.security_discharged event — atomically with the final loan repayment posting in MOD-001, such that no partially-discharged state can persist. |
MOD-116 — Mortgage servicing engine¶
| Code | Requirement |
|---|---|
| FR-525 | System shall manage the fixed rate period state machine for residential mortgages, transitioning from FIXED to EXPIRING exactly 90 days before the fixed period end date, dispatching notifications via MOD-063 at 90, 60, and 30 days before expiry, and automatically reverting to the variable rate on the expiry date if no rate election has been recorded by the customer — with no manual intervention required for any transition. |
| FR-526 | System shall calculate a break cost for early repayment of any fixed rate loan using the formula max(0, (contract_rate − reinvestment_rate) × outstanding_balance × remaining_fixed_days / 365), source the reinvestment_rate from MOD-085 (wholesale swap rate for the remaining term), disclose the calculated break cost to the customer via MOD-050 before processing the repayment, and block repayment processing until the disclosure is acknowledged. |
| FR-527 | System shall process a mortgage discharge request — calculating any break cost (if fixed rate), confirming no arrears with MOD-065, posting the final repayment and releasing the security via MOD-115, and issuing a discharge notice via MOD-073 — completing all steps within 5 business days of the final payment being received. |
| FR-528 | System shall detect a missed scheduled mortgage repayment by end of the payment due date, emit a bank.credit.repayment_missed event, dispatch a Day 1 notification to the customer via MOD-063, set a hardship flag on the account via MOD-007 at Day 7, and escalate to the MOD-065 collections workflow at Day 30 — with all transitions logged to credit.mortgage_notifications. |
MOD-117 — Overdraft management engine¶
| Code | Requirement |
|---|---|
| FR-529 | System shall maintain an approved overdraft limit per transaction account, include the overdraft headroom in the available balance returned by MOD-003 whenever the facility status is active, and ensure that the payment validation module (MOD-020) uses the combined available balance — not just the ledger credit balance — when deciding whether to approve or decline a payment. |
| FR-530 | System shall calculate daily interest on any negative account balance using the formula daily_interest = abs(negative_balance) × (annual_rate / 365), insert the result into credit.overdraft_daily_accruals marked posted = false, and post the cumulative monthly accrual as a single debit entry via MOD-001 on the last calendar day of each month, setting all accruals for the period to posted = true in the same database transaction. |
| FR-531 | System shall assess a monthly facility fee to the account on the last calendar day of each month if any day during the month had a negative ledger balance, post the fee via MOD-001, and record a fee waiver event in MOD-110 if the account remained in credit throughout the month — with the waiver reason overdraft_not_used. |
| FR-532 | System shall detect when a customer has maintained a negative balance on an overdraft facility for more than 60 consecutive days, emit a bank.credit.overdraft_hardship_flag event, set the hardship flag on the account via MOD-007, and dispatch alerts to both the customer and the back-office team via MOD-063 — no later than 24 hours after the 60-day threshold is crossed. |
MOD-118 — Member equity and share registry¶
| Code | Requirement |
|---|---|
| FR-533 | System shall maintain a member register with a unique membership number per member, record all share transactions (purchase, redemption, transfer, dividend reinvestment) in core.share_transactions with an immutable event log, and post every share capital movement as a ledger entry to an equity account — not a deposit liability account — via MOD-001. |
| FR-534 | System shall enforce a capital gate on share redemption requests: before processing any redemption, call MOD-033 to retrieve the current CET1 ratio, and if the post-redemption CET1 ratio would fall below the configured minimum, set the transaction status to blocked with reason capital_gate and notify the member that their redemption is queued pending capital headroom restoration. |
| FR-535 | System shall execute the full dividend distribution workflow on the declared payment date: calculate each member's gross dividend as shares_at_record_date × rate_per_share, calculate tax withheld at the applicable rate, post the net dividend as a credit to each member's nominated account via MOD-001, and generate a tax certificate for each member via MOD-113 — completing all payments within 1 business day of the declared payment date. |
| FR-536 | System shall generate an annual member statement for each active member via MOD-113 showing: opening shareholding, all share transactions during the year, dividends declared and paid with dates, voting participation record, and closing shareholding — and deliver it to the member's document vault (MOD-073) and nominated email address within 5 business days of the institution's financial year end. |
MOD-119 — BPAY payment integration¶
| Code | Requirement |
|---|---|
| FR-537 | System shall resolve a biller code to biller name and CRN format from the bpay_biller_cache within 500 milliseconds of the customer entering the biller code in the payment flow, refresh the cache daily from the sponsor bank's BPAY biller directory API, and fall back to a real-time sponsor bank lookup with a 5-second timeout if the biller code is absent from the cache. |
| FR-538 | System shall validate the customer reference number (CRN) against the biller's declared CRN format (Luhn check or regex) before allowing the payment to proceed, display an inline validation error if the CRN format is invalid, and block submission until a valid CRN is entered. |
| FR-539 | System shall submit a validated BPAY payment to the sponsor bank before the configured daily cut-off time (default 17:00 AEST, tenant-configurable), post the account debit via MOD-001 at submission time, record the sponsor reference, and update the payment status to settled upon receiving settlement confirmation from the sponsor bank — with MOD-081 reconciling the settlement batch. |
| FR-540 | System shall process a BPAY return — when a payment is returned by the biller or the scheme — by crediting the account via MOD-001, setting payment status to returned, dispatching a customer notification via MOD-063 with the return reason in plain language within 60 seconds of receiving the return instruction, and making the return reason visible on the transaction detail screen. |
MOD-120 — PayID and Osko integration¶
| Code | Requirement |
|---|---|
| FR-541 | System shall register a customer's mobile number and/or email address as a PayID with the NPP directory via the sponsor bank within 60 seconds of the customer confirming registration, allow the customer to manage (add, change display name, suspend, deregister) their PayID from the customer profile settings (MOD-072), and deregister a PayID within 2 minutes of a deregistration request per NPP Rule 4.7. |
| FR-542 | System shall resolve a PayID to an account holder display name via the NPP directory within 2 seconds, display the resolved name to the paying customer before any amount is entered, require the customer to explicitly confirm the displayed name before the payment can proceed (name confirmation is mandatory and cannot be bypassed), and record name_confirmed = true and name_confirmed_at on the payment record before committing funds. |
| FR-543 | System shall post an inbound Osko credit to the destination account via MOD-001 within 5 seconds of receiving the credit notification from the sponsor bank, and dispatch a push notification to the receiving customer via MOD-063 within 5 seconds of the credit posting — with the sender's display name and amount included in the notification. |
| FR-544 | System shall process an Osko payment return — when a payment cannot be delivered (account closed, PayID deregistered) — by crediting the originating account via MOD-001, setting payment status to returned, dispatching a customer notification via MOD-063 with the return reason mapped to a plain-language description, and providing the customer with a direct path to the in-app dispute flow (MOD-053) from the transaction detail screen. |
MOD-121 — Construction loan drawdown engine¶
| Code | Requirement |
|---|---|
| FR-545 | System shall prevent drawdown disbursement unless the corresponding tranche has status certified — no drawdown may be posted without a completed milestone certification; the gate must be enforced at the data layer, not only in application code. |
| FR-546 | System shall post each approved drawdown as a ledger debit via MOD-001 and update total_drawn in the same atomic transaction — no partial state where the debit is posted but total_drawn is not updated, or vice versa, may persist. |
| FR-547 | System shall supply total_drawn (not total_facility) to MOD-005 as the accrual base after each drawdown, refreshing the value within 60 seconds of the drawdown posting, so that daily interest accrues only on funds actually drawn and not on the undrawn commitment. |
| FR-548 | System shall trigger MOD-112 to generate a full P&I amortisation schedule when all tranches reach status drawn or when construction_end_date is reached, whichever is first, using conversion_date as the schedule start date and delivering the schedule to the customer via MOD-063 within 24 hours. |
MOD-130 — Notice account management¶
| Code | Requirement |
|---|---|
| FR-549 | System shall enforce the notice period as a technical gate on withdrawals: any withdrawal attempt against an account with an active lodgement where withdrawal_date > today must be rejected; the rejection response must include the upcoming withdrawal date and the pending lodgement reference; no staff override path may bypass this gate without explicit early withdrawal acknowledgement. |
| FR-550 | System shall calculate early withdrawal penalty as notice_period_days × (annual_rate / 365) × amount, display the exact penalty amount to the customer via MOD-050 before any withdrawal action is taken, and block processing until the customer has explicitly acknowledged the penalty — the acknowledgement reference must be recorded on the withdrawal record. |
| FR-551 | System shall run a daily scheduled job that identifies all notice lodgements where withdrawal_date = today and status = pending, posts the withdrawal via MOD-001, transitions the account state via MOD-007, and dispatches a "funds available" notification via MOD-063 — completing all releases without manual intervention for any customer. |
| FR-552 | System shall provide MOD-032 with a daily snapshot of all notice account balances bucketed by withdrawal date (within 30 days, 31–60 days, 61–90 days), so that notice deposits are correctly classified as non-at-call funding in the LCR/NSFR stable funding ratio calculation. |
MOD-122 — NZ faster payments and A2A integration¶
| Code | Requirement |
|---|---|
| FR-553 | System shall validate the format and Payments NZ checksum of outbound NZ interbank account numbers before submission to the clearing network, rejecting invalid account numbers with a descriptive error message that identifies the failing validation step. |
| FR-554 | System shall submit validated outbound NZ interbank payments to the clearing network via the sponsor bank API, post the account debit via MOD-001 at submission time, record the clearing reference, and settle payments submitted before the daily cut-off time on the same business day and payments submitted after cut-off on the next business day. |
| FR-555 | System shall post inbound NZ interbank credits to the destination account via MOD-001 and dispatch a customer notification via MOD-063 within 60 minutes of receipt during business hours, meeting the Payments NZ obligation for prompt crediting of received funds. |
| FR-556 | System shall process returned outbound NZ interbank payments by crediting the originating account via MOD-001, setting payment status to returned, and dispatching a customer notification via MOD-063 with the return reason expressed in plain language within 60 minutes of receiving the return instruction. |
MOD-123 — ATM network integration¶
| Code | Requirement |
|---|---|
| FR-557 | System shall respond to inbound ATM authorisation requests within 800 milliseconds, performing the following checks in sequence before returning a response: available balance via MOD-003, ATM toggle status via MOD-078, daily ATM limit via MOD-021, and fraud score via MOD-023 — a failure on any check must produce a declined response with the decline reason code. |
| FR-558 | System shall post a pre-authorisation hold via MOD-001 for every approved ATM withdrawal at the time of authorisation, reducing the customer's available balance immediately, and must finalise the hold on settlement confirmation or reverse it on a dispense-failure reversal message — no pre-auth hold may remain unresolved for more than 5 business days. |
| FR-559 | System shall process an ATM reversal message — received when a terminal confirms no cash was dispensed — by releasing the pre-authorisation hold via MOD-001 within 60 seconds of the reversal message being received, and notifying the customer via MOD-063 when the reversal was not initiated by the customer. |
| FR-560 | System shall reconcile ATM transaction records against the sponsor bank's daily ATM settlement file via MOD-081, identifying and flagging any discrepancy to the operations queue within 2 hours of the settlement file being received. |
MOD-124 — Physical card issuance and bureau integration¶
| Code | Requirement |
|---|---|
| FR-561 | System shall generate card personalisation data using the platform HSM for PAN generation per card scheme specifications, submit the personalisation file to the bureau API, record the bureau order_reference and estimated dispatch date, and notify the customer via MOD-063 within 60 seconds of order confirmation. |
| FR-562 | System shall activate a physical card on customer confirmation via the app by calling the bureau to activate the PAN in the card network, updating card status to active, simultaneously submitting a tokenisation request to the card scheme to enrol the card in Apple Pay and Google Pay, and confirming activation to the customer via MOD-063 — all within 30 seconds. |
| FR-563 | System shall process all PIN set and PIN change operations via the platform HSM such that the PIN is never in plaintext at any point in the processing chain — the PIN block must be encrypted on-device before transmission, and translated to a network PIN block at the HSM before submission to the card scheme; any PIN processing path that does not use the HSM must be technically blocked. |
| FR-564 | System shall initiate an automatic replacement card order within 60 seconds of a lost-or-stolen report, simultaneously cancelling the reported card at the network via the sponsor bank; and shall auto-order replacement cards 60 days before any card's expiry date, without requiring manual triggering. |
MOD-125 — Joint account management¶
| Code | Requirement |
|---|---|
| FR-565 | System shall enforce multi-party account activation: account status must not advance to active until all required holders have individually completed eIDV via MOD-009 and each holder's consent has been recorded; the activation gate must be enforced at the account state machine layer in MOD-007, not only in application code. |
| FR-566 | System shall enforce the account's signing_authority mode on every outbound transaction: any mode permits any single holder to authorise; all mode must collect approval from every holder before the transaction can be submitted; any_two mode must collect approval from at least two distinct holders — attempts to bypass multi-party approval must be technically blocked. |
| FR-567 | System shall maintain balance_share_pct per active joint account holder, enforce that the sum of all active holders' shares equals 100.00 at all times, and expose a per-holder balance query endpoint that REP-007 can call to generate the Single Depositor View file required under the NZ Depositor Compensation Scheme. |
| FR-568 | System shall, upon receiving notification of a holder's death, immediately set the deceased holder's record to status deceased, freeze that holder's share to prevent redistribution, flag the account for back-office review, and block any change to holder records or balance share percentages until valid legal documentation (probate, letters of administration) has been recorded in MOD-073. |
MOD-126 — Power of attorney and third-party authority¶
| Code | Requirement |
|---|---|
| FR-569 | System shall enforce that no third-party authority may be set to active status until the grantee holds a verified KYC record via MOD-009; the gate must be enforced at the data layer via a foreign key constraint between app.third_party_authorities.grantee_customer_id and the KYC status table, not only in application-layer validation. |
| FR-570 | System shall enforce that EPoA activation requires: submission of incapacity evidence to MOD-073, back-office review by an authorised agent, and sign-off by a second authorised supervisor; the activated_at timestamp must not be set until all three conditions are recorded; automated or single-person activation must be technically blocked. |
| FR-571 | System shall tag every transaction initiated by an attorney or authorised third party with the authority_id at the point of posting in MOD-001, and log the grantee's identity as the acting party in MOD-047; any transaction posted under an authority without an authority_id tag must be treated as a system error and queued for operations review. |
| FR-572 | System shall run a weekly monitoring job for all accounts with active PoA or EPoA authorities, comparing transaction frequency and value in the past 30 days against the prior 3-month baseline, and must emit a bank.app.authority_abuse_alert event and create a MOD-053 case within 24 hours whenever either metric exceeds 3× the baseline — the 3× threshold must be configurable. |
MOD-127 — Product configuration panel¶
| Code | Requirement |
|---|---|
| FR-573 | System shall enforce that every product configuration change proposal requires review and approval by a second authorised staff member who is distinct from the proposer; the proposed_by ≠ reviewed_by constraint must be enforced at the database layer; any attempt to self-approve a proposal must be rejected at the data layer, not only in application code. |
| FR-574 | System shall classify every approved configuration change as favourable or unfavourable relative to the current parameter value, and for unfavourable changes must block the applied_at transition until notification_confirmed_at is set by a MOD-063 dispatch callback confirming that all affected customers have received notification with the required advance notice period. |
| FR-575 | System shall propagate applied configuration changes to all dependent modules — including MOD-110 (fee engine), MOD-050 (disclosure management), and MOD-113 (statement generation) — within 60 seconds of the change being applied, so that live product behaviour and customer disclosures are consistent with the new configuration from the effective date. |
| FR-576 | System shall log every configuration proposal and every status transition to MOD-047, recording the staff member ID, timestamp, and full before/after parameter values; the log must be queryable by product, parameter, and date range; no log record may be modified or deleted after creation. |
MOD-128 — Credit bureau enquiry and CCR integration¶
| Code | Requirement |
|---|---|
| FR-577 | System shall verify that a valid bureau enquiry consent record exists for the customer and enquiry purpose before placing any call to a bureau API; if consent is absent or expired, the call must be blocked and a structured error returned to the calling module — no bypass path may exist that allows a bureau call without a consent reference. |
| FR-578 | System shall check for an existing bureau report for the same customer_id and enquiry_purpose created within the configured suppression window (default 30 days) before placing a new bureau call, and must return the cached report with suppressed = true rather than placing a duplicate hard enquiry on the customer's credit file. |
| FR-579 | System shall support a primary and fallback bureau configuration per product type for AU credit assessments; if the primary bureau returns no_file or a timeout within the configured SLA, the system must automatically route to the fallback bureau without manual intervention, recording both the primary failure and fallback result on the enquiry record. |
| FR-580 | System shall, when a bureau response includes non-empty adverse_flags that contribute to an unfavourable credit decision, call MOD-050 to deliver an adverse action disclosure to the applicant before the decision is communicated, including the bureau name, nature of adverse information, and the applicant's right to access their credit report directly from the bureau. |
MOD-129 — Teller operations and branch cash management¶
| Code | Requirement |
|---|---|
| FR-581 | System shall record the teller's staff_id, branch_code, and drawer_id in the posting metadata of every teller-initiated transaction in MOD-001; no teller posting may be made without an active teller session; the teller identity must be written at the data layer and must be immutable on the posting record after confirmation. |
| FR-582 | System shall detect when a cash transaction amount equals or exceeds the jurisdiction-specific AML reporting threshold (NZD 10,000 / AUD 10,000), insert an identity confirmation step before the posting is finalised, set ctr_required = true on the teller transaction record, and block the posting until a valid identity_method is recorded — no cash transaction at or above the threshold may be posted without a confirmed identity method. |
| FR-583 | System shall apply the same pre-payment validation checks to all teller-initiated cash withdrawals as are applied to digital channel payments — including available balance check via MOD-003, account status check, and sanctions screen — and must return a decline with the same decline reason code that the digital channel would return for an identical transaction; no teller override path may bypass a validation decline without supervisor authorisation recorded against the transaction. |
| FR-584 | System shall calculate expected_balance on session close as the sum of the session's opening balance plus all deposits minus all withdrawals, compare it to the teller-entered closing_balance, record the variance, and flag sessions where the absolute variance exceeds the configured tolerance to the branch operations queue; a session with an out-of-tolerance variance must not reach closed status without a variance_reason being recorded. |
MOD-131 — Mutual governance and AGM administration¶
| Code | Requirement |
|---|---|
| FR-585 | System shall enforce the AGM notice period as a technical gate: the meeting status must not advance past notice_dispatched to in_progress unless MOD-063 confirms dispatch to all eligible members at least the configured minimum days before the meeting date; the gate check must use the MOD-063 dispatch confirmation timestamp, not the scheduled dispatch date; meetings where notice has not been confirmed dispatched in time must be held at planned status with a blocking error. |
| FR-586 | System shall record every proxy submission with the member ID, receipt timestamp, directed voting instructions, and validity status; proxies received after the configured proxy cut-off time must be automatically set to valid = false with an invalidation reason and must not be counted in quorum or voting calculations; the proxy count and directed vote breakdown must flow automatically into the resolution voting totals. |
| FR-587 | System shall derive resolution outcomes from the recorded votes_for, votes_against, and abstentions counts — including proxy votes — and must not allow an outcome to be recorded without those counts being present; the AGM minutes document must be uploaded to MOD-073 and dispatched to all members via MOD-063 within 30 days of the meeting date, with the dispatch event logged to MOD-047. |
| FR-588 | System shall dispatch the annual report to all active members via MOD-063 when triggered from the governance workflow, track delivery status per member, log the dispatch event to MOD-047 with the MOD-073 document reference and counts of successful and failed deliveries, and make the delivery report available for regulatory examination — this module is active only when institution_type: mutual is set. |
MOD-132 — Loan restructure and variation workflow¶
| Code | Requirement |
|---|---|
| FR-589 | System shall determine whether a requested loan variation requires credit reassessment by comparing the variation type against the configured materiality rules; material variations (term extension >12 months, rate type switch, capitalisation of arrears) must invoke MOD-029 before proceeding; non-material variations (repayment frequency change, minor term adjustment) must proceed to disclosure without reassessment. |
| FR-590 | System shall generate an updated amortisation schedule via MOD-112 for every confirmed loan variation and deliver it to the customer via MOD-063 and MOD-050 within 24 hours of the variation being confirmed, showing the revised repayment amount, new term end date, and any change in total interest payable. |
| FR-591 | System shall enforce the break cost disclosure gate for any variation that involves early repayment or conversion of a fixed rate period — the variation must not be confirmed until the customer has acknowledged the break cost calculated by MOD-163 via MOD-050; the acknowledgement reference must be recorded on the variation record. |
| FR-592 | System shall log every loan variation event — request, assessment decision, disclosure dispatch, customer confirmation, and any rejection — as an immutable record in credit.loan_variation_events with the requesting party, timestamp, and full before/after terms; the log must be available for regulatory examination without reconstruction. |
MOD-133 — Trust account management¶
| Code | Requirement |
|---|---|
| FR-593 | System shall prevent a trust account from activating until all trustees and all beneficial owners with an ownership interest ≥ 25% have individually completed eIDV via MOD-009, have been assigned a CDD risk tier, and the trust deed has been uploaded to MOD-073; partial KYC completion must not allow the account to open. |
| FR-594 | System shall record all trust parties — trustees, beneficial owners, appointors, protectors — in core.trust_parties with their role, ownership percentage where applicable, and KYC status; the sum of beneficial owner percentages need not equal 100% (discretionary trusts have no fixed beneficial interest) but any party with ≥ 25% interest must pass enhanced due diligence. |
| FR-595 | System shall trigger a trust account CDD review when any of the following occur: a trustee is added or removed, a beneficial owner change is notified, the account's AML risk rating is elevated by MOD-034, or the configured periodic review date is reached; the review must be completed within 30 days of the trigger event. |
| FR-596 | System shall store the trust deed and any deed of variation in MOD-073 with a reference from the trust account record; the trust deed reference must be present before the account can activate; replacement deeds must be stored as a new version, retaining the previous version for audit purposes. |
MOD-134 — Community account management¶
| Code | Requirement |
|---|---|
| FR-597 | System shall prevent a community account from activating until all designated authorised signatories have individually completed eIDV via MOD-009 and the association's governing document (constitution or rules) has been uploaded to MOD-073; the number of required signatories and the signing rule must be set at account opening and enforced on all subsequent transactions. |
| FR-598 | System shall enforce the community account's signing rule on all outbound transactions: any_one allows any single signatory to authorise; any_two requires approval from two distinct signatories; all requires approval from every active signatory; the rule must be enforced at the transaction authorisation layer, not only in the UI. |
| FR-599 | System shall support an annual signatory refresh workflow: the account holder (existing signatory with sufficient authority) can add new signatories, deactivate outgoing signatories, and upload an updated authority resolution to MOD-073; outgoing signatories must be set to valid_until = today and must lose transaction authority immediately; the refresh event must be logged to MOD-047. |
| FR-600 | System shall detect when all active signatories on a community account have had their KYC status degraded below the required threshold and must place the account in a restricted state that blocks outgoing transactions until at least the minimum number of signatories for the account's signing rule have refreshed their KYC; the account holder must be notified via MOD-063. |
MOD-135 — Batch payment and payroll file processing¶
| Code | Requirement |
|---|---|
| FR-601 | System shall validate each batch file against the declared format specification (ABA field positions and hash total for AU; CSV column spec and row count for NZ/AU) before accepting the file, rejecting files that fail format validation with a structured error identifying the failing row or field, and must not partially process a file that fails format validation. |
| FR-602 | System shall check the source account's available balance against the total batch amount via MOD-020 before processing any items; if funds are insufficient for the full batch, the system must present the shortfall to the customer and must not process the batch until the customer confirms they want to proceed with partial funding or until sufficient funds are available. |
| FR-603 | System shall screen each batch item through the transaction fraud scorer (MOD-023) and the AML transaction screening engine independently; items that generate a screening alert must be quarantined with status quarantined and reason recorded; quarantined items must not block non-alerted items from being submitted; the customer must be notified of any quarantined items within 60 seconds of the batch being submitted. |
| FR-604 | System shall post the source account debit and each individual beneficiary credit via MOD-001 as separate atomic transactions — the source debit for the total settled amount and each credit must both succeed or both fail; a credit that cannot be posted (account closed, invalid account) must be returned and the corresponding source account amount re-credited within the same business day. |
MOD-136 — BPAY biller registration and inbound BPAY¶
| Code | Requirement |
|---|---|
| FR-605 | System shall manage the BPAY biller registration lifecycle — from back-office initiation through to sponsor bank scheme registration confirmation; the biller record must remain in pending_registration status until the sponsor bank confirms the biller code has been assigned; no inbound payments may be credited to a biller in pending_registration status. |
| FR-606 | System shall validate the CRN on each inbound BPAY payment against the registered biller's CRN format specification (Luhn check, regex, or length-only as configured); CRNs that fail validation must be quarantined with status returned and reported to the operations queue within 60 minutes; the payer's bank must be notified via the scheme return mechanism. |
| FR-607 | System shall post each valid inbound BPAY receipt as a credit to the registered biller's account via MOD-001 on the day of receipt (same-day settlement for payments included in the sponsor bank's daily settlement file), record the BPAY payment date and scheme references on the transaction, and dispatch a payment received notification to the biller via MOD-063 within 60 seconds of posting. |
| FR-608 | System shall reconcile each inbound BPAY settlement batch against the sponsor bank's BPAY settlement file via MOD-081, identifying any discrepancy between expected and received totals per biller, and must flag unmatched items to the operations queue within 2 hours of the settlement file being received; unreconciled items must not remain open beyond end of the following business day without an escalation. |
MOD-137 — Agency banking adapter¶
| Code | Requirement |
|---|---|
| FR-609 | System shall process incoming agency batch files by parsing each transaction, matching the account number to a live account in the platform, and validating the account status and available balance (for withdrawals) before posting; items that cannot be matched to an account, or where the account fails validation, must be quarantined with a structured failure reason and reported to the operations queue within 2 hours of the batch being received. |
| FR-610 | System shall post each valid agency deposit as a credit and each valid agency withdrawal as a debit via MOD-001 on the transaction date indicated in the batch file, and must dispatch a transaction notification to the customer via MOD-063 within 60 minutes of the posting for each agency transaction. |
| FR-611 | System shall detect agency cash transactions at or above the jurisdiction-specific AML reporting threshold in the batch file and must flag these items for cash transaction reporting via the AML monitoring platform, recording the terminal_id and agent_outlet_code as location metadata on the transaction — the AML flag must not delay the posting of the transaction. |
| FR-612 | System shall reconcile each processed agency batch against the agency network's settlement file via MOD-081, comparing item counts and total amounts per transaction type; any discrepancy must be flagged to the operations queue within 2 hours of reconciliation completing; unresolved discrepancies must be escalated to the agency network within 1 business day. |
MOD-138 — Deceased customer and estate management¶
| Code | Requirement |
|---|---|
| FR-613 | System shall, upon recording a notification of death for a customer, immediately suspend all outgoing payments from the deceased customer's accounts (direct debits, standing orders, scheduled payments) within 60 seconds of the notification being confirmed by a back-office staff member, while allowing incoming credits to continue to be received; any existing PoA or EPoA on the deceased's accounts must be automatically set to status revoked_by_death via MOD-126 in the same operation. |
| FR-614 | System shall require verification of the legal personal representative's (LPR) identity via MOD-009 and upload of the LPR's legal authority document to MOD-073 (grant of probate, letters of administration, or small estate affidavit) before granting the LPR any access to the deceased customer's accounts; the back-office staff member must complete a two-step approval of both the identity check and the legal authority document before access is activated. |
| FR-615 | System shall support the small estate simplified pathway: for estates where the total balance across all accounts is below the configured small estate threshold, the system must accept a statutory declaration or affidavit of claim in lieu of probate, with back-office approval, and must allow distribution to the declared beneficiary without requiring full probate — the threshold must be configurable per jurisdiction. |
| FR-616 | System shall process estate distribution by posting the distribution amount from the deceased's account to the nominated recipient account or external account via MOD-001, recording the estate_id and distribution_id on the transaction, and must close the deceased customer's account and update the customer record to deceased_closed status upon confirmation that all accounts have been distributed and balances are zero. |
MOD-139 — Financial hardship formal variation workflow¶
| Code | Requirement |
|---|---|
| FR-617 | System shall record the statutory assessment deadline on every hardship application at the point of submission — 10 working days from receipt for NZ (CCCFA s102), 21 calendar days for AU (NCCP Part 4.1A) — and must alert the assessor via MOD-063 at 5 days before the deadline and again at the deadline if no decision has been recorded; the application status must be escalated to a supervisor if the deadline is missed. |
| FR-618 | System shall suspend all collections activity from MOD-065 for an account once a hardship application is received, maintaining the suspension until either the application is declined or a variation agreement is confirmed and active; no new collections escalation, default notice, or credit default listing may be initiated during the hardship assessment period. |
| FR-619 | System shall, upon a hardship variation being accepted by the customer, regenerate the loan's amortisation schedule via MOD-112 reflecting the varied terms, deliver the updated schedule to the customer via MOD-050 as the formal variation agreement, set the account's hardship flag in MOD-007, and post any capitalised interest amount via MOD-001 — all steps completing atomically before the variation is set to active status. |
| FR-620 | System shall monitor active hardship variations daily and must alert the back-office hardship team via MOD-063 when: a customer misses a varied repayment during the variation period; the variation end date is within 14 days (advance notice to customer and staff); and when the variation period ends, triggering reversion to original terms or assessment for a further variation if needed. |
MOD-140 — Chart of accounts and GL configuration¶
| Code | Requirement |
|---|---|
| FR-621 | System shall validate every posting in MOD-001 against the chart of accounts — the GL account codes in both the debit and credit legs must exist in core.gl_accounts with status active; postings referencing unknown or inactive GL codes must be rejected with a structured error identifying the invalid code. |
| FR-622 | System shall enforce four-eyes approval for all chart of accounts changes using the same maker/checker pattern as MOD-127; the proposer must not be the approver; system accounts (flagged is_system_account = true) must not be modifiable by back-office staff — changes to system accounts require a platform deployment. |
| FR-623 | System shall propagate activated GL account changes to MOD-080 (statutory reporting) and any downstream reporting modules within 60 seconds of activation, so that report templates reference only current, active account codes; deprecated accounts must remain queryable for historical reporting but must not be selectable for new postings. |
| FR-624 | System shall validate each GL account's regulatory_mappings against the known regulatory line item taxonomy before activation — accounts that are mapped to a regulatory line item that has been retired or renamed must be flagged for review; the platform must ship with a default chart pre-mapped to RBNZ BS2A and APRA ARS 720 classifications that satisfies regulatory reporting requirements without customisation. |
MOD-141 — Intra-bank transfer engine¶
| Code | Requirement |
|---|---|
| FR-625 | System shall detect whether a payment destination resolves to an account within the same institution before routing — if the destination account exists in the platform, the payment must be routed to the intra-bank transfer engine rather than any external payment rail; this routing decision must be transparent to the customer (both the debit and credit are shown as an immediate transfer). |
| FR-626 | System shall execute intra-bank transfers as a single atomic double-entry transaction in MOD-001, debiting the source account and crediting the destination account in the same database transaction; the transfer must either fully complete or fully fail — partial postings (debit without credit or credit without debit) must be technically impossible. |
| FR-627 | System shall apply the same pre-payment validation (MOD-020) and transaction fraud scoring (MOD-023) to intra-bank transfers as to external payments; intra-bank status must not be used to bypass or reduce any validation check; a fraudulent intra-bank transfer is as harmful as a fraudulent external payment. |
| FR-628 | System shall complete an intra-bank transfer from initiation to both accounts reflecting the updated balance within 5 seconds under normal conditions; the destination account holder must receive a credit notification via MOD-063 within 10 seconds of the transfer posting — these performance targets apply 24/7/365 with no cut-off window. |
MOD-142 — Deposit guarantee scheme disclosure¶
| Code | Requirement |
|---|---|
| FR-629 | System shall deliver a DCS (NZ) or FCS (AU) disclosure to the customer at account opening via MOD-050, including the scheme name, coverage limit, eligibility conditions, and a statement that investment products are not covered; the account must not activate until the customer has acknowledged the disclosure; the acknowledgement must be recorded in app.dcs_fcs_disclosures with a timestamp. |
| FR-630 | System shall include a deposit guarantee scheme coverage statement in every periodic account statement generated by MOD-113, showing the scheme name, coverage limit per person, and a note that the customer's total deposits at this institution count toward a single limit — the statement insert must be present even when the balance is below the coverage limit. |
| FR-631 | System shall display a real-time coverage indicator on the account detail screen showing: the customer's total eligible deposit balance at this institution (including their apportioned share of joint accounts from MOD-125), the applicable scheme limit, the protected amount, and any uncovered amount above the limit; the indicator must refresh within 5 seconds of a balance change. |
| FR-632 | System shall send a notification via MOD-063 when a customer's total eligible deposit balance first exceeds the scheme coverage limit, advising the customer of the uncovered amount and suggesting they consider spreading deposits across institutions — this notification is sent once per calendar year per customer if their balance remains above the limit. |
MOD-143 — OBR pre-positioning¶
| Code | Requirement |
|---|---|
| FR-633 | System shall maintain a resolution_state flag on the platform instance with values normal, pre_positioned, and activated; the flag must default to pre_positioned on production deployment and must only transition to activated via an authenticated API call from a user with the rbnz_resolution_officer role; all state transitions must be recorded in core.obr_partition_events with the activating user identity, timestamp, and RBNZ instruction reference. |
| FR-634 | System shall, upon transition to activated resolution state, calculate and apply OBR balance partitions atomically across all deposit accounts in a single database transaction — for each account, obr_frozen_amount shall equal balance × haircut_pct and obr_available_amount shall equal balance × (1 - haircut_pct); for joint accounts, the partition must be applied to each holder's SDV-apportioned share from MOD-125 before aggregation; the transaction must complete or fully roll back with no partial state. |
| FR-635 | System shall, while resolution_state = activated, restrict all customer-facing channels so that only the obr_available_amount is accessible for withdrawals and outbound payments; any payment instruction that would reduce the account balance below obr_available_amount must be rejected with a machine-readable OBR_FROZEN_BALANCE error code; incoming credits must continue to be received and posted normally. |
| FR-636 | System shall, upon receipt of an RBNZ resolution end instruction, unwind the OBR partition by clearing obr_frozen_amount and obr_available_amount on all accounts and returning resolution_state to normal; any haircut write-off amounts confirmed by RBNZ must be posted as credit loss entries in MOD-001 against the institution's credit loss GL account; the unwind must be atomic and the completion event logged with the RBNZ instruction reference. |
SD04 — Payments Processing (bank-payments)¶
MOD-144 — Confirmation of payee — account name verification¶
| Code | Requirement |
|---|---|
| FR-637 | System shall, for every outbound domestic AU payment using BSB and account number routing (not resolved via PayID), submit the destination BSB, account number, and customer-entered payee name to the NPP Confirmation of Payee service before presenting the payment confirmation screen; the CoP result (match, close_match, no_match, unavailable) must be stored in payments.cop_checks and linked to the payment record via cop_check_id. |
| FR-638 | System shall present the CoP result to the customer on the payment confirmation screen: a match result must be displayed as a green verified indicator; a close_match result must display the registered account name alongside an amber warning and require explicit customer acknowledgement before the payment can be confirmed; a no_match result must display the registered name (if available), a red warning, and require the customer to enter a free-text override reason before the payment can proceed. |
| FR-639 | System shall block any outbound BSB/account payment from reaching the settlement layer unless a cop_check_id is present on the payment record and the associated check was performed within the last 60 seconds; payments where the CoP check result is no_match and no override reason has been recorded must be blocked at the settlement layer regardless of prior UI acknowledgement. |
| FR-640 | System shall apply CoP validation per-item to batch payment files processed by MOD-135; items where the CoP result is no_match must be quarantined with status cop_failed and reported to the batch operator in the post-processing report before the remainder of the batch is submitted; the operator must explicitly release each quarantined item with a documented override reason before it can be included in a resubmission. |
MOD-145 — Payment hold & friction engine¶
| Code | Requirement |
|---|---|
| FR-641 | System shall evaluate every outbound payment through the hold risk engine before it reaches the settlement layer; the engine must calculate a hold risk score using configurable signals (new payee, amount above threshold, payee added within N hours, CoP no_match, velocity anomaly, AML flag) and must apply the appropriate friction level — advisory, soft_hold, or hard_hold — based on configurable score thresholds; all scoring inputs, the calculated score, and the applied friction level must be recorded in payments.payment_holds. |
| FR-642 | System shall, for payments assigned soft_hold status, queue the payment in pending state and dispatch a hold notification to the customer via MOD-063 within 30 seconds; the customer must be able to reconfirm or cancel the payment from within the notification or in-app interface; if no customer action is taken within the configured hold window (default 24 hours), the payment must be auto-cancelled and the customer notified of the cancellation. |
| FR-643 | System shall, for payments assigned hard_hold status, queue the payment and make it available in the back-office fraud review queue; the queue must be accessible only to users with the fraud_analyst role; the reviewing officer must be able to release the payment to settlement or block it permanently; the decision, the reviewing officer's identity, and a mandatory reason must be recorded before any action is taken; hard_hold payments must not auto-release on expiry. |
| FR-644 | System shall bypass hold evaluation for intra-bank transfers processed by MOD-141, BPAY payments to billers on the institution's trusted biller list, and internal system payments; all other outbound payment types must pass through hold evaluation without exception; any bypass event must be logged with the bypass reason. |
MOD-149 — Scam intelligence reporting & reimbursement¶
| Code | Requirement |
|---|---|
| FR-657 | System shall generate a weekly scam intelligence export from confirmed scam events in the AML case management system and payment fraud records, formatted to the ABA Scam Intelligence Hub API specification, including scam typologies, mule account BSBs and account numbers, payment corridors, and aggregate loss figures; the export must be submitted automatically to the Hub via secure API and the submission reference stored in payments.scam_intelligence_submissions; failed submissions must be retried and escalated to the compliance team if unacknowledged after 48 hours. |
| FR-658 | System shall allow the compliance team to suppress individual mule account records from a scheduled submission before it is sent; suppressions must be documented with a reason (default: legal_proceedings_ongoing) and the suppressed record must be held for inclusion in a future submission once the suppression is lifted; the suppression record must be immutable once the submission containing it has been sent. |
| FR-659 | System shall create a scam_reimbursement case in MOD-053 when a customer reports a scam payment, capturing: the payment ID, claimed amount, scam typology, and the CoP result and hold engine decision from the original payment; the assessment workflow must record bank fault determination (whether the bank's controls failed), customer care determination, and the approved reimbursement amount; the IDR SLA timers from CON-002 must apply from the moment the case is created. |
| FR-660 | System shall, upon approval of a reimbursement, post the approved amount as a credit to the customer's account via MOD-001, debiting the institution's fraud loss GL account configured in MOD-140, and record the reimbursement_id on the MOD-001 transaction; the posting must be atomic — the credit and debit must complete together or not at all; the customer must receive a notification via MOD-063 confirming the reimbursement within 60 seconds of the posting completing. |
SD06 — Risk Platform (bank-risk-platform)¶
MOD-147 — Related party exposure monitor¶
| Code | Requirement |
|---|---|
| FR-649 | System shall maintain a related party designation register linking customer IDs to relationship types (director, senior_manager, associate, parent, subsidiary, other); designations must be created and revoked only by users with the compliance_officer role; each designation must record the designating officer, designation date, and optional expiry date; expired designations must be automatically set to inactive and an alert sent to the compliance team. |
| FR-650 | System shall calculate the total credit exposure to each designated related party — aggregating outstanding loan balances, overdraft utilisations, undrawn committed facilities, and guarantees from MOD-001 — and express it as a percentage of the current Tier 1 capital figure from MOD-033; calculations must refresh within 60 seconds of any balance change or Tier 1 capital update affecting a related party. |
| FR-651 | System shall generate an alert to the Chief Risk Officer and Chief Financial Officer when any single related party's exposure reaches the configured warning threshold (default 80% of the regulatory limit), and a further alert to those officers plus the Board Risk Committee chair when any exposure reaches or exceeds the regulatory limit; alerts must include the counterparty name, current exposure amount, exposure percentage, and the regulatory limit percentage; all alerts must be logged as immutable records in MOD-048. |
| FR-652 | System shall generate a quarterly related party exposure report in PDF format, listing all designated related parties, their current exposure, limit headroom, and a 12-month exposure trend chart; the report must be available to users with the risk_officer and board_risk roles and must include a data certification statement confirming the figures are derived from the live ledger as at the report date. |
SD08 — App & Back Office (bank-app)¶
MOD-146 — Restricted activities enforcement¶
| Code | Requirement |
|---|---|
| FR-645 | System shall maintain a restricted activities register listing product types and feature flags classified as restricted under the NZ DTA Restricted Activities Standard; when a MOD-127 product configuration proposal enables a product type or feature flag on the restricted register, the proposal must be automatically set to blocked_pending_authorisation status and the proposer notified that regulatory authorisation is required before approval can proceed. |
| FR-646 | System shall require that before a blocked_pending_authorisation configuration proposal can be approved, a compliance officer must attach a documented authorisation of type rbnz_consent (with RBNZ reference number), board_resolution (with board minute reference and confirmation of RBNZ notification), or vendor_reclassification (with platform vendor advisory reference); the authorisation record must be stored in app.restricted_activity_authorisations and linked to the proposal. |
| FR-647 | System shall enforce restricted activity classification at the platform configuration layer such that it is not possible to activate a restricted product type or feature through any back-office interface, API call, or bulk import without a valid authorisation record on file; attempts to bypass the authorisation requirement must be rejected with a structured error and logged as a security event. |
| FR-648 | System shall include the restricted activity authorisation log in the RBNZ examination data export, providing for each authorisation: the product type or feature, the authorisation type, the reference document identifier, the authorising officer, the authorisation date, any expiry, and the current status of the associated configuration proposal; this data must be exportable in machine-readable format within 30 minutes of an RBNZ data request. |
MOD-148 — Privacy access request (DSAR) workflow¶
| Code | Requirement |
|---|---|
| FR-653 | System shall create a privacy access request case in MOD-053 when a customer submits a DSAR through any channel (in-app, staff-created); the case must record the request type (access, correction, erasure_query), the customer's jurisdiction (NZ or AU), and must automatically calculate and display the SLA due date — 20 working days from receipt for NZ (Privacy Act 2020 IPP 6), 30 calendar days for AU (APP 12); the SLA timer must start at the moment of submission receipt, not at first agent assignment. |
| FR-654 | System shall assemble a structured personal data extract for each DSAR case by querying all platform systems for data held about the identified customer — including CDD profile, account data, transaction history, loan records, communication logs, marketing preferences, and consents — presenting the assembled data to the reviewing agent for inspection and redaction before any disclosure; the assembly must complete within 4 hours of case creation. |
| FR-655 | System shall generate an alert to the Privacy Officer when a DSAR case reaches 50% of the SLA remaining, and escalate to the Privacy Officer and their manager when 20% of the SLA remains with no disclosure recorded; if the SLA deadline is missed without a formal refusal being recorded, the system must flag the case as sla_breached and notify the Privacy Officer immediately. |
| FR-656 | System shall, for DSAR cases where a refusal is recorded, generate a formal refusal letter addressed to the customer citing the refusal ground, inform the customer of their right to complain to the relevant Privacy Commissioner (NZ: OPC, AU: OAIC), and record the refusal reason and customer notification timestamp as immutable records; the system must track any subsequent Privacy Commissioner referral and link it to the originating DSAR case. |
MOD-050 — Disclosure enforcement module (NZ DTA KIS extension)¶
| Code | Requirement |
|---|---|
| FR-661 | System shall, for every NZ deposit product opened by a customer of a NZ-licensed deposit taker, generate a Key Information Summary in the RBNZ DTA Disclosure Standard prescribed format, populated from the product's live configuration record in MOD-127; the KIS must be presented to the customer as a hard gate during account opening — the product cannot activate until the customer has acknowledged it; the KIS version hash and acknowledgement timestamp must be recorded in app.dcs_fcs_disclosures. |
| FR-662 | System shall assign a content-addressed version identifier (kis_version_id) to each KIS, derived from a hash of all KIS content fields; any change to the product configuration that affects KIS content must trigger a new KIS version; old versions must be retained as immutable records and never deleted; when a new KIS version is activated for a product, existing account holders must receive a notification via MOD-063 and the new KIS must be surfaced in the account detail screen within 24 hours of activation. |
| FR-663 | System shall make the current KIS for each deposit product persistently accessible to the customer from the account detail screen at any time after account opening; the displayed KIS must reflect the currently active version; when a KIS is updated, the customer must acknowledge the updated version within 30 days — the system must send reminder notifications at day 14 and day 28 if no acknowledgement is recorded; unacknowledged KIS updates must be flagged in the back-office compliance queue but must not block account access. |
| FR-664 | System shall update the KIS template to reflect changes to the RBNZ DTA Disclosure Standard as a platform update, without requiring a database schema migration; the template renderer must be configurable per jurisdiction — the KIS gate is active only for NZ-jurisdiction accounts; AU accounts and accounts in other jurisdictions must not have the KIS gate applied unless explicitly configured for a future equivalent standard. |
MOD-061 — Open banking API platform (multi-jurisdiction extension)¶
| Code | Requirement |
|---|---|
| FR-665 | System shall support multiple simultaneously active jurisdiction profiles on the same gateway instance, with each profile operating on its own base path, accreditation registry, consent schema, and token issuer; a request arriving on one profile's base path must not be processable using a token issued under a different profile; the set of active profiles must be configurable via openbanking.profiles.enabled without a code deployment. |
| FR-666 | System shall ship with the following built-in profiles and their associated OpenAPI specifications: au_cdr (Consumer Data Standards v1.x), nz_payments_nz (Payments NZ API Centre v2.x), uk_open_banking (OBIE Read/Write API v3.x), eu_psd2 (Berlin Group NextGenPSD2 v1.3), generic_fapi2 (FAPI 2.0 with DPoP and PAR); each profile must define its security profile, consent schema, permission/scope mapping, endpoint structure, and accreditation registry source as a declarative profile document. |
| FR-667 | System shall enforce FAPI 2.0 (Demonstrating Proof of Possession / DPoP and Pushed Authorisation Requests / PAR) as the minimum security baseline for all active profiles; profiles that mandate a higher security level (e.g. AU CDR's FAPI 1.0 Advanced with PKCE) must apply that profile's additional requirements on top of the FAPI 2.0 baseline; any inbound token that does not meet the active profile's security requirements must be rejected with a standards-compliant error response. |
| FR-668 | System shall log every third-party API call with: TPP identity and accreditation status, customer identity (hashed), active profile, endpoint called, internal data clusters returned, consent ID validated, response latency, and HTTP response code; these logs must be queryable by the compliance team by TPP, profile, customer, or date range; a real-time alert must fire when any TPP's call volume exceeds their configured rate limit or when an accreditation expiry is within 30 days. |
MOD-049 — Open banking consent management (multi-jurisdiction extension)¶
| Code | Requirement |
|---|---|
| FR-669 | System shall store each open banking consent as a jurisdiction-profile-aware object with fields: consent_id, jurisdiction_profile, customer_id, third_party_id, granted_scopes (list of internal scope identifiers), granted_at, expires_at (nullable), status [active/revoked/expired/suspended], and consent_payload (JSONB — full jurisdiction-specific consent representation); internal scope identifiers must be profile-agnostic so that the gateway can enforce scopes without profile-specific logic. |
| FR-670 | System shall provide a synchronous consent validation endpoint returning {valid: boolean, reason?: string, expires_at?: timestamp} within 50 ms for a given (third_party_id, customer_id, requested_scopes, jurisdiction_profile) tuple; the validation must check that the consent is active, that all requested scopes are present in granted_scopes, that the consent has not expired, and that it has not been revoked; a revocation must propagate to validation responses within 60 seconds of being recorded. |
| FR-671 | System shall capture consent for each active jurisdiction profile using that profile's native authorisation flow: AU CDR arrangement via CDR authorisation code flow; NZ Payments NZ consent via API Centre authorisation; UK Open Banking permissions object via OBIE authorisation; EU PSD2 SCA + authorisation; Generic FAPI 2.0 via Rich Authorization Requests (RAR); the consent capture UI must be rendered in the customer's current language and must present human-readable descriptions of each permission being granted. |
| FR-672 | System shall provide a customer-facing consent management interface from the in-app settings screen listing all active open banking consents — showing TPP name, jurisdiction profile, human-readable granted permissions, expiry date, and a single-tap revoke button; revocation must take effect immediately with no grace period; the customer must receive a confirmation notification via MOD-063 within 60 seconds of revocation. |
MOD-084 — Open banking data access — data recipient (multi-jurisdiction extension)¶
| Code | Requirement |
|---|---|
| FR-673 | System shall support outbound open banking data retrieval for all active jurisdiction profiles, connecting to external Data Holder institutions using the appropriate profile's token exchange, endpoint discovery, and API specification; the connection layer must be abstracted so that consuming workflows (account migration, affordability assessment, account pre-fill) receive a normalised data structure regardless of the source institution's jurisdiction profile. |
| FR-674 | System shall maintain an institution directory for each active profile, populated from the relevant accreditation registry on a daily schedule, listing connectable Data Holder institutions with their endpoint discovery documents and accreditation status; a Data Holder that has had their accreditation suspended or revoked must be removed from the connectable list within 60 minutes of the registry update; the customer-facing institution picker must show only currently accredited institutions. |
| FR-675 | System shall store retrieved open banking data in a purpose-scoped temporary store with a TTL tied to the consuming workflow; data must be hard-deleted when the workflow completes, is abandoned, or the TTL expires — whichever is earliest; the deletion must occur at the data layer (not application logic), must be irreversible, and must be logged with a deletion timestamp; no retrieved data may be retained beyond its declared purpose or TTL under any circumstances. |
| FR-676 | System shall log every outbound data retrieval event with: external institution ID, jurisdiction profile, data scopes requested, data volume received (record count by category, not content), consuming workflow ID, consent ID validated, retrieval latency, and deletion timestamp; these logs must be available for regulatory examination for a minimum of 7 years; an alert must fire if a retrieval attempt fails three or more times consecutively for the same institution, indicating a connectivity or accreditation issue. |
SD02 — KYC Platform (bank-kyc) — continued¶
MOD-153 — Customer acceptance engine¶
| Code | Requirement |
|---|---|
| FR-709 | System shall evaluate the customer acceptance rule set for every product application before any account or facility can be activated, applying rules in sequence: identity verification status, sanctions screening result, PEP status and EDD completion, onboarding fraud score, CDD tier vs. product minimum, customer risk score, jurisdiction eligibility, and product suitability; no account activation may proceed without an ACCEPT outcome on record. |
| FR-710 | System shall produce one of four outcomes for each acceptance evaluation: ACCEPT (all rules passed), DECLINE (hard-fail rule triggered — sanctions hit, failed identity, jurisdiction ineligible), REFER (soft-fail — high risk score, unresolved PEP EDD requirement, fraud score above threshold), or HOLD_FOR_EDD (PEP or high-risk customer awaiting EDD completion); no other outcomes are permitted. |
| FR-711 | System shall write an acceptance decision record to kyc.acceptance_decisions for every evaluation containing: customer_id, product_id, decision, decision_at, methodology_version, a JSONB snapshot of all rule inputs at evaluation time, the list of rules applied, the list of rules triggered, machine-readable reason_codes, and the decision_officer identifier (null for automated decisions). |
| FR-712 | System shall block activation of any product account or facility where no ACCEPT decision exists for the customer-product pair, or where the most recent decision for that pair is DECLINE, REFER, or HOLD_FOR_EDD; the block must be enforced at the service layer and cannot be bypassed by any client application or back-office operator. |
| FR-713 | System shall create a risk case in MOD-151 for every REFER and HOLD_FOR_EDD outcome within 60 seconds of the decision, carrying the full acceptance context, rule trace, and reason codes for compliance officer review; the case must be resolved before the hold can be lifted and activation can proceed. |
| FR-714 | System shall generate an adverse action notice for every DECLINE outcome on a credit product, citing the applicable reason code in terms that satisfy NZ CCCFA s.9B and AU NCCP s.130 credit decision communication obligations; the notice must be delivered to the customer via MOD-063 within 24 hours of the decline decision. |
| FR-715 | System shall log every acceptance decision as an immutable entry in the system decision log (MOD-048) before any downstream action is taken, ensuring that the log entry exists regardless of whether the subsequent activation succeeds or fails. |
| FR-716 | System shall automatically re-evaluate the acceptance decision for a customer-product pair when any of the following events occur: CDD tier change, PEP status update, sanctions screening result change, or customer risk score moving above the configured high-risk threshold; a DECLINE result from re-evaluation must create a compliance officer case in MOD-151 and must not auto-close the existing account. |
SD04 — Payments Processing (bank-payments) — continued¶
MOD-154 — Correspondent banking risk gate¶
| Code | Requirement |
|---|---|
| FR-717 | System shall maintain a correspondent bank registry in payments.correspondent_banks containing: institution name, BIC/SWIFT code, jurisdiction, AML risk rating, approval status (active/suspended/terminated), settlement limit, onboarding date, last review date, next review due, and linked due diligence document identifiers; only correspondents with approval_status = active may be used for payment routing. |
| FR-718 | System shall block routing of any outbound payment through a correspondent whose BIC is not present in the registry with approval_status = active; the payment must be returned to the originating system with a machine-readable CORRESPONDENT_NOT_APPROVED error; the block must be logged as an immutable entry in MOD-048. |
| FR-719 | System shall calculate the projected unsettled nostro exposure to the target correspondent after routing each payment and block routing if the projected exposure would exceed the correspondent's configured settlement limit from MOD-082; the blocking check must run within the p99 payment authorisation latency budget. |
| FR-720 | System shall screen the BIC of every correspondent institution and every named intermediary in a payment chain against the current sanctions list before routing; a sanctions match must block the payment immediately and trigger a compliance alert regardless of the correspondent's prior approval status. |
| FR-721 | System shall detect payable-through account indicators in inbound SWIFT MT/MX payment messages; where an inbound payment cannot be attributed to an identifiable originating customer, the payment must be held and a compliance review case created in MOD-151 before the payment is credited. |
| FR-722 | System shall create a correspondent onboarding case in MOD-151 for every new correspondent relationship, presenting a structured due diligence checklist covering: AML programme assessment, beneficial ownership, FATF jurisdiction risk, sanctions history, regulatory standing, payable-through account usage, and disclosed nested correspondents; the case must require completion of all checklist items before it can proceed to the approval step. |
| FR-723 | System shall require dual approval from both the Head of Payments role and the Chief Compliance Officer role before any correspondent's approval_status can be set to active; a single approver is insufficient; both approvals must be recorded with officer identity and timestamp before status transition. |
| FR-724 | System shall log all correspondent registry changes, payment routing decisions (approved and blocked), onboarding case milestones, and sanctions screening results as immutable entries in the system decision log (MOD-048) with a payment_id or case_id foreign key on each entry. |
SD06 — Risk Platform (bank-risk-platform) — continued¶
MOD-150 — Risk management platform¶
| Code | Requirement |
|---|---|
| FR-677 | System shall auto-create an incident record in risk.incidents within 60 seconds of every P1 or P2 alert fired by MOD-076, classifying the incident by severity, assigning an SLA resolution deadline (P1: 4 hours, P2: 24 hours), and routing it to MOD-151 as a risk case; the incident record must exist in the log before the case is created. |
| FR-678 | System shall maintain an operational risk register in risk.operational_risk_events auto-populated from system events (MOD-076 alerts, MOD-048 decision log anomalies, CloudTrail IAM events, CI/CD pipeline failures); no manual entry of risk events is required or permitted; each entry must record: source_module, risk_domain (D01–D12), event_type, severity, description, occurred_at, and auto_resolved flag. |
| FR-679 | System shall compute the Risk Appetite Framework (RAF) dashboard continuously by aggregating CET1 ratio (MOD-033), LCR and NSFR (MOD-032), EVE sensitivity (MOD-035), capital stress test result (MOD-034), related party exposure % (MOD-147), and high-risk customer concentration (MOD-039); each indicator must refresh within 5 minutes of a source module update. |
| FR-680 | System shall automatically generate an alert to the CRO and Board Risk Committee chair within 5 minutes of any RAF indicator breaching its configured threshold; the alert must identify the indicator, the current value, the threshold, and the trend over the prior 30 days; all alerts must be logged as immutable entries in MOD-048. |
| FR-681 | System shall maintain a model inventory in risk.model_inventory auto-populated from CI/CD deployment events; each entry must record: model_id, owner_module, model_type, deployment_status, deployed_at, last_validated_at, next_review_at, performance_thresholds (JSONB), and current_psi; no model may be set to production status without a validation_report_id on record. |
| FR-682 | System shall run nightly PSI and accuracy monitoring jobs for all production models in the inventory; a model whose PSI exceeds 0.25 or whose accuracy drops below its configured threshold must have its status set to performance_review and a validation case created in MOD-151 automatically. |
| FR-683 | System shall health-check all registered critical third-party services every 60 seconds using their configured health endpoints; a check failure or SLA breach (uptime or latency) must auto-create a vendor incident in risk.incidents within 60 seconds. |
| FR-684 | System shall compute the intraday payment system exposure by aggregating payment events from MOD-020 in real time; the running intraday position — gross inflows, gross outflows, net position, and peak exposure per payment system — must be queryable with a maximum staleness of 5 minutes; a breach of the configured intraday exposure limit must trigger an immediate alert to Treasury. |
| FR-685 | System shall auto-assemble a regulatory breach notification document when a P1 incident is flagged as regulatory_notification_required; the document must include: institution name, incident description, affected services, estimated customer impact, onset time, current status, and contact details; the assembled draft must be staged in MOD-151 for compliance officer review within 30 minutes of incident creation. |
| FR-686 | System shall create a change record in risk.change_records for every CI/CD deployment event — success, failure, or rollback — recording: module_id, environment, artefact_hash, deployed_at, outcome, and rollback_of reference; a post-implementation review case must be created in MOD-151 for any deployment resulting in rollback or for any module that incurred a P1 incident within 72 hours of deployment. |
| FR-687 | System shall generate a Board risk report in structured data format (JSON) and PDF on the configured schedule, pulling live values and 90-day trends for all RAF indicators, all open P1 and P2 incidents, the model inventory summary, and the vendor health summary; the report must complete generation within 30 minutes of its scheduled time. |
| FR-688 | System shall enforce the model validation gate: a CI/CD deployment hook must call the model inventory API before any model deployment to production; if the target model_id does not have a validation_report_id on record with an approved status, the hook must return a non-zero exit code causing the pipeline to fail. |
| FR-689 | System shall retain all risk register entries, incident records, model inventory records, RAF snapshots, and change records for a minimum of 7 years from the event date, enforced by a row-level retention policy that prevents deletion regardless of the requesting role. |
| FR-690 | System shall expose the operational risk register, RAF dashboard indicators, model inventory, and incident register via a read-only internal API accessible to users with the risk_officer or board_risk role; all API responses must return within p99 500 ms. |
| FR-691 | System shall flag for immediate CRO review any model in the production inventory that has not been re-validated within its configured review SLA; models overdue for validation by more than 30 days must be set to validation_overdue status and a validation case created in MOD-151. |
| FR-692 | System shall monitor correspondent bank nostro balances from MOD-082 as a continuous settlement risk indicator in the RAF dashboard, alerting Treasury when any single correspondent nostro balance falls below the configured minimum operating balance. |
MOD-152 — Climate risk assessment¶
| Code | Requirement |
|---|---|
| FR-701 | System shall obtain physical climate hazard risk scores for all properties held as mortgage collateral via a configured third-party property hazard API; scores must cover flood risk (1-in-100-year probability), wildfire risk, and coastal inundation risk under +1.0m sea level rise; scores must be refreshed at least annually and on receipt of a material dataset update notification from the provider. |
| FR-702 | System shall assign each scored property to a physical risk tier (low / medium / high / very high) and compute portfolio-level exposure metrics by tier: total outstanding balance, count of properties, and LVR-weighted average exposure; these metrics must be stored in risk.portfolio_climate_metrics with a calculated_at timestamp and must refresh within 24 hours of a score update. |
| FR-703 | System shall classify every business and SME lending counterparty by ANZSIC sector code from their CDD profile and map each code to a climate transition risk tier; the portfolio concentration by transition risk tier — expressed as a percentage of total business lending exposure — must be computed continuously and stored alongside physical risk metrics. |
| FR-704 | System shall generate an automatic alert to the CRO when portfolio physical risk concentration in any single tier exceeds the configured RAF threshold, and a separate alert when high-transition-risk sector concentration exceeds its configured threshold; both alerts must include the current metric value, threshold, and a breakdown by geography and sector respectively. |
| FR-705 | System shall register two climate stress scenarios with the stress testing engine (MOD-034): (1) an acute physical risk scenario using RBNZ FSAP-aligned specifications for a severe flood event; (2) a rapid policy transition scenario modelling a carbon price shock on high-transition-risk sectors; both scenarios must be available in MOD-034's scenario library and produce CET1 impact output. |
| FR-706 | System shall generate an annual TCFD-aligned climate disclosure document on the configured schedule; the Metrics & Targets section must be auto-populated with live model outputs; the Governance, Strategy, and Risk Management sections must use institution-editable templates; the system must notify the nominated disclosure officer when the report is ready for review. |
| FR-707 | System shall store each completed annual TCFD disclosure as a versioned, immutable record in bank-reports-prod S3 with a content hash; no version may be deleted; all versions must be accessible for regulatory examination for a minimum of 7 years. |
| FR-708 | System shall include climate risk indicators — physical risk concentration by tier and transition risk sector concentration — in the MOD-150 RAF dashboard as configured metrics with user-defined thresholds; a breach of either threshold must follow the same RAF alert path as other indicators. |
SD08 — App & Back Office (bank-app) — continued¶
MOD-151 — Risk case console¶
| Code | Requirement |
|---|---|
| FR-693 | System shall display all open risk cases from MOD-150 in a prioritised inbox, showing for each case: case type, severity, SLA remaining (with colour-coded urgency), assigned owner, and the required action to resolve the case; cases must be sortable by severity, SLA remaining, and case type. |
| FR-694 | System shall enforce a root-cause-required gate on all P1 incident cases: the case cannot be set to resolved status until a root cause description, contributing factors, and at least one corrective action with an owner and due date have been recorded; the gate must be enforced at the service layer. |
| FR-695 | System shall provide a whistleblower intake channel accessible at a public URL and from within the authenticated app; the channel must accept anonymous submissions; submitted cases must be routed exclusively to users with the board_audit_committee role; no management role (CEO, COO, CTO, CISO, or below) may view whistleblower cases. |
| FR-696 | System shall store the whistleblower submitter's identity fields in risk.whistleblower_cases with column-level encryption using a key accessible only to the board_audit_committee role; no application-layer logic may substitute for this database-level control; management roles must receive a permission denied error on any attempt to read these columns. |
| FR-697 | System shall create a model validation case when MOD-150 flags a model as requiring validation, assigning it to an independent validator role; the case must enforce: validator assignment required, validation report file upload required, and an explicit approve or reject decision required before the case can be closed; a closed approved validation case is the prerequisite for model production promotion in MOD-150. |
| FR-698 | System shall apply SLA timers to all risk case types, generating an amber warning notification at 50% of elapsed time and a red escalation notification at 80%; if a case is not resolved or formally extended before the deadline, it must be auto-escalated to the risk officer's manager and flagged in the RAF dashboard. |
| FR-699 | System shall log every risk case decision and action as an immutable entry in the system decision log (MOD-048) before any status change takes effect; the log entry must record: case_id, action_type, actor_identity, timestamp, and the new case status. |
| FR-700 | System shall provide a board_risk and risk_officer role RAF summary panel showing: count of open P1 and P2 incidents, count of models in performance_review or validation_overdue status, count of vendor health failures, RAF indicator traffic-light status for all configured indicators, and a link to the full risk case inbox; this panel must refresh every 5 minutes. |
MOD-155 — Target Market Determination (AU DDO)¶
| Code | Requirement |
|---|---|
| FR-725 | System shall require an approved, current TMD to exist in app.target_market_determinations before any AU-jurisdiction retail product can be set to distributable status in MOD-127; an attempt to activate an AU product without a current TMD must be blocked with a machine-readable TMD_REQUIRED error. |
| FR-726 | System shall automatically set an AU product's distribution status to suspended in MOD-127 when its TMD status changes from current to expired or under_review; the product must remain suspended until a new or affirmed TMD has been approved by a compliance_officer and status is returned to current. |
| FR-727 | System shall evaluate the acquiring customer's characteristics from MOD-010 against the product's TMD target market criteria for every AU product sale or referral; the result (in_market / out_of_market / insufficient_data) must be recorded in app.tmd_distribution_events alongside the specific criteria evaluated, the values compared, and the mismatch description where out_of_market is returned. |
| FR-728 | System shall monitor each product's configured TMD review triggers — complaint rate, early redemption rate, out-of-market event count, distribution channel incident, and product change — and create a TMD review case in MOD-053 automatically when any trigger threshold is breached; the review case must block new compliance_officer TMD approvals until the review is formally assessed and either the TMD is updated or the current TMD is affirmed. |
| FR-729 | System shall identify significant out-of-target-market dealings — defined as individual transactions above the configured significance threshold or patterns exceeding the configured systemic threshold — and compile a structured ASIC significant dealings report in the format specified by ASIC DDO guidance; the report must be available for submission within 10 business days of the end of the relevant reporting period. |
| FR-730 | System shall retain all TMD versions as immutable records in app.target_market_determinations; no TMD version may be deleted or modified after approval; superseded versions must remain queryable for regulatory examination with their full approval history. |
| FR-731 | System shall require explicit compliance_officer role approval before any TMD can transition to current status; a single approver is required; the approver must not be the same person who authored the TMD; the approval must be recorded with approver identity, timestamp, and a declaration that the TMD accurately describes the target market. |
| FR-732 | System shall log all TMD approvals, distribution event evaluations, trigger threshold breaches, ASIC report submissions, and product distribution suspensions as immutable entries in the system decision log (MOD-048) with the tmd_id or product_id on each entry. |
SD07 — Data Platform (bank-platform) — continued¶
MOD-156 — CI/CD pipeline platform¶
| Code | Requirement |
|---|---|
| FR-733 | System shall provide a reusable GitHub Actions workflow template for Lambda-type modules, parameterised on module_id, module_dir, node_version, and stage; the template shall execute in order: dependency install, TypeScript typecheck, unit tests with a ≥80% coverage gate, integration tests when RUN_INTEGRATION=1, SST deploy using the OIDC-assumed role, and wiki status update via update-wiki.py; the template shall not contain any skip flag or bypass condition. |
| FR-734 | System shall provide a reusable GitHub Actions workflow template for IaC-type modules, parameterised on module_id, module_dir, and stage; the template shall execute: dependency install, SST drift detection (sst diff) on every pull request, SST deploy on merge to main using the OIDC-assumed role, SSM output verification confirming every declared output path resolves, and wiki status update via update-wiki.py. |
| FR-735 | System shall include a generate-workflows.py script that reads module YAML files from source/entities/modules/ in the wiki, resolves the module dependency graph into a phase-ordered DAG matching the build sequence, and emits per-repo GitHub Actions workflow YAML files; within each phase independent modules shall be emitted as parallel jobs; between phases jobs shall declare explicit needs: dependencies on all modules in the preceding phase. |
| FR-736 | update-wiki.py shall fire a repository_dispatch event to the GitHub repository of every module that lists the just-advanced module as a dependency, immediately after a module's build_status is written as Built; the dispatch payload shall include triggering_module_id and new_build_status; dispatches shall be sent in parallel and any individual failure shall be logged without blocking the wiki commit. |
| FR-737 | System shall configure three GitHub Environments (dev, uat, prod) on all eight code repositories; dev shall be ungated; uat shall require approval from at least one member of the platform-leads GitHub team; prod shall require approval from at least two members of platform-leads; required reviewers shall be enforced at the GitHub Environment level, not at the workflow level. |
| FR-738 | System shall enforce branch protection on the main branch of all eight code repositories with the following rules: all CI status checks defined in the generated module workflow must pass, at least one approving human review is required on every pull request, stale review approvals are dismissed when new commits are pushed, and no identity (including repository administrators) may push directly to main without a pull request. |
| FR-739 | System shall configure GitHub Actions OIDC federation on all eight code repositories, authenticating against the AWS IAM OIDC provider provisioned by MOD-104 and assuming the role ARN stored at SSM parameter /bank/{env}/iam/cicd/arn; no long-lived AWS credentials shall be stored as GitHub repository secrets or environment variables in any workflow file. |
SD05 — Credit Decisioning & Loan Platform (bank-credit) — continued¶
MOD-162 — Loan facility & component manager¶
| Code | Requirement |
|---|---|
| FR-741 | System shall create a facility entity with a single approved credit limit, single expiry date, and master agreement reference, within which one or more components may be established; the sum of all active component principals must not exceed the facility limit at any time; any component creation that would breach this constraint must be rejected with a machine-readable LIMIT_EXCEEDED error. |
| FR-742 | System shall permit one floating-rate component as the unallocated residual leg (repriced each period off the configured benchmark rate plus customer margin) and one or more fixed-rate components (each with a locked rate, principal, term, and amortisation profile) within a single facility; the floating residual component must always be present and its principal must equal the facility limit minus the sum of all active fixed component principals. |
| FR-743 | System shall compute and persist the principal-weighted effective interest rate across all active components within 500 ms of any component lifecycle event (creation, rollover, partial repayment, maturity, termination), storing the result on the facility record; the effective rate is Σ(component_principal × component_rate) / Σ(component_principal) across all ACTIVE components. |
| FR-744 | System shall record every component state transition as an immutable append-only history row capturing: previous state, new state, trigger reason, component rate, outstanding principal, and effective date; the immutability trigger must reject any UPDATE or DELETE on rows whose status is MATURED, PREPAID, or CANCELLED. |
MOD-163 — Break-cost calculator¶
| Code | Requirement |
|---|---|
| FR-745 | System shall calculate break cost or benefit on any fixed-rate component as the present value of (contracted_rate − current_market_rate) × outstanding_principal over the remaining term in months, where current_market_rate is the mid-market swap rate for the residual tenor sourced from MOD-085 at the moment of calculation; a positive result is a cost owed by the customer; a negative result is a benefit owed by the bank to the customer. |
| FR-746 | System shall expose an on-demand indicative break-cost quotation API returning a result within p99 ≤ 500 ms, callable by any authenticated customer holding an active facility at any time; the indicative call must not trigger any account action, state change, or commitment on the component. |
| FR-747 | System shall record every break-cost calculation — indicative and binding — as an immutable audit row capturing: calculation type, contracted rate, current market rate, market rate source identifier, market rate timestamp, outstanding principal, remaining term in months, discount rate, break cost or benefit amount, currency, and formula version; rows must be Cat 1 immutable via the ADR-048 trigger pattern. |
| FR-748 | System shall require customer acknowledgement of the binding break-cost disclosure delivered via MOD-050 before any early termination or pre-maturity rollover of a fixed-rate component is processed; the component status handler must verify that a confirmed acknowledgement record ID is present and was issued against the same binding calculation ID before the component state change is applied. |
MOD-164 — Facility component self-service¶
| Code | Requirement |
|---|---|
| FR-749 | System shall provide an authenticated customer view of all active facility components displaying: component type, principal, contracted rate or benchmark-plus-margin, maturity date (fixed components), current indicative break cost or benefit (sourced from MOD-163 on screen load), and the facility-level principal-weighted effective interest rate. |
| FR-750 | System shall provide a component rollover flow allowing the customer to elect rate type, principal, and term for a component at or approaching maturity; where rollover occurs before maturity, the flow must obtain a binding break-cost calculation from MOD-163 and enforce the MOD-050 acknowledgement gate before the rollover instruction is submitted; rate quotes presented in the rollover flow must expire after the configured validity window (default: 15 minutes) and must be refreshed before submission if expired. |
| FR-751 | System shall provide an add-component flow allowing the customer to convert a portion of the floating residual into a new fixed-rate component; the nominated principal must be at least the configured minimum component size and must not exceed the current floating residual balance; the flow must enforce a MOD-050 product disclosure gate before the component creation instruction is submitted. |
| FR-752 | System shall provide a partial prepayment flow for fixed-rate components that obtains a binding break-cost calculation from MOD-163, enforces the MOD-050 break-cost acknowledgement gate, and submits the prepayment instruction to MOD-162 only after a confirmed acknowledgement record ID is returned; break benefits arising from the prepayment must be displayed prominently and credited to the customer's nominated account via MOD-001. |
SD06 — Snowflake Analytics & Risk Platform (bank-risk-platform) — continued¶
MOD-165 — Synthetic swap book aggregator¶
| Code | Requirement |
|---|---|
| FR-753 | System shall consume bank.credit.component_created and bank.credit.component_status_changed events from the bank-credit EventBridge bus and maintain a near-real-time register (risk.synthetic_swap_positions) of all active fixed-rate loan component positions, updating position status to MATURED or PREPAID on the corresponding terminal-state events. |
| FR-754 | System shall assign a matched-tenor FTP rate from MOD-161 to each new fixed-rate component position at the time of its creation event, locking the rate on the position record for the life of the component; the FTP tenor must match the component's original term in months rounded to the nearest available tenor in the MOD-161 rate curve. |
| FR-755 | System shall aggregate active fixed-rate component positions into the standard Basel repricing maturity buckets (overnight, 1M, 3M, 6M, 1Y, 2Y, 3Y, 5Y, 7Y, 10Y, 15Y, 15Y+) per RBNZ BS13 and APRA APS-117 requirements, computing for each bucket and each jurisdiction: total notional, position count, principal-weighted average contracted rate, principal-weighted average FTP rate, and annual NIM contribution. |
| FR-756 | System shall compute EVE and 12-month NII sensitivity metrics for the synthetic swap book under at minimum six parallel rate-shift scenarios (±100bp, ±200bp, ±300bp) in addition to the base-case position, store the results as a dated daily snapshot in risk.irrbb_repricing_summary after each daily sweep, and publish bank.risk.irrbb_snapshot_updated on completion. |
SD09 — Brand & Public Surfaces (bank-public-website)¶
MOD-169 — Public website¶
| Code | Requirement |
|---|---|
| FR-757 | System shall build reproducibly from source: a clean checkout followed by pnpm install and pnpm build shall produce a deployable dist/ artefact with no manual steps and no environment-specific configuration. |
| FR-758 | System shall render all published pages with no broken internal or external links; a post-build link checker shall fail the pipeline on any 4xx or 5xx response from any href in the built site. |
| FR-759 | System shall deliver contact form submissions to the configured marketing ops inbox within 60 seconds of submission; the deploy smoke test shall assert a 2xx response from the Cloudflare Pages Function and that MailChannels accepted the message. |
| FR-760 | System shall serve the site at http://localhost:4321 via pnpm dev with hot reload on source changes, enabling content review without a CI build. |
| FR-761 | System shall meet Core Web Vitals targets on the home page and each product page: LCP < 2.5 s, CLS < 0.1, INP < 200 ms; measured by Lighthouse CI in the smoke stage with soft-fail (warns on regression, does not block deploy). |
SD07 — Data Platform (bank-platform) — EIP modules¶
MOD-087 — Transaction enrichment engine¶
| Code | Requirement |
|---|---|
| FR-762 | System shall resolve raw acquirer merchant names to a canonical merchant identity — normalised merchant name, merchant logo, and MCC code — using a merchant enrichment API and an internal normalisation dictionary, caching resolved identities to eliminate redundant enrichment API calls for the same merchant. |
| FR-763 | System shall attach geolocation (latitude and longitude) to each enriched transaction record where merchant location data is available from the enrichment source. |
| FR-764 | System shall publish an enriched transaction event to the EIP event bus after each enrichment, including all enriched fields, for consumption by MOD-088, MOD-089, MOD-091, and the customer app. |
MOD-093 — Accounting mapper¶
| Code | Requirement |
|---|---|
| FR-784 | System shall push pre-classified transactions to Xero via the Xero API (OAuth 2.0) with account code, tax code, and tracking category pre-populated from the MOD-088 classification and MOD-092 tax logic output. |
| FR-785 | System shall push pre-classified transactions to MYOB AccountRight and MYOB Essentials APIs with equivalent account code, tax code, and category fields populated, supporting AU-market entities using MYOB. |
| FR-786 | System shall attach receipt image files sourced from MOD-091 to the corresponding Xero transactions as Xero file attachments when available. |
| FR-787 | System shall produce accountant export files in CSV, ICFM, and Xero-compatible formats, each including the full audit trail of classification decisions from MOD-088 and rule overrides from MOD-090. |
SD06 — Risk Platform (bank-risk-platform) — EIP modules¶
MOD-088 — Expense classification engine¶
| Code | Requirement |
|---|---|
| FR-765 | System shall classify each enriched transaction across four dimensions: ownership (Personal / Business / Mixed / Property), purpose, tax treatment (Fully claimable / Partially claimable / Non-claimable), and accounting code mapping. |
| FR-766 | System shall produce a confidence score (0–100%) and a classification basis indicator (Merchant / Behavioural / Geo / Rule / User-confirmed) for each classification decision and store these alongside the classification output. |
| FR-767 | System shall incorporate geo-spatial signals (home cluster, work cluster, travel period) from MOD-089 as classification inputs when those signals are available for the transaction's merchant location. |
| FR-768 | System shall incorporate user-confirmed and implicit rules from MOD-090 as classification overrides, applying them in the priority order defined by MOD-090 before emitting the final classification. |
| FR-769 | System shall retrain the classification model periodically from user-confirmed classifications across the anonymised customer portfolio, incorporating the updated model without requiring a full redeploy. |
MOD-089 — Geo-spatial processor¶
| Code | Requirement |
|---|---|
| FR-770 | System shall derive and continuously maintain a home cluster (centroid and radius), a work cluster, and a set of detected travel periods for each customer from enriched transaction location data. |
| FR-771 | System shall detect a travel period when sustained transaction sequences occur outside both the home and work clusters for more than one day, and close the travel period when transactions return to the home geography. |
| FR-772 | System shall emit geo-spatial classification signals (within-home-cluster, within-work-cluster, travel-period, recurring-travel) for each enriched transaction to be consumed by MOD-088 as classification inputs. |
MOD-092 — Tax logic engine¶
| Code | Requirement |
|---|---|
| FR-780 | System shall accumulate NZ GST return inputs (output tax on taxable sales, input tax credits on business expenses) per GST period for each NZ GST-registered entity and produce a quarterly GST return summary ready for customer review. |
| FR-781 | System shall produce Australian Business Activity Statement inputs — G1 (total sales), G11 (non-capital purchases for creditable purposes), and net GST position — per BAS period for each AU entity. |
| FR-782 | System shall apply NZ income tax expense deductibility rules to each business expense classification: 50% cap on business entertainment, home office apportionment by use proportion, vehicle deductibility by logbook or kilometre rate, and exclusion of commute expenses. |
| FR-783 | System shall maintain a rolling provisional tax estimate for NZ sole traders based on year-to-date classified taxable income and total deductible expenses, updating the estimate after each classified transaction event. |
MOD-094 — Property attribution engine¶
| Code | Requirement |
|---|---|
| FR-788 | System shall detect recurring inbound payment patterns consistent with rental income and surface a confirmation prompt to the customer to attribute those payments to a specific property. |
| FR-789 | System shall attribute expense transactions to specific rental properties using explicit merchant rules, address-derived geo-spatial proximity signals, and customer-confirmed implicit rules learned over time. |
| FR-790 | System shall detect large repair or improvement transactions and present a capital-vs-revenue determination prompt to the customer; the customer's determination must be stored with a timestamp for IRD audit purposes. |
| FR-791 | System shall maintain a running property-level P&L per period for each rental property, comprising: rental income received, operating expenses, financing costs (mortgage interest), and net result before ring-fencing. |
MOD-095 — Ring-fencing logic engine¶
| Code | Requirement |
|---|---|
| FR-792 | System shall apply NZ residential ring-fencing rules (Income Tax Act 2007 ss EE 1–8) to each property in the portfolio at period end, ring-fencing any net loss into a carry-forward register that is not available to offset other income. |
| FR-793 | System shall apply portfolio-level profit offset, allowing ring-fenced losses from one property to offset rental profits from another property in the same customer portfolio. |
| FR-794 | System shall test and apply the portfolio profitability exemption (ring-fencing does not apply when total portfolio income exceeds total portfolio losses), the land business exemption (flagged for manual review), and mixed-use holiday home apportionment rules. |
| FR-795 | System shall maintain a ring-fenced loss carry-forward register with chronological application of oldest losses first to future rental profits, and provide this register to MOD-093 for inclusion in tax summary outputs and accountant exports. |
SD08 — App (bank-app) — EIP modules¶
MOD-090 — Auto rules engine¶
| Code | Requirement |
|---|---|
| FR-773 | System shall allow customers to create explicit classification rules scoped to a merchant, merchant category, or time-bounded condition, and apply those rules to all matching future transactions. |
| FR-774 | System shall generate implicit classification rules from user correction patterns after a configurable confirmation threshold is reached, and present each inferred rule for one-time customer review before it is activated. |
| FR-775 | System shall apply rules in priority order (explicit rules override implicit rules, which override the base model output from MOD-088) and log the applied rule ID and rule basis against each overridden transaction for customer audit. |
| FR-776 | System shall feed confirmed and corrected classifications back to MOD-088 as labelled training examples to personalise the classification model over time. |
MOD-091 — Receipt processor¶
| Code | Requirement |
|---|---|
| FR-777 | System shall accept receipt images via in-app camera capture and via customer email forwarding to a dedicated ingestion address, queuing both for OCR processing. |
| FR-778 | System shall extract merchant name, transaction date and time, total amount, GST amount where shown separately, and payment method from receipt images and email receipts using an OCR pipeline. |
| FR-779 | System shall match each extracted receipt to a candidate transaction by amount, date (within a configurable window, default ±3 days), and merchant name similarity; automatically attaching receipts above a high-confidence threshold and presenting a customer confirmation prompt below it. |
SD02 — KYC Platform (bank-kyc) — EIP modules¶
MOD-096 — Multi-entity party graph manager¶
| Code | Requirement |
|---|---|
| FR-796 | System shall maintain a directed graph of party entities with five node types (NATURAL_PERSON, SOLE_TRADER, COMPANY, TRUST, PROPERTY_CONTEXT) and typed relationship edges (IS_DIRECTOR_OF, IS_TRUSTEE_OF, IS_BENEFICIAL_OWNER_OF, OPERATES_AS) representing the legal and economic structure of a single customer login. |
| FR-797 | System shall trigger the appropriate KYC/CDD check (via MOD-009 for natural person entities or MOD-010 for business entities) for each new party node before that entity relationship is activated in the graph — satisfying the AML-002 GATE requirement. |
| FR-798 | System shall provide the customer app with a context-switcher representation of all entities in the party graph under the customer's login, with appropriate data scoping and access controls applied per entity context. |
SD07 — Data Platform (bank-platform) — governance modules¶
MOD-168 — Maker-checker enforcement engine¶
| Code | Requirement |
|---|---|
| FR-799 | System shall expose five API endpoints (submit, list, get, approve, reject) for managing maker-checker proposals, with all requests authenticated by staff JWT and all responses conforming to the published OpenAPI contract. |
| FR-800 | System shall block self-approval unconditionally — any request where the reviewing staff ID matches the proposing staff ID must return 422 SELF_APPROVAL_FORBIDDEN; this constraint must be enforced at both the application layer and via a database-level CHECK (proposed_by != reviewed_by) constraint that no role or configuration flag can disable. |
| FR-801 | System shall automatically transition any proposal whose expires_at timestamp has passed to EXPIRED status and emit the corresponding audit event; no expired proposal may be approved or rejected. |
| FR-802 | System shall emit an immutable audit event to MOD-047 on every proposal state transition (submitted, approved, rejected, expired, withdrawn), and a system decision event to MOD-048 on approval and rejection only. |
| FR-803 | System shall enforce a configurable minimum review window for TIER-3 proposals — any approval attempt before review_window_until must return 422 REVIEW_WINDOW_NOT_ELAPSED; TIER-2 proposals have no review window and may be approved immediately after submission. (v1: TIER-3 returns 501 TIER_3_NOT_IMPLEMENTED; this FR governs the v2 implementation.) |
SD06 — Risk Platform dashboards & submissions portal (bank-risk-platform)¶
MOD-170 — Regulatory Submissions Portal¶
| Code | Requirement |
|---|---|
| FR-804 | System shall present an authorised Finance or Compliance officer with a unified submission calendar aggregating all regulatory returns across MOD-036, MOD-037, MOD-057, and MOD-060, showing each return's status (ASSEMBLING / VALIDATED / AWAITING_APPROVAL / APPROVED / SUBMITTED / ACKED / OVERDUE) updated within 1 hour of any status change. |
| FR-805 | System shall provide a cell-level return viewer for each assembled regulatory return, displaying every line item with its value, source view name, source run_id, and upstream model_run_id lineage, allowing the reviewing officer to drill from any cell back to the source DT row that produced it. |
| FR-806 | System shall provide an approval form within the return viewer permitting an authorised Finance officer to approve or reject an assembled return; approval shall write an immutable record to REGULATORY.RETURN_APPROVALS containing the approving officer's staff_id, timestamp, run_id, return_code, jurisdiction, and a mandatory sign-off reason; the approving officer must be a different identity from the assembling system actor. |
| FR-807 | System shall require a valid REGULATORY.RETURN_APPROVALS record for the current (run_id, return_code) pair before the submission orchestrator in any regulatory return module (MOD-036, MOD-037, MOD-057, MOD-060) may post to a regulator endpoint; any orchestrator invocation that finds no approval record must abort, log the rejection reason, and alert the Finance team — automated submission without human sign-off is prohibited. |
| FR-808 | System shall maintain a historical submissions log showing every return submitted across all regulatory modules, with regulator acknowledgement status, content hash, submission reference, and submission timestamp, retained for a minimum of 7 years. |
MOD-171 — Risk Intelligence Dashboard¶
| Code | Requirement |
|---|---|
| FR-809 | System shall present a unified Risk Appetite Framework (RAF) summary showing all configured quantitative indicators (CET1 ratio, LCR, NSFR, EVE sensitivity, stress test capital headroom, related party exposure percentage) against their board-approved RAF thresholds, with a 90-day trend chart for each indicator, updated within 1 hour of the underlying model refreshing. |
| FR-810 | System shall provide a capital adequacy deep-dive aggregating CET1, Tier 1, Total Capital, and RWA data from MOD-033, with period-over-period comparison and a breakdown of RWA by exposure class. |
| FR-811 | System shall provide a liquidity dashboard showing LCR and NSFR from MOD-032 for the current period, with a 30-day history chart, and an intraday exposure view sourced from MOD-032's intraday extension. |
| FR-812 | System shall provide an IRRBB sensitivity dashboard showing EVE and NII sensitivity across all standard interest rate shock scenarios from MOD-035, with scenario comparison and period-over-period delta. |
| FR-813 | System shall provide a risk metrics overview page showing customer risk score distribution (MOD-039), FTP rate table by product and tenor (MOD-086), and cost attribution by system domain (MOD-098), each linking to the owning module's Streamlit page for drill-down. |
MOD-172 — Operations & Model Intelligence Dashboard¶
| Code | Requirement |
|---|---|
| FR-814 | System shall provide a data quality scorecard aggregating DQ break counts, break rates, and open-break trending over 30 days from MOD-038, broken down by system domain, showing which domains have active DQ breaks and their severity. |
| FR-815 | System shall provide a statutory financials viewer showing the most recently closed period's profit and loss, balance sheet, and cash flow statement sourced from MOD-080's published views, with the ability to navigate to prior periods. |
| FR-816 | System shall provide a model performance dashboard showing accuracy, population stability index (PSI), and drift alert status for each deployed SD06 model (MOD-039 customer risk score, MOD-040 churn model, MOD-041 categorisation model), sourced from the models' published performance views. |
| FR-817 | System shall provide a cost attribution view showing cost allocation by system domain and product line sourced from MOD-098, updated daily, with period-over-period comparison. |
| FR-818 | System shall provide a navigation link from the Operations & Model Intelligence Dashboard to the MOD-056 Compliance Visibility Engine Streamlit, presented as an embedded section or clearly labelled navigation item, so operators can move between operational and compliance views without changing applications. |