Skip to main content

Semantic Library

The Semantic Library extension records the controls that govern what an AI system may say, assert, recommend or emit, and ties each one to the obligation it enforces and the part of the business it applies to. It has two record types:

  • Obligation: a requirement captured at clause level from its governing source: a statute, prudential standard, regulatory guidance, industry code, contract, clinical standard or internal policy.
  • Semantic constraint: a typed, governed constraint on AI output, with the obligations it enforces, the enforcement tier it is routed to and why, its stewardship and lifecycle, and the calibration or conformance evidence for its tier.

Schemas: obligation.schema.json, semantic-constraint.schema.json
Specification: JSON Schema Draft-07

Why it belongs in the metamodel​

Authoring a single constraint well is a technical problem. Keeping a library of them coherent is a governance problem, and most of what it needs is context the metamodel already describes:

The library needsThe metamodel provides
A faceted taxonomy to author against, so a constraint is written once and applied in many contextsTyped domains and the shared, versioned vocabulary in common.schema.json
Traceability from source clause to control to evidenceObligation records, linked from each constraint's obligationMappings
An inventory of AI use cases, with ownersModel Risk Management model profiles, referenced by governedModelIDs
Where AI output reaches customersChannels, services, products and value-stream stages, referenced by appliesTo
Who owns, writes and approves each controlOrganization units and roles, in stewardship
A record of why the library changedTriggers whose affectedEntities name the changed obligations
Coverage of obligations by controlsCoverage expectations and status by domain

The extension does not hold the semantic machinery itself. Reference vectors, projections and thresholds are produced by the authoring method and stored as artifacts; the record keeps references to them, the model they were calibrated for, and the evidence that they passed validation.

Routing a constraint to a tier​

Every constraint is routed to one enforcement tier, and the reason is recorded in tierRationale:

Tier (enforcementTier)Use whenExample
rulesTierCompliance can be decided from the form of the output aloneThe response must contain the approved warning; the output must validate against a JSON Schema
semanticTierCompliance depends on what the output means; two outputs with identical form can differIs this general or personal advice? Is this sustainability claim substantiated?
humanAdjudicationCompliance needs facts outside the output, or is genuinely contestedIs this recommendation in the member's best interests?

When a requirement has a part decidable by form and a part that depends on meaning, split it into two constraints and link them with splitFromConstraintID, so the residual is visible rather than lost. The worked example below does this.

Obligation​

AttributeTypeDescriptionRequired
obligationIDStringUnique identifier for the obligation, e.g. OBL-001✓
titleStringShort name of the obligation✓
statementStringThe obligation in plain language: what must or must not be done✓
obligationTypeEnumKind of source the obligation comes from. recognisedStandard = a published standard or framework from a standards body (for example ISO/IEC 42001 or the NIST AI RMF): statutory, prudentialStandard, regulatoryGuidance, industryCode, recognisedStandard, contractual, clinicalStandard, internalPolicy, other✓
sourceObjectThe governing source, cited precisely enough to find the clause✓
source.authorityStringBody that issues or enforces the source, e.g. Parliament, APRA, ASIC, a standards body, the organization itself (required)
source.instrumentStringThe instrument, e.g. Corporations Act 2001 (Cth), CPS 230, RG 271, an internal policy (required)
source.citationStringSection, paragraph or clause, e.g. s766B(3) (required)
source.instrumentVersionStringVersion, compilation or amendment of the instrument the obligation was captured from
source.urlStringLink to the authoritative text
source.externalOrgIDStringExternal Organization record for the authority, when one exists
source.provisionStringShort heading of the provision cited, e.g. 'Material service providers'
jurisdictionStringJurisdiction in which the obligation applies, e.g. AU
sourceTierEnumTier of the source the obligation comes from: binding (law or prudential standard in force), expected (regulator expectation, guidance or recognised standard) or anticipated (made but not yet in force, under consultation, or a pending bill). Describes the source only: binding, expected, anticipated
tierBasisArray[Object]Other obligations this one rests on, with their tiers. Lets a record carry a second tier, as when a regulator's expectation rests on a binding standard
tierBasis[].obligationIDStringThe obligation relied on (required)
tierBasis[].sourceTierEnumTier of that obligation's source: binding, expected, anticipated (required)
tierBasis[].noteStringHow the one rests on the other
entityTypesArray[Enum]Kinds of entity the source is addressed to: authorisedDepositTakingInstitution, generalInsurer, lifeInsurer, privateHealthInsurer, superannuationTrustee, financialServicesLicensee, creditLicensee, listedEntity, bank, insurer, capitalMarketsIntermediary, paymentServiceProvider, financialInstitution, anyOrganization, other
rolesArray[Enum]Roles within an entity or an AI value chain that the source addresses: regulatedEntity, board, seniorManagement, accountablePerson, provider, deployer, serviceProvider, importer, distributor
useCaseIDsArray[String]Standardised AI use cases (Use Case records) the obligation may reach
effectiveDateDateDate from which the obligation applies
effectiveDatesArray[Object]Key dates for the source and the provisions it contains, such as when it was made, when it commences, when particular provisions apply, or when a consultation closes. effectiveDate keeps the main date
effectiveDates[].dateTypeEnumWhat the date marks: made, published, commences, applies, transitionEnds, consultationOpens, consultationCloses, reviewDue, repealed (required)
effectiveDates[].dateDateThe date (required)
effectiveDates[].provisionsStringProvisions the date applies to, when not the whole instrument, e.g. 'sections 5-6'
effectiveDates[].noteStringContext for the date
statusEnumWhether the obligation currently applies: proposed, pending, inForce, amended, superseded, repealed, withdrawn✓
supersededByObligationIDStringThe obligation that replaces this one, when status is superseded or amended
appliesToArray[Object]Context the obligation applies to: products, services, channels, customer segments, value streams, capabilities or organization units
appliesTo[].domainTypeEnumDomain of the referenced entity, from the shared domain list (domainType in common.schema.json) (required)
appliesTo[].entityIDStringUnique identifier of a record within its domain, for example "CAP-001" or "MKT-ENTSW-001" (required)
appliesTo[].titleStringName of the referenced entity, for readability
implementingPolicyIDsArray[String]Internal policies (Policy domain) that implement the obligation
orgUnitTitleStringOrganization unit accountable for meeting the obligation
orgUnitIDStringID of the organization unit named in orgUnitTitle
accountablePersonStringNamed role personally accountable for the obligation, e.g. an accountable person under an accountability regime
riskLevelEnumConsequence of failing the obligation: low, medium, high, critical
complianceStatusEnumCurrent assessed compliance with the obligation: compliant, partiallyCompliant, nonCompliant, underReview, exempt, notApplicable
relatedObligationIDsArray[String]Obligations that overlap with or depend on this one
monitoringFrequencyEnumHow often the source is watched for change: continuous, realTime, hourly, daily, weekly, monthly, quarterly, semiAnnually, annually, eventDriven, onDemand, adHoc
lastReviewDateDateDate the obligation was last checked against its source
lastVerifiedDateDate the record was last checked against the official text by its publisher. Unlike lastReviewDate, which is the organization's own review, this is the date a reference dataset confirmed the record
provenanceRecordIDsArray[String]Provenance records, issued through the governance interface, that trace how this record was sourced, extracted, reconciled and approved

An obligation that is superseded or amended must name its successor in supersededByObligationID. A binding obligation cannot be proposed, pending or withdrawn, and an anticipated one cannot be inForce, amended or repealed.

Obligations as a reference dataset​

Obligations can also be published as a reference dataset, such as a register of AI governance obligations by jurisdiction. In that use each record carries a source tier, the entity types, roles and standardised use cases it may reach, its key dates, and when its publisher last verified it against the official text. The records can be governed through the governance interface, which adds provenance and a named approver to every change of status, date or tier.

Source Tier (sourceTier)​

A tier describes the source, never the position of anyone the source might apply to. It does not say that an organization is compliant or in breach, that it must meet the source, or that an anticipated source will apply.

ValueSourceExamples
bindingLaw or prudential standard in forceA prudential standard's paragraphs on material service providers; EU AI Act provisions already applying
expectedRegulator expectations, guidance and recognised standardsA regulator's letter setting minimum expectations; ISO/IEC 42001; NIST AI RMF
anticipatedMade but not yet in force, under consultation, or a pending billGuidelines whose later sections apply from a future date; EU AI Act provisions with later start dates

A record can carry a second tier through tierBasis, where an expectation rests on a binding standard: a regulator's expectation about board risk appetite, for example, resting on the risk management and operational risk standards.

Semantic Constraint​

AttributeTypeDescriptionRequired
semanticConstraintIDStringUnique identifier for the constraint, e.g. SC-001✓
titleStringShort name of the constraint✓
statementStringThe constraint in plain language, as an approver would read it✓
constraintTypeEnumKind of constraint: prohibition, boundedRange, requiredProperty, structuralForm, closedVocabulary, gradedSeverity✓
obligationMappingsArray[Object]Obligations the constraint enforces✓
obligationMappings[].obligationIDStringThe obligation enforced (required)
obligationMappings[].mappingRoleEnumWhether this constraint is the obligation's primary control or supports another: primary, supporting (required)
obligationMappings[].noteStringHow the constraint covers the obligation, and any part it leaves to other controls
enforcementTierEnumTier the constraint is enforced in: rulesTier, semanticTier, humanAdjudication✓
tierRationaleStringWhy the constraint is routed to this tier: whether compliance is decidable from form, depends on meaning, or needs facts or judgement outside the output✓
splitFromConstraintIDStringWhen a requirement was split across tiers, the constraint holding the other part
appliesToArray[Object]Business context the constraint governs: products, services, channels, customer segments, value streams or capabilities. Constraints are authored against one distinction with this context as metadata, not re-authored per context.
appliesTo[].domainTypeEnumDomain of the referenced entity, from the shared domain list (domainType in common.schema.json) (required)
appliesTo[].entityIDStringUnique identifier of a record within its domain, for example "CAP-001" or "MKT-ENTSW-001" (required)
appliesTo[].titleStringName of the referenced entity, for readability
governedModelIDsArray[String]AI systems the constraint governs, as Model Risk Management model profiles (the AI use-case inventory)
severityScaleArray[Object]Graded-severity ladder, lowest first; required for gradedSeverity constraints
severityScale[].levelIntegerPosition on the ladder; higher is more severe (required)
severityScale[].labelStringShort name of the level (required)
severityScale[].descriptionStringWhat a statement at this level does, with the distinction from the level below (required)
severityScale[].dispositionEnumWhat happens to a statement at this level: allow, allowWithControl, escalate, block
contestedDispositionEnumWhat the constraint does in a contested or uncertain region: enforce, abstainAndEscalate, advisoryOnly
exemplarSetsArray[Object]Curated example sets the constraint is authored, calibrated and regression-tested from
exemplarSets[].exemplarSetIDStringUnique identifier for the exemplar set (required)
exemplarSets[].setTypeEnumRole of the set: canonical, adversarial, calibration, regression, mustAccept, mustReject (required)
exemplarSets[].itemCountIntegerNumber of labelled items in the set
exemplarSets[].versionStringVersion of the set
exemplarSets[].locationStringWhere the set is stored, e.g. a repository path or URI (required)
exemplarSets[].provenanceStringWhere the items came from: source clauses, adjudicated incidents, promoted novel cases, red-team runs
semanticEnvelopeObjectCalibration and validation record for a semantic-tier constraint. Records references to artifacts, not the vectors themselves.
semanticEnvelope.embeddingModelObjectThe exact model a calibration is valid for (required)
semanticEnvelope.embeddingModel.modelNameStringName of the embedding model (required)
semanticEnvelope.embeddingModel.modelVersionStringVersion identifier of the embedding model (required)
semanticEnvelope.embeddingModel.modelHashStringWeight or version hash, where the model can be attested
semanticEnvelope.methodologyVersionStringAuthoring methodology and version the envelope was validated under, e.g. PACE 2.0 (required)
semanticEnvelope.divergenceMetricEnumDivergence measure between the reference and the governed output: cosine, euclidean, mahalanobis, klDivergence, jensenShannon (required)
semanticEnvelope.thresholdNumberCalibrated divergence threshold above which the constraint fires (required)
semanticEnvelope.alphaNumberConformal significance level the threshold was calibrated to (target error rate) (required)
semanticEnvelope.calibrationDateDateDate the threshold was last calibrated (required)
semanticEnvelope.referenceArtifactStringLocation and hash of the reference vector and projection artifacts
semanticEnvelope.validationObjectResult of the constraint validation harness, the ship gate for publication
semanticEnvelope.validation.validatedDateDateDate the harness was run (required)
semanticEnvelope.validation.passedBooleanWhether the constraint cleared every registered floor (required)
semanticEnvelope.validation.separationAUCNumberSeparation of compliant from non-compliant exemplars
semanticEnvelope.validation.recallNumberRecall at the operating point
semanticEnvelope.validation.falsePositiveRateNumberFalse positive rate at the operating point
semanticEnvelope.validation.monotonicityPassedBooleanWhether divergence increases with authored severity
semanticEnvelope.validation.beatsBaselineBooleanWhether the constraint outperforms the registered baseline
semanticEnvelope.validation.shiftRobustnessPassedBooleanWhether performance held under the distribution-shift test
semanticEnvelope.validation.leakagePassedBooleanWhether the leakage check found no concept leakage
semanticEnvelope.validation.evidenceLocationStringWhere the harness evidence pack is stored
grammarArtifactObjectSpecification and conformance record for a rules-tier constraint
grammarArtifact.formalismEnumFormalism the rule is expressed in: jsonSchema, regularExpression, contextFreeGrammar, closedVocabulary, other (required)
grammarArtifact.artifactLocationStringWhere the grammar, schema or vocabulary is stored (required)
grammarArtifact.artifactVersionStringVersion of the grammar artifact
grammarArtifact.compiledArtifactHashStringHash of the compiled automaton or enforcement artifact
grammarArtifact.methodologyVersionStringAuthoring methodology and version, e.g. GRACE 0.1 (required)
grammarArtifact.conformanceObjectResult of the conformance harness, the ship gate for publication
grammarArtifact.conformance.validatedDateDateDate the harness was run (required)
grammarArtifact.conformance.passedBooleanWhether the grammar cleared every registered floor (required)
grammarArtifact.conformance.mustAcceptPassRateNumberShare of must-accept items accepted
grammarArtifact.conformance.mustRejectAcceptancesIntegerMust-reject items wrongly accepted (the gate requires zero)
grammarArtifact.conformance.mutationKillRateNumberShare of grammar mutants the corpus detects
grammarArtifact.conformance.evidenceLocationStringWhere the harness evidence pack is stored
stewardshipObjectWho owns, writes, calibrates and approves the constraint. The author and approver must be different people (separation of duties).✓
stewardship.policyOwnerStringAccountable for the intent the constraint enforces (required)
stewardship.policyOwnerOrgUnitIDStringOrganization unit of the policy owner
stewardship.authorStringSemantic librarian or constraint engineer who drafted the constraint (required)
stewardship.calibratorStringPerson who set and validated the threshold (semantic tier)
stewardship.approverStringEditorial board member or delegate who approved publication; not the author
stewardship.approvalDateDateDate the current version was approved
monitoringObjectHow the constraint is watched once published, and what prompts a review
monitoring.monitoringFrequencyEnumHow often coverage and drift are reviewed: continuous, realTime, hourly, daily, weekly, monthly, quarterly, semiAnnually, annually, eventDriven, onDemand, adHoc
monitoring.coverageFloorNumberRegistered minimum coverage; falling below it triggers recalibration
monitoring.reviewTriggersArray[Enum]Events that put the constraint back through review: coverageDegradation, guaranteeInvalidation, suspectedLeakage, obligationChange, modelChange, novelCasePromotion, incidentAdjudication, scheduledReview
monitoring.lastReviewDateDateDate of the last review
statusEnumLifecycle state. Constraints are never deleted or edited in place: a constraint that no longer reflects its obligation is deprecated with a pointer to its successor: draft, validated, published, deprecated, inactivated✓
versionStringSemantic version of the constraint✓
supersededByConstraintIDStringSuccessor constraint; required when deprecated. An inactivated constraint (e.g. its obligation was repealed) may have none.
relatedConstraintIDsArray[String]Constraints that overlap with or complement this one; overlaps are reviewed so each obligation has one primary constraint

Rules the schema enforces​

  • Every constraint maps to at least one obligation.
  • A gradedSeverity constraint has a severityScale of at least two levels.
  • A semanticTier constraint has exemplarSets; once validated or published it has a semanticEnvelope with its harness validation result.
  • A rulesTier constraint has a grammarArtifact; once validated or published it has its conformance result.
  • A published constraint names its approver and approvalDate.
  • A deprecated constraint names its successor in supersededByConstraintID. Constraints are never deleted or edited in place.

Separation of duties (the approver is not the author) cannot be expressed in JSON Schema; check it in the approval workflow.

Worked example: the advice boundary​

A superannuation fund's member-services assistant may give factual information and general advice, but its chat channel is not authorised to give personal advice. All names, numbers and dates are illustrative; no calibration has been run, and the obligation statements summarise the cited provisions for the example, not as legal advice. The full example, with a model profile for the assistant, is in the repository: examples/semantic-library-advice-boundary.md.

Obligations​

{
"obligationID": "OBL-001",
"title": "No personal advice through unauthorised member channels",
"statement": "Member channels operating without a personal-advice authorisation must not give personal advice: a recommendation or opinion that takes into account the member's objectives, financial situation or needs.",
"obligationType": "statutory",
"source": {
"authority": "Commonwealth Parliament; administered by ASIC",
"instrument": "Corporations Act 2001 (Cth)",
"citation": "s766B(3) (personal advice); s911A (need for a licence)",
"url": "https://www.legislation.gov.au/C2004A00818/latest"
},
"jurisdiction": "AU",
"status": "inForce",
"appliesTo": [
{ "domainType": "channel", "entityID": "CH-MEMBER-CHAT", "title": "Member services chat" },
{ "domainType": "product", "entityID": "PROD-ACCUM", "title": "Accumulation account" }
],
"implementingPolicyIDs": ["POL-ADVICE-001"],
"orgUnitTitle": "Member Advice",
"orgUnitID": "OU-ADVICE",
"accountablePerson": "Chief Member Officer (accountable person)",
"riskLevel": "critical",
"complianceStatus": "underReview",
"relatedObligationIDs": ["OBL-002"],
"monitoringFrequency": "monthly",
"lastReviewDate": "2026-10-01"
}
{
"obligationID": "OBL-002",
"title": "General advice warning",
"statement": "When general advice is given to a retail client, warn the client that the advice does not take into account their objectives, financial situation or needs.",
"obligationType": "statutory",
"source": {
"authority": "Commonwealth Parliament; administered by ASIC",
"instrument": "Corporations Act 2001 (Cth)",
"citation": "s949A"
},
"jurisdiction": "AU",
"status": "inForce",
"appliesTo": [
{ "domainType": "channel", "entityID": "CH-MEMBER-CHAT", "title": "Member services chat" }
],
"implementingPolicyIDs": ["POL-ADVICE-001"],
"orgUnitTitle": "Member Advice",
"orgUnitID": "OU-ADVICE",
"riskLevel": "high",
"relatedObligationIDs": ["OBL-001"]
}

The advice-boundary constraint (semantic tier)​

A graded-severity constraint: factual information is allowed, general advice is allowed with the warning, borderline responses escalate to a person, and personal advice is blocked.

{
"semanticConstraintID": "SC-001",
"title": "Advice boundary for member chat",
"statement": "The member services assistant must not make a recommendation or state an opinion that takes into account the member's objectives, financial situation or needs.",
"constraintType": "gradedSeverity",
"obligationMappings": [
{ "obligationID": "OBL-001", "mappingRole": "primary" }
],
"enforcementTier": "semanticTier",
"tierRationale": "Whether a response is personal advice depends on its meaning: two responses with identical form can differ in whether they consider the member's circumstances. A keyword list would be evaded by paraphrase.",
"appliesTo": [
{ "domainType": "channel", "entityID": "CH-MEMBER-CHAT", "title": "Member services chat" },
{ "domainType": "valueStream", "entityID": "VS-MEMBER-ENQ", "title": "Resolve member enquiry" }
],
"governedModelIDs": ["MODEL-CHAT-001"],
"severityScale": [
{ "level": 0, "label": "Factual information", "description": "States facts about the fund, products or rules without recommending anything", "disposition": "allow" },
{ "level": 1, "label": "General advice", "description": "Recommends or gives an opinion without reference to the member's own circumstances", "disposition": "allowWithControl" },
{ "level": 2, "label": "Borderline", "description": "General advice framed around details the member has shared, where it is unclear whether their circumstances were taken into account", "disposition": "escalate" },
{ "level": 3, "label": "Personal advice", "description": "Recommends a course of action for this member based on their objectives, financial situation or needs", "disposition": "block" }
],
"contestedDisposition": "abstainAndEscalate",
"exemplarSets": [
{ "exemplarSetID": "EXS-001-CAN", "setType": "canonical", "itemCount": 240, "version": "1.0", "location": "library/advice-boundary/canonical", "provenance": "Written by the advice team against s766B and the fund's advice policy; each item labelled with a severity level" },
{ "exemplarSetID": "EXS-001-ADV", "setType": "adversarial", "itemCount": 600, "version": "1.0", "location": "library/advice-boundary/adversarial", "provenance": "Paraphrase red-team runs" },
{ "exemplarSetID": "EXS-001-CAL", "setType": "calibration", "itemCount": 1500, "version": "1.0", "location": "library/advice-boundary/calibration", "provenance": "Labelled sample of historical chat transcripts" }
],
"semanticEnvelope": {
"embeddingModel": { "modelName": "example-embedding-model", "modelVersion": "2026-06" },
"methodologyVersion": "PACE 2.0",
"divergenceMetric": "cosine",
"threshold": 0.31,
"alpha": 0.05,
"calibrationDate": "2026-10-15",
"validation": {
"validatedDate": "2026-10-16",
"passed": true,
"separationAUC": 0.94,
"recall": 0.95,
"falsePositiveRate": 0.04,
"monotonicityPassed": true,
"beatsBaseline": true,
"shiftRobustnessPassed": true,
"leakagePassed": true,
"evidenceLocation": "library/advice-boundary/evidence/2026-10-16"
}
},
"stewardship": {
"policyOwner": "Head of Advice",
"policyOwnerOrgUnitID": "OU-ADVICE",
"author": "Semantic librarian, Member Advice",
"calibrator": "Model validation analyst",
"approver": "Editorial board chair"
},
"monitoring": {
"monitoringFrequency": "weekly",
"coverageFloor": 0.95,
"reviewTriggers": ["coverageDegradation", "guaranteeInvalidation", "suspectedLeakage", "obligationChange", "modelChange", "novelCasePromotion", "incidentAdjudication"]
},
"status": "validated",
"version": "1.0.0",
"relatedConstraintIDs": ["SC-002"]
}

The general advice warning (rules tier)​

The other half of the split: once a response is classified as general advice, whether it carries the approved warning is decidable from the text.

{
"semanticConstraintID": "SC-002",
"title": "General advice warning present",
"statement": "A response classified as general advice must include the fund's approved general advice warning.",
"constraintType": "requiredProperty",
"obligationMappings": [
{ "obligationID": "OBL-002", "mappingRole": "primary" }
],
"enforcementTier": "rulesTier",
"tierRationale": "Once the response is classified as general advice, the presence of the approved warning is decidable from the text alone.",
"splitFromConstraintID": "SC-001",
"appliesTo": [
{ "domainType": "channel", "entityID": "CH-MEMBER-CHAT", "title": "Member services chat" }
],
"governedModelIDs": ["MODEL-CHAT-001"],
"exemplarSets": [
{ "exemplarSetID": "EXS-002-ACC", "setType": "mustAccept", "itemCount": 120, "location": "library/general-advice-warning/must-accept", "provenance": "Approved warning wordings in context" },
{ "exemplarSetID": "EXS-002-REJ", "setType": "mustReject", "itemCount": 80, "location": "library/general-advice-warning/must-reject", "provenance": "Truncated, reworded and missing warnings" }
],
"grammarArtifact": {
"formalism": "regularExpression",
"artifactLocation": "library/general-advice-warning/warning.regex",
"artifactVersion": "0.1",
"methodologyVersion": "GRACE 0.1"
},
"stewardship": {
"policyOwner": "Head of Advice",
"policyOwnerOrgUnitID": "OU-ADVICE",
"author": "Semantic librarian, Member Advice"
},
"status": "draft",
"version": "0.1.0",
"relatedConstraintIDs": ["SC-001"]
}

When a source changes​

A trigger records the change; its affectedEntities name the obligations, and the constraints that map to them are reviewed.

{
"triggerID": "TRG-101",
"label": "Regulator updates guidance on general and personal advice",
"description": "Updated regulatory guidance changes the examples of where general advice becomes personal advice in digital channels",
"primaryCategory": "regulatoryCompliance",
"subCategory": "Advice guidance",
"origin": "External",
"timeHorizon": "shortTerm",
"impactLevel": "high",
"detectionMethod": "Regulatory watch",
"detectionDate": "2026-10-20",
"affectedEntities": [
{ "domainType": "obligation", "entityID": "OBL-001", "title": "No personal advice through unauthorised member channels" },
{ "domainType": "obligation", "entityID": "OBL-002", "title": "General advice warning" }
]
}