v0.24.0
Added
-
kac report <name>prints a report over the corpus and everything it imports. Two reports ship.kac report coveragenames every policy clause and what discharges it, with the deviations departing from it, the controls behind
each covering standard, and any clause elsewhere sharing its key.kac report frameworksnames every external
framework reference the clause tables cite, the standing the register files each framework under, the clauses citing
each one, and how many rest on a single citation. Each row of both carries an emptyNote, for whoever confirms
the report. Output is markdown on standard output, so a caller pipes it where they want it. Every run stamps
generatedandsourcesinto the frontmatter it writes, naming the tool version, the moment, and the
content-versioneach corpus answered at. The tool printscoveredanduncoveredand never splits a gap from
something out of scope, because only a person can tell those apart. -
A standard's
implements:and itsCoverslines reach a consumer. The record carriesimplements, and each
rule line carriescovers, holding the clause ids that rule discharges. A corpus inheriting the policies it answers
to can now count its own coverage: before this, it saw what its own standards covered and nothing that arrived with
the policies.part.citations.<Label>is the export source behind the rule line, and it takes the ids from the
labelled footnote closing a part. Neither addition movesstandards@1, because a reader written against the shape
before them is still correct. -
framework-uncitedfails a framework on the register that no clause cites. The register is the list of
frameworks an estate has taken a standing against, so an entry nothing reaches is a standing nobody acts on, and it
reads as coverage to whoever is looking for evidence. It is the third checkalignment-rollupreports under. The
register is found by following a clause's own link, so a corpus whose clauses cite nothing has none in view. A
finding lands on the policy that reached the page and names the page the entry is deleted from. -
policies/frameworks.jsonltravels in the export. One line per external framework reference, naming the
standing the register files it under, the clauses citing it, the policies holding those clauses, and the page and
anchor the register entry sits at. A type names the file withframeworks:in itsexport:block and the exporter
fills the keys, because a reference is read from a clause's cell and from the register the cell links to rather than
from any field a type declares. Navigation stays one way:clauses.jsonlis unchanged, and a clause still carries no
framework. Bothpolicies@2andformatVersionstand, because a reader written against the shape before this is
still correct. -
report-stalewarns where a report answers for a version the corpus has left behind. Every other record is
about the estate, so a corpus that moved leaves it as true as it was; a report is about the corpus, and the same
change can make it wrong with nothing in the record showing it. Eachsourcesentry is held against the version in
front of the reader: the descriptor's owncontent-version, or the version a consumed corpus's restore resolved to.
A warning, because the report may well still hold, and whoever owns it either confirms that and raises the version by
hand or runs it again. -
reportsis a knowledge type the framework ships. A finished report is a record: it has an
owner, a person confirms it before it is published, and a reader browsing the corpus finds it beside everything else.
generatednames what produced the content and when,sourcesnames each corpus it answers for and the
content-versioneach was at, andconfirmednames every person who has checked it since. Sections are free-form,
because a report's headings follow the question it answers. Take it withkac update --add-type reports. -
A field may hold one object, and a shared shape may say what it holds.
type: objectdeclares a value that is
one mapping, and its keys are held to their own declarations exactly as a list's object entries are._shapes.yaml
joins_enums.yamlas a shared block, declaring an object shape a field takes whole withshape: <name>. Nothing
narrows a shape at the point of use, so a type holding one of its keys to a narrower value writes a rule.event,
an actor doing something at a point in time, is the shape that ships. This moves the template to version 8, so a
corpus takes_shapes.yamlwithkac update. -
entries_match('field', 'key', 're')joins the expression facts. It reads one key inside every object a field
holds: each entry of a list of them, and the one anobjectfield holds. It is true where the field is absent and
true where an object omits the key, because presence isrequired-field's question andentry-key's, so a rule
written on top of it reports one fault once. -
A whole number is a field type the tool checks.
type: int, andof: inton a list, are read by
int-format: plain decimal with an optional leading sign, and within what a 64-bit number holds. A separator or a
base prefix is refused rather than decoded, because YAML reads1_000and0x1fas numbers of its own and an
author should not have to know which spellings the parser admits.ado-epicson a capability is the field this
reaches, and its entries were checked by nothing before.
Changed
- An FAQ's
confirmed.byis held to a person by a rule rather than by a pattern. The finding moves from
field-patternon the entry's own line toconfirmed-by-a-personagainst the record, and the message says why a
post, an agent and a team alias are each refused.confirmednow takes the sharedeventshape, whosebyis a
plain string, and who may confirm is the FAQ type's own question to ask.
Fixed
-
kac updatewrites the descriptor's upstream block with one space after each colon. It padded every key it
stamped to a column, andyamllint --strictrefuses that under itscolonsrule, so a corpus running the linter its
template ships went red oncommit,template-versionandtaken-onthe moment it updated. The next run repairs a
descriptor an earlier one aligned. -
A field's
type:andof:are held to what the tool dispatches. Either naming a value no check reads now fails
schema-dispatchwhen the schema loads, sotype: tiemstampis reported rather than loading and holding the field
to nothing. An entry key answers to the same vocabulary, to whatever depth anentry:block nests, because its value
goes back through the same checks. The types aredate,enum,id,int,list,stringandtimestamp; a
list's entries areid,int,objectandstring.boolwas offered bymeta/type.schema.jsonand dispatched
by nothing, as wasof: date, and both are gone from it. -
An
of:on a field that is not a list is reported. It is read from a list's entries and nowhere else, so a
scalar carrying one states a shape its value can never take.values:,min-items:andmin-records:were already
held to the field type they are read against, andof:now joins them. -
An unquoted placeholder in a record is reported. YAML reads
owner: {{owner}}as a flow mapping rather than as
text, so the value reached no check at all and the record validated clean.bare-keynow reports it and names the
quoting that fixes it, andrequired-fieldreports the field missing where the type requires it. A template still
reports the same spelling undertemplate-fields, which answers for the documents copied from it. The two seed
recordskac newwrites carried the mark, and now name an owner.