Metanorma machine-readable requirements ("MRR") requirements model scheme
General
Metanorma machine-readable requirements ("MRR") is a generic requirements model scheme developed according to the needs of NIST and ITU with a focus on machine-readability.
This document describes the models provided by the MRR scheme and their usage.
Understanding MRR
The major benefit of MRR, in comparison with other requirements model schemes, is its focus on making requirements machine-readable and executable.
Many standards and specifications today are meant for encoding data and behavioral requirements intended for machines or software. Instead of needing human intervention or re-interpretation of these requirements for machines, it is possible to streamline the semantics between the specification of requirements and the machine usage of such requirements.
MRR was originally announced at the ISO/TMB/SAG_MRS ("Special Advisory Group for Machine-Readable Standards") in 2019, and placed into production the same year.
Note
|
The Multi-Modal Modelling Language ("MMEL"), a core component of the BSI SMART program supported by the Ministry of Defense, UK, is implemented as a superset of MRR. |
Use cases supported by MRR include:
-
representation of a requirements collection or a requirements graph of a coherent set of compliance criteria;
-
automated validation of the consistency of a set of requirements;
-
automated execution of automated processing steps as specified by as requirements;
-
automated compliance checks against machine-readable verification tests.
The architecture of MRR is described in the MRR model diagram.
MRR provides:
-
Two core classes:
-
Provision
-
ProvisionPart
-
-
Three models that can be instantiated:
-
Requirement
-
Recommendation
-
Permission
-
The three instantiable models provide the basis for encoding machine-readable requirements. The only difference between these three models is the obligation, which binds the subject to a different strength in terms of compliance.
One aspect that MRR differs from other requirements model schemes is that it relies on "components" to differentiate roles of provisions. (see Components for details). Components may be targeted towards human- or machine-readability.
Instances
Instance syntax
The method of encoding an MRR model follows the general syntax described in requirements.
The encoding syntax is as follows, where the block definition describes the type of the model.
[permission]
====
This is the permission statement.
====
Note
|
Additional examples of MRR encodings are available at metanorma-mrr-samples. |
When using MRR within other documents that, by default, uses another
requirements model scheme, it is necessary specify the instance with the model
attribute.
[requirement,model=mrr]
====
This is an MRR requirement
====
Instance attributes
An MRR model instance is encoded with one of these block types:
-
[requirement]
for Requirement -
[recommendation]
for Recommendation -
[permission]
for Permission
All instantiable models in MRR share the same set of attributes.
The following attributes are supported:
model
-
(optional) The requirement model scheme that applies to the instance. (default:
basic
) type
-
(optional) The model of the instance, typically not necessary given the type has been specified at the block level (e.g.
permission
). identifier
-
The identifier assigned to an instance. Identifiers can be simple strings, and are often entered as URIs or URNs. If present, it will be rendered in final output. [added in https://github.com/metanorma/metanorma-standoc/releases/tag/v2.2.0]
Noteidentifier
was previously calledlabel
. classification
-
May be used to give an arbitrary number of key-value pairs of tags describing the instance. Key and value are separated by a colon, multiple values are delimited by comma, and key-value pairs are delimited by semicolon. Both key and value are expected to be tokens containing no punctuation.
obligation
-
(optional) Modality of the instance, as in the strength to which it pertains to compliance. Can contain one or more of
requirement
,permission
,recommendation
, comma-delimited. Using this attribute will override the obligation of the requirement. inherit
-
May be used to reference the label of a requirement or definition that is imported or presupposed by this requirement. Can contain multiple semicolon-delimited identifiers. [added in https://github.com/metanorma/metanorma-standoc/releases/tag/v1.3.14].
Multiple instances of
inherit
can also be expressed with theinherit
command, which can contain markup including cross-references [added in https://github.com/metanorma/metanorma-standoc/releases/tag/v1.3.21].inherit:[<<ref1>>]
class
-
Declares a custom category of provisions labelled and numbered separately to "requirements", "recommendations" and "permissions" [added in https://github.com/metanorma/mn-requirements/releases/tag/v0.4.1].
Example 3. Rendering of a custom category called "Provision"[requirement] -- [%metadata] class:: Provision -- [requirement] -- -- [requirement] -- [%metadata] class:: Provision --
Rendered as:
Provision 1
Requirement 1
Provision 2
Any attributes that are not included in the list of requirement attributes above are treated as "classification tags". [added in https://github.com/metanorma/metanorma-standoc/releases/tag/v2.2.0]
Components
Component types
Components are a core part of how to represent content within MRR instances.
The recognized component types are:
-
Specification:
specification
-
Measurement target:
measurement-target
(for quantitative requirements) -
Verification steps:
verification
(verification steps for the requirement) -
Behavioral interfaces (code stubs):
import
-
Undifferentiated components:
component
[added in https://github.com/metanorma/metanorma-standoc/releases/tag/v1.10.4]
Components of a requirement can be encoded in order to make it machine-readable in Metanorma normative outputs, although this is not expected to be reflected in renderings.
Component syntax
Components are encoded within an MRR instance using named blocks. Each block needs to be named with the kind of component it contains as a role attribute.
A component block is encoded using the following mechanisms:
-
open blocks, which are marked up with a succession of two or more hyphens (
--
,---
…), [added in https://github.com/metanorma/metanorma-standoc/releases/tag/v1.10.6] -
example blocks, which are marked up with a succession of four or more equals signs (
====
,=====
…).
Any text not wrapped in a named block is considered to be part of the description of the outermost MRR instance (e.g. a requirement).
[requirement]
====
[specification]
--
This is a formal specification
--
[measurement-target]
=====
This is a measurement target
=====
[verification]
--
This is a verification step
--
[import]
--
This is a code stub
--
====
Component types
Specification
A specification is a formal statement that describes the object of the requirement.
The specification component is identified by the specification
type.
[requirement]
====
[specification]
--
An identifier shall be unique.
--
====
Specifications can be described with machine-readable content. These components
can be specified with the classification of type:{specification-type}
.
In the following example, an OpenAPI specification is used directly to specify requirements on the subject.
[requirement]
====
[%metadata]
identifier:: /openapi/3.0/
classification:: type:openapi
[specification]
--
[source,yaml]
----
include::openapi.yaml[]
----
--
====
Measurement target
A measurement target indicates the target that a measurement is to be taken from, in order to express quantitative requirements.
The measurement target component is identified by the measurement-target
type.
[requirement]
====
[measurement-target]
--
The value for stem:[alpha] shall be within 0.1 and 0.3.
--
====
Verification steps
A verification component provides verification steps for the MRR instance. This is typically a set of sequential steps that verifies compliance towards the instance.
The measurement target component is identified by the verification
type,
with contents encoded as an ordered list.
[requirement]
====
[%metadata]
identifier:: /ss/584/2015/level/1
subject:: The Cloud Service Provider's management and board of directors
classification:: type:text
[specification]
--
. Managing information security risks related to people, process, technology and
governance.
. Oversight of the effective implementation of the technology controls.
. Oversight of risk management practices.
--
[verification]
--
. Determine that the responsibilities of management and board of directors in
managing and overseeing information security risks are documented and
communicated.
. Inspect documents such as meeting minutes and committee charter to identify
the participants involved in the meeting or committee, their respective job
functions and the reporting relationship.
. Determine whether the management and board of directors meet regularly, at an
appropriate and monitored frequency.
. Determine whether the information security function is headed by a Chief
Information Security Officer (CISO) or similar function.
--
====
Behavioral interfaces
A behavioral interface specifies compliance conditions of the target subject, by specifying the desired behavior of the subject.
A behavioral interface can be specified with a mix of human-readable and machine-readable content.
The behavioral interface component is specified with the import
type.
Depending on the language used within the import
block, different attributes
are available.
Note
|
The term "interface" originates from its meaning from programming languages, and can be considered a way of entering "acceptance tests". |
.Generic Structure for Permutation Testing
[requirement]
====
[%metadata]
identifier:: /iid-testing/permutation-test/
[description]
--
Input:: stem:[S = (s_1, ... s_L)]
Output:: Decision on the IID assumption
--
[verification]
--
. For each test stem:[i]
.. Assign the counters stem:[C_(i, 0)] and stem:[C_(i, 1)] to zero.
.. Calculate the test statistic stem:[T_(i)] on stem:[S].
. For stem:[j = 1] to 10 000
.. Permute stem:[S] using the Fisher-Yates shuffle algorithm.
.. For each test stem:[i]
... Calculate the test statistic stem:[T] on the permuted data.
... If (stem:[T > T_(i)]), increment stem:[C_(i, 0)]. If (stem:[T = T_(i)]),
increment stem:[C_(i, 1)].
. If ( (stem:[C_(i, 0) + C_(i, 1) <= 5]) or (stem:[C_(i, 0) >= 9995]) ) for any
stem:[i], reject the IID assumption; else, assume that the noise source
outputs are IID.
--
[import, type="pseudo-fortress", run="DecideIID"]
----
import FisherYatesShuffle, TestStatistic
DecideIID(S: ZZ[], L: RR) : Boolean =
for i <- 1 : L do
C[i, 0] <- 0, C[i, 1] <- 0
T[i] <- TestStatistic(S)
end
for j <- 1 : 10000 do
S' <- FisherYatesShuffle(S)
for i <- 1: L do
T <- TestStatistic(S')
if T' > T'[i]
C[i, 0] <- C[i, 0] + 1
end
if T' == T[i]
C[i, 1] <- C[i, 1] + 1
end
end
end
for i <- 1 : L do
if (C[i, 0] + C[i, 1] <= 5) or (C[i, 0] >= 9995)
return false
end
end
return true
----
====
Custom components
A custom component (not among the defined components allowed) can be encoded
using the class
attribute, to specify the particular kind of component. If no
such attribute is given, the default value is the undifferentiated component
(component
) [added in https://github.com/metanorma/metanorma-standoc/releases/tag/v1.10.4].
[requirement]
====
[component,class=conditions]
--
The following conditions need to be fulfilled in this requirement...
--
====
Machine-readable components
General
Any component may include or consist of machine-readable code.
Components can be specified with a "type" if they are intended to be machine-readable. The "type" refers to the conventions or computer frameworks that they follow.
They are given by setting the type
attribute on the component block:
[requirement]
====
[%metadata]
identifier:: requirement A
This is some descriptive text.
[specification,type=ABNF]
--
[source,abnf]
----
status = ( "draft" / "cancelled" ) / stage
stage = "stage-" stagecode ["." iteration]
stagecode = DIGIT DIGIT "." DIGIT DIGIT
iteration = "v" DIGITS
----
--
This is some more descriptive text.
====
Source code as specification
Such content is to be provided within a [source]
block, which is expected to
contain an attribute giving the computer language the block is expressed in.
Note
|
The notion of "language" may be expanded to include a particular computer framework that the code is to be run under. |
It is also possible specify “source code” that is meant to be human readable,
by [source,text]
.
The language of a source code block is likely to be distinct from the type of named block it is contained in.
[requirement]
====
[%metadata]
identifier:: Requirement A
This is some descriptive text.
[verification,type=heuristic]
--
[source,ruby]
----
instances.each do |i|
warn "uh-oh" if i > 5
end
----
--
====
Machine-readable content as alternative representation
By default, all components and descriptions will be included in final output.
Often, though not always, components can contain machine-readable code which is not intended to be included in the output, but is supplemental to the human-readable description.
That is signalled through the options attribute exclude
on the named block.
[recommendation]
====
[%metadata]
identifier:: /ogc/recommendation/wfs/2
subject:: user
I recommend _this_.
[specification,type="tabular"]
--
This is the object of the recommendation:
|===
|Object |Value
|Mission | Accomplished
|===
--
As for the measurement targets,
[measurement-target]
--
The measurement target shall be measured as:
[stem]
++++
r/1 = 0
++++
--
[verification,type="comprehensive"]
--
The following code will be run for verification:
[source,CoreRoot]
----
CoreRoot(success): HttpResponse
if (success)
recommendation(label: success-response)
end
----
--
[import%exclude]
--
[source,CoreRoot]
----
success-response()
----
--
====
Nested requirements
Nested requirements can be encoded with a combination of internal blocks.
MRR requirements can be nested by adding one or more delimiter symbols than its containing block.
[permission]
====
The permission statement surrounded by 4 delimiter symbols.
[example]
=====
An example within the permission surrounded by 5 delimiter symbols.
=====
[permission]
=====
A sub-permission surrounded by 5 delimiter symbols.
=====
[requirement]
=====
A requirement if the permission is adopted.
=====
====
Note
|
Nested requirements are marked up just like nested examples. |
[requirement]
====
[%metadata]
identifier:: requirement A
[requirement]
=====
[%metadata]
identifier:: requirement A1
[specification]
--
This is a formal specification.
--
=====
[requirement]
=====
[%metadata]
identifier:: requirement A2
[measurement-target]
--
This is a measurement target.
--
=====
====