CompoundWise · governance

Strategy Advisor — what it measures, what it approximates, what it has not validated

Written for a reader who will test each number against the convention it is named for. Built from the model register, so it describes the engine that ships; the built-from stamp in this page's source is checked against the register in CI.

This is an analytics tool, not investment advice. It does not know your whole financial picture unless you enter it, it makes no suitability determination in the regulatory sense, and no recommendation it produces has a validated forward track record. Read it as a second opinion with its working shown.

Against the CFA Institute Standards of Professional Conduct

Each line names the mechanism a reader can check. NOT YET is written where it is true.

StandardWhat the advisor doesWhere to check
I.C MisrepresentationEvery published figure names its coverage and its basis. Unknown inputs are never substituted with a plausible number; a sector the vendor does not describe is reported as unclassified, never as a sector.signal_engine.GUARDED_INPUTS; advisor_engine._sector_or_none; tests/invariants/test_advisor_absence_invariants.py, test_fund_lookthrough_invariants.py
III.C SuitabilityA minimum profile set is scored before a plan is more than a draft. Below it, every action is marked review-only, loses its timing and names the missing fields. Declared constraints (drawdown, exclusions, liquidity, objective) narrow the plan; a proposal is never widened. This is an analytics analogue of a determination, not a regulatory determination.advisor_engine.MINIMUM_SUITABILITY_FIELDS, _suitability_completeness, _suitability_gate; tests/invariants/test_advisor_suitability_completeness_invariants.py, test_advisor_suitability_invariants.py
III.C Suitability — allocation policyA declared investment policy is the first lens and a breach is the first action. With no policy on file the questionnaire's mix is shown as a PROPOSAL awaiting acceptance; drift is never measured against it. A breach names EVERY class outside the band, not only the largest, and states the trade in DOLLARS: the over-weighted class and the under-weighted one are a single trade, and naming one side leaves half an instruction. Every class moves to the target the client declared, so the legs balance. The funding split is reported because it decides the cost - money moved out of cash is not a disposition and realises nothing, while selling equity or bonds realises a gain or loss in a non-registered account. The TAX ITSELF IS NOT ESTIMATED: it depends on which lots in which accounts are sold, which this path is not given, so an unknown stays unknown (I.C). Nothing is executed - the report proposes and the client acts. Rebalancing to a policy the client declared is arithmetic, so no claim is made that it improves a return or reduces risk by any figure; none has been validated (V.A).advisor_engine._ips_drift, _policy_rebalance_trade, _enforce_policy_first, _proposed_policy_from_questionnaire; tests/invariants/test_advisor_ips_drift_invariants.py, test_policy_rebalance_invariants.py, test_goal_feasibility_invariants.py
V.A Diligence and Reasonable BasisNOT YET. No recommendation, score or diversifier pick has a graded out-of-sample record. Picks are logged with entry price and distance from the 52-week high; the grader abstains until a cohort matures. Nothing may describe the output as validated, backtested or predictive until it does.advisor_picks table; scripts/advisor_pick_track_record.py; scripts/deep_score_track_record.py (UNCERTIFIED)
V.A — goal feasibilityA goal is measured against the expected return of the policy mix on FP Canada's 2026 Projection Assumption Guidelines, net of the book's fund MER and any declared advisory fee when every fund's MER is on file and labelled gross (with the reason) when not, with a seeded probability of success; a shortfall is answered with the client's levers — contribution, horizon, target — never with more risk.retirement_sim.PAG_REAL_RETURN_PCT, PAG_INFLATION_PCT, return_basis, goal_success_probability; advisor_engine.book_fund_costs, _goal_feasibility; tests/invariants/test_goal_feasibility_invariants.py, test_plan_net_of_fees.py
V.B Communication with ClientsFact and opinion are separated: engine figures are reconciled against the written narrative and a mismatch is disclosed; a constraint inferred from the questionnaire is labelled as such beside one the client declared; the AI-unavailable state is a visible banner, never a silent stub.advisor_engine._validate_narrative, _figure_mismatches, investor_profile._provenance; tests/invariants/test_advisor_narrative_validation_invariants.py, test_risk_questionnaire_reaches_the_advisor.py
V.B — what a recommendation rests onTwo dependences are disclosed by the ENGINE, after the model has written, so the model whose output they qualify cannot omit them. (1) Where a recommended single name owes more of its Deep Score to the Growth pillar than an evenly-scoring name would - above the pillar's own weight share of 25% - that share is stated in the recommendation itself, together with the finding that long-term earnings growth has shown no persistence beyond chance (Chan, Karceski & Lakonishok 2003) and that the fastest-growing names have historically underperformed over five years (Lakonishok, Shleifer & Vishny 1994). The text says screen, not forecast: no forward claim is made, because none has been validated (V.A above). (2) The share of the portfolio held as individual securities rather than funds is stated against the 20% default budget, with its basis (Bessembinder 2018; Statman 1987; Domian, Louton & Racine 2007). NEITHER CHANGES A PICK, A RANK OR A SIZE, and the single-name budget is disclosed, not enforced - no trade is blocked and no plan rejected for exceeding it.advisor_engine._apply_engine_disclosures, _disclose_growth_pillar_dependence, _CANDIDATE_FIELDS; intel_agent._growth_pillar_share; strategy_report._single_name_note, _SINGLE_NAME_BUDGET_PCT; tests/invariants/test_growth_and_concentration_disclosure.py
V.A - what a diversification claim rests onA single name is RESEARCH and carries no position size. Each one states the basis for calling it a diversifier: the screen selects candidates OUTSIDE the client's overweight sectors, which is a real basis and a weak one - two different sectors can move together closely. Where enough price history exists the report adds the MEASURED change in the portfolio's effective number of independent bets, computed through the same engine the Risk X-Ray uses; measured 2026-09-24, only 4 of 10 live candidates carry enough history, and the other 6 say NOT MEASURED rather than staying silent. A candidate that measurably does NOT diversify is disclosed as such beside the recommendation. The screen is also subject to a SUSPENSION rule: if graded cohorts persistently underperform it stops recommending single names entirely and reverts to allocation-level advice. That rule cannot fire yet - no cohort has been graded - and it reports that state explicitly rather than an all-clear.advisor_engine._disclose_diversification_basis, _diversification_delta, _sleeve_suspension, _apply_sleeve_suspension; risk_data.build_returns_panel; risk_concentration.compute_concentration; tests/invariants/test_diversification_basis.py, test_sleeve_suspension.py
V.C Record RetentionEvery report is stored with its prompt version and model id; every scan date carries the git SHA that produced it, so a changed number can be attributed to the code or to the data.advisor_engine._prompt_version; scanner.record_scan_provenance; scripts/scan_lineage.py
VI.A Disclosure of ConflictsThe platform holds no positions, earns no commission on any action and is paid only by subscription; AI generation cost is shown to the user before each run.web/components/instrument/ai/DisclosureFooter.tsx; the access/spend confirmation flow

Measured · proxy · unvalidated

Measured

Proxy

Unvalidated

From the model register — limitations, monitoring, validation

Strategy Advisor — signal rule engine v1.3.0 · reviewed 2026-10-01

monitoring: NOT MONITORED · metric: forward outcome of TRIM/SELL signals

validated by: tests/invariants/test_advisor_signal_invariants.py + test_advisor_absence_invariants.py — soft-reason tax guard, verdict never silence, tax always stated, one decider, unknown is never a number

Strategy Advisor — orchestration, suitability, tax allocation, AI validation v1.16.0 · reviewed 2026-10-06

monitoring: LOGGING — picks recorded since 2026-09-10, none matured; not yet graded · metric: forward return of diversifier picks vs SPY, by cohort · log: advisor_picks

validated by: tests/invariants/test_advisor_*.py, test_fund_lookthrough_invariants.py, test_stress_replay_invariants.py, test_risk_questionnaire_reaches_the_advisor.py, test_growth_and_concentration_disclosure.py — absence never a number, registered-first allocation, AI figures reconciled to the engine, fund fold-through on both spellings of absence, and the two engine-enforced disclosures: the threshold is the pillar's own weight share, an unmeasured share is silence and never 0%, the candidate whitelist carries the measurement through to the report, and no disclosure makes a forward claim the score has not been validated for (CFA V.A), each proven red by 16 entries in tests/parity/test_gate_injections.py

CompoundWise internal · not investment advice · generated from data/model_register.json (register 2.0.0, 2026-09-23).