pub struct PolicyError {
pub kind: &'static str,
pub token: String,
pub accepted: Vec<String>,
pub rule: String,
pub message: String,
pub line: usize,
pub text: String,
pub fatal: bool,
}Expand description
⟨0.24⟩ ONE POLICY LINE THE PARSER DID NOT HONOUR AS WRITTEN (SPEC §3.1 901f14d / 195d45a).
THE DEFECT. parsepolicy emitted no errors key at all (measured 2026-07-28 on the
conformance battery: java 10, ts 4, rust 0, swift 0). Every one of these facts existed — they were
printed to stderr as “ignoring policy rule …” — so the verb whose entire purpose is to let a consumer
diff what an engine made of a policy answered the question with the not-honoured half deleted. Worse,
it was INCONSISTENT with this engine’s own gate: the gate refuses an unrecognised class token while
the parse narrowed it silently, which is two answers to one question.
kind IS A CLOSED SET, AND IT IS THE SPEC’S, NOT THE REFERENCE ENGINE’S. 901f14d pins four
values: reason-class/alias, Net destination-class, effect-name, rule-kind. Measured, candor-java
emits forbid form, allow values and rule kind (space, not hyphen) — three values outside the set
and one spelling divergence — and candor-ts renames kind→vocabulary and rule→where and emits
accepted as a PROSE STRING. This engine follows the clause: a line that names a rule keyword but does
not form that keyword’s rule formed no rule kind, so it is rule-kind.
accepted is an ARRAY OF TOKENS — the tokens that WOULD have been honoured in the position the bad one
occupies. Empty where the position is open-ended (a host, a path), which is a fact about the grammar
rather than a gap in the report.
Fields§
§kind: &'static strOne of PolicyError::KIND_REASON_CLASS, PolicyError::KIND_NET_CLASS,
PolicyError::KIND_EFFECT_NAME, PolicyError::KIND_RULE_KIND.
token: StringThe offending token, verbatim. Empty when the position was EMPTY (a missing arrow, an allow with
no values) — which is itself the finding.
accepted: Vec<String>The tokens accepted in that position. Empty ⇒ the position takes an open-ended literal.
rule: StringThe raw policy line, verbatim.
message: StringThe human sentence — the same text the stderr channel carries, so the two cannot disagree.
line: usize⟨0.28⟩ The 1-based SOURCE LINE the error sits on — SPEC §6.2 pins the verdict’s ignored
disclosure as [{ line, text, reason }], and a consumer’s next action is to go to that line.
Counted over the normalized text (bare \r line breaks count like \n, matching the split).
text: String⟨0.28⟩ The source line VERBATIM — before comment-stripping and trimming, unlike rule, because
§6.2’s text is “the source line, verbatim” and the operator matches it against their file.
fatal: bool⟨0.24⟩ Does this error make the policy UNHONOURABLE, so every gate route must refuse (exit 2)?
FATAL and REPORTED are different questions and this field is the only place they are told apart.
A dropped nonsense line is reported and survivable — the rest of the policy means what it says.
A rewritten deny Unknown[dispatch,nativ] is not: the rule that RAN is not the rule that was
written, and the direction that matters NARROWS it.
Implementations§
Source§impl PolicyError
impl PolicyError
pub const KIND_REASON_CLASS: &'static str = "reason-class/alias"
pub const KIND_NET_CLASS: &'static str = "Net destination-class"
pub const KIND_EFFECT_NAME: &'static str = "effect-name"
pub const KIND_RULE_KIND: &'static str = "rule-kind"
Trait Implementations§
Source§impl Clone for PolicyError
impl Clone for PolicyError
Source§fn clone(&self) -> PolicyError
fn clone(&self) -> PolicyError
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more