okf-core-0.5.0.0: CHANGELOG.md
# Changelog
All notable changes to okf are recorded here.
The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and
this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
## [0.5.0.0] - 2026-08-01
### Added
- **OKF v0.2 core semantics.** okf now tracks version 0.2 of the Open Knowledge
Format. Every family below is optional; `type` remains the only key a concept
must have, and no bundle is ever rejected for omitting one.
- `Okf.Actor`: the specification §7 actor convention, with `parseActor` (total,
never fails), `renderActor` (its exact inverse), and `isHumanActor`, which is
the single test separating the machine-confirmed trust tier from
human-reviewed. Four fields carry an actor: `generated.by`, `verified[].by`,
and `sources[].author`.
- The trust family (§5.2): `Generated`/`readGenerated`/`setGenerated` for who or
what produced a concept's content and when, and
`Verification`/`readVerified`/`setVerified` for independent confirmation.
`readVerified` accepts a bare mapping as a one-element list, as §5.2 requires.
- The lifecycle family (§5.4, §5.5): `Status`/`readStatus`/`renderStatus`/
`setStatus`, where an absent key means `stable`, and `readStaleAfter`/
`setStaleAfter`.
- The provenance family (§5.1): `Source`/`readSources`/`setSources` with the
credibility signals `author`, `usage_count`, and `last_modified`, plus
`UsageWindow`/`readUsageWindow`/`setUsageWindow` and `effectiveUsageWindow`,
which resolves an entry's own window against the document-scope one.
`usage_count` is read only from a YAML integer; a numeric string is not
coerced.
- `Okf.Trust`: `trustTier`, `renderTrustTier`, `latestVerification`,
`staleness`, and `renderStaleness`. Everything here is derived on read and
never stored, and no function in `okf-core` reads the clock — `staleness`
takes the current day as an argument. See
`docs/adr/8-derived-not-stored-trust-and-credibility.md`.
- `Okf.Bundle.Concept` projects six more typed fields from frontmatter —
`generated`, `verified`, `status`, `staleAfter`, `sources`, `usageWindow` —
with matching accessors. Every projection restates frontmatter; none is a
derivation.
- The bundle-root version declaration of §12: `OkfVersion`,
`VersionDeclaration`, `readBundleVersion`, `parseOkfVersion`,
`renderOkfVersion`, `supportedOkfVersion`, and `renderRootIndex` in
`Okf.Index`. `Okf.Validation.versionGate` is the one place that decides what a
declared version implies, and `gateDeclaresAtLeast` is the only question a
check asks of it. An unknown minor within a known major is read as the highest
known version; an unknown major is read permissively. Neither is ever a refusal.
See `docs/adr/10-okf-version-declaration-and-best-effort-reading.md`.
- `Okf.Markdown`, with one shared `markdownOptions` list, `extractFootnoteLabels`,
and `footnoteLabelsUsed`. All three `commonmarkToNode` call sites now route
through it and Markdown footnotes are enabled. See
`docs/adr/9-one-markdown-parse-configuration-and-source-scanned-authoring-checks.md`.
- `okf-core/test/fixtures/v01-legacy-bundle`, a deliberately unmigrated v0.1
bundle that keeps the legacy fallback under test. Do not migrate it.
- **Object rules on profile field rules.** `FieldRule` gains
`objectFields :: Maybe NestedRules`, describing the record that *is* a key's
value, as distinct from `elementFields`, which describes the record inside each
element of a list. Both take the same `NestedRules` value and their members are
checked identically; only the reported `FieldPath` differs (`generated.by`
against `reviews[0].kind`). Declaring both accepts either spelling, which is how
a profile describes the OKF v0.2 `verified` key. `NestedFieldRule` gains
neither member, so the descriptor stays depth-bounded.
`EffectiveFieldRule` gains the `fieldRuleObjectFields` accessor, and generated
profile documentation gains an `- Object fields:` bullet. Declaring
`objectFields` and no explicit cardinality refines the rule to the new
compiled-only `Cardinality` constructor `Object`; pairing it with an explicit
`Scalar` or `List` is the new definition error
`ObjectFieldsRequireObjectShape`. See
`docs/adr/11-growing-the-profile-descriptor-language.md`.
- `okf-core/test/fixtures/profiles/object-fields-mp8-ep1.dhall`, the frozen
descriptor generation from immediately before `objectFields` existed. Do not
edit it.
- **The OKF v0.2 `Attested Computation` concept type (§10).** A concept of that
exact type carries a sanctioned way to compute a value, so a consumer can
confirm a number came from running the blessed computation rather than from an
agent improvising its own query. `Okf.Document` reads the five contract keys —
`runtime`, `parameters`, `computation`, `executor`, `attester` — with
`Parameter`, `Executor`, `Attester`, and `attestedComputationType`, the exact
case-sensitive type string. All five joined `coreFrontmatterFieldOrder` and
`fieldsIntroducedInV02`, between `status` and `generated`, which is §10.2's own
worked-example order, so serialization round-trips a §10.2 concept unchanged.
`Okf.Bundle` projects the lot onto `Concept`.
- The body half of §10.3: `Okf.Markdown.computationBlocks` finds the code blocks
under a `# Computation` heading, bounded at the next heading of the same or
shallower level, and accepts both the fenced spelling §10.3's prose names and
the indented one §10.2's own example writes. `Okf.Document.ComputationSource`
and `readComputationSources` restate what a document offers — file before
inline — and `Okf.Bundle.conceptComputationSources` projects it. Every one of
these is type-agnostic and never reports; scoping to the type is
`Okf.Validation`'s job.
- Four strict-mode `ValidationError` constructors for that type and no other:
`AttestedComputationMissingRuntime` for §10.2's one REQUIRED field, and
`AttestedComputationHasNoComputation`, `AttestedComputationHasBothComputations`,
and `AttestedComputationHasManyBlocks Int` for the three ways §10.3's
exactly-one rule breaks. Strict-only, per
`docs/adr/7-okf-v0-1-legacy-fallback-policy.md`: §11's conformance list reaches
none of them and separately forbids rejecting a bundle for an unknown `type`,
so "REQUIRED for this type" binds the producer and does not license a consumer
to refuse.
- **Path-valued frontmatter fields are resolved against the bundle** (§6.2), a
gap that predates attested computations — nothing in okf had ever looked at a
path sitting in a frontmatter value. `Okf.Path` gains existence checking, and
`Okf.Validation` reports `DanglingFrontmatterPath` under `StrictAuthoring` for
`resource`, `computation`, `executor.resource`, and `attester.resource`. A
relative path that would have resolved from the bundle root is told the
leading-slash spelling to write instead. `sources[].resource` is deliberately
excluded: §5.1 sanctions a scope descriptor there, so path-checking it would
report correct bundles as broken. See
`docs/adr/12-frontmatter-path-resolution.md`.
- `Okf.Profile.validateProfileWith` takes a `BundleInventory`, so a profile
`path` rule resolves against every file in the bundle rather than only `.md`
concepts — which is what §6.3's own `references/attesters/revenue.py` example
needs. `validateProfile` is defined in terms of it and keeps its exact meaning:
a caller that supplies no inventory has not looked, and okf reports nothing it
did not check. See `docs/adr/13-the-references-convention-and-non-markdown-files.md`.
- `Okf.Index` lists a directory's non-Markdown files under a `# Files` heading,
so a `references/attesters/` directory holding only `.py` files no longer
generates a one-byte `index.md`.
- `okf-core/test/fixtures/attested-computation/`, a bundle carrying one complete
contract, one of each §10.3 failure, one `Metric` that must never be mistaken
for a computation, and one concept that is core-clean and deviates only from a
house profile. `okf-core/test/fixtures/profiles/attested-computation-house.dhall`
is that house profile, and is the descriptor `docs/user/profiles.md` documents.
- `Okf.Profile.Documentation.defaultDocumentationActor`, the actor
`defaultDocumentationOptions` names as the producer of a generated
documentation bundle: `ProcessActor "okf-profile-document"`. Deliberately
version-free, so generated output stays byte-identical across okf releases.
- A profile may require its bundle to declare an OKF version.
`ProfileSpec.requireBundleVersion` holds a minimum as `Just "0.2"`, and the new
`Okf.Profile.validateProfileVersion` reports an undeclared, older, or
unparseable declaration as `RequiredBundleVersionUnmet`. Specification §12
makes the declaration a MAY, so `validateBundle` still never asks for one; this
is the house-convention half, inert until a profile author writes the field.
`compiledProfileRequiredBundleVersion` reads the parsed minimum off a compiled
profile. See
`docs/adr/10-okf-version-declaration-and-best-effort-reading.md`.
- `validateProfileVersion` is a new entry point rather than a parameter on
`validateProfile` or `validateProfileWith`, whose signatures are unchanged: the
check consults no concepts, and adding a parameter would break every caller.
- The generated profile documentation bundle gains a `Required bundle version`
bullet in its `## Settings` list, so a profile setting cannot be a silent hole
in its own documentation. Regenerating a committed documentation bundle
produces that one added line.
### Changed
- **Breaking for exhaustive consumers, from the attested computation work.**
Four changes, listed together because a consumer moving its okf pin meets them
as one surface. `Okf.Validation.validateBundle` takes a required
`BundleInventory` before its list of concepts — required rather than defaulted,
so no caller can pass an empty inventory and have every path report as
dangling. `BundleValidationError` gains `DanglingFrontmatterPath ConceptId Text
FilePath (Maybe FilePath)`. `ValidationError` gains the four
`AttestedComputation*` constructors listed above. And `Okf.Index.renderIndex`
takes two further parameters, for the non-Markdown files in a directory.
The arity change on `validateBundle` is the one that breaks a caller outright;
the constructor additions break only an exhaustive `case`. Mori
(`mori://shinzui/mori`) matches `ProfileViolation` and not `ValidationError` or
`BundleValidationError` as of 2026-08-01, so the constructors do not reach it,
but its call to `validateBundle` does — check before moving the pin rather than
assuming, since that is a position on a date and not a guarantee.
`Okf.Profile.validateProfile` is unchanged in signature and meaning.
- **Breaking for exhaustive consumers.** `Cardinality` gains a fourth
constructor, `Object`, and `ProfileDefinitionError` gains
`ObjectFieldsRequireObjectShape`. The `Cardinality` addition is the wider of
the two: that type appears in `ConflictingCardinality`,
`ElementFieldsRequireList`, `ConditionFieldNotScalar`, and
`CardinalityMismatch`, so a consumer that renders a cardinality needs a new
case even if it declares no object rules. `Object` is deliberately unreachable
from Dhall — the published union in `okf-core/dhall/Cardinality.dhall` keeps
exactly its three alternatives — so no pinned descriptor changes type. No
`ProfileViolation` constructor was added.
- Adding `objectFields` to the closed Dhall `FieldRule` record is a schema
event. The complete optional-presence generation is frozen before it and
upgrades with `objectFields = None`, so descriptors written with record
completion or the `mk` constructors are unaffected; a descriptor that annotates
itself against okf's current schema by relative path must add the field, since
Dhall rejects the annotation before any fallback decoder runs.
- A missing member of a nested record now carries the member's `description`
prose in parentheses, as a missing top-level key already did. This applies to
list elements as well as object members, and emits nothing where a member
declares no description.
- **Breaking for exhaustive consumers.** `validateBundle` takes a
`VersionDeclaration` between the profile and the concepts:
`ValidationProfile -> VersionDeclaration -> [Concept] -> [BundleValidationError]`.
Passing `VersionUndeclared` reproduces the previous behaviour exactly.
`ValidationError` gains `MissingGeneratedField`, `GeneratedMustHaveActor`,
`SourceMissingResource`, `DuplicateSourceId`, `FootnoteLabelNotInSources`,
`SourceIdNotCited`, and `LegacyFieldInDeclaredV2`; `BundleValidationError`
gains `BundleVersionUnparseable` and `BundleVersionNotUnderstood`. Every new
diagnostic is `StrictAuthoring` only.
- **Strict validation asks for `generated` rather than `timestamp`**, falling
back to a legacy `timestamp` when `generated` is absent, so nothing that
passed before fails now. The message for a concept with neither changes from
`missing recommended field: timestamp` to
`missing generated field (or legacy timestamp)`. The fallback is silent in an
undeclared bundle and reported in one that declares `okf_version: "0.2"`; see
`docs/adr/7-okf-v0-1-legacy-fallback-policy.md`.
- **`logStaleness` reads `generated.at` first**, falling back to `timestamp`. A
v0.2 concept with no `timestamp` at all is staleness-checked for the first
time.
- `coreFrontmatterFieldOrder` gains all six v0.2 concept keys, so re-serializing
a document orders them deterministically and a closed profile
(`allowUnknownFields = False`) permits them without redeclaring. `timestamp`
moved to the end of that order, which reorders it once in any document a
producer re-serializes.
- Markdown bodies parse with footnotes enabled. This also fixes a bug: a
single-token footnote definition such as `[^src]: doc.md` previously parsed as
a link reference definition, producing a phantom dangling link.
- `setTimestamp`, `OkfCommon`'s `commonTimestamp`, and reading a v0.1
`timestamp` are all retained. Writing v0.1 on purpose stays supported.
- `Okf.Profile.Documentation.DocumentationOptions` gains a `generated ::
Maybe Generated` field carrying the OKF v0.2 `generated` family written on
every generated document, and `defaultDocumentationOptions` now supplies one.
`Nothing` omits the key. Generation still reads no clock: `generatedAt` is
caller-supplied and absent by default.
- **Breaking for record-literal callers.** A consumer that constructs
`DocumentationOptions` as a record literal rather than by overriding
`defaultDocumentationOptions` must add the new field. The module Haddock has
always directed callers to start from `defaultDocumentationOptions` for
exactly this reason; a call site that does so is unaffected.
- **Breaking for exhaustive matchers and record-literal callers**, from
`requireBundleVersion`. `ProfileSpec` gains a field, so a consumer building one
as a record literal must add it. `ProfileViolation` gains
`RequiredBundleVersionUnmet` — the first violation that carries no `ConceptId`,
so a consumer grouping violations by concept needs a case for it — and
`ProfileDefinitionError` gains `InvalidRequiredBundleVersion`. Handle all three
before moving an okf pin. `okf profile show --json` gains a
`requireBundleVersion` key for the same reason.
- The published Dhall schema `okf-core/dhall/Profile.dhall` gains
`requireBundleVersion : Optional Text`, defaulted to `None Text` in
`okf-core/dhall/defaults/Profile.dhall`. A descriptor written as
`Profile::{ … }` is unaffected; one written as a bare record literal annotated
`: Profile` must add the member, and one pinned at an earlier release keeps
decoding through a new frozen generation
(`okf-core/test/fixtures/profiles/pre-bundle-version.dhall`).
### Fixed
- The sdist ships `test/fixtures/**/*.sql`. The `attested-computation` fixture
points a `computation` field at a `.sql` file, so without it `cabal test` on
the released tarball reported that path as dangling — a failure only someone
building from Hackage with tests enabled would ever have seen.
## [0.4.0.0] - 2026-07-30
### Added
- An `optional` presence list on `FrontmatterRules` and `NestedRules`, defaulted
to empty. Optional rules compile to an `EffectiveFieldRule` with no presence
clauses, so `applicablePresenceClause` can never report their absence in either
`ValidationProfile`, while every vocabulary, cardinality, format, reference,
and nested-shape check still runs on a present value. Optional keys are part of
the compiled rule map, so they count as declared for `allowUnknownFields =
False` and carry their prose into `profileFieldDescriptionForType`.
`profileFieldDescription` searches the third list after the first two.
- `ProfileDefinitionError` gains `OptionalFieldWithCondition`, raised when an
optional rule carries `when` at either top level or nested level.
`ConflictingFieldRequirement` now also covers a key declared in `optional` plus
either other list at the same scope. An optional declaration at one scope does
not cancel a presence clause declared at the other.
- The complete reference-aware descriptor generation is frozen as a private
compatibility decoder and upgrades with `optional = []` at both levels, so
descriptors written against the previous published schema keep loading.
### Changed
- **Breaking for exhaustive consumers.** Matches on `ProfileDefinitionError`
must handle `OptionalFieldWithCondition`, and code constructing
`FrontmatterRules` or `NestedRules` must supply the `optional` field. A
descriptor that annotates itself against okf's current `Profile.dhall` by
relative path must add `optional`; one pinned to an older schema URL, or with
no annotation at all, is unaffected.
## [0.3.0.0] - 2026-07-29
### Added
- Top-level document-reference policies through `HandleReferenceRule`, with a
required local handle prefix, explicit external URI schemes, and configurable
self-reference. Compilation validates and merges policies; bundle validation
builds one valid-owner index and reports dangling, wrong-prefix, malformed,
disallowed-external, and self references with indexed `FieldPath` values.
Duplicate owners count as present and retain the existing duplicate-ID
diagnostic. The complete condition-aware descriptor generation is frozen and
upgrades with `reference = Nothing`.
- Same-scope conditional presence through `FieldCondition` and the defaulted
`when` field on top-level and nested field rules. Compilation rejects empty,
undeclared, non-scalar, open-vocabulary, self-referential, and unreachable
predicates; validation evaluates required and strict-recommended clauses
without cascading from invalid sources. The complete bounded-nested descriptor
shape is frozen as a compatibility decoder and upgrades with no condition.
- Bounded one-level nested record rules through `FieldRule.elementFields`,
non-recursive `NestedRules`/`NestedFieldRule` Dhall and Haskell types,
profile/type compilation, indexed `FieldPath` diagnostics, JSON, constructors,
and validation of nested presence, vocabulary, cardinality, and named formats.
The complete EP-4 descriptor shape is frozen as a compatibility decoder and
upgrades with no nested rule.
- Named `FieldFormat` constraints (`Rfc3339Utc`, `Date`, `Uri`,
`UriWithScheme`, and `DocumentHandle`) on `FieldRule`, including parser-backed
scalar/list validation, parameter checks, profile/type refinement, JSON and
Dhall representations, and `ValueFormatMismatch` diagnostics. The complete
EP-3 schema is frozen as a compatibility decoder whose fields upgrade to no
format constraint.
- `Cardinality` (`Any`, `Scalar`, or `List`) on every `FieldRule`, compiled
profile/type merge checks, shape-aware presence, and
`CardinalityMismatch`. Frozen older descriptors upgrade to `Any`.
- `FieldRule.allowedValues`, `ProfileSpec.allowUnknownFields`, structural
`FieldPath` diagnostics, and compiled validation for textual vocabularies and
closed top-level field names. Older descriptors upgrade to unconstrained,
open defaults.
- `coreFrontmatterFields` and deterministic `frontmatterKeys` in
`Okf.Document`, shared by closed-profile validation.
- Type-aware frontmatter rules: each `TypeRule` now carries its own
`FrontmatterRules`, merged with profile-wide rules for matching concepts.
- `CompiledProfile`, `ProfileDefinitionError`, `compileProfile`,
`compiledProfileSpec`, and `profileFieldDescriptionForType`. Compilation
rejects duplicate type rules and ambiguous field declarations before bundle
validation begins.
- `MissingRecommendedProfileField`, emitted for profile recommendations under
`StrictAuthoring`.
- `Okf.Profile.Registry`, which evaluates a registry reference — a Dhall file, a
directory holding `package.dhall`, or a Dhall expression — and enumerates
every profile it publishes under a dotted export path. Discovery is
structural: each field of the normalized record is tested by decoding it, so
no manifest is needed. Schema records exported as `{ Type, default }` are
skipped, and a reference that is itself a profile reports one root entry.
- `ToJSON` instances for `ProfileSpec`, `FrontmatterRules`, and `TypeRule`. A
type rule's name is emitted under the key `type`, matching the Dhall field
rather than the Haskell field `type_`.
- `FieldRule` — `{ field :: Text, description :: Maybe Text, allowedValues :: [Text], cardinality :: Cardinality }`
— one documented and optionally constrained frontmatter key.
- `profileFieldDescription :: ProfileSpec -> Text -> Maybe Text`, the prose a
profile attaches to a frontmatter key, searching `required` then
`recommended`.
- `decodeProfileExpr :: Expr Src Void -> Maybe ProfileSpec`, which decodes an
already-evaluated Dhall expression under the current schema and each frozen
compatibility generation. `Okf.Profile.Registry` uses it, so older profile
registries still enumerate.
- Published Dhall: `dhall/FieldRule.dhall`, `dhall/defaults/FieldRule.dhall`,
and `dhall/mk/FieldRule.dhall` (constructors `plain`, `documented`, `enum`,
`scalar`, and `list`), all
re-exported from `dhall/package.dhall`, which gains a top-level `mk` record.
### Changed
- **Breaking.** `FieldRule` gains
`reference :: Maybe HandleReferenceRule`; `ProfileViolation` gains
`DanglingHandleReference`, `ReferenceHandlePrefixMismatch`,
`MalformedDocumentReference`, `ExternalReferenceSchemeNotAllowed`, and
`SelfDocumentReference`; and `ProfileDefinitionError` gains structured
reference-policy errors. Exhaustive consumers, including Mori, must update
these cases as well as the earlier conditional missing-field patterns before
moving both their `cabal.project` and `flake.nix` okf pins.
- **Breaking.** `FieldRule` and `NestedFieldRule` gain
`when :: Maybe FieldCondition`; missing-field `ProfileViolation` constructors
carry the activating condition; and `ProfileDefinitionError` gains structured
condition errors. Exhaustive consumers, including Mori, must update before
moving their `okf-core` pin.
- **Breaking.** `FieldRule` gains `elementFields :: Maybe NestedRules` and
`ProfileViolation` gains `MissingNestedProfileField`,
`MissingRecommendedNestedProfileField`, and `NestedElementNotRecord`.
`ProfileDefinitionError` gains `ElementFieldsRequireList`. Exhaustive library
consumers, including Mori, must handle the new diagnostics.
- **Breaking.** `FieldRule` gains `format :: Maybe FieldFormat`;
`ProfileDefinitionError` gains `InvalidFormatParameter` and
`ConflictingFieldFormat`; and `ProfileViolation` gains
`ValueFormatMismatch`. Exhaustive consumers, including Mori, must handle the
new constructors. The published Dhall schema adds defaulted
`format : Optional FieldFormat` and exports format constructors.
- `okf-core` now depends on `network-uri >=2.6.4 && <2.7` for absolute RFC 3986
URI parsing. Hackage marks 2.7.0.0 deprecated; 2.6.4.2 is the newest normal,
upstream-tagged release.
- **Breaking.** `validateProfile` now accepts `ValidationProfile` and an opaque
`CompiledProfile` rather than a raw `ProfileSpec`. Library consumers must call
`compileProfile` once, handle definition errors, and select
`PermissiveConformance` or `StrictAuthoring`. Exhaustive
`ProfileViolation` matches must handle `MissingRecommendedProfileField`.
- **Breaking Dhall schema.** `TypeRule` gained
`frontmatter : FrontmatterRules`. `defaults.TypeRule` supplies empty rules;
direct record literals must add the field. A frozen decoder continues to load
the previous self-documenting shape, and the 0.2.x fallback remains intact.
- Profile-wide frontmatter rules now apply to allowed and disallowed unknown
types. Value constraints merge across profile and type scopes, presence
declarations remain ordered clauses, applicable required clauses precede
strict recommendations, and type-level prose wins when present.
- **Breaking.** `FrontmatterRules`'s `required` and `recommended` are now
`[FieldRule]` rather than `[Text]`, and `ProfileSpec` and `TypeRule` each
gained `description :: Maybe Text`. The published Dhall schema changed to
match. Code that constructs or pattern-matches these records must be updated.
- `loadProfileFile` accepts okf 0.2.x descriptors by falling back to a private
legacy decoder and upgrading the result with every description set to
`Nothing`. When both decoders fail it reports the *current* decoder's error,
since that is the schema an author is writing against. The frozen legacy
shape is kept exercised by `test/fixtures/profiles/legacy-0.2.dhall`, which
must never be updated.
- Descriptions remain documentary, but their lookup now follows the compiled
effective rule for a concept type.
## [0.2.0.0] - 2026-07-26
### Added
- Profile-declared stable document IDs with strict parsing, missing/malformed/
duplicate validation, allocation helpers, and bundle lookup by handle.
- `Okf.Discovery`, which finds OKF bundle roots in a directory tree: directories
holding an `index.md` or a concept document with a non-empty `type`, pruned at
the first match so nested directories of a bundle are not reported separately.
### Changed
- The published profile Dhall schema gained required `idField` and `idPrefix`
record fields. Existing descriptors, including those in the separate
`okf-profiles` repository, must add `idField` and `idPrefix` values or adopt
the new record-completion defaults under `dhall/defaults/`. This is a breaking
schema change.
## [0.1.2.0] - 2026-07-14
### Added
- `okf kit` command for installing reusable AI-agent skills and subagents from a
configured `okf-kit` git repository (`list`, `install`, `update`, `uninstall`,
`status`), with user and project (`--project`) scopes.
- `okf assist` command that launches an interactive Claude session seeded with a
prompt and your installed okf skills on its path; `--print-command` prints the
command line without launching.
- `okf config` command for managing the optional agent-assistance settings
(`show`, `path`, `init`, `init --global`), sourced from `okf-config.dhall`,
`~/.config/okf/config.dhall`, or `OKF_CONFIG` with built-in defaults.
- `okf help` topics for `kit`, `config`, and `agents` documenting the kit,
configuration, and assist workflows.
### Changed
- Wired the baikai kit and agent-assist dependencies into the build.
- Updated the bundled baikai packages.
## [0.1.1.0] - 2026-06-28
### Added
- `okf --version`, including git SHA reporting for Cabal and Nix builds when
available.
- Shell completion generation for supported shells.
- `okf help` command with embedded conceptual topic guides (`okf`, `format`,
`validation`, `profiles`), including a guide explaining what the Open Knowledge
Format is. The guides are plain text baked into the binary at compile time, so
`okf help <topic>` works with no network or docs checkout.
- Profile-based validation: `okf validate --profile <descriptor>.dhall` checks a
bundle against a team's house conventions (allowed `type` strings, required
frontmatter keys, `resource:` schemes, file layout, and `# Schema` columns)
declared in a Dhall descriptor. Profiles are not part of the OKF standard, so
deviations are advisory by default; `--profile-enforce` fails the command on
drift. Ships an example bundle (`examples/postgresql-sample`), a sample
descriptor (`docs/profiles/postgresql.dhall`), and a user guide
(`docs/user/profiles.md`).
- Log support: `okf-core` can parse, serialize, and validate `log.md` files;
`okf-cli` can preview, validate, author log entries, and report drift between
bundle logs and git history.
- Canonical OKF profile schema Dhall modules with drift tests.
### Changed
- Expanded the README and user guides to cover the current CLI, profile
validation, and log workflows.
- Updated release, Nix, and repository metadata so both packages build and check
as separate Hackage packages.
## [0.1.0.0] - 2026-06-19
Initial release.
### Added
- `okf-core` library: OKF document parser (`Okf.Document`), bundle graph
indexing (`Okf.Index`, `Okf.Graph`), bundle validation with referential
integrity (`Okf.Validation`, `Okf.Bundle`), concept construction and bundle
writing, concept-link rendering with a round-trip guarantee, and a frontmatter
authoring API.
- `okf-cli` library and `okf` executable: bundle validation and document
authoring commands over the core API.