active_sanction 1.0.0

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.
Files changed (143) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +538 -0
  3. data/CODE_OF_CONDUCT.md +74 -0
  4. data/CONTRIBUTING.md +312 -0
  5. data/LICENSE.txt +21 -0
  6. data/README.md +616 -0
  7. data/SECURITY.md +97 -0
  8. data/active_sanction.gemspec +98 -0
  9. data/docs/adding_a_source.md +1083 -0
  10. data/docs/api_stability.md +357 -0
  11. data/docs/bundle_format.md +407 -0
  12. data/lib/active_sanction/address.rb +170 -0
  13. data/lib/active_sanction/client.rb +341 -0
  14. data/lib/active_sanction/configuration.rb +721 -0
  15. data/lib/active_sanction/countries.txt +292 -0
  16. data/lib/active_sanction/country.rb +164 -0
  17. data/lib/active_sanction/deprecation.rb +168 -0
  18. data/lib/active_sanction/diff/change.rb +208 -0
  19. data/lib/active_sanction/diff.rb +348 -0
  20. data/lib/active_sanction/doctor/checkup.rb +356 -0
  21. data/lib/active_sanction/doctor/diagnosis.rb +245 -0
  22. data/lib/active_sanction/doctor/finding.rb +183 -0
  23. data/lib/active_sanction/doctor/profile.rb +384 -0
  24. data/lib/active_sanction/doctor/report.rb +227 -0
  25. data/lib/active_sanction/doctor.rb +347 -0
  26. data/lib/active_sanction/entity.rb +293 -0
  27. data/lib/active_sanction/error.rb +332 -0
  28. data/lib/active_sanction/fetcher/result.rb +116 -0
  29. data/lib/active_sanction/fetcher.rb +242 -0
  30. data/lib/active_sanction/http_client/errors.rb +94 -0
  31. data/lib/active_sanction/http_client/response.rb +129 -0
  32. data/lib/active_sanction/http_client.rb +324 -0
  33. data/lib/active_sanction/identifier.rb +212 -0
  34. data/lib/active_sanction/index/builder.rb +89 -0
  35. data/lib/active_sanction/index/candidate.rb +63 -0
  36. data/lib/active_sanction/index/entry.rb +66 -0
  37. data/lib/active_sanction/index/features.rb +112 -0
  38. data/lib/active_sanction/index.rb +381 -0
  39. data/lib/active_sanction/match_result.rb +345 -0
  40. data/lib/active_sanction/matcher.rb +388 -0
  41. data/lib/active_sanction/name.rb +183 -0
  42. data/lib/active_sanction/normalizer/cache.rb +82 -0
  43. data/lib/active_sanction/normalizer/dictionaries/honorifics.txt +30 -0
  44. data/lib/active_sanction/normalizer/dictionaries/legal_forms.txt +72 -0
  45. data/lib/active_sanction/normalizer/dictionaries/organization_stopwords.txt +20 -0
  46. data/lib/active_sanction/normalizer/dictionaries/particles.txt +35 -0
  47. data/lib/active_sanction/normalizer/dictionary/stoplist.rb +121 -0
  48. data/lib/active_sanction/normalizer/dictionary.rb +243 -0
  49. data/lib/active_sanction/normalizer/form.rb +279 -0
  50. data/lib/active_sanction/normalizer.rb +137 -0
  51. data/lib/active_sanction/parsers/column_shape.rb +274 -0
  52. data/lib/active_sanction/parsers/delimited_table/reader.rb +194 -0
  53. data/lib/active_sanction/parsers/delimited_table/row.rb +81 -0
  54. data/lib/active_sanction/parsers/delimited_table.rb +151 -0
  55. data/lib/active_sanction/parsers/format.rb +107 -0
  56. data/lib/active_sanction/parsers/join.rb +149 -0
  57. data/lib/active_sanction/parsers/spreadsheet/archive.rb +258 -0
  58. data/lib/active_sanction/parsers/spreadsheet/reader.rb +213 -0
  59. data/lib/active_sanction/parsers/spreadsheet/row.rb +88 -0
  60. data/lib/active_sanction/parsers/spreadsheet/workbook.rb +314 -0
  61. data/lib/active_sanction/parsers/spreadsheet.rb +168 -0
  62. data/lib/active_sanction/parsers/xml_records/backends/nokogiri.rb +134 -0
  63. data/lib/active_sanction/parsers/xml_records/backends/rexml.rb +157 -0
  64. data/lib/active_sanction/parsers/xml_records/backends.rb +103 -0
  65. data/lib/active_sanction/parsers/xml_records/builder.rb +90 -0
  66. data/lib/active_sanction/parsers/xml_records/reader.rb +134 -0
  67. data/lib/active_sanction/parsers/xml_records/record.rb +174 -0
  68. data/lib/active_sanction/parsers/xml_records.rb +140 -0
  69. data/lib/active_sanction/parsers.rb +94 -0
  70. data/lib/active_sanction/partial_date/parser.rb +124 -0
  71. data/lib/active_sanction/partial_date.rb +303 -0
  72. data/lib/active_sanction/payload_cache/checksum.rb +66 -0
  73. data/lib/active_sanction/payload_cache/entry.rb +304 -0
  74. data/lib/active_sanction/payload_cache.rb +366 -0
  75. data/lib/active_sanction/phonetics/double_metaphone.rb +662 -0
  76. data/lib/active_sanction/phonetics.rb +40 -0
  77. data/lib/active_sanction/query.rb +290 -0
  78. data/lib/active_sanction/rescreen/alert.rb +314 -0
  79. data/lib/active_sanction/rescreen.rb +332 -0
  80. data/lib/active_sanction/scorer/adjustments.rb +241 -0
  81. data/lib/active_sanction/scorer/name_score.rb +279 -0
  82. data/lib/active_sanction/scorer/reason.rb +136 -0
  83. data/lib/active_sanction/scorer/result.rb +129 -0
  84. data/lib/active_sanction/scorer/subject.rb +235 -0
  85. data/lib/active_sanction/scorer/weights.rb +306 -0
  86. data/lib/active_sanction/scorer.rb +303 -0
  87. data/lib/active_sanction/similarity/jaro_winkler.rb +210 -0
  88. data/lib/active_sanction/similarity/levenshtein.rb +179 -0
  89. data/lib/active_sanction/similarity/token_set.rb +159 -0
  90. data/lib/active_sanction/similarity/token_sort.rb +120 -0
  91. data/lib/active_sanction/similarity.rb +183 -0
  92. data/lib/active_sanction/snapshot/bundle/header.rb +302 -0
  93. data/lib/active_sanction/snapshot/bundle/payload.rb +185 -0
  94. data/lib/active_sanction/snapshot/bundle/signature.rb +201 -0
  95. data/lib/active_sanction/snapshot/bundle.rb +381 -0
  96. data/lib/active_sanction/snapshot.rb +305 -0
  97. data/lib/active_sanction/sources/australia_dfat/published_date.rb +166 -0
  98. data/lib/active_sanction/sources/australia_dfat/record.rb +319 -0
  99. data/lib/active_sanction/sources/australia_dfat.rb +291 -0
  100. data/lib/active_sanction/sources/base.rb +295 -0
  101. data/lib/active_sanction/sources/canada_sema/record.rb +282 -0
  102. data/lib/active_sanction/sources/canada_sema/source_ref.rb +89 -0
  103. data/lib/active_sanction/sources/canada_sema.rb +153 -0
  104. data/lib/active_sanction/sources/definition.rb +360 -0
  105. data/lib/active_sanction/sources/eu_fsf/record.rb +467 -0
  106. data/lib/active_sanction/sources/eu_fsf.rb +203 -0
  107. data/lib/active_sanction/sources/ofac/record.rb +251 -0
  108. data/lib/active_sanction/sources/ofac/remarks_parser/coverage.rb +120 -0
  109. data/lib/active_sanction/sources/ofac/remarks_parser/vocabulary.rb +121 -0
  110. data/lib/active_sanction/sources/ofac/remarks_parser.rb +312 -0
  111. data/lib/active_sanction/sources/ofac.rb +248 -0
  112. data/lib/active_sanction/sources/ofac_consolidated/record.rb +37 -0
  113. data/lib/active_sanction/sources/ofac_consolidated.rb +203 -0
  114. data/lib/active_sanction/sources/ofac_sdn.rb +43 -0
  115. data/lib/active_sanction/sources/remarks.rb +84 -0
  116. data/lib/active_sanction/sources/uk_sanctions_list/published_date.rb +104 -0
  117. data/lib/active_sanction/sources/uk_sanctions_list/record.rb +412 -0
  118. data/lib/active_sanction/sources/uk_sanctions_list.rb +214 -0
  119. data/lib/active_sanction/sources/un_consolidated/record.rb +279 -0
  120. data/lib/active_sanction/sources/un_consolidated.rb +140 -0
  121. data/lib/active_sanction/sources.rb +196 -0
  122. data/lib/active_sanction/storage/active_record/reader.rb +124 -0
  123. data/lib/active_sanction/storage/active_record/row.rb +175 -0
  124. data/lib/active_sanction/storage/active_record/writer.rb +141 -0
  125. data/lib/active_sanction/storage/active_record.rb +277 -0
  126. data/lib/active_sanction/storage/base.rb +216 -0
  127. data/lib/active_sanction/storage/file_system.rb +373 -0
  128. data/lib/active_sanction/storage/memory.rb +67 -0
  129. data/lib/active_sanction/storage/meta.rb +188 -0
  130. data/lib/active_sanction/storage.rb +74 -0
  131. data/lib/active_sanction/subject.rb +271 -0
  132. data/lib/active_sanction/sync/report.rb +245 -0
  133. data/lib/active_sanction/sync/result.rb +296 -0
  134. data/lib/active_sanction/sync.rb +390 -0
  135. data/lib/active_sanction/validator_store/file_system.rb +103 -0
  136. data/lib/active_sanction/validator_store/memory.rb +41 -0
  137. data/lib/active_sanction/validator_store.rb +119 -0
  138. data/lib/active_sanction/validators.rb +195 -0
  139. data/lib/active_sanction/version.rb +23 -0
  140. data/lib/active_sanction.rb +331 -0
  141. data/lib/generators/active_sanction/install/install_generator.rb +60 -0
  142. data/lib/generators/active_sanction/install/templates/create_active_sanction_tables.rb.tt +142 -0
  143. metadata +236 -0
@@ -0,0 +1,357 @@
1
+ # API stability
2
+
3
+ What this gem promises not to break, and what it reserves the right to change
4
+ in any release.
5
+
6
+ **The public surface is enumerated below, not inferred.** A constant being
7
+ reachable does not make it public; nearly 500 of them are reachable and 137 are
8
+ promised. Everything else is marked `@api private` in the source, is hidden
9
+ from the rendered documentation, and may be renamed, moved or deleted in a
10
+ patch release without a note anywhere. If you need something that is not on
11
+ this list, open an issue rather than reaching for it — the whole point of
12
+ writing the boundary down is that widening it is a conversation rather than an
13
+ accident.
14
+
15
+ [`spec/api_surface_spec.rb`](../spec/api_surface_spec.rb) reads this file and
16
+ fails when the code and this list stop agreeing, in either direction. A new
17
+ public constant that nobody added here fails the suite; a name here that no
18
+ longer exists fails it too.
19
+
20
+ ## Versioning
21
+
22
+ This project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
23
+
24
+ **The first release is 1.0.0, and there was no 0.x.** A leading zero says a
25
+ minor version may remove what the last one promised, and that is not what this
26
+ library is doing: the surface below was inventoried before it shipped and
27
+ `spec/api_surface_spec.rb` fails the build in both directions. Publishing an
28
+ enumerated, test-enforced surface under a number that means *this may move* is
29
+ a contradiction, so the number matches the inventory instead.
30
+
31
+ **So the deprecation path below is in force from 1.0.0.** Nothing enumerated
32
+ here is removed without a warning first, and a breaking change waits for 2.0.0.
33
+ A patch release never breaks anything.
34
+
35
+ Two version numbers move independently, and only one of them is what this
36
+ document is about:
37
+
38
+ | | |
39
+ |---|---|
40
+ | `ActiveSanction::VERSION` | The gem. This document governs it. |
41
+ | `ActiveSanction::MATCHER_VERSION` | The matching pipeline. Bumped whenever a change could move a score. |
42
+
43
+ `MATCHER_VERSION` is not a compatibility promise and never gates a rescue or a
44
+ version constraint. It is stamped onto every `MatchResult` so that an auditor
45
+ asking *would this screening have come out the same?* has an answer that a gem
46
+ version cannot give them — a release that only adds a source adapter moves one
47
+ of these numbers and not the other.
48
+
49
+ ## Deprecation
50
+
51
+ Nothing on the enumerated list is removed without a warning first.
52
+
53
+ 1. The release that deprecates something keeps it working and warns.
54
+ 2. It goes on working for **one full minor release** after that one.
55
+ 3. It may be removed in the minor after that.
56
+
57
+ So something deprecated in `1.4.0` works through all of `1.5.x` and may be
58
+ removed in `1.6.0`. An application that upgrades one minor at a time always
59
+ meets the warning at least one release before the breakage.
60
+
61
+ `ActiveSanction::Deprecation.removal_for` computes that date rather than
62
+ leaving it to be remembered, and the warning says it out loud:
63
+
64
+ ```
65
+ active_sanction: ActiveSanction.old_thing is deprecated since 1.4.0 and will
66
+ be removed in 1.6.0. Use ActiveSanction.new_thing instead.
67
+ Called from app/jobs/screen_job.rb:31
68
+ ```
69
+
70
+ **Warnings go through Ruby's own switch.** They are `Kernel#warn` with
71
+ `category: :deprecated`, so `Warning[:deprecated] = false` silences them —
72
+ the same line that silences every other deprecation in a Ruby process, rather
73
+ than a setting of ours that has to be discovered. Ruby's default is off outside
74
+ verbose mode, which is kept: the audience for a deprecation is a developer
75
+ running `ruby -w`, a suite, or a CI build.
76
+
77
+ Each call site warns once, however many times it is reached. A deprecated
78
+ method called while looping over 19,000 records writes one line, not 19,000.
79
+
80
+ Every deprecation also gets a `CHANGELOG.md` entry under `Deprecated` in the
81
+ release that introduces it, and a second under `Removed` in the release that
82
+ carries it out.
83
+
84
+ ## The extension points carry the strongest guarantee
85
+
86
+ Three of these are load-bearing for code that is not in this repository:
87
+
88
+ ```
89
+ ActiveSanction::Sources::Base
90
+ ActiveSanction::Storage::Base
91
+ ActiveSanction::ValidatorStore
92
+ ```
93
+
94
+ Breaking one of them forks every downstream adapter at once — a bank's internal
95
+ watchlist, a store backed by somebody's own database — and those authors are
96
+ not reading this repository's release notes. So the required methods of each,
97
+ their arguments and what they must return do not change within a major version,
98
+ and the shared conformance groups
99
+ ([`spec/active_sanction/sources/conformance_spec.rb`](../spec/active_sanction/sources/conformance_spec.rb),
100
+ [`spec/active_sanction/storage/conformance_spec.rb`](../spec/active_sanction/storage/conformance_spec.rb))
101
+ are the executable statement of what they require. An adapter that passes them
102
+ today passes them for the life of the major version.
103
+
104
+ New *optional* hooks may be added — a method with a default implementation on
105
+ the base class is not a break, because an adapter that does not define it goes
106
+ on working.
107
+
108
+ ## Contracts that are not constants
109
+
110
+ Four promises here are about behaviour rather than about a name, and none of
111
+ them is enforceable by the surface spec.
112
+
113
+ **The error hierarchy.** Within a major version an error does not move to a
114
+ different parent, and no attribute is removed from one. New subclasses may
115
+ appear under an existing parent — that is what keeps `rescue FetchError`
116
+ working when a new transport failure earns a name of its own — so a `case` over
117
+ error classes wants an `else`. `retryable?`, `source_id`, `status` and `to_h`
118
+ are part of the promise; the wording of a message is not, and was never
119
+ something to match on.
120
+
121
+ **The bundle format** is specified in [`bundle_format.md`](bundle_format.md),
122
+ which is the contract — not the Ruby constants that implement it, which are
123
+ private. A bundle carries its own format version, and this gem reads every
124
+ version in its declared readable range. The format is open and unencumbered:
125
+ anyone may produce or consume one, in any language.
126
+
127
+ **The stored snapshot format** carries a schema version for the same reason. A
128
+ store written against one schema version keeps being readable; the file layout
129
+ underneath a shipped store is not public and may change.
130
+
131
+ **A `MatchResult` is reproducible.** The snapshot checksum, matcher version,
132
+ weights and query it stamps are what let a screening decision be re-derived
133
+ years later. Fields may be added to that stamp; the meaning of an existing one
134
+ does not change under it.
135
+
136
+ ## What is deliberately not public
137
+
138
+ Named here because their absence from the list is a decision rather than an
139
+ oversight:
140
+
141
+ - **The matching internals** — `Index`, `Similarity`, `Phonetics`, and the
142
+ scorer's `Adjustments` and `NameScore`. These are where accuracy work
143
+ happens, and accuracy work that had to preserve a signature would stop.
144
+ `Scorer`, `Scorer::Weights` and `Normalizer` are public because a host tunes
145
+ and calls them; the machinery underneath them is not.
146
+ - **`HttpClient`, `Fetcher` and `PayloadCache`** as classes. Their *errors* are
147
+ public, because a host rescues those, but nothing else about how bytes are
148
+ obtained is. A host that wants to control fetching does it through
149
+ `Configuration`.
150
+ - **Every `MEMBERS` list.** They are the serialization order of a value object,
151
+ read by `to_h` and by the snapshot checksum. They look like an enumeration of
152
+ a record's fields and they are not one.
153
+ - **The per-adapter `Record` classes and column constants.** Nothing under
154
+ `Sources::OfacSdn::Record` or its siblings is public: those track what a
155
+ government publishes, and a publisher changing a column is exactly the change
156
+ that must not require a major version here.
157
+ - **The parser toolkits' readers, backends and workbooks.** The toolkits
158
+ themselves are public — they are how an adapter is written — but the classes
159
+ that do the reading underneath them are not.
160
+ - **Anything under `spec/`, `benchmark/`, `canary/` or `bin/`.** None of it
161
+ ships in the gem. The one exception in spirit is the two conformance groups,
162
+ which do not ship either but which an adapter author is expected to run.
163
+
164
+ ## The enumerated public surface
165
+
166
+ Every name below is promised under the rules above. Nothing else is.
167
+
168
+ ### The entry point, and configuration
169
+
170
+ ```
171
+ ActiveSanction
172
+ ActiveSanction::VERSION
173
+ ActiveSanction::MATCHER_VERSION
174
+ ActiveSanction::Client
175
+ ActiveSanction::Configuration
176
+ ActiveSanction::Deprecation
177
+ ActiveSanction::Configuration::DEFAULT_CACHE_DIRNAME
178
+ ActiveSanction::Configuration::DEFAULT_CANDIDATE_LIMIT
179
+ ActiveSanction::Configuration::DEFAULT_DOCTOR_TOLERANCE
180
+ ActiveSanction::Configuration::DEFAULT_MAX_REDIRECTS
181
+ ActiveSanction::Configuration::DEFAULT_MAX_RETRIES
182
+ ActiveSanction::Configuration::DEFAULT_OPEN_TIMEOUT
183
+ ActiveSanction::Configuration::DEFAULT_READ_TIMEOUT
184
+ ActiveSanction::Configuration::DEFAULT_RETAIN_PAYLOADS
185
+ ActiveSanction::Configuration::DEFAULT_RETRY_BACKOFF
186
+ ActiveSanction::Configuration::DEFAULT_SCREENING_LIMIT
187
+ ActiveSanction::Configuration::DEFAULT_SCREENING_THRESHOLD
188
+ ActiveSanction::Configuration::DEFAULT_SOURCES
189
+ ActiveSanction::Configuration::DEFAULT_STALE_AFTER
190
+ ActiveSanction::Configuration::DEFAULT_STORAGE_DIRNAME
191
+ ActiveSanction::Configuration::DEFAULT_SYNC_CONCURRENCY
192
+ ActiveSanction::Configuration::DEFAULT_USER_AGENT
193
+ ActiveSanction::Configuration::DEFAULT_XML_BACKEND
194
+ ```
195
+
196
+ ### The canonical record
197
+
198
+ ```
199
+ ActiveSanction::Entity
200
+ ActiveSanction::Entity::TYPES
201
+ ActiveSanction::Name
202
+ ActiveSanction::Name::KINDS
203
+ ActiveSanction::Name::QUALITIES
204
+ ActiveSanction::Name::SCRIPTS
205
+ ActiveSanction::PartialDate
206
+ ActiveSanction::PartialDate::PRECISIONS
207
+ ActiveSanction::Address
208
+ ActiveSanction::Identifier
209
+ ActiveSanction::Identifier::KINDS
210
+ ActiveSanction::Snapshot
211
+ ActiveSanction::Subject
212
+ ```
213
+
214
+ ### Screening
215
+
216
+ ```
217
+ ActiveSanction::Matcher
218
+ ActiveSanction::Query
219
+ ActiveSanction::MatchResult
220
+ ActiveSanction::Normalizer
221
+ ActiveSanction::Normalizer::Form
222
+ ActiveSanction::Normalizer::Dictionary
223
+ ActiveSanction::Scorer
224
+ ActiveSanction::Scorer::Subject
225
+ ActiveSanction::Scorer::Result
226
+ ActiveSanction::Scorer::Reason
227
+ ActiveSanction::Scorer::Weights
228
+ ActiveSanction::Scorer::Weights::DEFAULTS
229
+ ActiveSanction::Country
230
+ ```
231
+
232
+ ### Sources, and the toolkits an adapter is written with
233
+
234
+ ```
235
+ ActiveSanction::Sources
236
+ ActiveSanction::Sources::Base
237
+ ActiveSanction::Sources::Definition
238
+ ActiveSanction::Sources::Remarks
239
+ ActiveSanction::Sources::OfacSdn
240
+ ActiveSanction::Sources::OfacConsolidated
241
+ ActiveSanction::Sources::UnConsolidated
242
+ ActiveSanction::Sources::CanadaSema
243
+ ActiveSanction::Sources::EuFsf
244
+ ActiveSanction::Sources::UkSanctionsList
245
+ ActiveSanction::Sources::AustraliaDfat
246
+ ActiveSanction::Parsers
247
+ ActiveSanction::Parsers::DelimitedTable
248
+ ActiveSanction::Parsers::DelimitedTable::Row
249
+ ActiveSanction::Parsers::XmlRecords
250
+ ActiveSanction::Parsers::XmlRecords::Record
251
+ ActiveSanction::Parsers::Spreadsheet
252
+ ActiveSanction::Parsers::Spreadsheet::Row
253
+ ActiveSanction::Parsers::Join
254
+ ActiveSanction::Parsers::Warning
255
+ ActiveSanction::Parsers::ColumnShape
256
+ ```
257
+
258
+ ### Storage, and what a fetch remembers
259
+
260
+ ```
261
+ ActiveSanction::Storage
262
+ ActiveSanction::Storage::Base
263
+ ActiveSanction::Storage::Memory
264
+ ActiveSanction::Storage::FileSystem
265
+ ActiveSanction::Storage::ActiveRecord
266
+ ActiveSanction::Storage::Meta
267
+ ActiveSanction::Validators
268
+ ActiveSanction::ValidatorStore
269
+ ActiveSanction::ValidatorStore::FileSystem
270
+ ActiveSanction::ValidatorStore::Memory
271
+ ActiveSanction::Snapshot::Bundle
272
+ ActiveSanction::Snapshot::Bundle::Header
273
+ ```
274
+
275
+ ### Operations
276
+
277
+ ```
278
+ ActiveSanction::Sync
279
+ ActiveSanction::Sync::Report
280
+ ActiveSanction::Sync::Result
281
+ ActiveSanction::Sync::Result::STATUSES
282
+ ActiveSanction::Diff
283
+ ActiveSanction::Diff::Change
284
+ ActiveSanction::Rescreen
285
+ ActiveSanction::Rescreen::Alert
286
+ ActiveSanction::Rescreen::Alert::CHANGES
287
+ ActiveSanction::Doctor
288
+ ActiveSanction::Doctor::Report
289
+ ActiveSanction::Doctor::Diagnosis
290
+ ActiveSanction::Doctor::Diagnosis::STATUSES
291
+ ActiveSanction::Doctor::Finding
292
+ ActiveSanction::Doctor::Finding::SEVERITIES
293
+ ActiveSanction::Doctor::Checkup
294
+ ActiveSanction::Doctor::Profile
295
+ ```
296
+
297
+ ### The error hierarchy
298
+
299
+ ```
300
+ ActiveSanction::Error
301
+ ActiveSanction::ConfigurationError
302
+ ActiveSanction::SourceError
303
+ ActiveSanction::FetchError
304
+ ActiveSanction::ParseError
305
+ ActiveSanction::IntegrityError
306
+ ActiveSanction::StorageError
307
+ ActiveSanction::UnsupportedError
308
+ ActiveSanction::InvalidArgument
309
+ ActiveSanction::QueryError
310
+ ActiveSanction::MissingKey
311
+ ActiveSanction::Sources::DeclarationError
312
+ ActiveSanction::Sources::DuplicateKey
313
+ ActiveSanction::Sources::MissingPayload
314
+ ActiveSanction::Sources::UnknownSource
315
+ ActiveSanction::Parsers::ParseError
316
+ ActiveSanction::Parsers::XmlRecords::MalformedDocument
317
+ ActiveSanction::Storage::CorruptSnapshot
318
+ ActiveSanction::Storage::MissingSnapshot
319
+ ActiveSanction::Storage::UnsupportedSchema
320
+ ActiveSanction::ValidatorStore::CorruptStore
321
+ ActiveSanction::Snapshot::ChecksumMismatch
322
+ ActiveSanction::Snapshot::Bundle::Corrupt
323
+ ActiveSanction::Snapshot::Bundle::UntrustedSignature
324
+ ActiveSanction::Snapshot::Bundle::Unsigned
325
+ ActiveSanction::Snapshot::Bundle::UnsupportedFormat
326
+ ActiveSanction::HttpClient::Error
327
+ ActiveSanction::HttpClient::ConnectionError
328
+ ActiveSanction::HttpClient::TimeoutError
329
+ ActiveSanction::HttpClient::ResponseError
330
+ ActiveSanction::HttpClient::InvalidRedirect
331
+ ActiveSanction::HttpClient::RedirectLoop
332
+ ActiveSanction::HttpClient::TooManyRedirects
333
+ ActiveSanction::PayloadCache::CorruptEntry
334
+ ActiveSanction::PayloadCache::ChecksumMismatch
335
+ ActiveSanction::PayloadCache::PayloadMissing
336
+ ActiveSanction::Matcher::NotSynced
337
+ ActiveSanction::Sync::Failed
338
+ ```
339
+
340
+ ### Also public, and not a constant
341
+
342
+ - Every **public instance and class method** on the types above, and their
343
+ documented keyword arguments. A method that YARD marks `@api private` is not,
344
+ wherever it happens to live.
345
+ - The **module-level shorthand** — `ActiveSanction.screen`, `.sync!`, `.diff`,
346
+ `.rescreen`, `.doctor`, `.export`, `.import`, `.configure`, `.config`,
347
+ `.client`, `.storage`, `.matcher`, `.with_configuration`, `.reset!`,
348
+ `.reload!` — which is the documented quickstart and is the same API as
349
+ `Client`.
350
+ - The **Rails install generator** as a command — `rails generate
351
+ active_sanction:install` — and the schema of the migration it writes. The
352
+ generator *class* is marked private, because nothing outside Rails' own
353
+ generator lookup refers to it by name.
354
+ - The **source keys** — `:ofac_sdn`, `:ofac_consolidated`, `:un_consolidated`,
355
+ `:canada_sema`, `:eu_fsf`, `:uk_sanctions_list`, `:australia_dfat`. A key
356
+ names a list in configuration, in a snapshot and in a stored audit record, so
357
+ it does not change once published.