@1aboveio/skills 0.20.1 → 0.20.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -5
- package/package.json +1 -1
- package/runtime/skills/distribution/generated/recipes.json +220 -25
- package/runtime/skills/distribution/scripts/bundles.mjs +49 -5
- package/runtime/skills/engineering/engineering-runtime/scripts/workflow-coherence.mjs +4 -0
- package/runtime/skills/engineering/engineering-runtime/scripts/workflow-policy.mjs +1 -1
- package/skills/cicd-pipeline/cloud-build/SKILL.md +6 -6
- package/skills/compliance/compliance-audit/LICENSE +3 -0
- package/skills/compliance/compliance-audit/SKILL.md +466 -0
- package/skills/compliance/compliance-audit/references/findings-schema.md +290 -0
- package/skills/compliance/compliance-audit/references/vars-checklist.md +1068 -0
- package/skills/compliance/compliance-audit/references/vars-findings-schema.md +395 -0
- package/skills/compliance/compliance-audit/scripts/reconcile_tracker.py +454 -0
- package/skills/compliance/compliance-audit/scripts/test_validate_tracker.py +90 -0
- package/skills/compliance/compliance-audit/scripts/validate_tracker.py +752 -0
- package/skills/compliance/doc-authenticity/LICENSE +3 -0
- package/skills/compliance/doc-authenticity/SKILL.md +158 -0
- package/skills/compliance/doc-authenticity/references/agreement.md +66 -0
- package/skills/compliance/doc-authenticity/references/bank-statement.md +150 -0
- package/skills/compliance/doc-authenticity/references/forensic-signals.md +157 -0
- package/skills/compliance/doc-authenticity/references/image-signals.md +114 -0
- package/skills/compliance/doc-authenticity/references/invoice.md +66 -0
- package/skills/compliance/doc-authenticity/references/issuer-profiles.md +86 -0
- package/skills/compliance/doc-authenticity/references/verdict-and-report.md +95 -0
- package/skills/compliance/doc-authenticity/references/verdict.schema.json +81 -0
- package/skills/compliance/doc-authenticity/scripts/image_forensics.py +294 -0
- package/skills/compliance/doc-authenticity/scripts/pdf_forensics.py +401 -0
- package/skills/compliance/doc-authenticity/scripts/validate_codes.py +224 -0
- package/skills/compliance/doc-authenticity/scripts/validate_verdict.py +308 -0
- package/skills/compliance/report-writing/LICENSE +3 -0
- package/skills/compliance/report-writing/SKILL.md +206 -0
- package/skills/compliance/report-writing/references/audit-report-template.md +121 -0
- package/skills/compliance/report-writing/references/external-assessment-template.md +167 -0
- package/skills/compliance/report-writing/references/management-report-template.md +145 -0
- package/skills/compliance/report-writing/references/vars-report-template.md +224 -0
- package/skills/document-utils/doc-to-md/LICENSE +3 -0
- package/skills/document-utils/doc-to-md/SKILL.md +77 -0
- package/skills/document-utils/doc-to-md/scripts/convert.py +157 -0
- package/skills/document-utils/reg-parser/LICENSE +3 -0
- package/skills/document-utils/reg-parser/SKILL.md +201 -0
- package/skills/document-utils/reg-parser/references/checklist-schema.md +223 -0
- package/skills/document-utils/reg-parser/references/checklists/hk-amlo-checklist.json +1306 -0
- package/skills/document-utils/reg-parser/references/checklists/hk-amlo-checklist.md +469 -0
- package/skills/document-utils/reg-parser/references/checklists/hk-fi-corporate-onboarding-cdd-checklist.json +634 -0
- package/skills/document-utils/reg-parser/references/checklists/hk-fi-corporate-onboarding-cdd-checklist.md +233 -0
- package/skills/document-utils/reg-parser/references/checklists/hk-mso-guideline-checklist.json +2194 -0
- package/skills/document-utils/reg-parser/references/checklists/hk-mso-guideline-checklist.md +771 -0
- package/skills/document-utils/reg-parser/references/checklists/kyc-aml-checklist.md +258 -0
- package/skills/document-utils/reg-parser/references/checklists/visa-vars-checklist.md +1058 -0
- package/skills/document-utils/reg-parser/references/mandates/hk-amlo-cap615.md +389 -0
- package/skills/document-utils/reg-parser/references/mandates/visa-vars.md +205 -0
- package/skills/document-utils/reg-parser/scripts/compare_checklist.py +228 -0
- package/skills/document-utils/reg-parser/scripts/dump_checklist.py +348 -0
- package/skills/document-utils/reg-parser/scripts/preprocess-mandate.sh +171 -0
- package/skills/document-utils/reg-parser/scripts/test_quarantine.sh +102 -0
- package/skills/document-utils/reg-parser/scripts/validate_checklist.py +532 -0
- package/skills/document-utils/reg-parser/scripts/validate_mandate.py +242 -0
- package/skills/engineering/engineering-runtime/coherence/workflow.json +17 -17
- package/skills/engineering/engineering-runtime/scripts/workflow-coherence.mjs +4 -0
- package/skills/engineering/engineering-runtime/scripts/workflow-policy.mjs +1 -1
- package/skills/engineering/rush-release/SKILL.md +46 -25
- package/skills/engineering/rush-release/references/cut.md +21 -4
- package/skills/engineering/rush-release/references/preflight.md +25 -6
- package/skills/engineering/rush-release/references/promotion.md +70 -0
- package/skills/engineering/rush-release/references/publish.md +49 -16
- package/skills/engineering/rush-release/scripts/plan.mjs +33 -7
- package/skills/engineering/smoke/SKILL.md +4 -4
- package/skills/engineering/smoke/references/manifest.md +3 -3
- package/skills/payment/similar-domain/LICENSE +3 -0
- package/skills/payment/similar-domain/SKILL.md +178 -0
- package/skills/payment/similar-domain/references/entities.md +58 -0
- package/skills/payment/similar-domain/references/fingerprints.md +82 -0
- package/skills/payment/similar-domain/references/pivots.md +66 -0
- package/skills/payment/similar-domain/references/report-template.md +76 -0
- package/skills/payment/similar-domain/references/scoring.md +61 -0
- package/skills/payment/similar-domain/references/terminology.md +37 -0
- package/skills/payment/similar-domain/references/workflow.md +79 -0
- package/skills/payment/tld-detection/SKILL.md +76 -21
- package/skills/payment/tld-detection/references/clean.md +1 -1
- package/skills/payment/tld-detection/references/clustering.md +21 -6
- package/skills/payment/tld-detection/references/decision.md +7 -2
- package/skills/payment/tld-detection/references/fx-conversion.md +229 -0
- package/skills/payment/tld-detection/references/report-template.md +63 -27
- package/skills/payment/tld-detection/references/streams.md +90 -0
- package/skills/payment/tld-detection/references/terminology.md +15 -7
- package/skills/payment/tld-detection/references/workflow.md +1 -1
- package/skills/payment/tld-detection/scripts/detect_streams.py +542 -0
- package/skills/engineering/ensure-coverage/evals/evals.json +0 -125
- package/skills/engineering/rush-issues/evals/evals.json +0 -65
- package/skills/engineering/rush-release/evals/evals.json +0 -44
- package/skills/fullstack/shadcn/evals/evals.json +0 -90
- package/skills/payment/fraud-analysis/evals/evals.json +0 -40
- package/skills/payment/tld-detection/evals/evals.json +0 -107
- package/skills/payment/tld-detection/tests/test_detect_ladders.py +0 -132
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# Fingerprints
|
|
2
|
+
|
|
3
|
+
What to record for each domain, and why each item identifies the people
|
|
4
|
+
behind it rather than the industry it sits in. Record the value, the source
|
|
5
|
+
you read it from, and the time. Categories are ordered by how much they
|
|
6
|
+
usually pay off.
|
|
7
|
+
|
|
8
|
+
## Page and tag fingerprints (strongest)
|
|
9
|
+
|
|
10
|
+
These live inside the served HTML. They are set once by whoever configures
|
|
11
|
+
the site and copied across every site that person manages.
|
|
12
|
+
|
|
13
|
+
| Fingerprint | Why it identifies an operator |
|
|
14
|
+
|---|---|
|
|
15
|
+
| Analytics tokens (Cloudflare Web Analytics, Google Analytics / GTM container, Matomo, Yandex) | One account per operator; sharing it across brands is deliberate |
|
|
16
|
+
| Ad and tracking pixels (Meta, TikTok, Snap, affiliate-network pixels) | Tied to a paying advertiser account |
|
|
17
|
+
| Error-monitoring and session-replay keys (Sentry, Hotjar, Clarity, Smartlook) | Per-project keys from one engineering team |
|
|
18
|
+
| Block-page or error-page template: HTML skeleton, CSS reset, odd literal values (a specific outline colour, a min-width), font stack | A shared codebase; brands change the logo and palette, not the skeleton |
|
|
19
|
+
| Support-address pattern (`support@<brand>`) and the domain it points at | A mirror's support address names the parent brand |
|
|
20
|
+
| Hard-coded partner hosts: CDN paths, API hosts, game or payment providers, chat widgets | Platform vendor and integration account |
|
|
21
|
+
| Favicon and logo asset hashes | Reused assets across mirrors |
|
|
22
|
+
| JavaScript bundle names and hashes | Same build pipeline |
|
|
23
|
+
| Cookie names and consent-banner vendor IDs | Same front-end stack |
|
|
24
|
+
|
|
25
|
+
Distinguish **operator-level** identifiers (analytics account, template)
|
|
26
|
+
from **vendor-level** ones (a game provider, a chat widget). Vendor-level
|
|
27
|
+
identifiers narrow the field but are shared across many unrelated
|
|
28
|
+
operators.
|
|
29
|
+
|
|
30
|
+
## Mail fingerprints (strong)
|
|
31
|
+
|
|
32
|
+
| Fingerprint | Why |
|
|
33
|
+
|---|---|
|
|
34
|
+
| Exact SPF string, including the order of includes | The combination of mail vendors is chosen per operator; a byte-identical string across brands is rarely coincidence |
|
|
35
|
+
| DKIM selectors | Per-sending-account |
|
|
36
|
+
| MX target (Google, Microsoft 365, Zoho, self-hosted) | Splits clusters: an operator rarely runs two mail platforms |
|
|
37
|
+
| Verification TXT records (Microsoft tenant ID, vendor verifications) | Tenant IDs identify one organisation; Google site-verification tokens are per-domain and do not pivot |
|
|
38
|
+
| Mail-related subdomains from certificates (`mailer.`, `click.`, `email.updates.`) | Marketing-mail vendor and its account |
|
|
39
|
+
|
|
40
|
+
## Registration fingerprints (medium to strong)
|
|
41
|
+
|
|
42
|
+
| Fingerprint | Why |
|
|
43
|
+
|---|---|
|
|
44
|
+
| Registrar plus privacy-proxy service | Operators keep one registrar account per portfolio |
|
|
45
|
+
| Creation and last-updated timestamps | Same-hour timestamps across domains mean one batch action |
|
|
46
|
+
| Status-lock set (the exact combination of prohibited flags) | Set by registrar account defaults |
|
|
47
|
+
| Registrant fields when not private (organisation, country, state) | Direct |
|
|
48
|
+
| Expiry alignment | Renewed together |
|
|
49
|
+
|
|
50
|
+
## DNS and hosting fingerprints (medium)
|
|
51
|
+
|
|
52
|
+
| Fingerprint | Why |
|
|
53
|
+
|---|---|
|
|
54
|
+
| Nameserver pair | CDN providers assign pairs per account, but reuse pairs across many accounts; strong only combined with something else |
|
|
55
|
+
| Hosting address and ASN when not behind a CDN | Direct, but shared hosting is common |
|
|
56
|
+
| CNAME targets for `www`, `api`, `cdn`, `m` | Names the platform vendor and sometimes the tenant |
|
|
57
|
+
| Subdomain naming from certificate transparency | Platform-specific patterns (`api.`, `cl.`, `evolutiongaming.`) and mirror schemes (`dd20--brand`) |
|
|
58
|
+
| Wildcard certificate issuer and issuance cadence | Same automation |
|
|
59
|
+
|
|
60
|
+
## Brand and naming fingerprints (candidate generators, not evidence)
|
|
61
|
+
|
|
62
|
+
| Fingerprint | Use |
|
|
63
|
+
|---|---|
|
|
64
|
+
| Name stem and numbering scheme (`brand3`, `brand-9884`, `xx00--brand`) | Enumerate variants in step 3 |
|
|
65
|
+
| Licence seal number and validator link | Pivot into the licence register in step 4 |
|
|
66
|
+
| Legal entity, address, and licence text on the terms page | Entity pivot in step 4 |
|
|
67
|
+
| Affiliate program name | Brand-list pivot in step 4 |
|
|
68
|
+
| Sportsbook or casino platform named in the footer | Vendor-level filter |
|
|
69
|
+
|
|
70
|
+
## Behaviour fingerprints (supporting)
|
|
71
|
+
|
|
72
|
+
| Fingerprint | Use |
|
|
73
|
+
|---|---|
|
|
74
|
+
| Geo-block behaviour: which countries, what status code, challenge or branded page | Same edge configuration |
|
|
75
|
+
| Redirect chain (`www` to apex, mirror to parent, country path) | Reveals the parent brand |
|
|
76
|
+
| Response headers beyond the CDN defaults | Same origin stack |
|
|
77
|
+
|
|
78
|
+
## Recording rule
|
|
79
|
+
|
|
80
|
+
Every fingerprint row carries: domain, category, value, source (page,
|
|
81
|
+
DNS, certificate log, WHOIS, archive, review site), and observed-at time.
|
|
82
|
+
A fingerprint without a source cannot be re-checked and cannot be scored.
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Pivots
|
|
2
|
+
|
|
3
|
+
A pivot turns a fingerprint into the question "which other domains have
|
|
4
|
+
this value?" and sends it to a source class that can answer. This file
|
|
5
|
+
says which source class fits which fingerprint, what a hit means, and where
|
|
6
|
+
the false positives come from. It does not prescribe tools or commands.
|
|
7
|
+
|
|
8
|
+
## Source classes
|
|
9
|
+
|
|
10
|
+
| Source class | Answers | Examples of the class |
|
|
11
|
+
|---|---|---|
|
|
12
|
+
| Page-source index | Which pages contain this string (token, CSS literal, hostname) | Code-search engines for HTML, URL scanners with body search, internet-scan datasets with HTTP bodies |
|
|
13
|
+
| Passive DNS | Which domains have or had this nameserver, MX, TXT, CNAME, or address | Commercial passive-DNS services, historical DNS archives |
|
|
14
|
+
| Certificate transparency | Which names appear on certificates, and when | Public CT log search |
|
|
15
|
+
| Reverse WHOIS | Which domains share registrant fields, registrar, or timestamps | Reverse-WHOIS services, registrar-side history |
|
|
16
|
+
| Web archive | What the site served before it was blocked or rebranded | Public web archives, cached copies |
|
|
17
|
+
| Review aggregators | Operator, licence, launch year, affiliate program, complaints | Casino / merchant review directories, complaint forums |
|
|
18
|
+
| Licence register | Every domain licensed under one number or entity | Regulator's public register |
|
|
19
|
+
| Affiliate directory | Every brand an affiliate program pays for | Affiliate-program brand lists, affiliate forums |
|
|
20
|
+
| Ordinary web search | Brand reviews, news, forum threads | General search — note it does not index page source |
|
|
21
|
+
|
|
22
|
+
## Fingerprint to pivot map
|
|
23
|
+
|
|
24
|
+
| Fingerprint | Pivot to | Hit means | Trap |
|
|
25
|
+
|---|---|---|---|
|
|
26
|
+
| Analytics or pixel token | Page-source index | Same account configured both sites | A token can be scraped and pasted by an affiliate site; check the hit is the brand's own domain, not a review page |
|
|
27
|
+
| Block-page template literal | Page-source index | Same codebase | Framework defaults produce the same reset; pick a literal that is not in any public template |
|
|
28
|
+
| Support-address pattern | Page-source index, web search | Mirror names its parent | None significant |
|
|
29
|
+
| Exact SPF string | Passive DNS | Same mail-vendor set | Single common includes (a lone Google or Microsoft include) match millions of domains; pivot on the full string |
|
|
30
|
+
| Microsoft tenant or vendor verification TXT | Passive DNS | Same organisation tenant | Google site-verification tokens are per domain; they do not pivot |
|
|
31
|
+
| Nameserver pair | Passive DNS | Same CDN account, probably | CDN pairs are reused across accounts; always require a second fingerprint |
|
|
32
|
+
| Hosting address / ASN | Passive DNS, internet-scan dataset | Same origin | Shared hosting; CDN fronting hides the origin entirely |
|
|
33
|
+
| CNAME target | Passive DNS | Same platform tenant | Vendor-level unless the target embeds a tenant name |
|
|
34
|
+
| Subdomain naming scheme | Certificate transparency | Same platform or mirror generator | Scheme may belong to the platform vendor, shared by its unrelated tenants |
|
|
35
|
+
| Registrar + proxy + timestamp | Reverse WHOIS | Same registration batch | Popular registrar-proxy combinations are common; timestamps within minutes are the real signal |
|
|
36
|
+
| Brand name stem | Certificate transparency, web search | Candidate mirror | A name match is a candidate only; confirm with a fingerprint |
|
|
37
|
+
| Licence number | Licence register | Every domain under the licence | Registers lag; a delisted domain is history, not a false link |
|
|
38
|
+
| Legal entity or address | Web search, page-source index (terms pages) | Same operator on paper | Corporate-service addresses are shared by hundreds of unrelated companies |
|
|
39
|
+
| Affiliate program | Affiliate directory | Same marketing arm | Some programs serve several operators |
|
|
40
|
+
|
|
41
|
+
## Running a pivot
|
|
42
|
+
|
|
43
|
+
1. State the fingerprint, the source class, and the exact query.
|
|
44
|
+
2. Record the hit count, even if zero. Zero from a source that cannot see
|
|
45
|
+
the fingerprint (web search for a token) is "not observable", not
|
|
46
|
+
"absent".
|
|
47
|
+
3. For each hit, note which fingerprint produced it. A domain reached by
|
|
48
|
+
two independent pivots is already close to Confirmed.
|
|
49
|
+
4. Filter high-noise pivots (nameserver pair, registrar, single mail
|
|
50
|
+
include) by intersecting with the set of hits from a strong pivot before
|
|
51
|
+
any of them becomes a candidate.
|
|
52
|
+
5. Prefer pivots whose hit count is small. A pivot returning thousands of
|
|
53
|
+
domains is not evidence until narrowed.
|
|
54
|
+
|
|
55
|
+
## Blocked-site pivots
|
|
56
|
+
|
|
57
|
+
When the live site is unreachable:
|
|
58
|
+
|
|
59
|
+
- Pivot on the block page itself (template, token, support address).
|
|
60
|
+
- Use certificate history for subdomains and mirror schemes.
|
|
61
|
+
- Use web archives for the pre-block or pre-rebrand HTML, which usually
|
|
62
|
+
still carries the same tokens.
|
|
63
|
+
- Use mirrors that are reachable from the analyst's location; they share
|
|
64
|
+
the parent's fingerprints by design.
|
|
65
|
+
- Use review aggregators for the entity chain; they visited the site from
|
|
66
|
+
an allowed location.
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# Report template
|
|
2
|
+
|
|
3
|
+
Save:
|
|
4
|
+
|
|
5
|
+
```text
|
|
6
|
+
reports/similar-domain/<seed>_cluster.md
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
Use the first seed's registrable domain as `<seed>`; for multiple seeds
|
|
10
|
+
use a short scope name the user recognises. No Markdown bold in the report
|
|
11
|
+
body. After writing, grep banned strings in
|
|
12
|
+
[terminology.md](terminology.md).
|
|
13
|
+
|
|
14
|
+
```markdown
|
|
15
|
+
# Domain cluster — <seed or scope>
|
|
16
|
+
|
|
17
|
+
## Verdict
|
|
18
|
+
## Cluster
|
|
19
|
+
## Evidence matrix
|
|
20
|
+
## Entity chain
|
|
21
|
+
## Outliers
|
|
22
|
+
## Coverage and caveats
|
|
23
|
+
## Pivot log
|
|
24
|
+
## Sources
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Chapter requirements
|
|
28
|
+
|
|
29
|
+
### Verdict
|
|
30
|
+
|
|
31
|
+
At most three sentences: which domains form a cluster, what the strongest
|
|
32
|
+
evidence is, and which seeds do not belong. No new evidence here.
|
|
33
|
+
|
|
34
|
+
### Cluster
|
|
35
|
+
|
|
36
|
+
One row per domain, sorted Confirmed → Probable → Possible. Columns: domain,
|
|
37
|
+
brand, role (parent, mirror, acquired brand), label, registered date,
|
|
38
|
+
current operator (if known), strongest two links. Seeds that are Unrelated
|
|
39
|
+
go in Outliers, not here.
|
|
40
|
+
|
|
41
|
+
### Evidence matrix
|
|
42
|
+
|
|
43
|
+
Domains as rows, fingerprints as columns, cell shows the shared value or a
|
|
44
|
+
short marker. Include at least: analytics account, template, mail string
|
|
45
|
+
or platform, nameserver pair, registrar and proxy, registration timestamp,
|
|
46
|
+
licence or entity. This table is what lets a reader check the labels
|
|
47
|
+
without rerunning the work.
|
|
48
|
+
|
|
49
|
+
### Entity chain
|
|
50
|
+
|
|
51
|
+
The operator history with dates: entities, licences, migrations, brand
|
|
52
|
+
acquisitions. Present conflicting operator names as a dated sequence. Cite
|
|
53
|
+
the page for each fact.
|
|
54
|
+
|
|
55
|
+
### Outliers
|
|
56
|
+
|
|
57
|
+
Every seed or candidate that was checked and rejected, with the
|
|
58
|
+
fingerprints that differ. "Different brand" is not a reason; "different
|
|
59
|
+
analytics account, different mail platform, different CDN account" is.
|
|
60
|
+
|
|
61
|
+
### Coverage and caveats
|
|
62
|
+
|
|
63
|
+
What could not be observed and why: geo-blocks, bot challenges, private
|
|
64
|
+
registration, resolver artefacts, pivots not run for budget reasons,
|
|
65
|
+
source classes not available. State whether the cluster is closed (a full
|
|
66
|
+
pass added nothing) or open.
|
|
67
|
+
|
|
68
|
+
### Pivot log
|
|
69
|
+
|
|
70
|
+
One row per pivot: fingerprint, source class, query, hit count, domains
|
|
71
|
+
kept. Empty pivots stay in the log; they are what makes a negative result
|
|
72
|
+
credible.
|
|
73
|
+
|
|
74
|
+
### Sources
|
|
75
|
+
|
|
76
|
+
Every external page cited, as links.
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Scoring
|
|
2
|
+
|
|
3
|
+
Weight each link by how hard it is to share by accident, count independent
|
|
4
|
+
signals, and label every domain.
|
|
5
|
+
|
|
6
|
+
## Link strength
|
|
7
|
+
|
|
8
|
+
| Signal | Strength | Reason |
|
|
9
|
+
|---|---|---|
|
|
10
|
+
| Same analytics, tag-manager, pixel, or error-monitoring account ID | Very strong | One paying account, one admin |
|
|
11
|
+
| Same custom page template with non-default literals | Very strong | Shared codebase |
|
|
12
|
+
| Mirror serves the parent's support address or redirects to it | Very strong | Self-declared |
|
|
13
|
+
| Byte-identical SPF string with three or more vendor includes | Strong | Chosen combination of vendors |
|
|
14
|
+
| Same organisation tenant ID in TXT records | Strong | One tenant |
|
|
15
|
+
| Same registrar + proxy + timestamps within an hour | Strong | One batch action |
|
|
16
|
+
| Licence register lists both domains under one licence | Strong | Authoritative, but lags reality |
|
|
17
|
+
| Same registrar + proxy + identical lock set, days apart | Medium | Same account defaults |
|
|
18
|
+
| Same CDN nameserver pair | Medium | Per account, but pairs are reused |
|
|
19
|
+
| Same origin address or ASN outside a CDN | Medium | Shared hosting is common |
|
|
20
|
+
| Same platform vendor, CNAME target, or subdomain scheme | Weak | Vendor-level |
|
|
21
|
+
| Same affiliate program | Weak to medium | Some programs serve several operators |
|
|
22
|
+
| Same game providers, bonus wording, licence authority | Weak | Industry-wide |
|
|
23
|
+
| Similar brand name | Candidate only | Names are cheap |
|
|
24
|
+
|
|
25
|
+
## Independence
|
|
26
|
+
|
|
27
|
+
Two signals count as independent only if a different party controls
|
|
28
|
+
each. Examples that count once, not twice: analytics token and block-page
|
|
29
|
+
template (same front-end deployment); nameserver pair and CDN analytics
|
|
30
|
+
token (same CDN account); registrar and proxy service (same registrar
|
|
31
|
+
account). Examples that count separately: analytics token and SPF string;
|
|
32
|
+
registration batch and page template; licence register and mail tenant.
|
|
33
|
+
|
|
34
|
+
## Labels
|
|
35
|
+
|
|
36
|
+
| Label | Rule |
|
|
37
|
+
|---|---|
|
|
38
|
+
| Confirmed | Two independent strong-or-better signals, or one very strong signal plus any medium one |
|
|
39
|
+
| Probable | One strong or very strong signal, or two independent medium signals, or authoritative register listing without technical confirmation yet |
|
|
40
|
+
| Possible | One medium signal, or vendor-level signals only, or a name-scheme candidate |
|
|
41
|
+
| Unrelated | Checked, and the operator-level fingerprints differ (different analytics accounts, different template, different mail platform, different registrar behaviour) |
|
|
42
|
+
|
|
43
|
+
Only Confirmed and Probable enter the loop as new seeds. Possible domains
|
|
44
|
+
are parked with the one fingerprint that would promote them, so a later
|
|
45
|
+
pass can pick them up.
|
|
46
|
+
|
|
47
|
+
## Negative evidence
|
|
48
|
+
|
|
49
|
+
A domain can share medium signals and still be Unrelated. Different mail
|
|
50
|
+
platforms, different CDN accounts, different analytics accounts, and a
|
|
51
|
+
registration years apart together outweigh a shared nameserver pair or
|
|
52
|
+
shared licence authority. Say so explicitly in the outliers section
|
|
53
|
+
rather than leaving the domain unlabelled.
|
|
54
|
+
|
|
55
|
+
## Conflicts
|
|
56
|
+
|
|
57
|
+
When technical evidence and corporate evidence disagree, report both and
|
|
58
|
+
date them. Continuous technical evidence across a corporate break usually
|
|
59
|
+
means an entity swap on one platform; continuous corporate evidence across
|
|
60
|
+
a technical break usually means a platform migration. Neither breaks the
|
|
61
|
+
cluster; both belong in the entity chain.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Terminology
|
|
2
|
+
|
|
3
|
+
| Term | Meaning in this skill |
|
|
4
|
+
|---|---|
|
|
5
|
+
| Seed | A domain the user supplied or a Confirmed/Probable domain fed back into the loop |
|
|
6
|
+
| Fingerprint | Any identifier on a domain that is not the brand name and can be shared across domains |
|
|
7
|
+
| Pivot | A reverse query: "which other domains carry this fingerprint?" |
|
|
8
|
+
| Candidate | A domain returned by a pivot or a name scheme, not yet scored |
|
|
9
|
+
| Cluster | The set of Confirmed and Probable domains linked by operator-level fingerprints |
|
|
10
|
+
| Operator-level | A fingerprint tied to one paying account or one codebase (analytics ID, template, mail tenant) |
|
|
11
|
+
| Vendor-level | A fingerprint tied to a platform many operators use (game provider, CDN, chat widget) |
|
|
12
|
+
| Mirror | A domain serving or redirecting to a parent brand to evade blocking, usually numbered or hyphenated |
|
|
13
|
+
| Entity chain | The dated sequence of legal operators, licences, and migrations behind a brand |
|
|
14
|
+
| Closed cluster | A full loop pass added no domain |
|
|
15
|
+
| Open cluster | Expansion stopped for budget or access reasons; unexplored pivots are listed |
|
|
16
|
+
|
|
17
|
+
## Language
|
|
18
|
+
|
|
19
|
+
- Say "linked", "shares", "same account", "same template" for technical
|
|
20
|
+
evidence. Say "operated by", "licensed to" only with a cited entity
|
|
21
|
+
source.
|
|
22
|
+
- Say "not observable" when a source class cannot see the fingerprint;
|
|
23
|
+
say "absent" only when a source that can see it returned nothing.
|
|
24
|
+
- Say "Unrelated on current evidence" rather than "unrelated"; the
|
|
25
|
+
negative is bounded by the pivots run.
|
|
26
|
+
- Name the source class, not a product, when describing what was queried,
|
|
27
|
+
unless the user asked for the tool.
|
|
28
|
+
|
|
29
|
+
## Banned strings in the report body
|
|
30
|
+
|
|
31
|
+
- "owned by" or "same company" without an entity citation in the same
|
|
32
|
+
paragraph
|
|
33
|
+
- "confirmed" applied to ownership (Confirmed is a label for a link, not a
|
|
34
|
+
legal finding)
|
|
35
|
+
- "definitely", "certainly", "no doubt"
|
|
36
|
+
- "unrelated" without "on current evidence" or an outliers row
|
|
37
|
+
- Any fingerprint value presented without a source
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# Workflow detail
|
|
2
|
+
|
|
3
|
+
SKILL.md is the index. This file is the procedure those steps run.
|
|
4
|
+
|
|
5
|
+
## Input
|
|
6
|
+
|
|
7
|
+
One or more **seed domains** (bare domain or URL) and the question behind
|
|
8
|
+
them. Typical questions:
|
|
9
|
+
|
|
10
|
+
| Question | What the cluster must answer |
|
|
11
|
+
|---|---|
|
|
12
|
+
| "Are these domains related?" | Which seeds share an operator, and on what evidence |
|
|
13
|
+
| "Who is behind this site?" | Entity chain with dates and licence |
|
|
14
|
+
| "Find the mirrors / sister sites" | Every domain the same operator runs, labelled by confidence |
|
|
15
|
+
| "Merchant background check" | Cluster plus history: licence changes, operator migrations, complaints |
|
|
16
|
+
|
|
17
|
+
Optional context that changes the work: a transaction file whose descriptor
|
|
18
|
+
URL is the seed, a date range, a jurisdiction of interest, or a list of
|
|
19
|
+
domains the user already believes are related (treat that list as
|
|
20
|
+
hypotheses, not facts).
|
|
21
|
+
|
|
22
|
+
## Access limits
|
|
23
|
+
|
|
24
|
+
Expect at least one of these on every gambling, adult, crypto, or
|
|
25
|
+
high-risk-merchant seed:
|
|
26
|
+
|
|
27
|
+
- **Geo-block page** (403 with a branded page) — the page itself is a
|
|
28
|
+
fingerprint: template, analytics token, support address, favicon.
|
|
29
|
+
- **Bot challenge** (Cloudflare "Just a moment") — nothing behind it is
|
|
30
|
+
visible; use subdomains, certificate history, archives, and mirrors
|
|
31
|
+
instead.
|
|
32
|
+
- **Private registration** — the proxy service, registrar, dates, and lock
|
|
33
|
+
set are still visible and still cluster.
|
|
34
|
+
- **Local resolver artefacts** — a VPN or proxy on the analyst machine can
|
|
35
|
+
return fake addresses (for example the 198.18.0.0/15 range). Do not use
|
|
36
|
+
those as hosting fingerprints; use nameservers, certificates, and
|
|
37
|
+
third-party passive DNS instead.
|
|
38
|
+
|
|
39
|
+
Record each limit in the report's coverage caveats.
|
|
40
|
+
|
|
41
|
+
## Order that must not move
|
|
42
|
+
|
|
43
|
+
Fingerprint → pivot → expand names → entity → score → loop → report.
|
|
44
|
+
|
|
45
|
+
Fingerprint the seed completely before running any pivot. Pivots run on
|
|
46
|
+
fingerprints, not on brand names; the name scheme (step 3) is a candidate
|
|
47
|
+
generator that must be confirmed by a fingerprint. Entity research (step 4)
|
|
48
|
+
names and dates the cluster but never adds a domain that has no technical
|
|
49
|
+
link unless a licence register or the operator's own terms page lists it
|
|
50
|
+
explicitly. Scoring (step 5) happens before a domain enters the loop, so the
|
|
51
|
+
loop never expands on a Possible.
|
|
52
|
+
|
|
53
|
+
## Loop discipline
|
|
54
|
+
|
|
55
|
+
Each pass:
|
|
56
|
+
|
|
57
|
+
1. Take every domain labelled Confirmed or Probable that has not yet been
|
|
58
|
+
fingerprinted.
|
|
59
|
+
2. Fingerprint it fully (step 1).
|
|
60
|
+
3. Pivot on any fingerprint not already pivoted (step 2). Skip pivots whose
|
|
61
|
+
result is already known from an earlier pass.
|
|
62
|
+
4. Score new candidates (step 5).
|
|
63
|
+
|
|
64
|
+
Stop when a full pass adds no domain, or when the user's question is
|
|
65
|
+
answered and the remaining candidates are mirrors of brands already in the
|
|
66
|
+
cluster. State the stop reason in the report.
|
|
67
|
+
|
|
68
|
+
Set a budget before starting: a cluster of a large offshore operator can
|
|
69
|
+
run past a hundred domains. When the budget is hit, report the cluster as
|
|
70
|
+
"open" and list the unexplored pivots.
|
|
71
|
+
|
|
72
|
+
## What counts as done
|
|
73
|
+
|
|
74
|
+
- Every seed has a label and a row in the evidence matrix.
|
|
75
|
+
- Every non-seed member has at least one fingerprint link to a seed or to
|
|
76
|
+
another Confirmed member.
|
|
77
|
+
- The entity chain explains the cluster's history where sources allow.
|
|
78
|
+
- Outliers (seeds that did not join) are explained by absence of shared
|
|
79
|
+
fingerprints, not just by a different brand.
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: tld-detection
|
|
3
3
|
description: >
|
|
4
|
-
Explicit-only. Potential TLD (transaction-laundering) clusters from
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
Explicit-only. Potential TLD (transaction-laundering) clusters from an
|
|
5
|
+
authorization extract: stream inference first (wallet currency, preset
|
|
6
|
+
menus, frozen-rate batches, retail constants per descriptor and BIN-country
|
|
7
|
+
group), then exact original-currency amount pairs plus a separate
|
|
8
|
+
BIN-country base-currency FX sensitivity when requested or indicated, with
|
|
9
|
+
same-stream or same-descriptor baseline contrasts, high/medium/low risk
|
|
10
|
+
tiers, exposure sizing, and a ≤3-sentence decision.
|
|
11
|
+
Not payment-analysis, fraud-analysis, or website research (similar-domain).
|
|
9
12
|
disable-model-invocation: true
|
|
10
13
|
---
|
|
11
14
|
|
|
@@ -15,11 +18,23 @@ Find **potential TLD clusters** in an authorization extract. TLD here is
|
|
|
15
18
|
transaction laundering, not a domain name: hidden activity stuffed under a
|
|
16
19
|
normal MCC, often mixed across descriptors.
|
|
17
20
|
|
|
18
|
-
First partition the cleaned authorizations by **descriptor
|
|
19
|
-
descriptor
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
First partition the cleaned authorizations by **descriptor**, then infer the
|
|
22
|
+
**streams** inside each descriptor: a billing name is not a merchant, and one
|
|
23
|
+
descriptor can carry a casino cashier, a shop checkout and a generated batch
|
|
24
|
+
at once. Inside each stream, the clustering key is the
|
|
25
|
+
**currency-amount-pair**. Geometric relationships between exact anchors are
|
|
26
|
+
the stuffing signal (掺量) for traffic priced in the processing currency;
|
|
27
|
+
cashier menus converted live from a wallet currency do not form exact
|
|
28
|
+
ladders and are found by stream inference instead. BIN country is not a
|
|
29
|
+
membership key; report it in the cluster-versus-baseline comparison after
|
|
30
|
+
membership is frozen.
|
|
31
|
+
|
|
32
|
+
The original-currency run is canonical. When the user requests home/base-
|
|
33
|
+
currency detection, or when date-varying transaction amounts may conceal fixed
|
|
34
|
+
prices in card-origin currencies, add the separate BIN-country base-currency
|
|
35
|
+
FX sensitivity in [references/fx-conversion.md](references/fx-conversion.md).
|
|
36
|
+
Never merge its `FXC*` membership, exposure, or risk tiers into canonical
|
|
37
|
+
`C*` results.
|
|
23
38
|
|
|
24
39
|
**Produce:** cluster results and a separate run-specific methodology document
|
|
25
40
|
under `reports/tld-detection/`.
|
|
@@ -37,8 +52,9 @@ Follow these steps in order. Detail:
|
|
|
37
52
|
|---|---|---|
|
|
38
53
|
| 0 Pre-flight | File, grain, columns, window | Stop if auth grain, descriptor, amount, or currency column is missing; caption missing BIN country |
|
|
39
54
|
| 1 Clean | Dedup | Record drop counts; do not filter BIN country |
|
|
40
|
-
|
|
|
41
|
-
|
|
|
55
|
+
| 1b Streams | Infer wallet currency, preset menu, frozen-rate batches, retail lists per descriptor and BIN-country group with `scripts/detect_streams.py` | Every stream label carries coverage, day drift, scheme share; off-menu remainder is reported, never dropped |
|
|
56
|
+
| 2 Cluster | Run canonical original-currency detection inside each stream; add the separate FX sensitivity when applicable; freeze exact keys; compare with the same-stream baseline (same-descriptor when the descriptor has one stream) | Partition = descriptor, sub-partitioned by stream; ≥3 levels; adjacent levels = 2x; ≥100 attempts; absolute residual cap per candidate currency |
|
|
57
|
+
| 3 Risk | Assign high/medium/low investigation priority | In canonical results, Mixed BIN countries are neutral and exact 100% single-country concentration is a standout; FX concentration is descriptive only and cannot raise tier |
|
|
42
58
|
| 4 Decision | Conclusion + basis for the book | ≤3 sentences; no new evidence |
|
|
43
59
|
| 5 Report | Answer highest-risk, cluster-characteristic, and exposure questions; write + proofread | Sort high → medium → low; no confirmed-TLD wording |
|
|
44
60
|
|
|
@@ -51,7 +67,20 @@ column aliases: [workflow.md](references/workflow.md).
|
|
|
51
67
|
### 1 — Clean
|
|
52
68
|
|
|
53
69
|
[references/clean.md](references/clean.md). Deduplicate first. Do not
|
|
54
|
-
FX-convert the clustering key. Do not drop non-US BIN rows.
|
|
70
|
+
FX-convert the canonical clustering key. Do not drop non-US BIN rows.
|
|
71
|
+
|
|
72
|
+
### 1b — Streams
|
|
73
|
+
|
|
74
|
+
[references/streams.md](references/streams.md). Run
|
|
75
|
+
`scripts/detect_streams.py` on the cleaned universe with a daily FX cache.
|
|
76
|
+
It converts each charge into candidate wallet currencies (the card country's
|
|
77
|
+
legal tender, EUR, USD, GBP, CHF), finds the values charges pile up on, and
|
|
78
|
+
peels each descriptor-country group into streams: a wallet-currency preset
|
|
79
|
+
menu (10-scheme or 12-scheme), a retail price list times one constant, a
|
|
80
|
+
frozen-rate batch, or off-menu. Streams are the unit for the behaviour
|
|
81
|
+
contrast (repeat cards, retry after decline, hour concentration, address
|
|
82
|
+
verification, 3-D Secure) and for the same-descriptor baseline in step 2.
|
|
83
|
+
A descriptor with several streams is several upstreams; say so.
|
|
55
84
|
|
|
56
85
|
### 2 — Cluster
|
|
57
86
|
|
|
@@ -68,14 +97,27 @@ and amount; keep only clusters with ≥100 authorization attempts. Compare each
|
|
|
68
97
|
cluster with the baseline formed by removing that cluster from the same
|
|
69
98
|
descriptor. Do not invent clusters from MCC or comparison features.
|
|
70
99
|
|
|
100
|
+
If the FX sensitivity applies, run it only after the cleaned universe and
|
|
101
|
+
canonical partitions are frozen. Follow
|
|
102
|
+
[references/fx-conversion.md](references/fx-conversion.md) and its mandated
|
|
103
|
+
Frankfurter v2 request/cache contract. Within each frozen canonical descriptor
|
|
104
|
+
partition, `|P_FX|` is only its exact-date-converted attempts; use only `P_FX`
|
|
105
|
+
for FX high-count and rung-pool thresholds and the FX same-descriptor baseline.
|
|
106
|
+
Excluded rows stay outside FX detection and appear only in exclusion coverage
|
|
107
|
+
and reconciliation to canonical `U`. Use `FXC1`, `FXC2`, ... ids and publish
|
|
108
|
+
separate result and methodology files. Because BIN country constructs the
|
|
109
|
+
target currency in this view, country concentration, including 100%, is
|
|
110
|
+
descriptive only and cannot raise the FX tier.
|
|
111
|
+
|
|
71
112
|
### 3 — Risk
|
|
72
113
|
|
|
73
114
|
[references/decision.md](references/decision.md). Assign every identified
|
|
74
115
|
currency-amount pair exactly one investigation-priority tier: High, Medium,
|
|
75
|
-
or Low. BIN-country mixture is neutral and
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
116
|
+
or Low. In canonical results, BIN-country mixture is neutral and exact 100%
|
|
117
|
+
single-country concentration is a standout; separately report descriptor-
|
|
118
|
+
country slice coverage without a threshold or risk points. In FX results,
|
|
119
|
+
country concentration remains descriptive because it constructs the target
|
|
120
|
+
currency and is not independent risk evidence.
|
|
79
121
|
|
|
80
122
|
### 4 — Decision
|
|
81
123
|
|
|
@@ -84,7 +126,10 @@ book. A one-line table per cluster is allowed under that.
|
|
|
84
126
|
|
|
85
127
|
### 5 — Report
|
|
86
128
|
|
|
87
|
-
[references/report-template.md](references/report-template.md).
|
|
129
|
+
[references/report-template.md](references/report-template.md). The cluster
|
|
130
|
+
report opens with the stream table (one row per stream: label, attempts,
|
|
131
|
+
share, countries, behaviour), because the reader needs to know how many
|
|
132
|
+
upstreams share the descriptor before reading any cluster. Terms:
|
|
88
133
|
[references/terminology.md](references/terminology.md).
|
|
89
134
|
|
|
90
135
|
```text
|
|
@@ -112,6 +157,7 @@ Track a task plan. One item is `in_progress` at a time.
|
|
|
112
157
|
|
|
113
158
|
1. Pass pre-flight
|
|
114
159
|
2. Freeze cleaned universe and descriptor partitions
|
|
160
|
+
2b. Run stream inference and record streams per descriptor
|
|
115
161
|
3. Assign High / Medium / Low risk tiers
|
|
116
162
|
4. Publish descriptor currency-amount pairs + same-descriptor baselines
|
|
117
163
|
5. Write ≤3-sentence decision
|
|
@@ -121,7 +167,8 @@ Track a task plan. One item is `in_progress` at a time.
|
|
|
121
167
|
|
|
122
168
|
| Need | Skill |
|
|
123
169
|
|---|---|
|
|
124
|
-
| Potential TLD clusters, currency-amount pairs, stuffing / 掺量, MCC miscoding, descriptor mixing | `tld-detection` |
|
|
170
|
+
| Potential TLD clusters, currency-amount pairs, stuffing / 掺量, MCC miscoding, descriptor mixing, upstream streams behind one descriptor | `tld-detection` |
|
|
171
|
+
| Which websites, mirrors and operators sit behind a merchant domain | `similar-domain` |
|
|
125
172
|
| Volume, journey Sankey, auth rate, decline mix, settlement overview | `payment-analysis` |
|
|
126
173
|
| Proxy/confirmed fraud labels, holdout precision/recall, rule packages | `fraud-analysis` |
|
|
127
174
|
|
|
@@ -134,7 +181,9 @@ rule package.
|
|
|
134
181
|
|---|---|
|
|
135
182
|
| Grain, columns, window | [workflow.md](references/workflow.md) |
|
|
136
183
|
| Dedup | [clean.md](references/clean.md) |
|
|
184
|
+
| Wallet currency, preset menus, frozen-rate batches, retail constants, behaviour metrics | [streams.md](references/streams.md) |
|
|
137
185
|
| Currency-amount pairs, anchors, same-descriptor baseline | [clustering.md](references/clustering.md) |
|
|
186
|
+
| BIN-country base-currency FX sensitivity | [fx-conversion.md](references/fx-conversion.md) |
|
|
138
187
|
| ≤3-sentence conclusion | [decision.md](references/decision.md) |
|
|
139
188
|
| Report chapters | [report-template.md](references/report-template.md) |
|
|
140
189
|
| Language / banned strings | [terminology.md](references/terminology.md) |
|
|
@@ -143,7 +192,13 @@ rule package.
|
|
|
143
192
|
|
|
144
193
|
- [ ] Auth grain; dedup counts are stated; no BIN-country row filter
|
|
145
194
|
- [ ] Partition key is normalized descriptor; missing descriptor is an explicit bucket
|
|
195
|
+
- [ ] Stream inference ran; each descriptor lists its streams with coverage, scheme, drift and behaviour, and the off-menu remainder
|
|
196
|
+
- [ ] A frozen-rate stream is reported as generated traffic evidence, not as player deposits
|
|
146
197
|
- [ ] Clustering key is original currency + amount, not USD
|
|
198
|
+
- [ ] Canonical `C*` results use original amounts; any FX run is separate, uses `FXC*` ids, and does not alter canonical membership or exposure
|
|
199
|
+
- [ ] FX run records as-of-date country→legal-tender mapping, the versioned immutable Frankfurter v2 exact-date request/cache facts, formula, minor-unit rounding, exclusions, and converted-universe coverage
|
|
200
|
+
- [ ] Within each frozen descriptor, `|P_FX|` contains only exact-date-converted attempts; FX thresholds and same-descriptor baselines use only `P_FX`, while exclusions reconcile only to canonical `U`
|
|
201
|
+
- [ ] FX country concentration is descriptive only because BIN country constructs the target currency; it does not independently raise risk
|
|
147
202
|
- [ ] Each rung-pool currency has an explicit adjacent absolute-residual cap and sensitivity evidence
|
|
148
203
|
- [ ] Multi-anchor levels state their portfolio support floor; final membership uses exact selected amount keys
|
|
149
204
|
- [ ] Cluster attempts ≥100
|
|
@@ -151,9 +206,9 @@ rule package.
|
|
|
151
206
|
- [ ] Currency-amount pairs show seed and representative anchors; `*` marks a multi-amount level
|
|
152
207
|
- [ ] Same amount pair may recur across descriptor partitions; never merge them automatically
|
|
153
208
|
- [ ] BIN country is post-membership reporting data, not a membership key; Mixed is neutral
|
|
154
|
-
- [ ]
|
|
209
|
+
- [ ] Canonical exact 100% single-country concentration is a standout; FX concentration is descriptive only; descriptor-country coverage has no risk threshold
|
|
155
210
|
- [ ] Each cluster baseline is the same descriptor after removing that cluster
|
|
156
|
-
- [ ]
|
|
211
|
+
- [ ] Each cluster uses one consolidated profile/comparison table; descriptor, seed, anchors, attempts, descriptor totals/share, MCC, and baseline metrics are not repeated in separate definition/characteristic/metric tables
|
|
157
212
|
- [ ] Anchor table reports attempts, authorization success rate, and suspected-fraud share for every level, including n < 30
|
|
158
213
|
- [ ] Characteristics contain descriptor total, cluster attempts/share, MCC, and cluster-vs-baseline auth rate, suspected-fraud share, top 3 banks, and top 3 BIN countries
|
|
159
214
|
- [ ] Decision prose is ≤3 sentences (conclusion + basis)
|
|
@@ -26,7 +26,7 @@ the run. Do not invent a customer id from BIN + amount.
|
|
|
26
26
|
|
|
27
27
|
## 3. Amount and currency
|
|
28
28
|
|
|
29
|
-
-
|
|
29
|
+
- The canonical clustering key uses the **original** amount and currency. A BIN-country base-currency sensitivity may derive a separate key only after this cleaned universe is frozen; see [fx-conversion.md](fx-conversion.md).
|
|
30
30
|
- Normalize `10`, `10.0`, `10.00` to the same decimal key.
|
|
31
31
|
- Drop rows with missing amount or currency; count them.
|
|
32
32
|
- Do not FX-convert before clustering. A 9.99 EUR rung is not a 9.99 USD
|
|
@@ -5,6 +5,14 @@ as **approximate geometric ladders** inside each descriptor, then decompose
|
|
|
5
5
|
each qualifying ladder into BIN-country attribution components and contrast
|
|
6
6
|
it against the remainder.
|
|
7
7
|
|
|
8
|
+
## Streams first
|
|
9
|
+
|
|
10
|
+
Run [streams.md](streams.md) before ranking pairs. When a descriptor carries
|
|
11
|
+
several streams, treat each stream as the partition for rung pools, ladders
|
|
12
|
+
and the baseline; report descriptor totals alongside. Exact-key detection
|
|
13
|
+
finds frozen-rate batches (they are exact, geometric and repeated); it does not
|
|
14
|
+
find live-converted menus, which stream inference reports as menu streams.
|
|
15
|
+
|
|
8
16
|
## Descriptor partition
|
|
9
17
|
|
|
10
18
|
Partition key = `normalized descriptor`.
|
|
@@ -26,7 +34,10 @@ fraud rates, and local-hour shapes as attribution components.
|
|
|
26
34
|
|
|
27
35
|
## Currency-amount-pair
|
|
28
36
|
|
|
29
|
-
Key = (`currency`, `amount`) on the original (not FX-converted) amount.
|
|
37
|
+
Key = (`currency`, `amount`) on the original (not FX-converted) amount. This is
|
|
38
|
+
the canonical key. A requested BIN-country base-currency analysis is a separate
|
|
39
|
+
sensitivity under [fx-conversion.md](fx-conversion.md), never a replacement for
|
|
40
|
+
or input to canonical membership.
|
|
30
41
|
|
|
31
42
|
Count = authorization **attempts** in the current partition. Rank
|
|
32
43
|
descending by count. Ties: smaller amount first, then currency code.
|
|
@@ -195,10 +206,13 @@ authorization, suspected-fraud, issuing-bank, date, and local-hour behavior as
|
|
|
195
206
|
independent characteristics under thresholds declared in the run methodology.
|
|
196
207
|
|
|
197
208
|
For each Top 3 cluster BIN country, report both its share of the cluster and
|
|
198
|
-
the cluster's share of all attempts in the same descriptor-country slice.
|
|
199
|
-
exact 100% single-country cluster
|
|
200
|
-
|
|
201
|
-
or award risk points for values such as
|
|
209
|
+
the cluster's share of all attempts in the same descriptor-country slice. In
|
|
210
|
+
the canonical original-currency run only, an exact 100% single-country cluster
|
|
211
|
+
is a standout. `Mixed` is neutral, and country-slice coverage is descriptive
|
|
212
|
+
only: do not set a universal threshold or award risk points for values such as
|
|
213
|
+
20% or 33.8%. In the FX sensitivity, even 100% concentration is descriptive,
|
|
214
|
+
must be captioned as constructed by the target-currency mapping, and cannot
|
|
215
|
+
raise the FX tier.
|
|
202
216
|
|
|
203
217
|
## What not to do
|
|
204
218
|
|
|
@@ -206,9 +220,10 @@ or award risk points for values such as 20% or 33.8%.
|
|
|
206
220
|
- Do not discover ladders across descriptor boundaries.
|
|
207
221
|
- Do not use BIN country as a ladder partition or membership key.
|
|
208
222
|
- Do not k-means the amounts.
|
|
209
|
-
- Do not convert to USD and
|
|
223
|
+
- Do not convert to USD or another currency and use that result as the canonical ladder run. Keep any BIN-country base-currency detection in the separate FX sensitivity.
|
|
210
224
|
- Do not search only upward from the busiest rung.
|
|
211
225
|
- Do not use a percentage tolerance across amounts.
|
|
226
|
+
- Do not turn stream inference into cluster membership: its relative tolerance is discovery in the wallet currency; canonical membership stays exact on original currency and amount.
|
|
212
227
|
- Do not assign every amount inside an interval; select finite exact anchors first.
|
|
213
228
|
- Do not retain a low-support additional anchor merely because it is near a primary anchor.
|
|
214
229
|
- Do not report a cluster with fewer than three theoretical levels.
|