Rules

39 business rules described. A business rule is a condition the business imposes, with what it constrains and what happens when it is broken.

Severity
Sort: Links
Business ruleSeverityFirst lineLinks
AccessibilityerrorEvery screen of the generated site gives a screen reader or keyboard user the same information as everyone else. Five guarantees hold on every page, and the build and the test suite verify them without a browser.
Broken linkerrorA markdown link written in a note points to a file that does not exist in its source. The link is not recorded and the reader lands on nothing.
Conversion failedwarningAn office document could not be converted to PDF: timeout, size, corruption or missing converter. The document stays downloadable, without preview or extracted text.
Ambiguous relationinfoA link between two entities fell back to the generic relation because no section, no typed attribute and no single allowed relation decided it. It is kept at a capped confidence. The finding is raised by the relation typing step and points at the note the link was read in, on the line of its first located provenance; a link that co-occurrences alone know raises nothing, since a co-occurrence names no file and is unnamed by nature.
Relation typinginfoEvery link between two notes ends up with a relation of the profile, decided on four rungs, the first that applies winning: a mapped section (a business object under ## Objects of a screen is accesses), a typed frontmatter attribute (reads is accesses in read mode), a type pair that admits a single relation (a markdown link or a plain mention between a rule and a screen is constrains, marked relation_origin: pair and turned around when the profile only allows it the other way), then related, kept with its confidence capped at 0.60 and reported by the ambiguous relation check. The first two rungs come from what the author wrote and are never overturned; a declared relation the profile does not allow between the two types is dropped by the relation outside the matrix check. The labels shown for a relation, in either direction, come from the profile alone. The architecture guide and the writing guide describe it.
Stale sourcewarningA source or a note has not changed for longer than the configured threshold. The date comes from git and is always right.
Suggested domaininfoA note no frontmatter, folder or glob files lies within the radius of a pivot of the neighbourhood: a term with a note of its own whose distinct neighbours, over the typed links and the co-occurrence neighbourhood, reach the configured threshold. The note is a candidate for a domain named after the pivot, the last segment of its identifier, and is attached to the closest pivot, at equal distance to the one of highest degree, then to the first identifier in code-unit order. A stopword or a term the lock file rejects never pivots. The build proposes and files nothing: a growing corpus moves its pivots, and a note would swing from one domain to another between two builds. The proposal is promoted by declaring the domain in the configuration with the folders or globs that claim its notes, or by naming the note under domains in the lock file; the configuration may also let the build file every reached note itself, with the origin inferred.
Operation matchingwarningAn operation note attaches to the operation imported from the contract of its API on three rungs, tried in order, the first that matches winning: the operation_id of the frontmatter against the operation identifier of the contract; the method and path pair (or port and the title for a SOAP operation) against the operation's; the title of the note in comparison form, spaces and punctuation ignored, against the operation title or its identifier. The note names its API in the api attribute or through a markdown link; a note that names none is a candidate for every API of its source that declares a contract.
Relation outside the matrixerrorA declared relation joins two types the profile does not allow for it. The link is dropped from the model by the relation typing step. A frontmatter reference that names an existing note of a type the attribute does not accept is this finding, not an unresolved reference: the note exists, the relation is what the profile forbids.
Operation unmatchedwarningAn operation note that names an API with an imported contract, in its api attribute or through a markdown link, and that none of the three rungs of the operation matching attaches to an operation of that contract. One of two things is true: the operation disappeared from the contract and the note describes something that no longer exists, or the note is ahead of the contract and describes an operation the next version will declare. The build cannot tell which, so the finding says both, and the author decides: retire the note or point it at the operation that replaced its own, or keep it with the operation_id to come until the contract catches up. A note that names no API is not reported: it is a candidate for every contract of its source and may describe an API without a contract. A note taken in an ambiguity is reported by the matching rule instead.
Duplicate candidateinfoTwo resources look like forms of the same document, with a reconciliation score between 0.5 and 0.9. They stay separate until a human decides.
Linter and build parityerrorThe local lint says the same thing as the build. For the checks the linter computes in --scope repo, listed as LOCAL_CHECKS by the lint package (E-ENCODING, E-FM-INVALID, E-ID-DUP, E-ID-INVALID, E-LINK-BROKEN), concordance lint on a repository and concordance build on a configuration that declares it as a source produce the same findings: same check, source, path, line and entity, same severity, message and remediation. The build reports more, never less: the checks that need the whole model only exist there.
Cross-source linkwarningA markdown link leaves its source, with the <source>:<path> prefix or with a relative path that climbs above the source root into a sibling source, while inference.cross_source_links is off. The link is not recorded: the model keeps no relation between the two notes until the configuration allows links across sources, or the author links to a note of the same source. The linter in global scope reports the same finding from one repository when the link reaches a note of the published model and that model says it was built with cross-source links off; a link that leaves the source for a file that does not exist is a broken link once such links are allowed.
Unclassified domaininfoA note sits under no folder a declared domain claims, matches no domain glob and declares none in frontmatter. It lands in the unclassified domain. A domain claims a folder with folder: true, the folder named after its identifier, or folder: <name>, anywhere on the path of a note in any source; a subdomain declared by folder claims only the notes under its parent's folder, or anywhere on a path the parent's globs match when the parent is declared by globs. Folders and globs combine, the deepest domain winning, then the last declared.
Term homonyminfoTwo entities share a title or an alias once spellings are compared: same form after lower-casing, accent stripping and singularisation. The recognition dictionary keeps both, every occurrence of the form links to each entity at half the confidence it would have with a single target, glossary entities first, and the finding names the form and the entities. When the two are different things, distinct titles or aliases settle it; when they are one concept seen from two sides, as the glossary term and the business object called "Entity" in this wiki, both stay and a ## Not to be confused with section tells the reader which is which. The linter reports the same finding in global scope for a local title that an entity of another type carries in the published model. A twin folded into its note is no homonym: the twin resources are reconciled before the dictionary is built, and the titles and aliases of the folded twin name the entity it became, once.
Unresolved referencewarningA value of a reference-typed frontmatter attribute (reads, roles, rules, consumers, affects, broader among others) matches no note by identifier, by path relative to the source root or by exact title, or matches several notes by title. No link is recorded for that value; the other values of the attribute are unaffected. The fix is to write the identifier, the path or the exact title of an existing note, the identifier or the path when a title is shared: this repository names its roles by path, roles/publication/reader, because the glossary carries a term with the same title as one of them. A note found under a type the attribute does not accept is a relation outside the matrix, not an unresolved reference.
Document without markdowninfoA document has no markdown representation once the twin resources are reconciled: it stands as an entity of its own, or merged with other documents only. Its words are recorded from the text extracted from its PDF or its cues, but nobody wrote about it. The to-do page lists these documents; a note next to the document with the same base name, or declaring it under source, merges with it and lifts the finding.
Ambiguous operationwarningAt the rung of the operation matching where a match is found, two operation notes claim the same operation imported from a contract, or one note matches several operations of its API. Nothing is attached: the finding names every candidate, the imported operation stays a separate entity with the properties of the contract only, and the other notes and operations of the API are matched as usual. The operation_id of exactly one operation in each note settles it; a note that names no API and matches several contracts of its source names its API in the api attribute.
Undefined termwarningA recurring expression crosses the threshold without any note defining it. It has a keyword page built from its passages, but no definition.
Unreachable contractwarningThe contract an API note declares in its contract attribute, a URL or a path relative to the note, could not be fetched, read or parsed: the server answered with an error, the build ran without network access, the file is missing, or the document is neither an OpenAPI 3.x document in JSON or YAML nor a WSDL 1.1 or 2.0 document. No operation is imported from it, the note keeps the operations written by hand, and the build goes on; the API page has no imported operations until a later build reads the contract. A project whose contracts must be present raises the severity to error.

20 rules of 39 — pagination by twenty. The Links column counts the related pages, which brings the most central rules of the journey to the top.