Skip to content

v0.15.0

Choose a tag to compare

@github-actions github-actions released this 28 Aug 14:03
7381c18

Added

  • kac validate says when an import has fallen behind what its source publishes. kac restore keeps the version
    a consumes: entry locked for as long as the range still admits it, which is what makes a restore reproducible and
    is also how a corpus sits on a version nobody meant it to sit on. So validate asks each source what it holds now,
    once per run, and reports three new checks against .corpus.yaml.

    import-behind is a warning: a newer version sits inside the declared range, and kac restore takes it.
    import-capped is information: a newer version is published and the range holds it back, which is a decision
    the corpus already made. import-unreachable is information too, for a source this run could not ask, so a lock
    reads as unchecked rather than as current. None of the three fails the build, because failing on somebody else's
    release would turn every downstream red the day a governance corpus ships.

    A source answering with no versions at all reports as unreachable rather than as current, because a registry
    answers a private feed's anonymous reader exactly as it answers a package nobody has published. A corpus with no
    consumes: block reads no source and builds no client, and every other check still reads the working tree alone.

  • A third severity, info. kac validate counts it in its summary line and in --json, where
    summary.infos is new, and kac checks tallies it apart from the warnings. Neither a warning nor an info changes
    the exit code. A check declares severity: info in .schema/_checks.yaml. docs/design/checks.md covers it.

  • A corpus says who it is, and pack and bundle stop inventing it. Four new keys in .corpus.yaml:
    display-name, description, license and author. kac export carries them in a new about block, kac pack
    writes them into the package a registry lists, and kac bundle writes them into the plugin manifest somebody
    installs.

    A plugin's identity is now generated rather than copied. name, version, displayName, description,
    author, homepage, repository, license and keywords are all written from the corpus, and a key the corpus
    declared nothing for is removed rather than left standing. author is the exception, filed under the corpus's own
    name where it named nobody, because the format asks for one and claude plugin validate --strict fails a manifest
    carrying none. .plugin/.claude-plugin/plugin.json keeps only what the
    corpus declares: metadata.corpusRoot and metadata.components, plus any key this tool has never heard of. A
    manifest copied from a template no longer publishes under the template author's name, licence and repository.

    keywords are the types the export carried, so a plugin never advertises a type its corpus declined. kac new
    writes the four keys bare, because a value supplied there would be inherited rather than chosen.

  • kac export names the two keys that address a part. Each type's manifest entry gains recordKey and
    partKey, naming which key of a part line says which record it belongs to and which part of that record it is. A
    type names its own keys, so a consumer holding a corpus with a type it never adopted had no way to read them and had
    to assume a spelling. Both are absent where the type keeps no parts, as partsFile is. docs/design/export.md
    covers it.

  • kac validate resolves a reference across a corpus boundary. A citation carrying a producer's shortcode, as
    eng:pol-VURM.TIMEBOX, resolves against the export kac restore unpacked under .imports/. It is read in prose and
    in a field declaring a ref:, so implements: eng:pol-VURM.TIMEBOX names one clause rather than a whole policy, and
    both halves are held to existing. Local records and imported ones go through one lookup, so a corpus is not judged
    more loosely for having imported the record it cites.

    Each side keeps its own spelling. A record the reading corpus holds is cited bare, one it imported carries the
    shortcode, and writing either the other way is refused naming the spelling to write.

    A new import-restored check fails a corpus declaring an import that is not on disk, and names kac restore. Every
    citation into that shortcode then stays quiet, so a run that has not restored reports one line rather than one per
    reference. docs/cli/validate.md documents both.

  • kac restore fetches the corpora a corpus declares it consumes. A new consumes: block in .corpus.yaml names
    each producing corpus, the shortcode it is cited by, the version range it is wanted at and the source it comes from.
    restore resolves each range, fetches the package kac pack sealed, and unpacks it under .imports/<shortcode>/,
    which the template now gitignores. The version each range resolved to is written back onto its own entry, so
    .corpus.yaml stays the one description of what a corpus is.

    A source: names a registry's service index or a folder of packages. A folder holds the same sealed package a
    registry serves, so a corpus consuming a sibling in its own repository needs no registry, no token and no release. A
    path is relative to the corpus declaring it, as upstream.url is.

    A range says 1.2.0 or ^1.2.0 and nothing else, and a caret never takes a prerelease. A lock the range still
    admits is taken without asking the registry, so two restores of an unchanged descriptor write the same bytes. A run
    says what it fetched, at which version, and which corpora were already current.

    A shortcode two entries both claim is refused naming both, as is a corpus two entries both consume, as is a package
    whose own manifest is cited by a different shortcode from the one declared. KAC_REGISTRY_TOKEN in the environment
    carries a bearer token for a private feed. docs/cli/restore.md documents the verb, and docs/corpus-descriptor.md
    the block.