學習目標 · Learning Objectives
- Explain how commission is calculated, what the FYC / renewal tiers mean, why a sale quoted over a threshold may be restructured, and when clawback applies.
- Describe the licensing and supervision regime that governs the agent's own conduct — what an IFA or agency agent may and may not do, and who is accountable for their advice.
- Apply the IA Code of Conduct expectations that show up in daily POS usage — disclosure, not misleading the client, suitability, and record-keeping — to concrete scenarios, and use the POS CRM module responsibly: pipeline, follow-up cadence, and the AML record-keeping obligations that attach to client records you create and keep.
Commission, CRM & Compliance (佣金、CRM 與合規)
Learning Objectives
- Explain how commission is calculated, what the FYC / renewal tiers mean, why a sale quoted over a threshold may be restructured, and when clawback applies.
- Describe the licensing and supervision regime that governs the agent's own conduct — what an IFA or agency agent may and may not do, and who is accountable for their advice.
- Apply the IA Code of Conduct expectations that show up in daily POS usage — disclosure, not misleading the client, suitability, and record-keeping — to concrete scenarios, and use the POS CRM module responsibly: pipeline, follow-up cadence, and the AML record-keeping obligations that attach to client records you create and keep.
In practice: Lesson 12 is the capstone because these three things are not separate. Commission decides which product an agent is tempted to recommend; CRM decides which client gets which product; compliance decides what an agent is permitted to do about both. Every one of those three pressures exists in every other lesson in this course.
The Three Forces
graph TD
A[Agent's monthly income] -->|drives| B[Which product gets quoted first]
B -->|drives| C[Which client gets which recommendation]
C -->|must be filtered by| D[IA Code of Conduct<br/>suitability + disclosure]
C -->|documented in| E[CRM pipeline]
C -->|recorded for| F[AML record-keeping]
D -->|can end| G[Complaint / investigation]
F -->|missing| G
style A fill:#2d1b1b,stroke:#c0392b,color:#f0e0e0
style D fill:#1b2d1b,stroke:#27ae60,color:#e0f0e0
style G fill:#2d2d1b,stroke:#f39c12,color:#f0f0e0
The graph is the whole lesson. Commission flows from left, compliance stands in the middle, and the record of what you did flows to the right. The failure mode is not usually an agent doing something obviously wrong — it is an agent under commercial pressure who takes a shortcut that leaves no record, followed by a complaint eighteen months later.
Section 1: How Commission Actually Works
In practice: commission is not a percentage of premium. It is the product of a rate, a basis, a tier and a period, and all four are set by the carrier — which is exactly why "same premium" does not mean "same commission".
The four components
| Component | What it is | Typical values (illustrative) |
|---|---|---|
| Rate 佣金率 | Percentage applied to the commission basis | 15-60% first year, 5-15% renewal |
| Basis 佣金計算基礎 | What the rate applies to — not always premium | Annualized premium for protection; 10% of first premium for some savings; a flat fee for certain riders |
| Tier 分級 | Rate banded by the premium or first-year premium volume | e.g. <$5k = 25%, $5k-$20k = 35%, >$20k = 45% |
| Period 期間 | Which year of the policy the payment applies to | FYC (first year only) vs FYC + renewal commission over 5-10 years |
type CommissionStructure = {
carrierCode: string;
productCode: string;
basis: 'ANNUALIZED_PREMIUM' | 'FIRST_PREMIUM' | 'SUM_ASSURED' | 'FLAT_FEE' | 'PREMIUM_MINUS_GST';
// Illustrative only. Real schedules are contractual and far more conditional.
fycTiers: { min: number; max: number | null; ratePct: number }[];
renewalYearPct: Record<number, number>; // year index → % of year-1 premium
clawback: {
appliesOnRescission: boolean;
freeLookWindowDays: number;
appliesOnFreeLook: 'FULL' | 'AGENT_PORTION' | 'NONE';
appliesOnCoolingOffAfterYear1: 'FULL' | 'AGENT_PORTION' | 'NONE';
appliesOnLapse: boolean;
appliesOnUnderwritingVariation: 'NO_ADJUSTMENT' | 'ADJUST_ON_REFUND' | 'FYC_RECALCULATED';
};
qualification: { minFycHkd: number; minPervasiveDays: number; minTrainingHours: number };
};
function computeFyc(
policy: { productCode: string; annualPremiumHkd: number; firstPremiumHkd: number; sumAssuredHkd: number },
structure: CommissionStructure
): { basisAmount: number; ratePct: number; fycHkd: number; warnings: string[] } {
const warnings: string[] = [];
const basisAmount = (() => {
switch (structure.basis) {
case 'ANNUALIZED_PREMIUM': return policy.annualPremiumHkd;
case 'FIRST_PREMIUM': return policy.firstPremiumHkd;
case 'SUM_ASSURED': return policy.sumAssuredHkd * 0.005; // basis points of sum assured
case 'FLAT_FEE': return 800;
case 'PREMIUM_MINUS_GST': return policy.annualPremiumHkd - policy.annualPremiumHkd / 1.06;
default: return policy.annualPremiumHkd;
}
})();
const tier = structure.fycTiers
.slice()
.reverse()
.find(t => basisAmount >= t.min);
if (!tier) {
warnings.push(`Basis ${basisAmount} falls below the lowest tier — commission may be zero-rated.`);
return { basisAmount, ratePct: 0, fycHkd: 0, warnings };
}
// Guard the structural trap: a rate that only pays better at higher volume
// creates an incentive to over-sell the client's needs.
if (basisAmount >= 20000) {
warnings.push(
'This sale crosses the $20k tier boundary. Confirm with the client that the higher-premium ' +
'option serves their stated need, and record that conversation in the CRM.'
);
}
return { basisAmount, ratePct: tier.ratePct, fycHkd: round2(basisAmount * tier.ratePct / 100), warnings };
}
The four traps an agent must know
Trap 1 — basis is not premium. Two products with identical annualized premiums can carry materially different FYC because one pays on annualized premium and the other on a flat fee. An agent who quotes by FYC will misrank products whose commission bears no relation to their cost to the client.
Trap 2 — tier boundaries. Above a volume threshold the rate steps up. The consequence is that
the agent earns more by selling a bigger policy, which is precisely the incentive that produces
over-selling. The warnings array in the code above exists to force a recorded conversation at
the boundary. This is a compliance control implemented in the POS, and it is the single most
valuable commission-related feature an agent can have.
Trap 3 — first year only (FYC). A large FYC on an ill-suited savings product looks excellent this month and produces nothing in year two. An agent under monthly income pressure will over-index on FYC; an agent with renewal income in the mix will not. This is a personal financial structure problem, but it is also a compliance risk, because the pressure shows up as advice.
Trap 4 — clawback. Commission is provisional and reversed in defined circumstances:
| Clawback trigger | Typical treatment | Agent consequence |
|---|---|---|
| Free-look cancellation (14 days HK standard for many policies) | Full clawback in most structures | Selling to win a month's income at the cost of a cancellation you cannot afford |
| Cooling-off / rescission after year 1 | Often agent's portion only | Pro-rata reduction |
| Lapse during the commission-earning period | Often full FYC clawback | Poor persistency advice destroys your earnings |
| Underwriting variation (loading applied, or a lower benefit tier issued) | Basis recalculated | A $30k policy issued at a $15k tier pays on $15k |
The free-look row deserves emphasis. Selling a policy a client will cancel in two weeks is net negative for the agent, before any compliance question arises. The POS can and should surface the free-look period at the point of sale so this arithmetic is visible rather than abstract.
Renewal commission is a retention strategy
Every renewal-commission strategy is, underneath, a client-retention strategy. An agent who advises persistency properly earns more across the policy's life than one who maximises FYC and churns the client. The skills that produce retention — the servicing knowledge in Lesson 10, the claims handling in Lesson 11 — are financially motivated as well as professionally necessary.
// Two policies, same client, ten-year view. Same sale, different agent quality.
const tenYearValue = (fyc: number, renewals: number[], persistencyLossRate: number) => {
const years = [fyc];
let prev = fyc;
for (let i = 0; i < renewals.length; i++) {
const amount = renewals[i] * (1 - persistencyLossRate ** (i + 1));
years.push(amount);
prev = amount;
}
return years;
};
// Case A: aggressive FYC pitch, client cancels in 10 days
const aggressive = { fyc: 0, renewals: Array(9).fill(0), persistencyLossRate: 1 };
// Case B: needs-led recommendation, client stays 10 years
const needsLed = tenYearValue(18_400, [3_100, 3_100, 3_100, 3_100, 3_100, 2_600, 2_600, 2_600, 2_600], 0.04);
// Difference over 10 years: roughly 31x. The "ethical" choice is also the
// materially better financial choice — which is the argument to make to a
// new agent under income pressure, because it is true.
Section 2: Licensing, Regulation and Supervision
In practice: knowing who supervises whom, and where the responsibility sits, is what tells you which question to ask when you are stuck. It is also what a complaint investigation will trace.
The Hong Kong supervisory map
| Body | Supervises | Your relevance |
|---|---|---|
| Insurance Authority (IA) | The whole insurance market under the Insurance Ordinance — authorization, products, conduct standards, market conduct | The IA issues and enforces the IA Code of Conduct for Authorized Institutions' Insurance Intermediaries. It is the standard your advice is measured against |
| SFC | Securities and futures — including Type 1/4/9 licences covering certain insurance-linked investment products (ILAS structured as securities) | If you sell an ILAS structured as a securities product, SFC conduct rules apply to that element |
| HKMA | Banks — banks distributing their own insurance products | Relevant when your agency relationship is with a bank rather than an independent agency |
| Companies Registry | Agent and agency registration for companies in the agency business | Your employing agency must be properly registered |
Two structures, different accountability
| Dimension | Tied agent 掛單代理 | Independent agent / IFA 獨立代理/理財策劃人士 |
|---|---|---|
| Contractual | Employed or contracted by one agency / carrier | Contracted by clients directly, or by multiple agencies |
| Licence held | Agency registration; agent operates under it | Personal Type 1 / Type 9 SFC licence (where ILAS securities are involved) |
| Who is accountable for the advice | The agency carries compliance responsibility and supervises you; you are personally liable too | You carry primary responsibility for suitability and disclosure |
| Money received | Paid by the carrier via the agency, post-vetting | Paid by the client or by the carrier, disclosed on the illustration |
| Supervision | Agency compliance officer, internal audit | Your own compliance controls, plus SFC supervision |
| What changes for you | You can be disciplined by the agency, terminated | You own the record and the justification independently |
The practical consequence of the IFA structure is that there is no compliance officer to catch your mistake. Everything the agency would have caught — unsuitable recommendation, missing disclosure, incomplete CRM record — must be caught by you.
Self-employed check-in (自僱查詢)
Hong Kong requires agents to check whether they have reached a threshold at which they must register as self-employed tax rather than remaining a self-employed individual. This is an administrative obligation with real consequences, and it is frequently ignored. It belongs in the POS as a dated reminder, not in an agent's memory.
Section 3: The IA Code of Conduct — The Rules That Show Up in the POS
In practice: these are not abstract principles. Each one corresponds to a specific screen in the system you use every day.
Conduct expectations, mapped to POS behaviour
| Code expectation | What it means in the POS | The concrete failure |
|---|---|---|
| Clear, accurate disclosure — the client understands the product, its exclusions and its limitations before buying | Benefit summary and key exclusions shown before the client confirms; agent attestation that the client can explain the cover back | Client signs a proposal having been shown only a benefit illustration |
| Not misleading — no misleading or exaggerated statements about likely returns | Saving/retirement projections shown as base case plus clearly-labelled alternatives, never a single optimistic line | Showing the product's projected return as though it were guaranteed |
| Suitability — the recommendation fits this client's need and capacity | Need analysis (Lesson 04) and FNA (Lesson 05) completed before the recommendation, and referenced by the recommendation | Recommending a savings product to a client who needed protection, because the commission is better |
| Care and competence — act with the skill your role requires | Complete and accurate application data; no guessing at medical questions | Ticking a disclosure box the client has not understood |
| Fair treatment — no discrimination in how clients are advised | Consistent recommendation process regardless of premium size or client background | Advising a small-premium client less carefully because the commission is trivial |
| Records and accountability — records kept so advice can be reconstructed years later | CRM entries, FNA documents, comparison records, disclosure confirmations retained | No record of why the product was recommended |
| Referral and disclosure of capacity — the client knows who is advising and in what capacity | Agency and remuneration basis disclosed at first meeting and in documentation | Client believes advice is disinterested when a commission is attached |
The disclosure question, done properly
The disclosure duty applies at application and is absolute — see Lesson 06 for the underwriting consequences. For compliance purposes there is a second, separate disclosure obligation: the client must be told the remuneration basis. An illustration that shows commission but does not explain it fails; an illustration that shows a FYC figure without stating it is provisional and subject to clawback fails.
The record that must be reconstructable
Put the compliance test this way: if the client or the regulator asks you in three years why you recommended this product, what can you produce?
type AdviceRecord = {
clientId: string;
// The need, established before the product
needAnalysisId: string | null; // Lesson 04 — required before recommendation
fnaId: string | null; // Lesson 05 — required for savings/long-term
statedNeedSummary: string;
budgetHkdPerMonth: number;
existingCoverSummary: string;
// What was considered, and rejected
productsConsidered: {
productCode: string;
productVersion: string;
consideredAt: string;
rejectedReason: string; // REQUIRED — an empty reason means not really considered
}[];
// What was recommended, and why this one
recommended: {
productCode: string;
productVersion: string;
sumAssuredHkd: number;
premiumHkd: number;
reasonLinkedToNeed: string; // MUST reference the need analysis finding
remunerationBasis: string; // disclosed to client
clientAgreedOn: string;
};
// The comparison, if more than one was quoted
comparison: {
carriersCompared: string[];
normalisationBasis: string; // Lesson 07 — how unlike benefits were compared
clientsChosenWhatWhy: string;
} | null;
// Attestations
clientExplainedCoverBack: boolean; // teach-back confirmed
exclusionsDiscussed: string[]; // which exclusions were raised
freeLookExplained: boolean;
recordedAt: string;
agentId: string;
};
// Three years later, the only defensible answer is this record.
Three fields do the real work: rejectedReason (proves genuine comparison rather than
presenting one pre-chosen product), reasonLinkedToNeed (proves the product followed from the need
analysis rather than the commission), and exclusionsDiscussed (proves the client was told what it
does not cover).
Section 4: AML Record-Keeping
In practice: records you create in the POS are AML records. Keeping them is mostly a matter of not deleting them, and of knowing what to add.
type AmlObligation = {
clientId: string;
relationshipId: string;
// The onboarding record (Lesson 09)
cdDueDiligence: {
idType: 'HKID' | 'PASSPORT' | 'MAINLAND_ID';
idNumberMasked: string;
idExpiry: string;
addressProofType: 'UTILITY_BILL' | 'BANK_STATEMENT' | 'TAX_RETURN' | 'TENANCY_AGREEMENT' | 'CORRESPONDENCE';
addressVerifiedAt: string;
method: 'ONLINE_EKYC' | 'IN_PERSON' | 'POST';
officer: string;
};
// Ongoing monitoring
sanctionsPepScreening: {
screenedAt: string;
listVersion: string;
result: 'CLEAR' | 'MATCH' | 'POSSIBLE_MATCH';
ifMatch: { resolution: 'CLEARED_FALSE_POSITIVE' | 'ESCALATED' | 'CONFIRMED' | null; fourEyesBy: string | null };
}[];
// The transaction record
transactions: {
at: string;
type: 'PREMIUM' | 'FUND_VALUE_RECEIPT' | 'REFUND' | 'CLAIM_PAYMENT' | 'THIRD_PARTY_PAYMENT';
amountHkd: number;
sourceAccountName: string;
matchedToClient: boolean;
justification: string | null; // REQUIRED when matchedToClient === false
}[];
// The advice record (Section 3)
adviceRecords: AdviceRecord[];
retentionUntil: string; // not deletable before this date
};
The record that must explain itself
The single most important AML field is justification on a payment that did not match the
client. Under the AMLO regime a suspicious transaction requires a specified action — and the
essence of that action is being able to explain why you did it. A blank justification is
equivalent to not having performed the check.
What must never be deleted
| Record | Why | Practical control in the POS |
|---|---|---|
| ID and address verification evidence | Proves CDD was performed | Soft-delete only; retain masked copies |
| Sanctions / PEP screening results with list version | Proves screening happened against a real list | Append-only; never update in place |
| Four-eyes escalation and its resolution | Proves the escalation was reviewed | Append-only |
| Need analysis and FNA documents | Proves suitability reasoning | Versioned; superseded versions retained |
| Advice records | Proves what was recommended and why | Append-only |
| Payment source records | Proves source-of-funds legitimacy | Append-only |
| Claim file correspondence | Required for claims record-keeping | Append-only |
The POS should make deletion structurally impossible for these tables. This is a schema
decision, not a policy: a deletedAt column on a compliance table is a defect, because
deletedAt IS NULL is a query someone will eventually write.
Section 5: The CRM Module
In practice: the CRM is not a diary. It is the answer to "what do I owe this client, and when does it stop being reasonable that I have not contacted them?"
The pipeline
stateDiagram-v2
[*] --> LEAD: referral, walk-in, inbound enquiry
LEAD --> APPOINTMENT: meeting booked
APPOINTMENT --> ANALYSIS: need analysis done (Lesson 04)
ANALYSIS --> QUOTED: multi-carrier quote issued (Lessons 03, 07)
QUOTED --> FOLLOW_UP_1: no decision within 7 days
FOLLOW_UP_1 --> FOLLOW_UP_2: no decision within 14 days
FOLLOW_UP_2 --> CLOSED_LOST: client declines or unreachable
FOLLOW_UP_2 --> FOLLOW_UP_3: final attempt, then nurture
FOLLOW_UP_3 --> NURTURE: periodic review, not sales contact
QUOTED --> PROPOSAL_SENT: proposal issued
PROPOSAL_SENT --> IN_UNDERWRITING: application submitted (Lesson 08)
IN_UNDERWRITING --> POLICY_IN_FORCE: issued
POLICY_IN_FORWRANT --> [*]
POLICY_IN_FORCE --> REVIEW_DUE: annual review
REVIEW_DUE --> REVIEW_DONE: cover, sum assured, budget revisited
REVIEW_DONE --> REVIEW_DUE: next cycle
The states after POLICY_IN_FORCE are the ones that separate a professional from a salesperson.
A client whose circumstances change — new child, new mortgage, salary cut — is either contacted
before they contact a competitor, or not contacted at all.
type CrmOpportunity = {
id: string;
clientId: string;
stage: 'LEAD' | 'APPOINTMENT' | 'ANALYSIS' | 'QUOTED' | 'FOLLOW_UP_1' | 'FOLLOW_UP_2'
| 'CLOSED_LOST' | 'FOLLOW_UP_3' | 'NURTURE' | 'PROPOSAL_SENT' | 'IN_UNDERWRITING'
| 'POLICY_IN_FORCE' | 'REVIEW_DUE';
enteredStageAt: string;
nextActionDate: string;
nextAction: string;
lastContactAt: string;
linkedAdviceRecordId: string | null; // required from ANALYSIS onward
linkedPolicyNumber: string | null;
// Compliance flags derived automatically, not typed by the agent
flags: {
crossTierBoundary: boolean; // Lesson 12 §1
staleOpportunity: boolean; // in stage > SLA
noAdviceRecord: boolean; // recommended but no AdviceRecord
clientTemperatureCold: boolean; // no contact in N days
};
};
const FOLLOW_UP_SLA_DAYS: Record<string, number> = {
LEAD: 3, APPOINTMENT: 5, ANALYSIS: 7, QUOTED: 7,
FOLLOW_UP_1: 7, FOLLOW_UP_2: 14, PROPOSAL_SENT: 3, IN_UNDERWRITING: 5,
};
// The two metrics that actually predict a full year
const pipelineHealth = (opps: CrmOpportunity[]) => ({
staleCount: opps.filter(o => o.flags.staleOpportunity).length,
noAdviceCount: opps.filter(o => o.flags.noAdviceRecord).length,
crossTierCount: opps.filter(o => o.flags.crossTierBoundary).length,
policyInForceInPipeline: opps.filter(o => o.stage === 'POLICY_IN_FORCE').length,
reviewDueThisQuarter: opps.filter(o => o.stage === 'REVIEW_DUE').length,
});
Follow-up cadence — and the limit
| Stage | Expected contact | Content |
|---|---|---|
QUOTED | Day 7 | Answer questions on the comparison; offer to walk through it again |
FOLLOW_UP_1 | Day 14 | A different angle — what has changed since, or a gap in their cover |
FOLLOW_UP_2 | Day 30 | Explicit close-the-loop: "you wanted to think about it — where did you land?" |
FOLLOW_UP_3 | Day 60 | One final contact, then move to nurture |
NURTURE | Every 6 months | Market or plan change relevant to their profile — not product advertising |
POLICY_IN_FORCE | Annually | Coverage review: new dependants, new liabilities, budget still comfortable |
The discipline is in the transitions. Six follow-ups on a client who asked you to stop is a complaint and, in some cases, a conduct issue. A CRM that records the "stop" and stops is doing its job.
Section 6: The Compliance Module in the POS
In practice: compliance controls are only real if the agent cannot complete the transaction without passing them. A warning that can be dismissed is a suggestion.
| Control | Enforces | Blocking? | Lesson ref |
|---|---|---|---|
| Need analysis completed | Suitability reasoning exists before a recommendation | Yes | L04 |
| FNA completed | Required for savings / ILAS / long-term products | Yes | L05 |
| Rejected products recorded | Genuine comparison, not a single pre-chosen product | Yes, ≥2 rejections for multi-carrier | L07 |
| Disclosure attested | Client can explain cover back; exclusions raised | Yes | L06 |
| Free-look explained | Client knows the cancellation window | Yes | L10 |
| eKYC / CDD complete | Identity and address verified | Yes — cannot proceed to application | L09 |
| Sanctions / PEP clear | Screening current and within window | Yes — escalate if match | L09 |
| Cross-tier conversation recorded | Commission step-up justified by need | Yes, with free text | §1 |
| Advice record complete | All mandatory fields populated | Yes — blocks "mark as recommended" | §3 |
| CRM follow-up scheduled | Next action date set before advancing stage | Yes | §5 |
The pattern is consistent: each control corresponds to a specific lesson in this course. The compliance module is the place where lessons 04, 05, 06, 07, 09 and 10 become non-optional. That is why Lesson 12 is the capstone and not an appendix.
Section 7: Putting It Together — The Compliance Timeline of a Sale
In practice: the following sequence is what a compliant HK agent sale looks like end to end. Every artefact it produces is one the POS should already have created.
sequenceDiagram
participant A as Agent
participant C as Client
participant P as POS
participant K as Carrier
A->>C: 1. Disclose agency, capacity, remuneration basis
A->>P: 2. Open case; select products (L02 catalogue)
P-->>A: 3. Eligibility + rate table (L03)
A->>C: 4. Need analysis conversation (L04)
A->>P: 5. Record need analysis; compute FNA (L05)
A->>C: 6. Present multi-carrier comparison, normalised (L07)
C->>A: 7. Choose; client explains cover back
A->>P: 8. Record rejected reasons, exclusions discussed
A->>C: 9. Explain free-look period (L10)
A->>P: 10. eApplication; disclosure Q&A complete (L06, L08)
P->>P: 11. CDD / eKYC + sanctions screening (L09)
P-->>K: 12. Submit application
K->>P: 13. Underwriting outcome; policy in force
P-->>A: 14. Commission accrues (provisional)
A->>C: 15. Free-look check-in before expiry
P->>P: 16. Schedule policy review at 12 months
P-->>A: 17. Renewal commission accrues if persistency held
Steps 4, 5, 8, 9, 10 and 11 are the ones that get skipped under income pressure, and they are the ones that determine whether the sale is defensible three years later.
Reconstructing the Timeline From the Record Alone
The sequence above is what a compliant sale looks like in the moment. The question that matters three years later — or in a complaint investigation — is different: can the record, without interviewing anyone, prove that sequence happened?
Those are not the same question, and the gap between them is where investigations succeed. A complaint investigation is typically a documentation review conducted months after the agent has left the agency, the client has forgotten the conversation, and the carrier has closed its file. Nobody reconstructs the meeting from memory. Either the artefacts exist or they do not.
This is why the compliance module stores evidence rows rather than a completed: true flag. A
flag asserts that something happened; an evidence row carries the timestamp, the actor and the
artefact, and can be re-read.
| Step in the sequence | Artefact that must exist | Timestamp it must carry | Who can write it |
|---|---|---|---|
| 1 — Disclose agency and remuneration | agency_disclosure_attestation | Before step 2 | Agent, client-attested |
| 4 — Need analysis conversation | need_analysis_record with objectives[] | Before step 5 | Agent |
| 5 — FNA computed | fna_document + fna_acknowledgement | Before step 6 | System, client-signed |
| 6 — Multi-carrier comparison | comparison_set with ≥2 rejectedReason entries | Before step 8 | Agent |
| 7 — Client explains cover back | explain_back_result per benefit | Before step 9 | Client on their own device |
| 8 — Rejections and exclusions recorded | advice_record | Before step 10 | Agent |
| 9 — Free-look explained | free_look_disclosure | Before step 10 | Agent, client-attested |
| 10 — eApplication, disclosure Q&A | disclosure_answers append-only | At submission | Client only |
| 11 — CDD + sanctions screening | kyc_case with screening_result and screening_cleared_at | Before step 12 | System / MLRO |
| 15 — Free-look check-in | free_look_checkin | Before window expiry | Agent |
| 16 — 12-month review scheduled | crm_next_action | Before step 17 | Agent, blocking |
Three properties distinguish a real record from a plausible one, and all three are checkable without a human judgement call:
Ordering is verifiable, so it must be enforced. fna_acknowledgement.timestamp being later
than need_analysis_record.timestamp is not a convention — it is a constraint the POS enforces at
write time. A record where the FNA precedes the needs analysis is not "slightly out of order", it
is a file that could not have been produced honestly, and it is visible to a reviewer as exactly
that.
The actor is recorded, not inferred. Step 7's explain-back and step 10's disclosure answers are
written by the client on their own device, under the client's own authentication. The system records
that it was the client — not an agent asserting that the client said so. This is the same append-only
disclosure principle from Lesson 06, and it is the reason the compliance table has no
entered_by_agent nullable column.
Absent is different from incomplete. A missing artefact says nothing about the agent; a present but empty one says the check was performed and produced nothing, which is a materially different record. That is the same distinction Lesson 09 makes when a cleared screening hit is retained precisely because "we checked and dismissed it" must be provable.
// Reconstruct the sale from the record. Returns the gaps that would fail a review.
type SaleEvidence = {
saleId: string;
agencyDisclosure: EvidenceRow | null;
needAnalysis: EvidenceRow | null; // step 4
fnaAcknowledgement: EvidenceRow | null; // step 5
comparisonSet: EvidenceRow | null; // step 6, >=2 rejectedReason
explainBack: EvidenceRow | null; // step 7, client-authored
adviceRecord: EvidenceRow | null; // step 8
freeLookDisclosure: EvidenceRow | null; // step 9
disclosureAnswers: EvidenceRow | null; // step 10, client-authored
kycCase: EvidenceRow | null; // step 11
freeLookCheckin: EvidenceRow | null; // step 15
crmNextAction: EvidenceRow | null; // step 16
};
const ORDERED_STEPS = [
['agencyDisclosure', 'Agency and remuneration disclosed'],
['needAnalysis', 'Need analysis conversation recorded'],
['fnaAcknowledgement', 'FNA computed and acknowledged'],
['comparisonSet', 'Multi-carrier comparison with rejections'],
['explainBack', 'Client explained cover back'],
['adviceRecord', 'Advice record complete'],
['freeLookDisclosure', 'Free-look period explained'],
['disclosureAnswers', 'Disclosure questionnaire answered by client'],
['kycCase', 'CDD and sanctions screening cleared'],
['freeLookCheckin', 'Free-look check-in performed'],
['crmNextAction', 'Next action scheduled'],
] as const;
export function reconstructSale(evidence: SaleEvidence) {
const gaps: Array<{ step: string; problem: 'MISSING' | 'OUT_OF_ORDER'; detail: string }> = [];
let previous: EvidenceRow | null = null;
for (const [field, label] of ORDERED_STEPS) {
const row = evidence[field];
if (!row) {
gaps.push({ step: field, problem: 'MISSING', detail: `${label} — no artefact on file` });
continue;
}
// Ordering is a hard constraint, not a convention: a reverse-order file could
// not have been produced honestly, and that is exactly what a reviewer sees.
if (previous && row.at < previous.at) {
gaps.push({
step: field,
problem: 'OUT_OF_ORDER',
detail: `${label} at ${row.at} precedes ${previous.step} at ${previous.at}`,
});
}
previous = row;
}
return {
reconstructable: gaps.length === 0,
gaps,
// An empty-but-present artefact is a result. A missing one is not.
note: gaps.length === 0
? 'Every step provable from the record alone.'
: 'This sale cannot be evidenced without an interview.',
};
}
The reconstructable boolean is worth surfacing in the POS itself, not just in a review, for the
same reason the free-look clawback is surfaced at the point of sale: an agent who can see that a
missing row will fail a review three years from now is more likely to complete it now than an agent
who is told only that a field is mandatory. The distinction between "this field is required" and
"this file could not be defended" is the whole argument for evidence rows over completion flags.
Key Takeaways
- Commission is rate × basis × tier × period — and the basis is often not premium, so equal premiums can carry unequal FYC.
- Tier boundaries create an over-selling incentive, and the POS must counter it. A POS that forces a recorded client conversation at the boundary is a compliance control disguised as a convenience feature. Three of the four traps — the tier cliff, the free-look clawback, and the underwriting variation — are structural rather than behavioural: the payment schedule punishes or rewards the agent regardless of how well they act.
- Free-look cancellation is usually a full clawback — selling a policy the client will cancel in two weeks is net negative for the agent before any compliance question arises.
- Renewal commission is a retention strategy. Needs-led advice is both the compliant choice and the materially larger ten-year financial choice; make that argument to an agent under income pressure, because it is true.
- Tied agents have a compliance officer; IFAs do not. In the independent structure you own suitability, disclosure and record-keeping personally.
- The Code of Conduct is visible in the POS — disclosure, not misleading, suitability, fair treatment and record-keeping each map to a specific screen.
- Three fields make advice reconstructable: the
rejectedReasonfor every product not recommended, thereasonLinkedToNeedfor the one that was, and theexclusionsDiscussedlist. - Compliance records must be structurally undeletable, and an unexplained action is an
unperformed one. A
deletedAtcolumn on a compliance table is a schema defect, not a feature. A blankjustificationon an unmatched payment equals not performing the check — explaining why you did the thing is the substance of the AML obligation. - The CRM's job after
POLICY_IN_FORCEis the annual review, not the next sale. A client contacted before their circumstances change is a client who does not leave. Every blocking compliance control in this module maps to an earlier lesson, which is why this lesson is the capstone rather than an appendix.