<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://home-mandate.org/changelog/</id>
	<title>Home-Mandate Specification changelog</title>
	<updated>2026-11-04T00:00:00Z</updated>
	<author><name>Home-Mandate Specification</name></author>
	<link rel="self" type="application/atom+xml" href="https://home-mandate.org/changelog/feed.xml"/>
	<link rel="alternate" type="text/html" href="https://home-mandate.org/changelog/"/>
	<entry>
		<id>https://home-mandate.org/changelog/#v011-2026-11-04</id>
		<title>v0.1.1</title>
		<updated>2026-11-04T00:00:00Z</updated>
		<link rel="alternate" type="text/html" href="https://home-mandate.org/changelog/#v011-2026-11-04"/>
		<content type="html" xml:lang="en">&lt;p&gt;Corrections and a security fix. The &lt;code&gt;type&lt;/code&gt; of every format stays the same. Three things can
change an outcome, each named below: a noncharacter is no longer accepted in a new document,
a leap second in an audit entry stops verifying in the reference verifier, and a signature
under an Ed25519 key of small order stops verifying.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Correction &lt;code&gt;noncharacters&lt;/code&gt; (Section 14, a new kind of change, and &lt;code&gt;data/corrections-v0.json&lt;/code&gt;):
RFC 7493 forbids noncharacters in member names and string values, and Section 3.1 item 1
refers to it, but the list in that item did not name them and the reference implementation
accepted them. Item 1 now names them, and Section 9.1 names input that is not I-JSON among
what the log cannot record. A new entry &lt;strong&gt;MUST NOT&lt;/strong&gt; contain one. A verifier keeps accepting
them in existing audit logs, so that no unaltered log becomes invalid; the outcome of the
verification does not change. A stored document with a noncharacter is attributed as
before (Section 4.3). No valid mandate changes: the free-form strings of a mandate are
displayed text, which excludes noncharacters already, or printable ASCII. New conformance
cases &lt;code&gt;a213&lt;/code&gt; to &lt;code&gt;a220&lt;/code&gt;, &lt;code&gt;i158&lt;/code&gt; to &lt;code&gt;i163&lt;/code&gt;, &lt;code&gt;g24&lt;/code&gt;, &lt;code&gt;s29&lt;/code&gt;, &lt;code&gt;d52&lt;/code&gt;; beyond the correction, they
cover duplicate names after escapes, every form of a lone surrogate, the legal pair and the
number examples of RFC 7493.&lt;/li&gt;&lt;li&gt;Audit entries: a leap second in &lt;code&gt;recorded_at&lt;/code&gt;, &lt;code&gt;request.time&lt;/code&gt; or &lt;code&gt;approval.at&lt;/code&gt; is invalid, as
Section 3.1 item 0 says and the schema&amp;apos;s description already referred to. The pattern in
both schemas now excludes it. The reference verifier accepted it; spec-ts did not. This is
not a correction (Section 14), because implementations did not read it alike, so a log with
such an entry stops verifying in the reference verifier. No writer I know of produces one.&lt;/li&gt;&lt;li&gt;A &lt;code&gt;seq&lt;/code&gt; that is no integer, however close, gives &lt;code&gt;broken_at&lt;/code&gt; 0 (Section 9.4); the reference
verifier read it through floating point. A zero is zero whatever its exponent (Section 3.2),
also beyond the range of a machine integer: such documents become valid in the reference
implementation, as Section 14 allows.&lt;/li&gt;&lt;li&gt;Test interface: a &lt;code&gt;time&lt;/code&gt; that does not fit the grammar of RFC 3339 is not readable (Section
10.2). The reference harness and its checkpoint signing accepted offsets such as &lt;code&gt;+24:00&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;New conformance cases &lt;code&gt;a221&lt;/code&gt; to &lt;code&gt;a228&lt;/code&gt;, &lt;code&gt;c243&lt;/code&gt; to &lt;code&gt;c251&lt;/code&gt;, &lt;code&gt;d53&lt;/code&gt;, &lt;code&gt;i164&lt;/code&gt; to &lt;code&gt;i175&lt;/code&gt;, which also
cover bidirectional controls and separators in displayed text, field by field.&lt;/li&gt;&lt;li&gt;Security (GHSA-grm8-w7m9-fxj9), Section 7.1: an Ed25519 public key of small order is
rejected, because with it a signature verifies for every message of a class; the member
names of a JWK and a JWK Set are case-sensitive, &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt; allow no other character, and
a member &lt;code&gt;d&lt;/code&gt; with any value is a private key. One such key makes the whole key set unusable.
Section 10.2: &lt;code&gt;verify_signed&lt;/code&gt; with such a key set answers &lt;code&gt;{&amp;quot;valid&amp;quot;: false}&lt;/code&gt;. This can change
an outcome: a signed mandate or a checkpoint verified with a key of small order stops
verifying. That is the purpose, since anyone could
have produced those signatures. A key that combines a normal point with one of small order
stays accepted: only its holder can sign with it, so nothing can be forged. New conformance
cases &lt;code&gt;g25&lt;/code&gt; to &lt;code&gt;g35&lt;/code&gt;; checkpoints are covered by a test of the reference code.&lt;/li&gt;&lt;/ul&gt;</content>
	</entry>
	<entry>
		<id>https://home-mandate.org/changelog/#v010-2026-11-02</id>
		<title>v0.1.0</title>
		<updated>2026-11-02T00:00:00Z</updated>
		<link rel="alternate" type="text/html" href="https://home-mandate.org/changelog/#v010-2026-11-02"/>
		<content type="html" xml:lang="en">&lt;p&gt;First release without a pre-release suffix. The v0 formats (mandate, audit entry, audit
checkpoint) and the vocabulary &lt;code&gt;v0&lt;/code&gt; are frozen from this release on (Section 14). The
entries below are every change since the rename, through the pre-releases &lt;code&gt;v0.1.0-alpha.1&lt;/code&gt;
to &lt;code&gt;v0.1.0-rc.5&lt;/code&gt; and the changes after &lt;code&gt;v0.1.0-rc.5&lt;/code&gt;; &lt;code&gt;v0.1.0&lt;/code&gt; itself changes no rule, format
or conformance case (conformance manifest of commit 116d009).&lt;/p&gt;&lt;p&gt;Renamed: the specification formerly published as mandate-spec is now the &lt;strong&gt;Home-Mandate
Specification&lt;/strong&gt;; repository &lt;code&gt;github.com/home-mandate/spec&lt;/code&gt;, Go module
&lt;code&gt;github.com/home-mandate/spec&lt;/code&gt;, root package &lt;code&gt;spec&lt;/code&gt;. Versions start again at
&lt;code&gt;v0.1.0-alpha.1&lt;/code&gt;. The releases of mandate-spec (up to &lt;code&gt;v0.2.0-alpha.5&lt;/code&gt;) remain available
from the Go module proxy under the module path &lt;code&gt;github.com/mandate-spec/mandate-spec&lt;/code&gt;; their
changes are listed below.&lt;/p&gt;&lt;p&gt;Audit mode (Sections 2, 3, 3.1, 3.2, 3.5, 4, 4.1, 4.4, 4.6, 6, 8, 9.1, 9.2, 9.4, 10, 11,
12, 13):&lt;/p&gt;&lt;ul&gt;&lt;li&gt;New optional member &lt;code&gt;enforce&lt;/code&gt; of the mandate, only ever &lt;code&gt;false&lt;/code&gt; (&lt;code&gt;true&lt;/code&gt;, a string, a
number or &lt;code&gt;null&lt;/code&gt; are invalid, and a rule has no &lt;code&gt;enforce&lt;/code&gt;). A mandate with
&lt;code&gt;enforce: false&lt;/code&gt; is in audit mode: a &lt;code&gt;deny&lt;/code&gt; that results from its rules (&lt;code&gt;no_match&lt;/code&gt; or a
&lt;code&gt;deny&lt;/code&gt; rule) for an action that is not critical is evaluated and recorded but not
enforced; the PEP executes the request as if it were allowed. Critical actions, &lt;code&gt;ask&lt;/code&gt;,
&lt;code&gt;allow&lt;/code&gt;, every denial before the rules (invalid mandate or request, unknown resource,
category or action, revoked, not yet valid, expired) and every denial outside the
evaluation (rate limit, emergency stop, authentication, approval) are enforced as
before. The mandate &lt;code&gt;type&lt;/code&gt; stays &lt;code&gt;https://home-mandate.org/mandate/v0&lt;/code&gt;. Compatible:
every mandate that was valid stays valid, is evaluated the same way and keeps its
digest.&lt;/li&gt;&lt;li&gt;The result of the evaluation carries &lt;code&gt;enforced: false&lt;/code&gt; for such a &lt;code&gt;deny&lt;/code&gt;; the decision
stays &lt;code&gt;deny&lt;/code&gt;. In AuthZEN it is a member of the response context (Section 6); a PEP that
does not know it enforces the denial. In the test interface it is a member of the
&lt;code&gt;evaluate&lt;/code&gt; and &lt;code&gt;select&lt;/code&gt; response and compared over HTTP (Section 10); the conformance
cases have the new field &lt;code&gt;enforced&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;Audit entry: &lt;code&gt;evaluation.enforced&lt;/code&gt; (only &lt;code&gt;false&lt;/code&gt;, only for a &lt;code&gt;decision&lt;/code&gt; with
&lt;code&gt;evaluation.decision: deny&lt;/code&gt; and reason &lt;code&gt;no_match&lt;/code&gt; or &lt;code&gt;rule&lt;/code&gt;); only with it may a &lt;code&gt;deny&lt;/code&gt;
be &lt;code&gt;executed&lt;/code&gt; or &lt;code&gt;failed&lt;/code&gt;, and it is never &lt;code&gt;denied&lt;/code&gt; unless it also carries &lt;code&gt;confirm&lt;/code&gt;
(see &amp;quot;Audit mode and &lt;code&gt;ask&lt;/code&gt;&amp;quot; below). The audit &lt;code&gt;type&lt;/code&gt; stays
&lt;code&gt;https://home-mandate.org/audit/v0&lt;/code&gt;. Compatible for logs: every entry that was valid
stays valid. A verifier that does not know the member rejects a log that contains it
(Section 14, unknown members).&lt;/li&gt;&lt;li&gt;With &lt;code&gt;evaluation.enforced: false&lt;/code&gt;, an entry names &lt;code&gt;request&lt;/code&gt; with the &lt;code&gt;category&lt;/code&gt; of the
resource; it is invalid for a resource marked &lt;code&gt;critical&lt;/code&gt; (except for &lt;code&gt;read&lt;/code&gt;), and a
verifier &lt;strong&gt;MUST&lt;/strong&gt; reject it for an action that is critical in the vocabulary or not in it
(Sections 9.1, 9.4); &lt;code&gt;request.resource.critical&lt;/code&gt; is then required, &lt;code&gt;true&lt;/code&gt; or &lt;code&gt;false&lt;/code&gt;, so
that the marking cannot be left out. The reference verifier (&lt;code&gt;audit&lt;/code&gt;) checks this
against vocabulary v0 and against extension vocabularies it is given
(&lt;code&gt;audit.Options.Vocabularies&lt;/code&gt;, &lt;code&gt;audit.VerifyWith&lt;/code&gt;, &lt;code&gt;audit.VerifyJSONLinesWith&lt;/code&gt;); without
the vocabulary of an extension, a verifier cannot check its critical actions.&lt;/li&gt;&lt;li&gt;Obligations of the PEP (Section 11.6): the agent is told nothing about audit mode, nor
which resources of a request for several were not enforced (Section 4.4);
implementations &lt;strong&gt;MUST&lt;/strong&gt; show audit mode wherever they show mandates and &lt;strong&gt;SHOULD&lt;/strong&gt; warn when a
resource marked critical can be read under it; switching it is a &lt;code&gt;mandate.updated&lt;/code&gt;. An
implementation that does not offer audit mode &lt;strong&gt;MUST&lt;/strong&gt; refuse to store a mandate with
&lt;code&gt;enforce: false&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;Switching audit mode on (a mandate with &lt;code&gt;enforce: false&lt;/code&gt; while no mandate with its &lt;code&gt;id&lt;/code&gt;
in audit mode is valid, active and in force, which includes a predecessor that is
revoked, expired or not yet valid, a mandate from outside and a restore from a backup)
&lt;strong&gt;MUST&lt;/strong&gt; be confirmed explicitly by a human of the household before it takes effect, also
for a signed successor. The confirmation is bound to the digest of the version that is
adopted. Every approver &lt;strong&gt;MUST&lt;/strong&gt; be notified when the switch is proposed and when it takes
effect (Sections 3.5, 4.6, 11.6). Switching it off needs no confirmation.&lt;/li&gt;&lt;li&gt;A confirmed &lt;code&gt;ask&lt;/code&gt; is not executed if the evaluation before the execution yields any
&lt;code&gt;deny&lt;/code&gt;, enforced or not; it is recorded with the confirmed &lt;code&gt;ask&lt;/code&gt;, &lt;code&gt;approved&lt;/code&gt; and
&lt;code&gt;denied_by: mandate&lt;/code&gt; (Sections 9.1, 11.1 item 6).&lt;/li&gt;&lt;li&gt;Conformance cases &lt;code&gt;c174&lt;/code&gt;–&lt;code&gt;c192&lt;/code&gt; (new mandate &lt;code&gt;conformance/mandates/audit-mode.json&lt;/code&gt;),
&lt;code&gt;i144&lt;/code&gt;–&lt;code&gt;i148&lt;/code&gt;, &lt;code&gt;d43&lt;/code&gt;–&lt;code&gt;d44&lt;/code&gt;, &lt;code&gt;a111&lt;/code&gt;–&lt;code&gt;a125&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;Reference evaluator (Go): &lt;code&gt;Result.NotEnforced&lt;/code&gt;, &lt;code&gt;Mandate.Enforce&lt;/code&gt; and
&lt;code&gt;EntersAuditMode&lt;/code&gt; (whether adopting a mandate switches audit mode on, compared with the
stored mandate only if it is valid, active and in force).&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Permitted values and string parameters (Sections 3, 3.1, 3.2, 4, 4.5, 5, 6, 8, 9.1, 10, 12):&lt;/p&gt;&lt;ul&gt;&lt;li&gt;A parameter is an integer or a string. The vocabulary declares the type of every
parameter (&lt;code&gt;type&lt;/code&gt;: &lt;code&gt;integer&lt;/code&gt; with a &lt;code&gt;unit&lt;/code&gt;, or &lt;code&gt;string&lt;/code&gt;, optionally with permitted
&lt;code&gt;values&lt;/code&gt;); strings follow the rules of an area: 1 to 64 printable ASCII characters
without space, compared exactly and case-sensitive. There are still no fractions.
Incompatible for extension vocabularies (before &lt;code&gt;v0.1.0&lt;/code&gt;): they must declare the &lt;code&gt;type&lt;/code&gt;
of every parameter and list at most 32 permitted values; mandates stay valid.&lt;/li&gt;&lt;li&gt;New constraint &lt;code&gt;one_of&lt;/code&gt;: a list of 1 to 32 distinct permitted values of the parameter&amp;apos;s
type, for integer and string parameters; not together with &lt;code&gt;min&lt;/code&gt; or &lt;code&gt;max&lt;/code&gt;, which exist
only for integer parameters. A rule with &lt;code&gt;one_of&lt;/code&gt; matches only if the request carries
the parameter with one of the values. A constraint that does not fit the declared type,
or a string value outside the permitted values of the vocabulary, makes the mandate
invalid (Section 3.1 item 10). Every mandate that was valid stays valid: a constraint
with &lt;code&gt;min&lt;/code&gt; or &lt;code&gt;max&lt;/code&gt; on a parameter of the vocabulary was on an integer before as well.&lt;/li&gt;&lt;li&gt;&lt;code&gt;climate.set_mode&lt;/code&gt; gets the string parameter &lt;code&gt;mode&lt;/code&gt; with the permitted values of the
Matter Thermostat SystemMode: &lt;code&gt;off&lt;/code&gt;, &lt;code&gt;auto&lt;/code&gt;, &lt;code&gt;cool&lt;/code&gt;, &lt;code&gt;heat&lt;/code&gt;, &lt;code&gt;emergency_heat&lt;/code&gt;,
&lt;code&gt;precooling&lt;/code&gt;, &lt;code&gt;fan_only&lt;/code&gt;, &lt;code&gt;dry&lt;/code&gt;, &lt;code&gt;sleep&lt;/code&gt;. A household can now allow heating modes but
never &lt;code&gt;off&lt;/code&gt;. The vocabulary keeps &lt;code&gt;v0&lt;/code&gt;: it changes before the formats are frozen with
&lt;code&gt;v0.1.0&lt;/code&gt;. &lt;code&gt;other.set&lt;/code&gt; stays critical and without parameters.&lt;/li&gt;&lt;li&gt;A request is invalid (&lt;code&gt;invalid_request&lt;/code&gt;) if a parameter is neither an integer nor such a
string, if a parameter the action declares has another type (&lt;code&gt;&amp;quot;50&amp;quot;&lt;/code&gt; for &lt;code&gt;brightness&lt;/code&gt;,
&lt;code&gt;4&lt;/code&gt; for &lt;code&gt;mode&lt;/code&gt;), if a string is not among the permitted values, or if an integer lies
outside the range of the vocabulary (&lt;code&gt;brightness&lt;/code&gt;, &lt;code&gt;position&lt;/code&gt; and &lt;code&gt;volume&lt;/code&gt; 0 to 100;
&lt;code&gt;temperature&lt;/code&gt; and &lt;code&gt;temperature_f&lt;/code&gt; have none). Before, the range was informative, and
&lt;code&gt;brightness: 101&lt;/code&gt; was evaluated like any other value. Constraints beyond the range stay
valid but never match. Before, &lt;code&gt;set_mode&lt;/code&gt;
had no parameters, and a PEP could pass any value without effect.&lt;/li&gt;&lt;li&gt;In the test interface (Section 10), in AuthZEN (&lt;code&gt;action.properties&lt;/code&gt;) and in the audit
entry (&lt;code&gt;request.parameters&lt;/code&gt;), a parameter value is a JSON integer or, new, a JSON
string. Incompatible: a string is never read as a number; the harness of the reference code
formerly accepted &lt;code&gt;&amp;quot;50&amp;quot;&lt;/code&gt; as the integer 50. The audit &lt;code&gt;type&lt;/code&gt; stays
&lt;code&gt;https://home-mandate.org/audit/v0&lt;/code&gt;: the change comes before the formats are frozen.
The audit log &lt;code&gt;a37&lt;/code&gt; carries a boolean instead of the string &lt;code&gt;&amp;quot;40&amp;quot;&lt;/code&gt; (a string is now a
valid value) and is chained anew; its expected result is unchanged.&lt;/li&gt;&lt;li&gt;Numbers are read by their exact value: a fraction is never rounded to an integer, however
small it is (&lt;code&gt;50.00000000000000000001&lt;/code&gt;, &lt;code&gt;1e-400&lt;/code&gt;). The reference code formerly read
request parameters through floating point and took such values for integers.&lt;/li&gt;&lt;li&gt;Conformance cases &lt;code&gt;c152&lt;/code&gt;–&lt;code&gt;c173&lt;/code&gt; (new mandate &lt;code&gt;conformance/mandates/one-of.json&lt;/code&gt;),
&lt;code&gt;i129&lt;/code&gt;–&lt;code&gt;i143&lt;/code&gt;, &lt;code&gt;d41&lt;/code&gt;–&lt;code&gt;d42&lt;/code&gt;, &lt;code&gt;a109&lt;/code&gt;–&lt;code&gt;a110&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;Profiles: Home Assistant and Matter map their climate modes to the values of &lt;code&gt;mode&lt;/code&gt;;
Home Assistant &lt;code&gt;heat_cool&lt;/code&gt; and &lt;code&gt;auto&lt;/code&gt; both map to &lt;code&gt;auto&lt;/code&gt; (Section 12.4).&lt;/li&gt;&lt;li&gt;Reference evaluator (Go), before &lt;code&gt;v0.1.0&lt;/code&gt;: &lt;code&gt;Request.Parameters&lt;/code&gt; is a
&lt;code&gt;map[string]Value&lt;/code&gt;; &lt;code&gt;Value&lt;/code&gt; is an integer or a string (&lt;code&gt;IntegerValue&lt;/code&gt;, &lt;code&gt;StringValue&lt;/code&gt;)
and reads and writes itself as JSON; &lt;code&gt;Limit.OneOf&lt;/code&gt; holds the permitted values of a
constraint.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Sets of areas (Sections 1.1, 2, 3.4, 4, 6, 8, 9.1, 10, 12):&lt;/p&gt;&lt;ul&gt;&lt;li&gt;A resource has a set of 0 to 16 areas instead of at most one: its room and every
location above it (for example garage, ground floor, home), or several rooms side by
side. A rule still names exactly one &lt;code&gt;area&lt;/code&gt; and matches if that area is in the set; the
mandate format does not change, and every mandate that was valid stays valid. A request
with more than 16 areas, the same area twice or an area that is no identifier is
invalid (&lt;code&gt;invalid_request&lt;/code&gt;). The duty to report affected mandates covers every area in
the set.&lt;/li&gt;&lt;li&gt;Incompatible: in the request of the test interface, in the directory of the HTTP binding,
in AuthZEN (&lt;code&gt;resource.properties.areas&lt;/code&gt;) and in the audit entry
(&lt;code&gt;request.resource.areas&lt;/code&gt;), &lt;code&gt;area&lt;/code&gt; (a string) became &lt;code&gt;areas&lt;/code&gt; (an array). An audit entry
with &lt;code&gt;request.resource.area&lt;/code&gt; is invalid. The audit &lt;code&gt;type&lt;/code&gt; stays
&lt;code&gt;https://home-mandate.org/audit/v0&lt;/code&gt;: the change comes before the formats are frozen
with &lt;code&gt;v0.1.0&lt;/code&gt;. The audit logs in &lt;code&gt;conformance/audit-v0.json&lt;/code&gt; carry &lt;code&gt;areas&lt;/code&gt; and are
chained anew; every expected result is unchanged.&lt;/li&gt;&lt;li&gt;Conformance cases &lt;code&gt;c140&lt;/code&gt;–&lt;code&gt;c151&lt;/code&gt; (new mandate &lt;code&gt;conformance/mandates/areas.json&lt;/code&gt;) and
&lt;code&gt;a106&lt;/code&gt;–&lt;code&gt;a108&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;Test interface (Section 10): a request with a member the section does not define is
malformed, so that a former &lt;code&gt;area&lt;/code&gt; is not evaluated as if it were absent.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Temperatures in degrees Fahrenheit (Sections 4.5, 5):&lt;/p&gt;&lt;ul&gt;&lt;li&gt;New parameter &lt;code&gt;temperature_f&lt;/code&gt; of &lt;code&gt;climate.set_temperature&lt;/code&gt; in hundredths of a degree
Fahrenheit, next to &lt;code&gt;temperature&lt;/code&gt; in hundredths of a degree Celsius, so that households
whose platform uses °F can constrain temperatures exactly. The PEP derives exactly one of
the two, in the platform&amp;apos;s unit, and never converts. Compatible for implementations that
load the vocabulary: a constraint on &lt;code&gt;temperature_f&lt;/code&gt; was invalid before. The vocabulary keeps &lt;code&gt;v0&lt;/code&gt;: the parameter is added
before the formats are frozen with &lt;code&gt;v0.1.0&lt;/code&gt;; from then on Section 5.1 holds without
exception. Conformance cases &lt;code&gt;c133&lt;/code&gt;–&lt;code&gt;c139&lt;/code&gt;, &lt;code&gt;i128&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;Section 4.5 says plainly that a value that cannot be expressed as an integer in the unit
makes the PEP refuse the request; it never leaves the parameter out.&lt;/li&gt;&lt;li&gt;Section 11.5 (new): a PEP &lt;strong&gt;MAY&lt;/strong&gt; tell an agent the limits of its own mandate (the
constraints of the &lt;code&gt;allow&lt;/code&gt; rules that match apart from them, in the agent&amp;apos;s units), but
never for a resource the agent may not read, of another mandate, of &lt;code&gt;deny&lt;/code&gt; or &lt;code&gt;ask&lt;/code&gt;
rules, in a unit it never derives, or while rules on a former identifier still apply.
The reference evaluator (Go) offers &lt;code&gt;Mandate.Limits&lt;/code&gt; for it; it decides nothing.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Overview (Sections 1.1 and 2, informative, no change to any rule):&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Section 1.1 (new) shows in a diagram how agent, implementation (PEP, PDP, audit log),
smart-home platform and human work together, which of these interfaces the specification
defines and which it leaves open. It names MCP as the agent interface of the reference
implementation, as an example.&lt;/li&gt;&lt;li&gt;Section 2 defines PDP and PEP.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The only path to the platform (Sections 12.2, 12.3, 12.4, text only, no change to any rule
or format):&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Section 12.3: new assumption that the agent reaches the platform only through the PEP,
holds no other credential for it and cannot create or change scripts, automations, rules
or other code that executes on it. Section 12.2: new row for an agent with a path past
the PEP.&lt;/li&gt;&lt;li&gt;Sections 12.2 and 12.4: automations and rules that react to a harmless-looking resource;
such a resource is marked critical, and interfaces show the household which resources
automations react to where the platform can tell (openHAB as the example).&lt;/li&gt;&lt;li&gt;Section 12.4: no tools that write platform configuration through the PEP (a request for
configuration is &lt;code&gt;deny&lt;/code&gt;); the PEP&amp;apos;s own platform credential is as restricted as the
platform allows and never given to the agent.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;MCP elicitation (Section 11.1, informative, no change to any rule):&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Note after the list of Section 11.1: URL mode elicitation (MCP &lt;code&gt;2025-11-25&lt;/code&gt; and later)
can be a confirmation path in the sense of item 4 when the PEP checks that the person who
confirms is an approver and binds the page to exactly one request; form mode elicitation
cannot, because the answer passes through the agent&amp;apos;s client. In both cases a PEP still
needs a path to the approvers.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Confirmations for several resources (Sections 4.4, 11.1):&lt;/p&gt;&lt;ul&gt;&lt;li&gt;A confirmation for a request that the PEP resolves into several resources covers exactly
the resolved set; the human is shown every resource of it (Section 11.1 item 2).&lt;/li&gt;&lt;li&gt;Before the execution the PEP resolves the request again and executes only if the set is
unchanged; a resource added, removed or replaced in the meantime prevents the execution
for the whole set, also when the mandate is unchanged and every resource still evaluates
to &lt;code&gt;ask&lt;/code&gt; or &lt;code&gt;allow&lt;/code&gt; (Section 11.1 item 6). New &lt;strong&gt;RECOMMENDED&lt;/strong&gt; code &lt;code&gt;resources_changed&lt;/code&gt;
(&lt;code&gt;failed&lt;/code&gt;). No change to any format.&lt;/li&gt;&lt;li&gt;The PEP executes a request for several resources on exactly the resources it evaluated
and names each of them to the platform, never the area, group or list it resolved them
from, so that the platform cannot add a resource that was not evaluated (Section 4.4).&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Versions (Section 14, rewritten):&lt;/p&gt;&lt;ul&gt;&lt;li&gt;The v0 formats (mandate, audit entry, audit checkpoint) are frozen from &lt;code&gt;v0.1.0&lt;/code&gt;, the first
release without a pre-release suffix. After that, every incompatible change requires a new
&lt;code&gt;type&lt;/code&gt; with the next major version; a document that was valid stays valid and is
evaluated the same way. Until &lt;code&gt;v0.1.0&lt;/code&gt;, incompatible changes remain possible and are
listed here.&lt;/li&gt;&lt;li&gt;Defined what is incompatible: a valid document becomes invalid, or a valid document is
evaluated differently (result, succession, digest, verification of an audit log).&lt;/li&gt;&lt;li&gt;Rule for mixed data: implementations read the older major and write the newer one; a
verifier accepts an audit log whose earlier entries carry an older major; mandates move
to a newer format only by succession and are never rewritten.&lt;/li&gt;&lt;li&gt;The vocabulary (Section 5.1) and the &lt;code&gt;$id&lt;/code&gt;s of the conformance schemas are versioned
independently of the formats.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;incompatible&lt;/strong&gt; &lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;type&lt;/code&gt; of mandates, audit entries and checkpoints and the schema &lt;code&gt;$id&lt;/code&gt; moved from
&lt;code&gt;https://mandate-spec.org/…&lt;/code&gt; to &lt;code&gt;https://home-mandate.org/…&lt;/code&gt;, e.g.
&lt;code&gt;https://home-mandate.org/mandate/v0&lt;/code&gt;. Mandates with the old identifier are invalid
(conformance case &lt;code&gt;i127&lt;/code&gt;). Data model and evaluation are otherwise unchanged.&lt;/li&gt;&lt;li&gt;Because the &lt;code&gt;type&lt;/code&gt; is part of every digest and signed payload, all digests, audit chains,
checkpoint signatures and signed mandates in &lt;code&gt;conformance/&lt;/code&gt; are new. Cases that are
invalid on purpose keep their defect.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;added&lt;/strong&gt; &lt;/p&gt;&lt;ul&gt;&lt;li&gt;Audit log: event &lt;code&gt;template.changed&lt;/code&gt; with the member &lt;code&gt;template&lt;/code&gt; records changes to
templates, the stored mandate drafts from which an implementation creates mandates
(Section 2): stored, removed, hidden and shown again, with the name and digests but never
the content. Event &lt;code&gt;approver.changed&lt;/code&gt; with the member &lt;code&gt;approver&lt;/code&gt; records humans added to
or removed from the implementation&amp;apos;s list of approvers (Section 11.1). Both have an actor
of kind &lt;code&gt;user&lt;/code&gt; or &lt;code&gt;system&lt;/code&gt;; &lt;code&gt;template.name&lt;/code&gt; and &lt;code&gt;approver.id&lt;/code&gt; are displayed text, and a
&lt;code&gt;previous_digest&lt;/code&gt; equal to &lt;code&gt;digest&lt;/code&gt; makes an entry invalid (Sections 9.1, 9.2).
Compatible for logs: every entry that was valid remains valid. A verifier that does not
know the events rejects a log that contains them (Section 14, unknown members).
Conformance cases &lt;code&gt;a58&lt;/code&gt;–&lt;code&gt;a76&lt;/code&gt; in &lt;code&gt;conformance/audit-v0.json&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;Audit log: events &lt;code&gt;mandate.removed&lt;/code&gt; and &lt;code&gt;agent.removed&lt;/code&gt; record that a revoked mandate or
a revoked agent was removed from the implementation&amp;apos;s lists, with the existing members
&lt;code&gt;mandate&lt;/code&gt; (&lt;code&gt;id&lt;/code&gt; and the digest of the last version) and &lt;code&gt;agent&lt;/code&gt;; their &lt;code&gt;actor&lt;/code&gt; is of kind
&lt;code&gt;user&lt;/code&gt; or &lt;code&gt;system&lt;/code&gt;. Event &lt;code&gt;agent.reconnected&lt;/code&gt; with the member &lt;code&gt;agent&lt;/code&gt; records that a
human gave new credentials to an existing agent that is not revoked, for example after an
emergency stop; its &lt;code&gt;actor&lt;/code&gt; is of kind &lt;code&gt;user&lt;/code&gt; (Sections 9.1, 9.2, 11.3). Only revoked
mandates and agents are removed; removal deletes no audit entries and keeps the
protection against rollback (Section 3.5).
Compatible for logs: every entry that was valid remains valid. A verifier that does not
know the events rejects a log that contains them (Section 14, unknown members).
Conformance cases &lt;code&gt;a77&lt;/code&gt;–&lt;code&gt;a88&lt;/code&gt; in &lt;code&gt;conformance/audit-v0.json&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;Approval requests that end without an answer before their timeout: new outcome
&lt;code&gt;cancelled&lt;/code&gt; with the member &lt;code&gt;approval.cause&lt;/code&gt; (&lt;code&gt;withdrawn&lt;/code&gt; by the agent, &lt;code&gt;revoked&lt;/code&gt;,
&lt;code&gt;emergency_stop&lt;/code&gt;, &lt;code&gt;interrupted&lt;/code&gt; by the end of the process), only with
&lt;code&gt;result.status: denied&lt;/code&gt; and the &lt;code&gt;denied_by&lt;/code&gt; matching the cause; nobody answered, so no
&lt;code&gt;by&lt;/code&gt; (Sections 9.1, 11.1 items 8 and 9). A request that a revocation or an emergency stop
ends is recorded with this outcome instead of without an &lt;code&gt;approval&lt;/code&gt; object. After a
restart no waiting request is executed, reopened or answered; an execution whose effect
is unknown is not repeated (&lt;code&gt;failed&lt;/code&gt;, &lt;strong&gt;RECOMMENDED&lt;/strong&gt; &lt;code&gt;error: outcome_unknown&lt;/code&gt;). New
&lt;strong&gt;RECOMMENDED&lt;/strong&gt; codes &lt;code&gt;already_in_state&lt;/code&gt; and &lt;code&gt;state_changed&lt;/code&gt; for a confirmed action that is
not executed because the state shown to the human no longer holds (Section 11.1 item 10).
Compatible for logs: every entry that was valid remains valid. A verifier that does not
know the outcome rejects a log that contains it (Section 14, unknown members).
Conformance cases &lt;code&gt;a89&lt;/code&gt;–&lt;code&gt;a105&lt;/code&gt; in &lt;code&gt;conformance/audit-v0.json&lt;/code&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Actions the resource cannot carry out (Section 11.1 item 11): an implementation that knows
that a resource cannot carry out the action &lt;strong&gt;SHOULD NOT&lt;/strong&gt; ask anyone for it; the entry is
&lt;code&gt;failed&lt;/code&gt; with the new &lt;strong&gt;RECOMMENDED&lt;/strong&gt; code &lt;code&gt;not_supported&lt;/code&gt; and without an &lt;code&gt;approval&lt;/code&gt;. Which
actions the resource can carry out is told only to an agent that may &lt;code&gt;read&lt;/code&gt; it (Section 13,
new item on features). No change
to the evaluation, to the vocabulary or to the format of mandates and logs. The profile for
Home Assistant names where the features of an entity come from.&lt;/p&gt;&lt;p&gt;Conformance cases (no change to any rule or format):&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Areas: &lt;code&gt;c193&lt;/code&gt;–&lt;code&gt;c199&lt;/code&gt; (an area of 64 characters, the edge characters &lt;code&gt;!&lt;/code&gt; and &lt;code&gt;~&lt;/code&gt;, U+007F,
non-ASCII, an empty area, &lt;code&gt;Home&lt;/code&gt; next to &lt;code&gt;home&lt;/code&gt;, a set in another order); two rules added
to &lt;code&gt;conformance/mandates/areas.json&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;Parameters: &lt;code&gt;c200&lt;/code&gt;–&lt;code&gt;c209&lt;/code&gt;, &lt;code&gt;c212&lt;/code&gt;, &lt;code&gt;c213&lt;/code&gt; (2^53 and 2^53 − 1, the spelling &lt;code&gt;5e1&lt;/code&gt;, the values of &lt;code&gt;mode&lt;/code&gt;
that &lt;code&gt;one_of&lt;/code&gt; does not list, a constraint beyond the range of the vocabulary), &lt;code&gt;d45&lt;/code&gt;–&lt;code&gt;d48&lt;/code&gt;
and &lt;code&gt;i149&lt;/code&gt; (&lt;code&gt;one_of&lt;/code&gt; with 32 values, a string value of 64 characters, &lt;code&gt;min&lt;/code&gt;/&lt;code&gt;max&lt;/code&gt; beyond
the range, &lt;code&gt;one_of&lt;/code&gt; for &lt;code&gt;mode&lt;/code&gt; in a rule without category).&lt;/li&gt;&lt;li&gt;Audit mode: &lt;code&gt;c210&lt;/code&gt;, &lt;code&gt;c211&lt;/code&gt; (new mandate &lt;code&gt;conformance/mandates/audit-mode-critical.json&lt;/code&gt;:
a &lt;code&gt;deny&lt;/code&gt; rule on a resource marked critical), &lt;code&gt;s20&lt;/code&gt; (selection; the selection cases accept
&lt;code&gt;enforced&lt;/code&gt; as the evaluation cases do), &lt;code&gt;v13&lt;/code&gt;, &lt;code&gt;v14&lt;/code&gt; (succession switching audit mode on
and off), &lt;code&gt;a127&lt;/code&gt;–&lt;code&gt;a129&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;Selection with a set of areas: &lt;code&gt;s21&lt;/code&gt;. Audit log: &lt;code&gt;a126&lt;/code&gt; (&lt;code&gt;not_supported&lt;/code&gt;, Section 11.1
item 11), &lt;code&gt;a130&lt;/code&gt;–&lt;code&gt;a133&lt;/code&gt; (16 and 0 areas, a fraction and an empty string as parameter).&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;What &lt;code&gt;request&lt;/code&gt; records (Section 9.1, text only, no change to any rule or format):&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;request&lt;/code&gt; records the input to the evaluation as the PEP determined it, also when the
evaluation found it invalid (&lt;code&gt;invalid_request&lt;/code&gt;); identifiers in it are limited in length
and number, not in their characters, as the schema has always had it.&lt;/li&gt;&lt;li&gt;Input that the log cannot record (a longer identifier, more than 16 areas or areas that
repeat, more than 16 parameters, a parameter value that is neither an integer nor a
string of the form of Section 4.5) is not a request: the PEP rejects it at its interface
before any evaluation. Conformance cases &lt;code&gt;a134&lt;/code&gt; (valid, an identifier with a space) and
&lt;code&gt;a135&lt;/code&gt; (invalid, an &lt;code&gt;entity_id&lt;/code&gt; of 256 characters).&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Audit mode and &lt;code&gt;ask&lt;/code&gt; (Sections 4, 4.1, 4.4, 4.6, 6, 8, 9.1, 10, 11.1, 11.6, 12, 13; issue #59):&lt;/p&gt;&lt;ul&gt;&lt;li&gt;In audit mode, a &lt;code&gt;deny&lt;/code&gt; rule that wins over a matching &lt;code&gt;ask&lt;/code&gt; rule no longer takes the
confirmation away. The &lt;code&gt;deny&lt;/code&gt; stays the decision and is not enforced, but the result
&lt;strong&gt;requires a confirmation&lt;/strong&gt;: it carries &lt;code&gt;confirm: true&lt;/code&gt; and the approval settings of the
&lt;code&gt;ask&lt;/code&gt; (Section 4.1), and the PEP executes it only after a confirmation, as an &lt;code&gt;ask&lt;/code&gt;
(Sections 4.6, 11.1, 11.6). Before, such a request was executed without asking anyone,
while the same request without the &lt;code&gt;deny&lt;/code&gt; rule needed a confirmation. A &lt;code&gt;deny&lt;/code&gt; without a
matching &lt;code&gt;ask&lt;/code&gt; rule is executed without a confirmation as before; critical actions are
enforced as before.&lt;/li&gt;&lt;li&gt;New member &lt;code&gt;confirm&lt;/code&gt; (only &lt;code&gt;true&lt;/code&gt;, only with &lt;code&gt;enforced: false&lt;/code&gt; and &lt;code&gt;reason: rule&lt;/code&gt;) of
the result of the evaluation, of the AuthZEN response context (Section 6, &lt;strong&gt;REQUIRED&lt;/strong&gt; there
together with &lt;code&gt;approval_timeout&lt;/code&gt; and &lt;code&gt;approvers&lt;/code&gt;), of the &lt;code&gt;evaluate&lt;/code&gt; and &lt;code&gt;select&lt;/code&gt;
responses of the test interface and of the conformance cases (Sections 8, 10), and of
&lt;code&gt;evaluation&lt;/code&gt; in the audit log (Section 9.1). A PEP that executes a &lt;code&gt;deny&lt;/code&gt; with
&lt;code&gt;enforced: false&lt;/code&gt; &lt;strong&gt;MUST&lt;/strong&gt; know &lt;code&gt;confirm&lt;/code&gt;; one that does not know &lt;code&gt;enforced&lt;/code&gt; still enforces
every &lt;code&gt;deny&lt;/code&gt;. Implementations that already offer audit mode &lt;strong&gt;MUST&lt;/strong&gt; add &lt;code&gt;confirm&lt;/code&gt;, or
they execute such a request without asking anyone.&lt;/li&gt;&lt;li&gt;Audit entry: an &lt;code&gt;approval&lt;/code&gt; object appears with &lt;code&gt;evaluation.decision: ask&lt;/code&gt; or with
&lt;code&gt;evaluation.confirm: true&lt;/code&gt;. With &lt;code&gt;confirm: true&lt;/code&gt;, &lt;code&gt;executed&lt;/code&gt; requires
&lt;code&gt;approval.outcome: approved&lt;/code&gt;, and the &lt;code&gt;result&lt;/code&gt; can be anything an &lt;code&gt;ask&lt;/code&gt; can have; without
it, a &lt;code&gt;deny&lt;/code&gt; with &lt;code&gt;enforced: false&lt;/code&gt; is still only &lt;code&gt;executed&lt;/code&gt; or &lt;code&gt;failed&lt;/code&gt;. Every entry
that was valid stays valid.&lt;/li&gt;&lt;li&gt;Before the execution (Section 11.1 item 6), a confirmed request with &lt;code&gt;confirm: true&lt;/code&gt; is
executed only if the evaluation then gives &lt;code&gt;allow&lt;/code&gt;, &lt;code&gt;ask&lt;/code&gt; or again a &lt;code&gt;deny&lt;/code&gt; with
&lt;code&gt;confirm: true&lt;/code&gt;, so that a time window that has closed prevails as for an &lt;code&gt;ask&lt;/code&gt;; a
confirmed &lt;code&gt;ask&lt;/code&gt; is still not executed after any &lt;code&gt;deny&lt;/code&gt;. In the audit log,
&lt;code&gt;denied_by: mandate&lt;/code&gt; with &lt;code&gt;confirm: true&lt;/code&gt; requires an approved or a revoked request. The human who confirms &lt;strong&gt;SHOULD&lt;/strong&gt; be shown that the
mandate in audit mode would deny the request, and by which rule (Section 11.1 item 2);
the agent is not told.&lt;/li&gt;&lt;li&gt;Conformance cases &lt;code&gt;c214&lt;/code&gt;–&lt;code&gt;c223&lt;/code&gt; (new mandate &lt;code&gt;conformance/mandates/audit-mode-ask.json&lt;/code&gt;),
&lt;code&gt;s22&lt;/code&gt; (the selection cases accept &lt;code&gt;approval_timeout&lt;/code&gt; and &lt;code&gt;confirm&lt;/code&gt;), &lt;code&gt;a136&lt;/code&gt; (valid: every
outcome of an approval request with &lt;code&gt;confirm: true&lt;/code&gt;) and &lt;code&gt;a137&lt;/code&gt;–&lt;code&gt;a145&lt;/code&gt; (invalid).&lt;/li&gt;&lt;li&gt;Reference evaluator (Go): &lt;code&gt;Result.Confirm&lt;/code&gt;; &lt;code&gt;Result.Approval&lt;/code&gt; is also set with it.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Recording before executing, and the agent&amp;apos;s values in the log (Sections 9, 9.1, 9.2, 11.1,
12.2, 12.4, 13; issues #86, #90):&lt;/p&gt;&lt;ul&gt;&lt;li&gt;A PEP stores what it will record before it dispatches a command, and does not execute
when it cannot: new value &lt;code&gt;audit&lt;/code&gt; of &lt;code&gt;result.denied_by&lt;/code&gt;, for a request that was not
executed because the log could not be written. Before, nothing said that recording comes
first; a full disk or a crash between the command and the entry could execute an &lt;code&gt;allow&lt;/code&gt;
without a trace, although Section 9 promises a log that shows which agent did what.
&lt;code&gt;denied_by: audit&lt;/code&gt; appears only where no other denial came first: authentication, the
emergency stop and the rate limit precede it; an answer other than &lt;code&gt;approved&lt;/code&gt; is still
denied by the approval, an enforced &lt;code&gt;deny&lt;/code&gt; by the mandate; an unenforced &lt;code&gt;deny&lt;/code&gt; (audit
mode) can now end so as well. &lt;code&gt;outcome_unknown&lt;/code&gt; after a restart now covers every action,
not only confirmed ones. Section 9 says what durable means and what becomes of denials
the PEP could not record yet. Compatible for writers of logs; a verifier of an earlier pre-release rejects an
entry with the new value (before &lt;code&gt;v0.1.0&lt;/code&gt;).&lt;/li&gt;&lt;li&gt;The values of &lt;code&gt;request&lt;/code&gt; come from the agent and from the directory and may contain any
character; whatever renders them for a human &lt;strong&gt;MUST&lt;/strong&gt; treat them as untrusted text and show
every character outside printable ASCII, and every backslash, as a JSON string shows
them, never interpret them. Exports carry them unchanged. Text only: the schema already
permitted the characters and Section 9.1 said so, but not what follows for interfaces,
verifier reports and readers of exports. Conformance cases record such values. The
reference verifier prints no value of an entry.&lt;/li&gt;&lt;li&gt;Conformance cases &lt;code&gt;a203&lt;/code&gt;–&lt;code&gt;a212&lt;/code&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Request parameters and vocabulary &lt;code&gt;v0.1&lt;/code&gt; (Sections 3.1, 4, 4.5, 5, 5.1, 9.1, 9.2, 10.2,
12.4, 14; issues #78, #84):&lt;/p&gt;&lt;ul&gt;&lt;li&gt;A request carries exactly the parameters its action declares: a parameter the action
does not declare makes it invalid (&lt;code&gt;c120&lt;/code&gt;, &lt;code&gt;c160&lt;/code&gt; and the unit tests change), as do more
than 16 parameters, a name outside &lt;code&gt;^[a-z][a-z0-9_]{0,63}$&lt;/code&gt;, a missing required
parameter, and none or more than one of the alternatives the action requires one of. The
vocabulary file gains &lt;code&gt;required&lt;/code&gt; per parameter and &lt;code&gt;required_one_of&lt;/code&gt; per action, the
table in Section 5 a column. Section 12.4 makes forwarding only what was evaluated a &lt;strong&gt;MUST&lt;/strong&gt;.
Incompatible for the class &lt;code&gt;evaluator&lt;/code&gt; (before &lt;code&gt;v0.1.0&lt;/code&gt;): &lt;code&gt;c117&lt;/code&gt;–&lt;code&gt;c120&lt;/code&gt;, &lt;code&gt;c122&lt;/code&gt;, &lt;code&gt;c138&lt;/code&gt;,
&lt;code&gt;c139&lt;/code&gt;, &lt;code&gt;c158&lt;/code&gt; and &lt;code&gt;c160&lt;/code&gt; are &lt;code&gt;invalid_request&lt;/code&gt; now; &lt;code&gt;c10&lt;/code&gt;, &lt;code&gt;c12&lt;/code&gt;, &lt;code&gt;c28&lt;/code&gt;–&lt;code&gt;c30&lt;/code&gt;,
&lt;code&gt;c47&lt;/code&gt;–&lt;code&gt;c49&lt;/code&gt; carry the parameter their action requires.&lt;/li&gt;&lt;li&gt;Vocabulary &lt;code&gt;v0.1&lt;/code&gt;: &lt;code&gt;alarm.arm&lt;/code&gt; takes the required &lt;code&gt;mode&lt;/code&gt; (&lt;code&gt;home&lt;/code&gt;, &lt;code&gt;away&lt;/code&gt;, &lt;code&gt;night&lt;/code&gt;,
&lt;code&gt;vacation&lt;/code&gt;, &lt;code&gt;custom_bypass&lt;/code&gt;); &lt;code&gt;climate.set_temperature&lt;/code&gt; takes a range setpoint,
&lt;code&gt;temperature_low&lt;/code&gt; with &lt;code&gt;temperature_high&lt;/code&gt; or the pair in degrees Fahrenheit, as one of
its alternatives; &lt;code&gt;mode&lt;/code&gt;, &lt;code&gt;position&lt;/code&gt; and &lt;code&gt;volume&lt;/code&gt; are required, &lt;code&gt;brightness&lt;/code&gt; stays
optional until the vocabulary names what else &lt;code&gt;light.set&lt;/code&gt; sets (#29). Section 14
now counts a new parameter that is not required as compatible and a newly required one as
incompatible.&lt;/li&gt;&lt;li&gt;Sections 9.1 and 9.2 name the parameter names among the input the log cannot record, and
say that such input is not a request and gets no entry; the &lt;code&gt;invalid_request&lt;/code&gt; results
exist so that an evaluator fails closed. Section 3.1 item 10 keeps constraints off &lt;code&gt;deny&lt;/code&gt;
and &lt;code&gt;ask&lt;/code&gt; rules and says why that still holds with required parameters.&lt;/li&gt;&lt;li&gt;No mandate changes validity: constraints on the new parameters become possible, nothing
becomes invalid. &lt;code&gt;decision&lt;/code&gt; entries recorded under vocabulary &lt;code&gt;v0&lt;/code&gt; keep their result; the
version they name decides (Section 9.2).&lt;/li&gt;&lt;li&gt;Conformance cases &lt;code&gt;c224&lt;/code&gt;–&lt;code&gt;c242&lt;/code&gt;, new mandate &lt;code&gt;conformance/mandates/parameters.json&lt;/code&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Acceptance and selection (Sections 3, 3.4, 3.5, 4.1, 4.3, 6, 7.1, 8, 8.1, 9.1, 9.2, 10.2,
11.3, 11.6, 12.2; issues #76, #79, #80, #81):&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Selection (#76): an agent whose only mandates are revoked is denied with &lt;code&gt;revoked&lt;/code&gt;, not
&lt;code&gt;no_mandate&lt;/code&gt;; the result names the revoked mandate if it is exactly one valid one. An
invalid stored document is a candidate for the agent and principal it names, or for every
agent and principal if these cannot be read. Section 4.3 says how a stored document
becomes invalid and that the household is shown such documents. The class &lt;code&gt;pdp&lt;/code&gt; runs the
evaluation cases whose mandate is not revoked; its &lt;code&gt;revoked&lt;/code&gt; is tested by the selection
cases. Incompatible for the classes &lt;code&gt;selection&lt;/code&gt; and &lt;code&gt;pdp&lt;/code&gt; (before &lt;code&gt;v0.1.0&lt;/code&gt;): &lt;code&gt;s07&lt;/code&gt;
changes.&lt;/li&gt;&lt;li&gt;Succession (#79): the stored mandate of the succession rule includes one that is
remembered after revocation, removal or expiry; the highest version is updated when a
mandate takes effect, and a later successor replaces a waiting proposal.&lt;/li&gt;&lt;li&gt;Accepted is not in effect (#80): a successor that does not merely narrow the stored
mandate (defined in Section 3.5), one that follows a revoked mandate, and a signed mandate
with &lt;code&gt;approvers&lt;/code&gt; the implementation does not know take effect only after a human
confirmed them, as audit mode did. The &lt;code&gt;succession&lt;/code&gt; operation of the process binding
answers &lt;code&gt;confirm: true&lt;/code&gt; for such a successor; cases carry &lt;code&gt;stored_revoked&lt;/code&gt; and &lt;code&gt;confirm&lt;/code&gt;.
The reference code offers &lt;code&gt;NeedsConfirmation&lt;/code&gt; and &lt;code&gt;Narrows&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;Signed mandates (#81): &lt;code&gt;audience&lt;/code&gt;, an optional member of the mandate with the form of
&lt;code&gt;agent.client_id&lt;/code&gt;, required in a signed mandate together with &lt;code&gt;expires&lt;/code&gt;; a verifier
accepts a signed mandate only for its own audience, never fetches keys from a location a
mandate names, and withdraws the effect of mandates accepted by a key it stops trusting.
Incompatible for the class &lt;code&gt;signatures&lt;/code&gt; (before &lt;code&gt;v0.1.0&lt;/code&gt;): the signed cases are
regenerated from a mandate with &lt;code&gt;audience&lt;/code&gt; and &lt;code&gt;expires&lt;/code&gt;; a mandate that uses &lt;code&gt;audience&lt;/code&gt;
is invalid for an implementation of an earlier pre-release (Section 14, unknown members).&lt;/li&gt;&lt;li&gt;Conformance cases &lt;code&gt;s07&lt;/code&gt; (changed), &lt;code&gt;s24&lt;/code&gt;–&lt;code&gt;s28&lt;/code&gt;, &lt;code&gt;v01&lt;/code&gt; and &lt;code&gt;v09&lt;/code&gt; (the offered mandate keeps
the rate limit), &lt;code&gt;v13&lt;/code&gt; (&lt;code&gt;confirm&lt;/code&gt;), &lt;code&gt;v15&lt;/code&gt;–&lt;code&gt;v23&lt;/code&gt;, &lt;code&gt;g01&lt;/code&gt;–&lt;code&gt;g21&lt;/code&gt; (regenerated), &lt;code&gt;g22&lt;/code&gt;, &lt;code&gt;g23&lt;/code&gt;,
&lt;code&gt;d51&lt;/code&gt;, &lt;code&gt;i156&lt;/code&gt;, &lt;code&gt;i157&lt;/code&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;AuthZEN mapping completed, optional mandate members, signed checkpoint time, further audit
events, EdDSA canonicality (Sections 3, 3.1, 4.1, 4.3, 6, 7.1, 9.1, 9.2, 9.5, 10.2, 10.3,
11.4, 12.2; issues #77, #82, #83, #93):&lt;/p&gt;&lt;ul&gt;&lt;li&gt;AuthZEN (#77): &lt;code&gt;resource.properties.critical&lt;/code&gt; and &lt;code&gt;context.timezone&lt;/code&gt; carry the critical
marking and the household time zone to a PDP that does not hold the directory; the
response context carries &lt;code&gt;mandate_id&lt;/code&gt; next to &lt;code&gt;mandate_digest&lt;/code&gt;; a subject whose &lt;code&gt;type&lt;/code&gt; is
not &lt;code&gt;agent&lt;/code&gt;, whose &lt;code&gt;id&lt;/code&gt; is missing or whose &lt;code&gt;principal&lt;/code&gt; does not match the pattern is
&lt;code&gt;invalid_request&lt;/code&gt; before any mandate is selected, also in the &lt;code&gt;select&lt;/code&gt; operation of the
process binding. The test tool compares &lt;code&gt;mandate_id&lt;/code&gt;. Incompatible for the classes
&lt;code&gt;selection&lt;/code&gt; and &lt;code&gt;pdp&lt;/code&gt; (before &lt;code&gt;v0.1.0&lt;/code&gt;): such a subject was &lt;code&gt;no_mandate&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;Mandate (#82): optional &lt;code&gt;name&lt;/code&gt; (1 to 64 code points) and per rule &lt;code&gt;note&lt;/code&gt; (1 to 200), both
displayed text, not part of the evaluation. A mandate that uses them is invalid for an
implementation of an earlier pre-release (Section 14, unknown members).&lt;/li&gt;&lt;li&gt;Checkpoint (#82): the signed payload gains &lt;code&gt;at&lt;/code&gt;, the &lt;code&gt;recorded_at&lt;/code&gt; of the checkpoint
entry. Incompatible for logs (before &lt;code&gt;v0.1.0&lt;/code&gt;): checkpoints signed before do not verify.&lt;/li&gt;&lt;li&gt;Audit log (#83): events &lt;code&gt;issuer.changed&lt;/code&gt; (member &lt;code&gt;issuer&lt;/code&gt;: &lt;code&gt;trusted&lt;/code&gt;, &lt;code&gt;untrusted&lt;/code&gt;,
&lt;code&gt;key_added&lt;/code&gt;, &lt;code&gt;key_removed&lt;/code&gt;, with &lt;code&gt;kid&lt;/code&gt; for the keys) and &lt;code&gt;config.changed&lt;/code&gt; (member
&lt;code&gt;config&lt;/code&gt;: &lt;code&gt;timezone&lt;/code&gt;, &lt;code&gt;clock_check&lt;/code&gt;, &lt;code&gt;checkpoint_key&lt;/code&gt;, with &lt;code&gt;value&lt;/code&gt; and
&lt;code&gt;previous_value&lt;/code&gt;). Compatible for logs: only entries that were invalid become valid; a
verifier that does not know the events rejects a log that contains them. The reference
verifier checks that &lt;code&gt;previous_value&lt;/code&gt; differs from &lt;code&gt;value&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;Signatures (#93): for EdDSA, &lt;code&gt;S&lt;/code&gt; &amp;lt; &lt;code&gt;L&lt;/code&gt; and canonical encodings of &lt;code&gt;R&lt;/code&gt; and of the public
key; &lt;code&gt;alg&lt;/code&gt; must match the key type. The text states what the reference already did; the
reference now also rejects an Ed25519 public key that is not canonically encoded.&lt;/li&gt;&lt;li&gt;Conformance cases &lt;code&gt;d50&lt;/code&gt;, &lt;code&gt;i152&lt;/code&gt;–&lt;code&gt;i155&lt;/code&gt;, &lt;code&gt;s23&lt;/code&gt;, &lt;code&gt;g19&lt;/code&gt;–&lt;code&gt;g21&lt;/code&gt;, &lt;code&gt;a194&lt;/code&gt;–&lt;code&gt;a202&lt;/code&gt;; &lt;code&gt;a39&lt;/code&gt;–&lt;code&gt;a44&lt;/code&gt;,
&lt;code&gt;a46&lt;/code&gt;–&lt;code&gt;a49&lt;/code&gt; and &lt;code&gt;a147&lt;/code&gt; re-signed with the time in the payload; the selection cases that
select no mandate now say &lt;code&gt;selected: null&lt;/code&gt;, so that the HTTP binding checks that
&lt;code&gt;mandate_id&lt;/code&gt; is absent.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Proposals name the version they would replace (Sections 9.1, 9.2, 11.6; issue #53):&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;mandate.previous_digest&lt;/code&gt; is allowed with &lt;code&gt;mandate.proposed&lt;/code&gt; and &lt;code&gt;mandate.discarded&lt;/code&gt;: the
digest of the version the implementation held when it recorded the proposal, present
whenever there was one; a &lt;code&gt;mandate.discarded&lt;/code&gt; repeats it. A proposal named only the
proposed version, so a reader had to search the log for the version in force at the time.&lt;/li&gt;&lt;li&gt;Section 11.6 item 4 now requires (&lt;strong&gt;MUST&lt;/strong&gt;) an implementation that offers audit mode to record
proposals and discards, as the table in Section 9.2 already did, and says how the
confirmation is linked to the proposal: the &lt;code&gt;mandate.updated&lt;/code&gt; (or &lt;code&gt;mandate.created&lt;/code&gt;, if no
version was stored) carries the same &lt;code&gt;digest&lt;/code&gt; and &lt;code&gt;previous_digest&lt;/code&gt;; no member of its own.&lt;/li&gt;&lt;li&gt;Compatible for logs: only entries that were invalid become valid.&lt;/li&gt;&lt;li&gt;Conformance cases &lt;code&gt;a190&lt;/code&gt;–&lt;code&gt;a193&lt;/code&gt;; &lt;code&gt;a157&lt;/code&gt; reworded.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;added&lt;/strong&gt; audit events (Sections 3.5, 4.4, 7.1, 9.1, 9.2, 11.4, 11.6, 13; issues #53, #73):&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;log.exported&lt;/code&gt;, with optional &lt;code&gt;exported&lt;/code&gt; (&lt;code&gt;from_seq&lt;/code&gt;, &lt;code&gt;to_seq&lt;/code&gt;): Section 13 asked for
exports to be recorded, but no event existed for it.&lt;/li&gt;&lt;li&gt;&lt;code&gt;directory.change&lt;/code&gt; gains &lt;code&gt;added&lt;/code&gt;, &lt;code&gt;removed&lt;/code&gt;, &lt;code&gt;category_changed&lt;/code&gt; (&lt;code&gt;previous_category&lt;/code&gt;,
&lt;code&gt;category&lt;/code&gt;) and &lt;code&gt;areas_changed&lt;/code&gt; (&lt;code&gt;previous_areas&lt;/code&gt;, &lt;code&gt;areas&lt;/code&gt;). A resource that enters the
scope of a rule, a category that changes the vocabulary that applies and a set of areas
that changes which rules match were not recordable.&lt;/li&gt;&lt;li&gt;&lt;code&gt;mandate.proposed&lt;/code&gt; and &lt;code&gt;mandate.discarded&lt;/code&gt; (with &lt;code&gt;mandate.cause&lt;/code&gt;): a mandate that would
switch audit mode on and waits for a confirmation, and a proposal that does not take
effect. Only the moment it took effect was recorded (#53). Added to &lt;code&gt;audit/v0&lt;/code&gt; now rather
than to a later audit version: after the freeze, every new event needs a new &lt;code&gt;type&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;&lt;code&gt;mandate.rejected&lt;/code&gt; (with &lt;code&gt;mandate.cause&lt;/code&gt;, and &lt;code&gt;mandate.id&lt;/code&gt; and &lt;code&gt;digest&lt;/code&gt; as far as the
document could be read): a mandate from outside that was not accepted. The protection
against rollback and forged signatures left no trace in the log.&lt;/li&gt;&lt;li&gt;&lt;code&gt;request.group&lt;/code&gt;, optional: connects the &lt;code&gt;decision&lt;/code&gt; entries of one request for several
resources.&lt;/li&gt;&lt;li&gt;Compatible: only entries that were invalid become valid; a verifier that does not know an
event or a member rejects a log that contains it (Section 14, unknown members). The
reference verifier checks &lt;code&gt;from_seq&lt;/code&gt; ≤ &lt;code&gt;to_seq&lt;/code&gt; &amp;lt; &lt;code&gt;seq&lt;/code&gt;, and that &lt;code&gt;category&lt;/code&gt; and &lt;code&gt;areas&lt;/code&gt;
differ from their former values.&lt;/li&gt;&lt;li&gt;Conformance cases &lt;code&gt;a170&lt;/code&gt;–&lt;code&gt;a189&lt;/code&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The vocabulary is bound to the formats (Sections 5, 5.1, 9.1, 9.2, 12.4, 14; issue #71):&lt;/p&gt;&lt;ul&gt;&lt;li&gt;The vocabulary &lt;code&gt;https://home-mandate.org/vocabulary/v0&lt;/code&gt; belongs to the v0 formats, and
the freeze covers it: from &lt;code&gt;v0.1.0&lt;/code&gt;, a new version under this &lt;code&gt;id&lt;/code&gt; only adds (a new
category, a new action, a new permitted value, a wider range). Removing or renaming a
category or an action, changing a critical marking or narrowing a parameter needs a new
&lt;code&gt;id&lt;/code&gt; with a new major of the formats. Before, Section 14 said only that the vocabulary is
versioned independently and never changes under the same &lt;code&gt;id&lt;/code&gt; and &lt;code&gt;version&lt;/code&gt;; nothing said
what a new version may change, although a removed action would have made valid mandates
invalid and a removed marking would have run an action without its confirmation. No
change to any document: &lt;code&gt;vocabulary/v0.json&lt;/code&gt; is unchanged and its &lt;code&gt;version&lt;/code&gt; stays &lt;code&gt;v0&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;An implementation evaluates and verifies with the newest vocabulary version it knows.
Until &lt;code&gt;v0.1.0&lt;/code&gt;, the vocabulary can still change incompatibly, like the formats.&lt;/li&gt;&lt;li&gt;Audit entry: new optional member &lt;code&gt;vocabulary&lt;/code&gt; (&lt;code&gt;id&lt;/code&gt;, &lt;code&gt;version&lt;/code&gt;) of a &lt;code&gt;decision&lt;/code&gt; entry
with &lt;code&gt;evaluation&lt;/code&gt;, the vocabulary the evaluation used. For a category of Section 5 the
&lt;code&gt;id&lt;/code&gt; is that of v0, for an extension category that of the extension; the reference
verifier checks it, and with the vocabularies of extensions it checks their &lt;code&gt;id&lt;/code&gt; too
(an extension vocabulary without &lt;code&gt;id&lt;/code&gt; is now rejected). Absent with &lt;code&gt;unknown_resource&lt;/code&gt;
and &lt;code&gt;unknown_category&lt;/code&gt;. Compatible: only entries that were invalid become valid; a
verifier that does not know the member rejects a log that contains it (Section 14,
unknown members). Implementations &lt;strong&gt;SHOULD&lt;/strong&gt; record it, so that a decision stays
reproducible after a vocabulary update.&lt;/li&gt;&lt;li&gt;Text only: &lt;code&gt;&amp;quot;*&amp;quot;&lt;/code&gt; includes the actions a later version adds (Section 12.4); extensions
&lt;strong&gt;SHOULD&lt;/strong&gt; follow the same rule (Section 5.1).&lt;/li&gt;&lt;li&gt;Conformance cases &lt;code&gt;a161&lt;/code&gt;–&lt;code&gt;a169&lt;/code&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Schemas and formats in detail (Sections 3.1, 3.3, 3.4, 5.1, 9.1):&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Audit entry: &lt;code&gt;emergency_stop.released&lt;/code&gt; has an &lt;code&gt;actor&lt;/code&gt; of kind &lt;code&gt;user&lt;/code&gt;; &lt;code&gt;mandate.created&lt;/code&gt;
and &lt;code&gt;mandate.updated&lt;/code&gt; have one of kind &lt;code&gt;user&lt;/code&gt; or &lt;code&gt;system&lt;/code&gt;. The text already said that only
a human releases the emergency stop and that the human chooses the mandate; the schema
permitted &lt;code&gt;agent&lt;/code&gt;. Incompatible for logs (before &lt;code&gt;v0.1.0&lt;/code&gt;). Agents may still revoke their
own mandate or themselves and activate the emergency stop.&lt;/li&gt;&lt;li&gt;Audit entry: &lt;code&gt;mandate.previous_digest&lt;/code&gt; appears only with &lt;code&gt;mandate.updated&lt;/code&gt; (later also
with &lt;code&gt;mandate.proposed&lt;/code&gt; and &lt;code&gt;mandate.discarded&lt;/code&gt;, see &amp;quot;Proposals name the version they
would replace&amp;quot; above) and differs from &lt;code&gt;digest&lt;/code&gt;, as for templates. Incompatible for logs
(before &lt;code&gt;v0.1.0&lt;/code&gt;).&lt;/li&gt;&lt;li&gt;Audit entry: &lt;code&gt;evaluation.approval_timeout&lt;/code&gt; is required for &lt;code&gt;ask&lt;/code&gt; and with &lt;code&gt;confirm&lt;/code&gt;, and
absent otherwise. Section 9.2 already required the entry to match the evaluation;
the schema did not check it. Incompatible for logs (before &lt;code&gt;v0.1.0&lt;/code&gt;).&lt;/li&gt;&lt;li&gt;Identifiers of humans have up to 128 characters everywhere: &lt;code&gt;approvers&lt;/code&gt; in a mandate,
&lt;code&gt;approval.by&lt;/code&gt; and &lt;code&gt;approver.id&lt;/code&gt; in the audit entry had 64, while &lt;code&gt;created_by&lt;/code&gt; and
&lt;code&gt;actor.id&lt;/code&gt; had 128. Compatible: only documents that were invalid become valid.&lt;/li&gt;&lt;li&gt;An extension category in a mandate has at most 32 characters before and after the colon,
as in a vocabulary file. Incompatible for mandates (before &lt;code&gt;v0.1.0&lt;/code&gt;): a rule for a longer
category could never match.&lt;/li&gt;&lt;li&gt;Text only: the size limit of a mandate counts the document as received, before
canonicalization, as the reference code always did; the forms of &lt;code&gt;agent.client_id&lt;/code&gt; and
&lt;code&gt;issuer&lt;/code&gt; name the scheme length and the query the schema permits, and that percent-encoded
dots are not dot segments; &lt;code&gt;approval.by&lt;/code&gt; with &lt;code&gt;timeout&lt;/code&gt; names an approver whose answer came
too late.&lt;/li&gt;&lt;li&gt;Conformance cases &lt;code&gt;a153&lt;/code&gt;–&lt;code&gt;a160&lt;/code&gt;, &lt;code&gt;i150&lt;/code&gt;, &lt;code&gt;i151&lt;/code&gt;, &lt;code&gt;d49&lt;/code&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Verification of audit logs (Sections 8.1, 9.4, 9.5):&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;broken_at&lt;/code&gt; is determined condition by condition: a schema violation anywhere in the log
comes before a wrong start or a broken chain, even if the chain breaks at an earlier
entry. Before, the text also called it &amp;quot;the first entry in file order&amp;quot;, which allowed two
readings; the reference verifier has always reported the schema violation.&lt;/li&gt;&lt;li&gt;&lt;code&gt;broken_at&lt;/code&gt; is &lt;code&gt;0&lt;/code&gt; for an entry without a &lt;code&gt;seq&lt;/code&gt; that can be read as an integer, and
&lt;code&gt;anchored&lt;/code&gt; is &lt;code&gt;0&lt;/code&gt; for a log without a verified checkpoint, as the conformance cases already
expected.&lt;/li&gt;&lt;li&gt;An entry is at most 65 536 bytes, as the reference verifier already required; a line of
white space only is an entry that violates the schema like an empty line.&lt;/li&gt;&lt;li&gt;New rule: the &lt;code&gt;up_to_seq&lt;/code&gt; of a &lt;code&gt;log.truncated&lt;/code&gt; entry is smaller than the entry&amp;apos;s own
&lt;code&gt;seq&lt;/code&gt;. Incompatible for logs (before &lt;code&gt;v0.1.0&lt;/code&gt;): an entry that names itself or a later
entry as deleted made the log invalid nowhere before; no implementation writes one.&lt;/li&gt;&lt;li&gt;All checkpoints of a log carry the same &lt;code&gt;log_id&lt;/code&gt; also when no keys are given; the class
&lt;code&gt;audit&lt;/code&gt; covers this check, as the reference verifier already did.&lt;/li&gt;&lt;li&gt;Conformance cases &lt;code&gt;a146&lt;/code&gt;–&lt;code&gt;a152&lt;/code&gt; in &lt;code&gt;conformance/audit-v0.json&lt;/code&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Conformance report (Section 10.4, no change to any rule or format; issue #65):&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;implementation.version&lt;/code&gt; is the release of the implementation, not the version of the
formats. Before, the reference harness reported &lt;code&gt;v0&lt;/code&gt;; it now reports its release.&lt;/li&gt;&lt;li&gt;Over the HTTP binding the test tool takes &lt;code&gt;implementation&lt;/code&gt; from the new options &lt;code&gt;-name&lt;/code&gt;
and &lt;code&gt;-version&lt;/code&gt;; before, it stayed empty, because the HTTP binding has no
&lt;code&gt;capabilities&lt;/code&gt;.&lt;/li&gt;&lt;/ul&gt;</content>
	</entry>
	<entry>
		<id>https://home-mandate.org/changelog/#history-as-mandate-spec</id>
		<title>History as mandate-spec</title>
		<updated>2026-11-04T00:00:00Z</updated>
		<link rel="alternate" type="text/html" href="https://home-mandate.org/changelog/#history-as-mandate-spec"/>
		<content type="html" xml:lang="en">&lt;p&gt;&lt;strong&gt;incompatible&lt;/strong&gt; mandates that were valid before can become invalid, and an invalid mandate
denies every request. Implementations &lt;strong&gt;SHOULD&lt;/strong&gt; check their stored mandates before they update:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;agent.client_id&lt;/code&gt; (new Section 3.3): https URLs need a lower-case host and a path and
must not contain userinfo, a fragment, white space or non-ASCII characters; no dot
segments. Newly permitted: other URIs such as &lt;code&gt;did:…&lt;/code&gt;, &lt;code&gt;spiffe://…&lt;/code&gt;, &lt;code&gt;urn:…&lt;/code&gt;.
Identifiers of the form &lt;code&gt;&amp;lt;namespace&amp;gt;:&amp;lt;id&amp;gt;&lt;/code&gt; remain valid.&lt;/li&gt;&lt;li&gt;Timestamps: at most 9 fractional digits; the year &lt;code&gt;0000&lt;/code&gt; and the offset &lt;code&gt;-00:00&lt;/code&gt; are
invalid (Section 3.1 item 0).&lt;/li&gt;&lt;li&gt;&lt;code&gt;entity_id&lt;/code&gt; and &lt;code&gt;area&lt;/code&gt; are opaque identifiers (new Section 3.4): printable ASCII without
space, up to 255 and 64 characters, compared exactly. Every identifier that was valid
before remains valid. The evaluation no longer rejects a request because of the form of
an identifier; the PEP &lt;strong&gt;MUST&lt;/strong&gt; resolve the requested resource in its directory (Section 4).&lt;/li&gt;&lt;li&gt;A resource without category is &lt;code&gt;deny&lt;/code&gt; with the new reason code &lt;code&gt;unknown_resource&lt;/code&gt;
instead of &lt;code&gt;invalid_request&lt;/code&gt; (Section 4.1).&lt;/li&gt;&lt;li&gt;A rule without category may only use actions that some category of the vocabulary has
(Section 3.1 item 4); before, such actions were not checked.&lt;/li&gt;&lt;li&gt;&lt;code&gt;scene.activate&lt;/code&gt; is critical (Section 5): an &lt;code&gt;allow&lt;/code&gt; rule without &lt;code&gt;allow_critical&lt;/code&gt; now
yields &lt;code&gt;ask&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;&lt;code&gt;allow_critical&lt;/code&gt; together with &lt;code&gt;&amp;quot;*&amp;quot;&lt;/code&gt; is invalid (Section 3.1 item 9).&lt;/li&gt;&lt;li&gt;&amp;quot;No mandate for the agent and principal&amp;quot; is &lt;code&gt;deny&lt;/code&gt; with the new reason code &lt;code&gt;no_mandate&lt;/code&gt;
instead of &lt;code&gt;invalid_mandate&lt;/code&gt;; several mandates at the same time are &lt;code&gt;ambiguous_mandate&lt;/code&gt;
(Sections 4.1, 4.3 and 6).&lt;/li&gt;&lt;li&gt;Audit log: &lt;code&gt;denied_by&lt;/code&gt; only with &lt;code&gt;denied&lt;/code&gt;, no &lt;code&gt;error&lt;/code&gt; with &lt;code&gt;executed&lt;/code&gt;;
&lt;code&gt;evaluation.reason&lt;/code&gt; must belong to &lt;code&gt;evaluation.decision&lt;/code&gt;; &lt;code&gt;log.truncated&lt;/code&gt; only by a user
or the system (Section 9.1).&lt;/li&gt;&lt;li&gt;Displayed text (Section 3.1 item 8): fixed code point list
&lt;code&gt;data/forbidden-codepoints-v0.json&lt;/code&gt; instead of the Unicode categories of the runtime;
additionally forbidden are private-use and invisible (default ignorable) characters and
characters, blank characters, noncharacters, every white space other than U+0020, a
space at the start or end and a combining mark at the start; newly permitted are ZWNJ
and ZWJ between other characters. The rule now also applies to &lt;code&gt;actor.id&lt;/code&gt;, &lt;code&gt;agent.display_name&lt;/code&gt; and
&lt;code&gt;approval.by&lt;/code&gt; in the audit log.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;clarified&lt;/strong&gt; each with new conformance cases:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Patterns apply to the entire string and use only a portable subset of regular
expressions (Section 3).&lt;/li&gt;&lt;li&gt;&lt;code&gt;approval.timeout&lt;/code&gt;: hours are permitted (&lt;code&gt;PT1H&lt;/code&gt;); at most 5 digits per component
(Section 3.1 item 7).&lt;/li&gt;&lt;li&gt;Numbers are read by their value: digest of a mandate (Section 3.2) and &lt;code&gt;seq&lt;/code&gt; in the audit
log (Section 9.1).&lt;/li&gt;&lt;li&gt;Time zones: links of the time zone database such as &lt;code&gt;US/Eastern&lt;/code&gt; are permitted
(Section 4.2).&lt;/li&gt;&lt;li&gt;Exchange format of the audit log: line feed as the only separator, no byte order mark, no
empty lines (Section 9.4). &lt;code&gt;conformance/audit-v0.json&lt;/code&gt; has the new field &lt;code&gt;jsonl&lt;/code&gt; for it.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;added&lt;/strong&gt; &lt;/p&gt;&lt;ul&gt;&lt;li&gt;Conformance classes (Section 8.1): &lt;code&gt;evaluator&lt;/code&gt;, &lt;code&gt;selection&lt;/code&gt;, &lt;code&gt;signatures&lt;/code&gt;, &lt;code&gt;audit&lt;/code&gt;,
&lt;code&gt;audit-anchored&lt;/code&gt;, &lt;code&gt;pdp&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;Test interface (Section 10) with a process binding (JSON lines over standard input and
output, no network) and an HTTP binding for PDPs; test tool &lt;code&gt;cmd/mandate-conformance&lt;/code&gt;
with a machine-readable report and &lt;code&gt;cmd/mandate-harness&lt;/code&gt; as the harness of the
reference code.&lt;/li&gt;&lt;li&gt;Sections 12 to 14: security considerations with the attackers and assumptions, privacy
considerations, versions and compatibility. More requirements are stated with the key
words of BCP 14.&lt;/li&gt;&lt;li&gt;Mandates can carry &lt;code&gt;issuer&lt;/code&gt; and &lt;code&gt;version&lt;/code&gt;; succession protects against rollback
(Section 3.5, &lt;code&gt;conformance/succession-v0.json&lt;/code&gt;).&lt;/li&gt;&lt;li&gt;Signed mandates: compact JWS over the canonical form with EdDSA or ES256, with exactly
one accepted spelling; Section 7 is normative now (&lt;code&gt;conformance/signed-v0.json&lt;/code&gt;).&lt;/li&gt;&lt;li&gt;Checkpoints anchor the audit log: event &lt;code&gt;log.checkpoint&lt;/code&gt; with a &lt;code&gt;log_id&lt;/code&gt; and a detached
JWS over the position and digest of the log (Section 9.5); verification with keys reports
up to which &lt;code&gt;seq&lt;/code&gt; the log is anchored.&lt;/li&gt;&lt;li&gt;Section 11, obligations of the PEP: approval (binding, single use, independence from the
agent, re-evaluation, limits), rate limit (at most N requests in every period of 3600
seconds, every request counts), revocation and emergency stop, clock.&lt;/li&gt;&lt;li&gt;AuthZEN: &lt;code&gt;approvers&lt;/code&gt; in the response context for &lt;code&gt;ask&lt;/code&gt;; trust between PEP and PDP
(Section 6).&lt;/li&gt;&lt;li&gt;Audit log: &lt;code&gt;result.count&lt;/code&gt; for combined rate limit denials; verification reports the
number of entries; Section 9.4 states what the hash chain proves and what not.&lt;/li&gt;&lt;li&gt;Critical resources: the resource directory can mark a resource as critical; then every
action except &lt;code&gt;read&lt;/code&gt; is critical (Section 4, step 5). New optional input &lt;code&gt;critical&lt;/code&gt; of
the evaluation, in the conformance cases and in &lt;code&gt;request.resource&lt;/code&gt; of the audit log.&lt;/li&gt;&lt;li&gt;Parameters and constraints (Section 4.5, Section 3.1 item 10): an &lt;code&gt;allow&lt;/code&gt; rule can limit
integer parameters of an action (&lt;code&gt;temperature&lt;/code&gt;, &lt;code&gt;position&lt;/code&gt;, &lt;code&gt;volume&lt;/code&gt;, &lt;code&gt;brightness&lt;/code&gt;);
the vocabulary names the parameters and their units. New optional input &lt;code&gt;parameters&lt;/code&gt;
of the evaluation, in the conformance cases, in &lt;code&gt;action.properties&lt;/code&gt; of the AuthZEN
request and in &lt;code&gt;request.parameters&lt;/code&gt; of the audit log.&lt;/li&gt;&lt;li&gt;Selection of the mandate (Section 4.3) with &lt;code&gt;conformance/selection-v0.json&lt;/code&gt;; requests for
several resources (Section 4.4).&lt;/li&gt;&lt;li&gt;&lt;code&gt;vocabulary/v0.json&lt;/code&gt;: the vocabulary of Section 5 as a normative file, with
&lt;code&gt;schema/vocabulary-v0.schema.json&lt;/code&gt;; the same format for extensions (Section 5.1).&lt;/li&gt;&lt;li&gt;&lt;code&gt;profiles/&lt;/code&gt;: informative mappings of platforms to the vocabulary. The Home Assistant and
Matter columns left the table in Section 5.&lt;/li&gt;&lt;li&gt;Conformance cases with identifiers in the style of several platforms
(&lt;code&gt;conformance/mandates/identifiers.json&lt;/code&gt;).&lt;/li&gt;&lt;li&gt;Reference code: &lt;code&gt;displaytext.Check&lt;/code&gt;, &lt;code&gt;evaluator.Approval.Duration&lt;/code&gt;,
&lt;code&gt;evaluator.SelectAndEvaluate&lt;/code&gt;, &lt;code&gt;evaluator.Resource.Critical&lt;/code&gt;,
&lt;code&gt;evaluator.Request.Parameters&lt;/code&gt;, package &lt;code&gt;ratelimit&lt;/code&gt; (a limiter that meets the bound
of Section 11.2), &lt;code&gt;audit.VerifyJSONLines&lt;/code&gt; reads the log as a stream, package &lt;code&gt;jws&lt;/code&gt;,
&lt;code&gt;evaluator.Sign&lt;/code&gt;, &lt;code&gt;evaluator.ParseSigned&lt;/code&gt;, &lt;code&gt;evaluator.CheckSuccessor&lt;/code&gt;,
&lt;code&gt;audit.SignCheckpoint&lt;/code&gt;, &lt;code&gt;audit.VerifyAnchored&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;&lt;code&gt;conformance/schema/&lt;/code&gt;: JSON Schemas of the conformance files; &lt;code&gt;conformance/manifest.json&lt;/code&gt;:
all machine-readable files with SHA-256 and number of cases (Section 8).&lt;/li&gt;&lt;li&gt;&lt;code&gt;LICENSE&lt;/code&gt; (Apache 2.0), &lt;code&gt;LICENSE-docs&lt;/code&gt; (CC BY 4.0), &lt;code&gt;SECURITY.md&lt;/code&gt;, &lt;code&gt;CONTRIBUTING.md&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;Audit log: optional &lt;code&gt;approval.via&lt;/code&gt;, the channel an answer came through (Section 9.1),
so that a log shows whether a person confirmed on a phone or in a user interface.
Conformance cases &lt;code&gt;a11&lt;/code&gt;–&lt;code&gt;a13&lt;/code&gt; in &lt;code&gt;conformance/audit-v0.json&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;Reference evaluator: &lt;code&gt;IsCritical&lt;/code&gt; exposes the critical actions of the vocabulary
(Section 5); anything outside the vocabulary counts as critical.&lt;/li&gt;&lt;li&gt;Audit log: event &lt;code&gt;directory.changed&lt;/code&gt; with the member &lt;code&gt;directory&lt;/code&gt; records changes to the
resource directory that affect the evaluation: the critical marking, renamed resources
and how a human resolved a rename (Sections 9.1, 9.2 and 11.4). Required for
implementations that let humans change the critical marking or track renamed resources.
Compatible for logs: every entry that was valid remains valid. A verifier that does not
know the event rejects a log that contains it (Section 14, unknown members). Conformance
cases &lt;code&gt;a50&lt;/code&gt;–&lt;code&gt;a57&lt;/code&gt; in &lt;code&gt;conformance/audit-v0.json&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;Examples in English: &lt;code&gt;examples/*.json&lt;/code&gt; use English display names, device identifiers and
areas, and so do the conformance cases on them. Their digests change: &lt;code&gt;d01&lt;/code&gt;–&lt;code&gt;d03&lt;/code&gt;, &lt;code&gt;d06&lt;/code&gt;
and &lt;code&gt;d08&lt;/code&gt; in &lt;code&gt;conformance/digest-v0.json&lt;/code&gt;. The audit vectors keep their mandate digest,
which is only data there.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;incompatible&lt;/strong&gt; &lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;type&lt;/code&gt; and schema &lt;code&gt;$id&lt;/code&gt; moved to the neutral domain:
&lt;code&gt;https://mandate-spec.org/mandate/v0&lt;/code&gt;. Name of the specification: mandate-spec.&lt;/li&gt;&lt;li&gt;New validity rules for mandates (Section 3.1): &lt;code&gt;format: date-time&lt;/code&gt; is validated,
no leap seconds, I-JSON, unique rule IDs, &lt;code&gt;time_window&lt;/code&gt; with distinct start
and end, actions matching the category, at most 256 KiB, &lt;code&gt;expires&lt;/code&gt; after &lt;code&gt;valid_from&lt;/code&gt;,
approval timeout 10 s to 1 h, no control or format characters in displayed texts.&lt;/li&gt;&lt;li&gt;&lt;code&gt;agent.client_id&lt;/code&gt;: https URL or &lt;code&gt;&amp;lt;namespace&amp;gt;:&amp;lt;id&amp;gt;&lt;/code&gt; instead of the product-specific
prefix &lt;code&gt;hm-client:&lt;/code&gt; (existing &lt;code&gt;hm-client:&lt;/code&gt; IDs remain valid).&lt;/li&gt;&lt;li&gt;Request: the entity ID is required and must match the pattern, as must the area; the status
of the mandate is required (&lt;code&gt;active&lt;/code&gt; or &lt;code&gt;revoked&lt;/code&gt;).&lt;/li&gt;&lt;li&gt;The schemas are normative.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;clarified&lt;/strong&gt; (Section 4), each with new conformance cases:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Pre-check: unknown category, action outside the vocabulary, invalid time specification
or invalid mandate → &lt;code&gt;deny&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;Validity period &lt;code&gt;valid_from ≤ t &amp;lt; expires&lt;/code&gt;; revocation as an input to the evaluation.&lt;/li&gt;&lt;li&gt;Local time via the household time zone; time window start inclusive, end
exclusive; weekday of the point in time; behavior during daylight saving time transitions.&lt;/li&gt;&lt;li&gt;&lt;code&gt;rule_id&lt;/code&gt; and approval settings in the result (Section 4.1).&lt;/li&gt;&lt;li&gt;&lt;code&gt;limits&lt;/code&gt; are not part of the evaluation.&lt;/li&gt;&lt;li&gt;Extensions without a known vocabulary → &lt;code&gt;deny&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;Origin of inputs: category, area, time, time zone and status come from the PEP,
never from the agent; comparison exact per character and case-sensitive.&lt;/li&gt;&lt;li&gt;Time zones: only &lt;code&gt;UTC&lt;/code&gt; or IANA identifiers of the form &lt;code&gt;Area/Location&lt;/code&gt;; seconds are
truncated.&lt;/li&gt;&lt;li&gt;AuthZEN mapping of the fields (Section 6); the Home Assistant and Matter columns in the
vocabulary are informative.&lt;/li&gt;&lt;li&gt;Audit log: required fields per event, &lt;code&gt;executed&lt;/code&gt; only after a permitting decision,
&lt;code&gt;broken_at&lt;/code&gt; also on schema violations (Section 9).&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;added&lt;/strong&gt; &lt;/p&gt;&lt;ul&gt;&lt;li&gt;Digest of a mandate (Section 3.2), reason codes (Section 4.1), both
required in the AuthZEN response context (Section 6).&lt;/li&gt;&lt;li&gt;Audit log with a fixed format and hash chain (Section 9, &lt;code&gt;schema/audit-v0.schema.json&lt;/code&gt;).&lt;/li&gt;&lt;li&gt;Schema: time fields additionally with &lt;code&gt;pattern&lt;/code&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Conformance cases: new fields &lt;code&gt;reason&lt;/code&gt; (required), &lt;code&gt;timezone&lt;/code&gt;, &lt;code&gt;revoked&lt;/code&gt;, &lt;code&gt;rule_id&lt;/code&gt;,
&lt;code&gt;approval_timeout&lt;/code&gt;; new files &lt;code&gt;conformance/invalid-v0.json&lt;/code&gt;, &lt;code&gt;conformance/digest-v0.json&lt;/code&gt;,
&lt;code&gt;conformance/audit-v0.json&lt;/code&gt;; test mandates under &lt;code&gt;conformance/mandates/&lt;/code&gt;.&lt;/p&gt;</content>
	</entry>
</feed>
