gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-docs] branch master updated: update KYC manual


From: gnunet
Subject: [taler-docs] branch master updated: update KYC manual
Date: Thu, 08 Aug 2024 22:50:13 +0200

This is an automated email from the git hooks/post-receive script.

grothoff pushed a commit to branch master
in repository docs.

The following commit(s) were added to refs/heads/master by this push:
     new 8e7c0540 update KYC manual
8e7c0540 is described below

commit 8e7c05407299cde7d2126eb92a1d020a239acd01
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Thu Aug 8 22:50:10 2024 +0200

    update KYC manual
---
 core/api-bank-wire.rst                       |  42 +-
 core/api-common.rst                          |  21 +-
 design-documents/023-taler-kyc.rst           |  16 +-
 design-documents/054-dynamic-form.rst        |  34 +-
 design-documents/056-weblate-integration.rst |  78 ++--
 taler-exchange-manual.rst                    |   9 +-
 taler-kyc-manual.rst                         | 610 ++++++++++++++++++---------
 7 files changed, 500 insertions(+), 310 deletions(-)

diff --git a/core/api-bank-wire.rst b/core/api-bank-wire.rst
index 6d667db2..f677152c 100644
--- a/core/api-bank-wire.rst
+++ b/core/api-bank-wire.rst
@@ -71,14 +71,14 @@ Making Transactions
 
 .. http:post:: /transfer
 
-  Initiate a new wire transfer from the exchange's bank account, typically to 
a 
+  Initiate a new wire transfer from the exchange's bank account, typically to a
   merchant.
-  
-  The exchange's bank account is not included in the request, but instead 
-  derived from the username in the ``Authorization`` header and/or the request 
+
+  The exchange's bank account is not included in the request, but instead
+  derived from the username in the ``Authorization`` header and/or the request
   base URL.
 
-  To make the API idempotent, the client must include a nonce. Requests with 
+  To make the API idempotent, the client must include a nonce. Requests with
   the same nonce are rejected unless the request is the same.
 
   **Request:**
@@ -155,9 +155,9 @@ Making Transactions
   **Request:**
 
   :query limit: *Optional.*
-    At most return the given number of results. Negative for descending by 
+    At most return the given number of results. Negative for descending by
     ``row_id``, positive for ascending by ``row_id``. Defaults to ``-20``.
-  :query offset: *Optional.* 
+  :query offset: *Optional.*
     Starting ``row_id`` for :ref:`pagination <row-id-pagination>`.
   :query status: *Optional*.
     Filters by status.
@@ -198,7 +198,7 @@ Making Transactions
       row_id: SafeUint64;
 
       // Current status of the transfer
-      // pending: the transfer is in progress 
+      // pending: the transfer is in progress
       // transient_failure: the transfer has failed but may succeed later
       // permanent_failure: the transfer has failed permanently and will never 
appear in the outgoing history
       // success: the transfer has succeeded  and appears in the outgoing 
history
@@ -244,14 +244,14 @@ Making Transactions
 
     interface TransferStatus {
       // Current status of the transfer
-      // pending: the transfer is in progress 
+      // pending: the transfer is in progress
       // transient_failure: the transfer has failed but may succeed later
       // permanent_failure: the transfer has failed permanently and will never 
appear in the outgoing history
       // success: the transfer has succeeded  and appears in the outgoing 
history
       status: "pending" | "transient_failure" | "permanent_failure" | 
"success";
 
       // Optional unstructured messages about the transfer's status. Can be 
used to document the reasons for failure or the state of progress.
-      status_msg: string?;
+      status_msg?: string;
 
       // Amount to transfer.
       amount: Amount;
@@ -282,10 +282,10 @@ Making Transactions
 Querying the transaction history
 --------------------------------
 
-The exchange's bank account is derived from the username in the 
-``Authorization`` header and/or the request's base URL. In fact, the 
-transaction history may come from a "virtual" account, where several real bank 
-accounts are merged into a single history.  
+The exchange's bank account is derived from the username in the
+``Authorization`` header and/or the request's base URL. In fact, the
+transaction history may come from a "virtual" account, where several real bank
+accounts are merged into a single history.
 
 .. http:get:: /history/incoming
 
@@ -299,7 +299,7 @@ accounts are merged into a single history.
 
   :query limit: *Optional.*
     At most return the given number of results. Negative for descending by 
``row_id``, positive for ascending by ``row_id``. Defaults to ``-20``. Since 
protocol v2.
-  :query offset: *Optional.* 
+  :query offset: *Optional.*
     Starting ``row_id`` for :ref:`pagination <row-id-pagination>`. Since 
protocol v2.
   :query timeout_ms: *Optional.*
     Timeout in milliseconds, for :ref:`long-polling <long-polling>`, to wait 
for at least one element to be shown. Only useful if *limit* is positive. Since 
protocol v2.
@@ -422,7 +422,7 @@ accounts are merged into a single history.
 
   :query limit: *Optional.*
     At most return the given number of results. Negative for descending by 
``row_id``, positive for ascending by ``row_id``. Defaults to ``-20``. Since 
protocol v2.
-  :query offset: *Optional.* 
+  :query offset: *Optional.*
     Starting ``row_id`` for :ref:`pagination <row-id-pagination>`. Since 
protocol v2.
   :query timeout_ms: *Optional.*
     Timeout in milliseconds, for :ref:`long-polling <long-polling>`, to wait 
for at least one element to be shown. Only useful if *limit* is positive. Since 
protocol v2.
@@ -432,7 +432,7 @@ accounts are merged into a single history.
     Deprecated in protocol v2. Use *offset* instead.
   :query long_poll_ms: *Optional.*
     Deprecated in protocol v2. Use *timeout_ms* instead.
-  
+
   **Response:**
 
   :http:statuscode:`200 OK`:
@@ -511,8 +511,8 @@ exposed by bank gateways in production.
       reserve_pub: EddsaPublicKey;
 
       // Account (as payto URI) that makes the wire transfer to the exchange.
-      // Usually this account must be created by the test harness before this 
-      // API is used. An exception is the "fakebank", where any debit account 
+      // Usually this account must be created by the test harness before this
+      // API is used. An exception is the "fakebank", where any debit account
       // can be specified, as it is automatically created.
       debit_account: string;
     }
@@ -572,8 +572,8 @@ exposed by bank gateways in production.
       account_pub: EddsaPublicKey;
 
       // Account (as payto URI) that makes the wire transfer to the exchange.
-      // Usually this account must be created by the test harness before this 
-      // API is used. An exception is the "fakebank", where any debit account 
+      // Usually this account must be created by the test harness before this
+      // API is used. An exception is the "fakebank", where any debit account
       // can be specified, as it is automatically created.
       debit_account: string;
     }
diff --git a/core/api-common.rst b/core/api-common.rst
index b9634c24..ef47107b 100644
--- a/core/api-common.rst
+++ b/core/api-common.rst
@@ -222,9 +222,9 @@ Common query patterns
 Row ID pagination
 ^^^^^^^^^^^^^^^^^
 
-Some endpoints paginate elements identified by an opaque numeric identifier, 
-referred to here as *row ID*. The semantics of the row ID (including its 
-sorting order) are determined by the server and are completely opaque to the 
+Some endpoints paginate elements identified by an opaque numeric identifier,
+referred to here as *row ID*. The semantics of the row ID (including its
+sorting order) are determined by the server and are completely opaque to the
 client.
 
 The list of returned elements is determined by a row ID *offset*
@@ -243,9 +243,9 @@ If *offset* is not explicitly given, it defaults to:
 * A value **larger** than all other row IDs if *limit* is **negative**.
 
 :query limit: *Optional.*
-  At most return the given number of results. Negative for descending by row 
+  At most return the given number of results. Negative for descending by row
   ID, positive for ascending by row ID.
-:query offset: *Optional.* 
+:query offset: *Optional.*
   Starting row ID for an iteration.
 
 .. _long-polling:
@@ -253,15 +253,15 @@ If *offset* is not explicitly given, it defaults to:
 Long polling
 ^^^^^^^^^^^^
 
-Endpoints can result in an empty response (pagination) or a negative response 
-(uncompleted operation, etc). Some endpoints allow clients to perform a form 
of 
-long polling by asking the server to wait until *timeout_ms* for a non-empty 
or 
+Endpoints can result in an empty response (pagination) or a negative response
+(uncompleted operation, etc). Some endpoints allow clients to perform a form of
+long polling by asking the server to wait until *timeout_ms* for a non-empty or
 positive result.
 
-In the case of pagination, the response is sent as soon as a matching element 
+In the case of pagination, the response is sent as soon as a matching element
 is found and, therefore, the response MAY contain fewer than *limit* elements.
 
-A client MUST never rely on this behavior, as a response can be sent 
+A client MUST never rely on this behavior, as a response can be sent
 immediately or after waiting only a fraction of *timeout_ms*.
 
 :query timeout_ms: *Optional.*
@@ -654,6 +654,7 @@ Unblinded coin
   }
 
 .. ts:def:: CsUnblindedSignature
+
   // Note, this is here for the sake of completeness, but not yet supported
   interface CsUnblindedSignature {
     cipher: "CS";
diff --git a/design-documents/023-taler-kyc.rst 
b/design-documents/023-taler-kyc.rst
index 23533443..5113d81f 100644
--- a/design-documents/023-taler-kyc.rst
+++ b/design-documents/023-taler-kyc.rst
@@ -421,17 +421,12 @@ This has several advantages:
   we can even deploy this without fully updating the logic everywhere to
   distinguish KYC transfers
 
-TODO: update wire gateway specification, update/new tables for KYC wire
-transfers, update API spec for attestation, update exchange API (below) to
-signal need for auth-payment via wire transfer, update merchant logic to
-expose merchant public key to SPA for wire transfer if needed for KYC.
-
 
 451 Response
 ^^^^^^^^^^^^
 
 When KYC operations are required, various endpoints may respond with a
-``451 Unavailable for Legal Reasons`` status code and a 
`LegitimziationNeededResponse`
+``451 Unavailable for Legal Reasons`` status code and a 
`LegitimizationNeededResponse`
 body.
 
 New endpoints
@@ -958,11 +953,6 @@ description of the high-level process for different 
providers.
   # (when run regularly).
   CONVERTER = taler-exchange-helper-$NAME
 
-  # Optional cost, useful if clients want to voluntarily
-  # trigger authentication procedures for attestation.
-  # Since **vATTEST**.
-  COST = EUR:5
-
   # Plus additional logic-specific options, e.g.:
   AUTHORIZATION_TOKEN = superdupersecret
 
@@ -1066,8 +1056,8 @@ configuration section:
   [kyc-rule-$RULE_NAME]
 
   # Operation that triggers this rule.
-  # Must be one of WITHDRAW, DEPOSIT, P2P-RECEIVE
-  # or WALLET-BALANCE.
+  # Must be one of WITHDRAW, DEPOSIT, MERGE,
+  # AGGREGATE or BALANCE.
   OPERATION_TYPE = WITHDRAW
 
   # Space-separated list of next measures to be performed.
diff --git a/design-documents/054-dynamic-form.rst 
b/design-documents/054-dynamic-form.rst
index 5567fc60..e69b80c5 100644
--- a/design-documents/054-dynamic-form.rst
+++ b/design-documents/054-dynamic-form.rst
@@ -1,10 +1,12 @@
-DD 54: Dynamic Form
-###################
+.. _dd54dynamicforms:
+
+DD 54: Dynamic Forms
+####################
 
 Summary
 =======
 
-This document outlines the design of forms defined in the 
+This document outlines the design of forms defined in the
 backend in a JSON file which will be rendered by a client
 for asking information to a person.
 
@@ -15,7 +17,7 @@ Motivation
 Currently, creating a new form for a web app involves coding a new
 page with HTML, CSS, and JS. Exchange AML requires multiple forms,
 and different instances may have distinct forms based on jurisdiction.
-Being able to define forms in a JSON file that a client software 
+Being able to define forms in a JSON file that a client software
 (not just web SPA) could use to ask the information helps to change
 it without requiring a new upgrade of the client app.
 
@@ -23,7 +25,7 @@ it without requiring a new upgrade of the client app.
 Requirements
 ============
 
-A form consist of a layout, a set of fields and metadata required to 
+A form consist of a layout, a set of fields and metadata required to
 recognice which form configuration was used to produce the saved value.
 
 Layout requirements
@@ -85,7 +87,7 @@ Form configuration
 
 Defies a basic structure and the set of fields the form is going to have.
 
-The ``FormConfiguration`` is an enumerated type which list can be extended in 
the 
+The ``FormConfiguration`` is an enumerated type which list can be extended in 
the
 future.
 
 .. code-block:: typescript
@@ -159,10 +161,10 @@ configuration to show a field.
 
     /* if the field should be initially hidden */
     hidden?: boolean;
-    
+
   };
 
-That will be enough for a decorative form element (like group element or 
+That will be enough for a decorative form element (like group element or
 a text element) but if it defines an input field then it should extend
 from ``UIFormFieldBaseConfig`` which add more information to the previously
 defined ``UIFieldElementDescription``.
@@ -190,20 +192,20 @@ defined ``UIFieldElementDescription``.
   };
 
   /**
-   * string which defined a json path 
-   * 
+   * string which defined a json path
+   *
    */
   type UIHandlerId = string
 
 
-The ``id`` property defines the location in which this information is going 
+The ``id`` property defines the location in which this information is going
 to be saved in the JSON result. Formally formally, it should be a 
``dot-selector``
 
 .. code-block:: ini
 
   dot-selector    = "." dot-member-name
   dot-member-name = name-first *name-char
-  name-first = ALPHA / "_" 
+  name-first = ALPHA / "_"
   name-char = DIGIT / name-first
 
   DIGIT           =  %x30-39              ; 0-9
@@ -213,14 +215,14 @@ to be saved in the JSON result. Formally formally, it 
should be a ``dot-selector
 All the input fields will create a string value located where the id
 points, unless a ``convertedId`` is specified. The ``convertedId`` is a 
reference
 to a converter that the client software implements. For example, an input field
-with ``convertedId = "Taler.Amount"`` will transform the value the user 
+with ``convertedId = "Taler.Amount"`` will transform the value the user
 entered into a *AmountString* with the currency in the configuration.
 
 
 Description of supported fields
 -------------------------------
 
-All of this fields defines an UI handler which help the user to input 
+All of this fields defines an UI handler which help the user to input
 the value with as handy as possible. The type of the field doesn't define
 the type of the value in the resulting JSON, that's defined by the 
``converterId``.
 
@@ -383,8 +385,8 @@ Money input.
 List input
 ``````````
 
-This input allows to enter more than element in the same field, and the 
-resulting JSON will have a json list. The UI should show the elements 
+This input allows to enter more than element in the same field, and the
+resulting JSON will have a json list. The UI should show the elements
 already present in the list, and for that it will use ``labelFieldId``.
 
 .. code-block:: typescript
diff --git a/design-documents/056-weblate-integration.rst 
b/design-documents/056-weblate-integration.rst
index a27b93c2..6569b9a5 100644
--- a/design-documents/056-weblate-integration.rst
+++ b/design-documents/056-weblate-integration.rst
@@ -4,69 +4,69 @@ DD 56: Weblate integration
 Summary
 =======
 
-We are using `Weblate <https://weblate.taler.net/>`__ to translate string in 
all 
-software components. Weblate should be able to read which strings needs to be 
-translated and return a translated version of the string for all the languages 
-supported. 
+We are using `Weblate <https://weblate.taler.net/>`__ to translate string in 
all
+software components. Weblate should be able to read which strings needs to be
+translated and return a translated version of the string for all the languages
+supported.
 
 Motivation
 ==========
 
-Every development ecosystem has it's own i18n framework. 
+Every development ecosystem has it's own i18n framework.
 
 * Android has strings.xml
 * Apple has Localizable.strings but it's deprecated
 * We are using gettext PO as default
 
 
-There is no standard file format in iOS, the current suggested format 
-is not supported by Weblate and looks like it's never going to be a 
+There is no standard file format in iOS, the current suggested format
+is not supported by Weblate and looks like it's never going to be a
 open documentation about it:
 
 from `Apple developer forum 
<https://forums.developer.apple.com/forums/thread/732120?answerId=756602022#756602022>`__
 
-  String Catalogs store an entire string table in a single JSON file, 
-  even if there are a large number of keys and languages. If this ends 
+  String Catalogs store an entire string table in a single JSON file,
+  even if there are a large number of keys and languages. If this ends
   up presenting a problem (with Xcode's performance, for example), please send
   some feedback our way.
-  As for the specifics of the JSON format itself, we have not published 
-  documentation because it is primarily intended to be read/written by Xcode. 
-  If you do end up writing your own parser for this format, please be aware 
+  As for the specifics of the JSON format itself, we have not published
+  documentation because it is primarily intended to be read/written by Xcode.
+  If you do end up writing your own parser for this format, please be aware
   that Xcode reserves the right to change it.
 
 
 What we are doing right now
 ---------------------------
 
-How strings are generated
+How strings are generated:
 
-*Android*: 
+*Android*:
   Defines a key (like "send_deposit_amount_effective" or "amount_effective"),
   this key has a default English translation in **strings.xml** and some other 
langs in **strings-{lang}.xml**.
 
-*iOS*: 
+*iOS*:
   Uses the English text in the source code, or can also use a key.
   It has just one file with translations, **Localizable.xcstrings**.
 
-*SPA*: 
+*SPA*:
   It has the English string enclosed with i18n reference
   and all those strings ends up in a file **src/i18n/strings.ts** which maps 
the English
   sentence with a translated phrase. (the english sentence is used as a key)
 
 For the integration in to weblate:
 
-*Android*: 
-  Weblate just takes **strings.xml** and **strings-{lang}.xml**, creates a 
list of all 
+*Android*:
+  Weblate just takes **strings.xml** and **strings-{lang}.xml**, creates a 
list of all
   strings to be translated and once you add new value for untranslated string 
or
-  change an existing one it modifies the correct file and commit with the new 
XML. 
+  change an existing one it modifies the correct file and commit with the new 
XML.
   The project will automatically take this values.
 
-*iOS*: 
+*iOS*:
   No integration has been found.
 
-*SPA*: 
-  The **strings.ts** file is not recognized by Weblate, so we generate **.po** 
files 
-  which are supported by weblate. We have a script (pogen) that parses all the 
source code and 
+*SPA*:
+  The **strings.ts** file is not recognized by Weblate, so we generate **.po** 
files
+  which are supported by weblate. We have a script (pogen) that parses all the 
source code and
   generate **.po** files, PO files are understood by Weblate and it will 
appear in the webapp
   to be translated. Once the translator change some strings the PO files are 
updated with
   the translations. When the changes are push into the repo, the developer can 
run a second
@@ -99,8 +99,8 @@ That will mean:
 3. translators translate and push changes
 4. dev run script to sync **file-that-weblate-understands.po** with 
**Localizable.xcstrings**
 
-We only need to use our existing software **pogen** to create **po** files 
from the 
-**Localizable.xcstrings** which seems really easy. And then also update the 
+We only need to use our existing software **pogen** to create **po** files 
from the
+**Localizable.xcstrings** which seems really easy. And then also update the
 **Localizable.xcstrings** from the updated **po** files.
 
 This will not stop us from using XLIFF exporting/importing.
@@ -112,26 +112,26 @@ We can split the problem in topics
 
 Using the same i18n key between apps:
   we should stick to DD53 Wallet Design and use this to define
-  which strings developers should use. If the string is defined 
-  there then it should be used in the code. That will create a spec 
+  which strings developers should use. If the string is defined
+  there then it should be used in the code. That will create a spec
   for the 3 platforms and it should use the same key.
 
-Using translation memory in weblate config: 
-  from weblate documenantion, this can be used to automatically 
+Using translation memory in weblate config:
+  from weblate documenantion, this can be used to automatically
   share translations.
 
 Using context keys for short keys:
   Sometimes the words like "close" or "transfer" could have separated
   meaning depending on the context. For that cases we have the
-  **msgctxt** (that is additional key in addition to the short 
-  sentence). Only same sentence with same context are equivalent. 
-  We can also add some more context, like a link to the screenshot 
-  in the design document so we can trigger an alarm if an image in the 
-  weblate translation is out of sync with an image in DD 53. 
-
-Using images in weblate: 
-  We should keep DD 53 updated (with the screens and text) and add 
-  information in the string sentence (like context) to point into 
+  **msgctxt** (that is additional key in addition to the short
+  sentence). Only same sentence with same context are equivalent.
+  We can also add some more context, like a link to the screenshot
+  in the design document so we can trigger an alarm if an image in the
+  weblate translation is out of sync with an image in DD 53.
+
+Using images in weblate:
+  We should keep DD 53 updated (with the screens and text) and add
+  information in the string sentence (like context) to point into
   the right location.
 
 
@@ -165,5 +165,3 @@ Drawbacks
 
 Discussion / Q&A
 ================
-
-
diff --git a/taler-exchange-manual.rst b/taler-exchange-manual.rst
index c0b99422..08c786cd 100644
--- a/taler-exchange-manual.rst
+++ b/taler-exchange-manual.rst
@@ -46,9 +46,12 @@ Organizational prerequisites
 
 Operating a GNU Taler exchange means that you are operating a payment service
 provider, which means that you will most likely need a bank license and/or
-follow applicable financial regulation. Exceptions may apply, especially if
-you are operating a regional currency or a payment system for an event with a
-closed user group.
+follow applicable financial regulation. The :ref:`Exchange KYC/AML Operator
+Manual <KycOperatorManual>` goes into depth for how an exchange can be
+configured for compliance.  Exceptions to compliance rules may apply,
+especially if you are operating a regional currency or a payment system for an
+event with a closed user group.  If in doubt, please contact a competent
+lawyer in your country about the legality of operating a GNU Taler exchange.
 
 GNU Taler payment service providers generally need to ensure high availability
 and should have *really* good backups (synchronous replication, asynchronous
diff --git a/taler-kyc-manual.rst b/taler-kyc-manual.rst
index eb818957..dd76e6b4 100644
--- a/taler-kyc-manual.rst
+++ b/taler-kyc-manual.rst
@@ -57,8 +57,8 @@ Legal conditions for using the service
 .. include:: frags/legal.rst
 
 
-KYC Configuration
-=================
+Know-Your-Customer Setup
+========================
 
 To legally operate, Taler exchange operators may have to comply with KYC
 regulation that requires financial institutions to identify parties involved
@@ -71,7 +71,7 @@ know-your-business (KYB) data under the following 
circumstances:
   * Wallet receives (via refunds) money resulting in a balance over a threshold
   * Wallet receives money via P2P payments over a threshold
   * Merchant receives money over a threshold
-  * Merchant deposits digital cash over a threshold (**planned feature**)
+  * Merchant deposits digital cash over a threshold (**planned feature, bug 
9040**)
   * Reserve is "opened" for invoicing (**planned feature**)
 
 Any of the above requests can trigger the KYC process,
@@ -84,118 +84,145 @@ original request, and assuming KYC was successful, the
 request should then succeed.
 
 
-Taler KYC Terminology
----------------------
+KYC Terminology
+---------------
+
+* **Attributes**: Attributes are used to represent KYC data obtained about
+  an account holder. Attributes include passport images, address data,
+  business registration documents, and indeed arbitrary forms filed by
+  AML staff or the customer themselves.  Attribute data is considered
+  sensitive private information and is thus stored encrypted within the
+  exchange database.
 
 * **Check**: A check establishes a particular attribute of a user, such as
   their name based on an ID document and lifeness, mailing address, phone
-  number, taxpayer identity, etc.
-
-* **Type of operation**: The operation type determines which Taler-specific
-  operation has triggered the KYC requirement. We support four types of
-  operation: withdraw (by customer), deposit (by merchant), P2P receive (by
-  wallet) and (high) wallet balance.
+  number, taxpayer identity, etc.  Checks may be given *context* (such as
+  whether a customer is an individual or a business) to run correctly. Checks
+  can also be AML staff inserting information for plausibilization.  Checks
+  result in *attributes* about the account's owner which are given to an
+  external AML *program* together with the *context* to determine an *outcome*.
+  KYC checks are always specified with a fallback *measure* to be taken if
+  the check fails.
 
 * **Condition**: A condition specifies when KYC is required. Conditions
   include the *type of operation*, a threshold amount (e.g. above EUR:1000)
   and possibly a time period (e.g. over the last month).
 
-* **Cost**: Metric for the business expense for a KYC check at a certain
-  *provider*. Not in any currency, costs are simply relative and non-negative
-  values. Costs are considered when multiple choices are allowed by the
-  *configuration*.
-
-* **Expiration**: KYC legitimizations may be outdated. Expiration rules
-  determine when *checks* have to be performed again.
-
-* **Legitimization rules**: The legitimization rules determine under which
-  *conditions* which *checks* must be performend and the *expiration* time
-  period for the *checks*.
+* **Configuration**: The configuration determines the *legitimization rules*,
+  and specifies which providers offer which *checks*.
+
+* **Context**: Context is information provided as input into a *check* and
+  *program* to customize their execution. The context is initially set by the
+  *measure* (possibly including data from the *trigger*).  Naturally, the
+  *program* may use its `AmlProgramInput` which includes *context* and
+  *attribute* data to compute an update *context* for the next set of
+  *measures* that it specifies in the `LegitimizationRuleSet` as part
+  of the `AmlOutcome`.  Thus, *context* is something that typically
+  evolves as the *account* undergoes *measures*.  Context is lost if
+  an account transitions to default *legitimization rules* due to
+  *expiration*.
+
+* **Display priority**: Every rule has a *display priority*. If a second
+  *rule* is *triggered* before the *outcome* of a *rule* could be determined,
+  the *rule* with the larger *display priority* becomes the requirement that
+  the account owner has to satisfy (and that thus will be displayed by the
+  KYC SPA).
+
+* **Expiration**: Except for the default rules, any set of KYC rules is
+  subject to *expiration*. This can be because *attributes* become outdated or
+  because sanctions have a time limit. The expiration time thus determines
+  when a new *measure* is triggered in the absence of a transaction crossing
+  thresholds in the current set of *legtimization rules*.
+
+* **Legitimization rules**: The *legitimization rules* determine under which
+  *conditions* which *measures* will be taken. A `LegitimizationRuleSet`
+  always also includes an *expiration* time period for (custom, non-default)
+  *legitimization rules* after which a fallback measure* will automatically
+  apply.  Legitimization rules may be *exposed* to the client (for example,
+  to allow a wallet to stay below hard withdraw thresholds) or could be secret.
 
 * **Logic**: Logic refers to a specific bit of code (realized as an exchange
   plugin) that enables the interaction with a specific *provider*.  Logic
-  typically requires configuration for access control (such as an
+  typically requires *configuration* for access control (such as an
   authorization token) and possibly the endpoint of the specific *provider*
   implementing the respective API.
 
+* **Measure**: Describes the possible outgoing edges from one state in the
+  state machine (including how to show the current state). Each edge is given
+  some *context* and a *check* to be performed as well as an AML *program*
+  which determines the *outcome*.  We generally distinguish between
+  "original" measures (defined globally in the exchange configuration) and
+  "custom" measures (defined specifically for an account by AML staff).
+
+* **Outcome**: An `AmlOutcome` describes the account state that an account
+  ends up in due to either an AML staff action or an AML *program* doing some
+  computation over the attributes resulting from a *check*.  Outcomes can be
+  that certain types of transactions are "verboten", that the account is (or
+  remains) under investigation by AML staff, that the account is given certain
+  properties, and/or that certain events are to be logged. Outcomes also
+  include a new set of *legitimization rules* to apply (and an *expiration*
+  time at which point a successor *measure* will be automatically taken).
+
 * **Provider**: A provider performs a specific set of *checks* at a certain
   *cost*. Interaction with a provider is performed by provider-specific
   *logic*.
 
-Configuration of possible KYC/AML checks
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The configuration specifies a set of possible KYC checks offered by external
-providers.  The names of the configuration sections must being with
-``kyc-check-`` followed by an arbitrary ``$CHECK_NAME``.
-
-The list of possible FORM names is fixed in the SPA
-for a particular exchange release.
+* **Program**: An AML helper *program* is given *context* about the current
+  state of an account and the attribute data from a *check* to compute the
+  *outcome*.  For example, a *program* may look at the "PEP" field of a KYC
+  check and decide if the outcome is to put the account into ``normal`` or
+  ``held-for-manual-review`` state.  AML programs are always specified
+  with a fallback *measure* to be taken if the program fails.
 
-The outcome of *any* check should always be uploaded encrypted into the
-``kyc_attributes`` table.  It MUST include an ``expiration_time``.
+* **Trigger**: A specific transaction that satisfies a **Condition**.
 
+* **Type of operation**: The operation type determines which Taler-specific
+  operation has triggered the KYC requirement. We support four types of
+  operation: withdraw (by customer), deposit (by merchant),
+  aggregate transfer (to merchant), P2P receive (by wallet) and
+  (high) wallet balance.
 
 
-KYC Configuration Options
--------------------------
+Configuration of possible KYC/AML providers
+-------------------------------------------
 
 The KYC configuration determines the *legitimization rules*, and specifies
-which providers offer which *checks* at what *cost*.
+which providers offer which *checks*.
 
-The configuration specifies a set of providers, one per configuration section. 
The names of the configuration
-sections must being with ``kyc-proider-`` followed by
-an arbitrary ``$PROVIDER_ID``:
+The configuration specifies a set of providers, one per configuration
+section. The names of the configuration sections must being with
+``kyc-proider-`` followed by an arbitrary ``$PROVIDER_ID``:
 
 .. code-block:: ini
   :caption: /etc/taler/conf.d/exchange-kyc-providers.conf
 
   [kyc-provider-$PROVIDER_ID]
-  # How expensive is it to use this provider?
-  # Used to pick the cheapest provider possible.
-  COST = 42
+
   # Which plugin is responsible for this provider?
   # Choices include "oauth2", "kycaid" and "persona".
   LOGIC = oauth2
-  # Which type of user does this provider handle?
-  # Either INDIVIDUAL or BUSINESS.
-  USER_TYPE = INDIVIDUAL
-  # Which checks does this provider provide?
-  # List of strings, no specific semantics.
-  PROVIDED_CHECKS = SMS GOVID PHOTO
-  # Plus additional logic-specific options, e.g.:
-  AUTHORIZATION_TOKEN = superdupersecret
-  FORM_ID = business_legi_form
-  # How long is the check considered valid?
-  EXPIRATION = 3650d
 
-The configuration also must specify a set of legitimization requirements, 
again one
-per configuration section:
+  # Name of a program to run on the output of the plugin
+  # to convert the result into the desired set of attributes.
+  # The converter must create a log for the system administrator
+  # if the provided inputs do not match expectations.
+  # Note that the converter will be expected to output the
+  # set of attributes listed under the respective ``[kyc-check-*]``
+  # sections. Calling the converter with ``--list-outputs``
+  # should generate a (newline-separated) list of attributes
+  # the converter promises to generate in its JSON output
+  # (when run regularly).
+  CONVERTER = taler-exchange-helper-$NAME
 
-.. code-block:: ini
-  :caption: /etc/taler/conf.d/exchange-kyc-rules.conf
+  # Plus additional logic-specific options, e.g.:
+  AUTHORIZATION_TOKEN = superdupersecret
 
-  [kyc-legitimization-$RULE_NAME]
-  # Operation that triggers this legitimization.
-  # Must be one of WITHDRAW, DEPOSIT, P2P-RECEIVE
-  # or WALLET-BALANCE.
-  OPERATION_TYPE = WITHDRAW
-  # Required checks to be performed.
-  # List of strings, must individually match the
-  # strings in one or more provider's PROVIDED_CHECKS.
-  REQUIRED_CHECKS = SMS GOVID
-  # Threshold amount above which the legitimization is
-  # triggered.  The total must be exceeded in the given
-  # timeframe.
-  THRESHOLD = KUDOS:100
-  # Timeframe over which the amount to be compared to
-  # the  THRESHOLD is calculated.  Can be 'forever'.
-  # Ignored for WALLET-BALANCE.
-  TIMEFRAME = 30d
+  # Other logic-specific internal options (example):
+  FORM_ID = business_legi_form
 
 
 OAuth 2.0 specifics
--------------------
+^^^^^^^^^^^^^^^^^^^
 
 In terms of configuration, the OAuth 2.0 logic requires the respective client
 credentials to be configured apriori to enable access to the legitimization
@@ -260,9 +287,8 @@ configuration above and an exchange running on the host
 ``https://exchange.example.com/kyc-proof/kyc-provider-challenger-oauth2/``.
 
 
-
 Persona specifics
------------------
+^^^^^^^^^^^^^^^^^
 
 We use the hosted flow. The Persona endpoints return a ``request-id``, which
 we log for diagnosis.
@@ -323,7 +349,7 @@ based on the attributes collected by the specific template.
 
 
 KYC AID specifics
------------------
+^^^^^^^^^^^^^^^^^
 
 We use the hosted flow.
 
@@ -362,143 +388,204 @@ need to be adjusted based on the attributes collected 
by the specific
 template.
 
 
+Configuration of possible KYC/AML checks
+----------------------------------------
 
-AML Configuration
-=================
-
-The AML configuration steps are used to add or remove keys of exchange
-operator staff that are responsible for anti-money laundering (AML)
-compliance.  These AML officers are shown suspicious transactions and are
-granted access to the KYC data of an exchange. They can then investigate the
-transaction and decide on freezing or permitting the transfer. They may also
-request additional KYC data from the consumer and can change the threshold
-amount above which a further AML review is triggered.
-
-AML Officer Setup
------------------
-
-To begin the AML setup, AML staff should launch the GNU Taler
-exchange AML SPA Web interface. (FIXME-Sebastian: how?). The
-SPA will generate a public-private key pair and store it in the
-local storage of the browser.  The public key will be displayed
-and must be securely transmitted to the offline system for
-approval.  Using the offline system, one can then configure
-which staff has access to the AML operations:
-
-.. code-block:: shell-session
-
-  [root@exchange-offline]# taler-exchange-offline \
-     aml-enable $PUBLIC_KEY "Legal Name" rw > aml.json
-  [root@exchange-online]# taler-exchange-offline \
-     upload < aml.json
-
-The above commands would add an AML officer with the given "Legal Name" with
-read-write (rw) access to the AML officer database.  Using "ro" instead of
-"rw" would grant read-only access to the data, leaving out the ability to
-actually make AML decisions.  Once AML access has been granted, the AML
-officer can use the SPA to review cases and (with "rw" access) take AML
-decisions.
-
-Access rights can be revoked at any time using:
+The configuration specifies a set of possible KYC checks offered by external
+providers, one per configuration section.  The names of the configuration
+sections must being with ``kyc-check-`` followed by an arbitrary
+``$CHECK_NAME``.
 
-.. code-block:: shell-session
+.. code-block:: ini
 
-  [root@exchange-offline]# taler-exchange-offline \
-     aml-disable $PUBLIC_KEY "Legal Name" > aml-off.json
-  [root@exchange-online]# taler-exchange-offline \
-     upload < aml-off.json
+  [kyc-check-$CHECK_NAME]
+
+  # Which type of check is this? Also determines
+  # the SPA form to show to the user for this check.
+  #
+  # INFO: wait for staff or contact staff out-of band
+  #          (only information shown, no SPA action)
+  # FORM: SPA should show an inline (HTML) form
+  # LINK: SPA may start external KYC process or upload
+  #
+  TYPE = INFO|LINK|FORM
+
+  # Optional. Set to YES to allow this check be
+  # done voluntarily by a client (they may then
+  # still have to pay for it). Used to offer the
+  # SPA to display checks even if they are
+  # not required. Default is NO.
+  # Since **vATTEST**.
+  VOLUNTARY = YES/NO
+
+  # Provider id, present only if type is LINK.
+  # Refers to a ``kyc-provider-$PROVIDER_ID`` section.
+  PROVIDER_ID = id
+
+  # Name of the SPA form, if type is FORM
+  # "INFO" and "LINK" are reserved and must not be used.
+  # The exchange server and the SPA must agree on a list
+  # of supported forms and the resulting attributes.
+  #
+  # The SPA should include a JSON resource file
+  # "forms.json" mapping form names to arrays of
+  # attribute names each form provides.
+  FORM_NAME = name
+
+  # Descriptions to use in the SPA to display the check.
+  DESCRIPTION = "Upload your passport picture"
+  DESCRIPTION_I18N = "{"en":"Upload scan of your passport"}"
+
+  # ';'-separated list of fields that the CONTEXT must
+  # provide as inputs to this check. For example,
+  # for a FORM of type CHOICE, this might state
+  # ``choices: string[];``. The type after the ":"
+  # is for now purely for documentation and is
+  # not checked. However, it may be shown to AML staff
+  # when they configure measures.
+  REQUIRES = requirement;
+
+  # Description of the outputs provided by the check.
+  # Basically, the check's output is expected to
+  # provide the following fields as attribute inputs into
+  # a subsequent AML program.
+  # Only given for type FORM; INFO never has any outputs,
+  # and for type LINK we can obtain the same information
+  # from the CONVERTER via ``--list-outputs``.
+  OUTPUTS = business_name street city country registration
+
+  # **original** measure to take if the check fails
+  # (for any reason, e.g. provider or form fail to
+  # satisfy constraints or provider signals user error)
+  # Usually should point to a measure that requests
+  # AML staff to investigate.  The fallback measure
+  # context always includes the reasons for the
+  # failure.
+  FALLBACK = MEASURE_NAME
 
+The list of possible FORM names is fixed in the SPA
+for a particular exchange release.
 
-AML Triggers
-------------
+The "check_name" value "skip" is reserved and must not be defined. It can be
+used in measures where the AML program must be run immediately without any
+input.
 
-AML decision processes are automatically triggered under certain configurable
-conditions.  The primary condition that *must* be configured is the
-``AML_THRESHOLD``:
+The outcome of *any* check is stored encrypted in the ``kyc_attributes``
+table.  It MUST include an ``expiration_time``.
 
-.. code-block:: ini
-  :caption: /etc/taler/conf.d/exchange-business.conf
 
-  [exchange]
-  # Accounts or wallets with monthly transaction volumes above this threshold
-  # are considered suspicious and are automatically flagged for AML review
-  # and put on hold until an AML officer has reached a decision.
-  AML_THRESHOLD = "EUR:1000000"
+Configuration of legitimization rules
+-------------------------------------
 
-Additionally, certain KYC attributes (such as the user being a
-politically exposed person) may lead to an account being
-flagged for AML review.  The specific logic is configured by
-providing the exchange with an external helper program that
-makes the decision given the KYC attributes:
+The configuration also must specify a set of legitimization rules, one per
+configuration section. Each rule specifies the condition and the measure the
+condition triggers:
 
 .. code-block:: ini
-  :caption: /etc/taler/conf.d/exchange-business.conf
 
-  [exchange]
-  # Specifies a program to run on KYC attribute data to decide
-  # whether we should immediately flag an account for AML review.
-  KYC_AML_TRIGGER = taler-exchange-kyc-aml-pep-trigger.sh
+  [kyc-rule-$RULE_NAME]
 
-The given program will be given the KYC attributes in JSON format on standard
-input, and must return 0 to continue without AML and non-zero to flag the
-account for manual review.  To disable this trigger, simply leave the option to
-its default value of '[/usr/bin/]true'. To flag all new users for manual
-review, simply set the program to '[/usr/bin/]false'.
+  # Operation that triggers this rule.
+  # Must be one of WITHDRAW, DEPOSIT, MERGE,
+  # AGGREGATE or BALANCE.
+  OPERATION_TYPE = WITHDRAW
 
-AML Forms
----------
+  # Space-separated list of next measures to be performed.
+  # The SPA should display *all* of these measures to the user.
+  # (They have a choice of either which ones, or in
+  # which order they are to be performed.)
+  # A special measure name "verboten" is used if the
+  # specified threshold may never be crossed
+  # (under this set of rules).
+  NEXT_MEASURES = SWISSNESS KYB
+
+  # "YES" if all NEXT_MEASURES will eventually need
+  # to be satisfied, "NO" if the user has a choice between
+  # them. Not actually enforced by the exchange, but
+  # primarily used to inform the user whether this is
+  # an "and" or "or". YES for "and".
+  IS_AND_COMBINATOR = YES
+
+  # YES if the rule (specifically, operation type,
+  # threshold, timeframe) and the general nature of
+  # the next measure (verboten or approval required)
+  # should be exposed to the client.
+  # Defaults to NO if not set.
+  EXPOSED = YES
+
+  # Threshold amount above which the rule is
+  # triggered.  The total must be exceeded in the given
+  # timeframe.
+  THRESHOLD = KUDOS:100
 
-AML forms are defined by the DD 54 dynamic forms.
-The shipped implementation with of the exchange is installed in
+  # Timeframe over which the amount to be compared to
+  # the THRESHOLD is calculated.
+  # Ignored for WALLET-BALANCE.  Can be 'forever'.
+  TIMEFRAME = 30 days
 
-.. code-block:: shell-session
+  # Set to YES to enable the rule (default is NO)
+  ENABLED = NO
 
-  ${INSTALL_PREFIX}/share/taler/exchange/spa/forms.js
 
+Configuration of AML programs
+-----------------------------
 
-The variable ``form`` contains the list of all form available. For
-every entry in the list the next properties are expected to be present:
+AML decision processes are automatically executed under certain configurable
+conditions.  Basically, any AML program that is run can flag an account for
+investigation by setting the respective flag in the `AmlOutcome`. Once this
+happens, the respective account will be highlighted to AML staff. The AML
+program can also limit the operations of the account by setting arbitrary
+thresholds for the various operations (including freezing the account by
+setting the thresholds to zero). AML staff investigating the account can then
+request further documentation or set new rules, including new thresholds.
 
-``label``: used in the UI as the name of the form
+AML programs can base their decisions on arbitrary attributes created by the
+KYC check (such as the user being a politically exposed person).
 
-``id``: identification name, this will be saved in the exchange database
-along with the values to correctly render the form again.
-It should simple, short and without any character outside numbers,
-letters and underscore.
+AML programs will be given the KYC attributes in JSON format on standard
+input, and must output the `AmlOutcome`. If AML programs fail (return non-zero
+status codes), a FALLBACK measure is automatically triggered.
 
-``version``: when editing a form, instead of just replacing fields
-it will be better to create a new form with the same id and new version.
-That way old forms in the database will used old definition of the form.
-It should be a number.
+AML programs are listed in the configuration file, one program per section:
 
-``impl`` : a function that returns the design and behavior of form.
-See DD 54 dynamic forms.
+.. code-block:: ini
 
-.. attention::
+  [aml-program-$PROG_NAME]
 
-  do not remove a form the list if it has been used. Otherwise you
-  won't be able to see the information save in the exchange database.
+  # Program to run.
+  COMMAND = taler-helper-aml-pep
 
-To add a new one you can simply copy and paste one element, and edit it.
+  # Human-readable description of what this
+  # AML helper program will do. Used to show
+  # to the AML staff.
+  DESCRIPTION = "check if the customer is a PEP"
 
-It is much easier to download ``@gnu-taler/aml-backoffice-ui`` source
-from ``https://git.taler.net/wallet-core.git/``, compile and copy the file
-from the ``dist/prod``.
+  # True if this AML program is enabled (and thus can be
+  # used in measures and exposed to AML staff).
+  # Optional, default is NO.
+  ENABLED = YES
 
+  # **original** measure to take if COMMAND fails
+  # Usually points to a measure that asks AML staff
+  # to contact the systems administrator. The fallback measure
+  # context always includes the reasons for the
+  # failure.
+  FALLBACK = MEASURE_NAME
 
-AML Programs
-------------
+Implementing your own AML programs
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-AML programs are helper programs that can:
+When implementing an AML program, developers must
+ensure to provide three main execution paths:
 
 * Generate a list of *required* context field names
-  for the helper (introspection!) using the "--required-context"
+  for the helper (introspection!) when given the "--required-context"
   command-line switch. The output should use the same
   syntax as the REQUIRES clause of ``[kyc-check-]``
   configuration sections, except that new lines
   MUST be used to separate fields instead of ";".
 * Generate a list of *required* attribute names
-  for the helper (introspection!) using the "--required-attributes"
+  for the helper (introspection!) when given the "--required-attributes"
   command-line switch. The output should use the same
   list of names as the ATTRIBUTES in the
   ``[kyc-provider-]`` configuration section
@@ -509,6 +596,11 @@ AML programs are helper programs that can:
   This is the default behavior if no command-line switches
   are provided.
 
+If the AML program fails (exits with a failure code or does not provide
+well-formed JSON output) the AML/KYC process continues with the FALLBACK
+measure. This should usually be one that asks AML staff to contact the systems
+administrator.
+
 .. ts:def:: AmlProgramInput
 
   interface AmlProgramInput {
@@ -639,31 +731,136 @@ process continues with the FALLBACK measure. This should
 usually be one that asks AML staff to contact the
 systems administrator.
 
-AML programs are listed in the configuration file, one program per section:
+
+
+Configuration of measures
+-------------------------
+
+Finally, the configuration specifies a set of
+**original** *measures* one per configuration section:
 
 .. code-block:: ini
 
-  [aml-program-$PROG_NAME]
+  [kyc-measure-$MEASURE_NAME]
 
-  # Program to run.
-  COMMAND = taler-helper-aml-pep
+  # Possible check for this measure.  Optional.
+  # If not given (or set to "SKIP"), PROGRAM should
+  # be run immediately (on an empty set of attributes).
+  CHECK_NAME = IB_FORM
 
-  # Human-readable description of what this
-  # AML helper program will do. Used to show
-  # to the AML staff.
-  DESCRIPTION = "check if the customer is a PEP"
+  # Context for the check. The context can be
+  # just an empty JSON object if there is none.
+  CONTEXT = {"choices":["individual","business"]}
 
-  # True if this AML program is enabled (and thus can be
-  # used in measures and exposed to AML staff).
-  # Optional, default is NO.
-  ENABLED = YES
+  # Program name to run on the context and check data to
+  # determine the outcome and next measure.
+  # Refers to a ``[aml-program-$PROG_NAME]`` section name.
+  PROGRAM = taler-aml-program
+
+If ``CHECK_NAME`` is set to "SKIP" (or is not provided at all), the AML
+``PROGRAM`` is to be run immediately.  This is useful if no client-interaction
+is required to arrive at a decision.
+
+.. note::
+
+  The list of *measures* in the configuration is not complete: AML staff may
+  freely define new measures dynamically, usually by selecting checks, an AML
+  program, and providing context.  The measures specified in the configuration
+  are called the *original measures* and only those can be used as FALLBACK
+  measures.
+
+
+
+AML Configuration
+=================
+
+The AML configuration steps are used to add or remove keys of exchange
+operator staff that are responsible for anti-money laundering (AML)
+compliance.  These AML officers are shown suspicious transactions and are
+granted access to the KYC data of an exchange. They can then investigate the
+transaction and decide on new rules for the respective user. They may request
+additional KYC data from the consumer, can change the thresholds up to which
+amounts transactions are allowed, and associate properties with the account
+that AML programs (and AML officers) may interpret for arbitrary future
+actions.
+
+
+AML Officer Setup
+-----------------
+
+To begin the AML setup, AML staff should launch the GNU Taler exchange AML SPA
+Web interface by going to the ``/aml-spa/`` endpoint of the exchange. This is
+generally a public endpoint, but of course an operator may restrict access via
+the reverse proxy. The SPA will generate a public-private key pair and store
+it in the local storage of the browser.  The public key will be displayed and
+**must** be securely transmitted to the offline system for approval.  Using the
+offline system, one can then configure which staff has access to the AML
+operations:
+
+.. code-block:: shell-session
+
+  [root@exchange-offline]# taler-exchange-offline \
+     aml-enable "$PUBLIC_KEY" "Legal Name" rw > aml.json
+  [root@exchange-online]# taler-exchange-offline \
+     upload < aml.json
+
+The above commands would add an AML officer with the given "Legal Name" with
+read-write (rw) access to the AML officer database.  Using "ro" instead of
+"rw" would grant read-only access to the data, leaving out the ability to
+actually make AML decisions.  Once AML access has been granted, the AML
+officer can use the SPA to review cases and (with "rw" access) take AML
+decisions.
+
+Access rights can be revoked at any time using:
+
+.. code-block:: shell-session
+
+  [root@exchange-offline]# taler-exchange-offline \
+     aml-disable $PUBLIC_KEY "Legal Name" > aml-off.json
+  [root@exchange-online]# taler-exchange-offline \
+     upload < aml-off.json
+
+
+AML Forms
+---------
+
+AML forms are defined by the :ref:`dynamic forms design document 
<dd54dynamicforms>`.
+The shipped implementation with of the exchange is installed in
+
+.. code-block:: shell-session
+
+  ${INSTALL_PREFIX}/share/taler/exchange/spa/forms.js
+
+
+The variable ``form`` contains the list of all form available. For
+every entry in the list the next properties are expected to be present:
+
+``label``: used in the UI as the name of the form
+
+``id``: identification name, this will be saved in the exchange database
+along with the values to correctly render the form again.
+It should simple, short and without any character outside numbers,
+letters and underscore.
+
+``version``: when editing a form, instead of just replacing fields
+it will be better to create a new form with the same id and new version.
+That way old forms in the database will used old definition of the form.
+It should be a number.
+
+``impl`` : a function that returns the design and behavior of form.
+See DD 54 dynamic forms.
+
+.. attention::
+
+  do not remove a form the list if it has been used. Otherwise you
+  won't be able to see the information save in the exchange database.
+
+To add a new one you can simply copy and paste one element, and edit it.
+
+It is much easier to download ``@gnu-taler/aml-backoffice-ui`` source
+from ``https://git.taler.net/wallet-core.git/``, compile and copy the file
+from the ``dist/prod``.
 
-  # **original** measure to take if COMMAND fails
-  # Usually points to a measure that asks AML staff
-  # to contact the systems administrator. The fallback measure
-  # context always includes the reasons for the
-  # failure.
-  FALLBACK = MEASURE_NAME
 
 AML Measures
 ------------
@@ -702,16 +899,16 @@ a decision.
 
 .. _ExchangeTemplateCustomization:
 
-Template Customization
-======================
+KYC Process Template Customization
+==================================
 
-The Exchange comes with various HTML templates that are shown to
-guide users through the KYC process. The Exchange uses `C implementation of 
mustache
+The Exchange comes with various HTML templates that are shown to guide users
+through the KYC process. The Exchange uses `C implementation of mustache
 <https://gitlab.com/jobol/mustach>`__ as the templating engine.  This section
 describes the various templates.  In general, the templates must be installed
-to the ``share/taler/exchange/templates/`` directory. The file names must be of
-the form ``$NAME.$LANG.must`` where ``$NAME`` is the name of the template and
-``$LANG`` is the 2-letter language code of the template. English templates
+to the ``share/taler/exchange/templates/`` directory. The file names must be
+of the form ``$NAME.$LANG.must`` where ``$NAME`` is the name of the template
+and ``$LANG`` is the 2-letter language code of the template. English templates
 must exist and will be used as a fallback.  If the browser (user-agent) has
 provided language preferences in the HTTP header and the respective language
 exists, the correct language will be automatically served.
@@ -784,9 +981,8 @@ This template is instantiated using the following 
information:
 oauth2-authorization-failure
 ----------------------------
 
-The OAuth2 server refused to return the KYC data
-because the authorization code provided was
-invalid (HTTP 403 Forbidden).
+The OAuth2 server refused to return the KYC data because the authorization
+code provided was invalid (HTTP 403 Forbidden).
 
 This template is instantiated using the following information:
 

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]