You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This commit was created on GitHub.com and signed with GitHub’s verified signature.
Added
A diagnosis branch that strands the reader is reported.escalation-required runs on runbooks. Every branch
under ## Diagnosis links to #resolution or #escalation, or ends on the word continue to fall through to the
next question. The last list in the section has nothing to fall through to, so continue there is reported as well.
One branch of the tree reaches #escalation, for the reader the tree does not answer. kac validate fails each
branch at fault under diagnosis-dead-end, quoting it, and the tree that never escalates under diagnosis-no-escalation. A Diagnosis written as prose has no branches and is passed over. The runbook _template.md teaches the form.
A standard's changelog runs newest first.kac validate warns where an entry is dated after the one above it,
and states both dates. A bullet that does not open on an ISO date before a colon is passed over, which is how a
template placeholder stays out of it. The rule is changelog-newest-first and it reports under changelog-order.
A control states the day somebody reads it again.controls declares review-by, required on every control. frequency says how often the check runs, and review-by says when somebody reads the record against it. The field
travels in the export after applies-to, kac generate lists it on the type page, and controls-lookup tells a
reader to check it beside status.
A review date that has passed is reported on every type that states one.control-in-date, policy-in-date, standard-in-date, nfr-in-date, fix-in-date, glossary-in-date and explanation-in-date run. kac validate
warns where review-by is earlier than the day of the run, as it already did for a tool, a data record and a
deviation. A warning does not fail the build.
A type says which status value means a record is in force.in-force: sits beside values: in .schema/<type>.yaml, and every type that states a range declares it. The value is not active throughout: an ADR
settles at accepted, an NFR at agreed, an offering and a service at live, a tool at approved, a postmortem at published. kac generate writes it into the status row of the type page, so an author reads the settled value
beside the range. kac validate fails a type that states a range and names no value, an in-force: the range does
not include, and an in-force: on a field that is not an enum.
A type: id with no ref: is reported.kac validate fails a schema whose field declares type: id, or of: id on a list, and states no folders for its ids to resolve against. The reference pass selects a field on its ref: before it reads the type, so the value reached no check while the type page rendered the field as a citation.
An id on an entry key is reported whatever the key declares, at any depth, because that pass reads a field's own
value and never walks an entry: block. Both are reported under schema-dispatch.
A framework citation that never became a link is reported.alignment-unlinked runs. kac validate fails a
policy whose Alignment cell writes [UK GDPR].Art.5(1)(e) with no link definition behind it. Markdown leaves the
brackets on the page as text, so the cell states no mapping. Reported once per label. While the definition is
missing, alignment-rollup does not report aligns-with as claiming that framework.
Removed
constraint-consistency is gone from nfrs. The rule compared an NFR's target against the their-sla of
each integration in constrained-by. Both fields are free text, so there was no pair of numbers to compare. The their-sla note in .schema/integrations.yaml no longer gives the rule as the reason to quote a contract, and constrained-by is unchanged.
Three rules nothing could run are gone from the schema.store-has-service on data, terms-are-singular on glossary and blameless on postmortems no longer appear on a type page under Declared, not yet enforced. kac checks closed word lists. Each of these three needs a judgement it cannot make: a store written as prose, an
English plural, a personal name. The type page and the _template.md for each type already tell an author what to
write, and ref-resolves already reports a data record whose owned-by names no service.
A corpus states which area path inside an Azure DevOps project its work is filed under.tracker: and framework: in .corpus.yaml each take an area, written below the project and separated by /. One project gives
one backlog to any number of corpora, so without it every corpus's findings land in one queue. kac export writes it
on all three trackers in manifest.json, and the two filing skills set System.AreaPath from it. area applies to azure-devops alone, so a new descriptor-area check fails one stated elsewhere and the export drops it. Nothing derives it: only the corpus knows which area inside a shared project is its own. descriptor-version moves to 6, and the export's formatVersion stays at 4.
Fixed
raise-finding and request-deviation file on the tracker rather than where the corpus publishes. Both read tracker and sources[].tracker from manifest.json, and neither reads publishing any more. On Azure DevOps the
two differ: publishing.base is a repository inside a project and the backlog is the project, so every work item went
to an address with no backlog. Both also decode a percent-encoded project name before passing it to az, so Engineering%20Standards reaches it as Engineering Standards. Nothing changes for a corpus on GitHub, where a
repository is its own issue list and the two addresses are one string.
clause-compound reads a whole modal word.kac validate no longer warns on a clause such as **MUST** be MUSTERED before the shift, where a longer word only begins with a modal. MAY inside MAYBE and SHALL inside SHALLOW did the same. A second modal is still all the check reads. Two obligations written under one modal pass,
and the check's description and the row on a policy's type page now say so.
label-canonical reads the label a reader sees.kac validate fails a shortcut or collapsed reference whose
use site mis-cases the label, such as [STD-ci] behind a [std-CI]: definition. Markdown matches the two
case-insensitively, so the page rendered an id no record carries and every check passed. A full reference such as [the workflows standard][ci-standard] displays its own words instead, so its label is now reported at the
definition alone and no longer quoted at a line where nobody can read it.