A structured, validated engineering wiki that both people and AI sessions can read from and contribute to.
Plain markdown in git, reviewed by PR, published as a wiki. What makes it more than a folder of documents is that every document has a type, and every type has a schema — so an index can be generated rather than maintained, a broken cross-reference fails CI rather than rotting quietly, and an agent can be told where a thing goes instead of guessing.
Two halves, and the split is the point.
The mechanism — kac, a validator and generator, plus the machine-readable schema it enforces. Generic. Portable to
any organisation. Shared byte-for-byte between every corpus running this framework.
The seeds — seventeen knowledge types, each with a root page explaining what it is and when to use it, and a template to copy. Opinionated, and meant to be forked: you take them once, then localise the examples to your own domain and never reconcile them again.
Which files fall on which side is declared in
knowledge-as-code/manifest.yaml, not asserted in prose.
Early. The mechanism is real and tested; the taxonomy is only partly proven.
kac validate |
~20 checks — frontmatter against schema, identity, structure, link resolution, graph reciprocity |
kac index |
Generates <type>/INDEX.md and the schema/checks tables inside each type root page |
kac checks |
Lists every check the validator implements |
| Tests | Eight fixture scenarios, run by .ci/kac-tests.cs, with golden expectations |
| Proven types | ADRs only. The other sixteen schemas are written but have never validated a real document |
That last row is the honest limit. The schema will be wrong in ways only real content reveals, and only one type has met real content so far. Treat the other sixteen as drafts.
Developed against a real engineering wiki and extracted once the mechanism was separable from the content. History starts fresh here by design — the original commits are interleaved with a client's decisions and belong with them.
Everything above orients you to this framework and where it came from. Everything below is the operational README a corpus carries — generic, and the part a derived copy keeps and adapts as its own.
Requires the .NET 10 SDK. kac is a file-based app — no project file, no build step.
git clone https://github.com/paul80nd/knowledge-as-code.git my-wiki
cd my-wiki
dotnet run .ci/kac.cs -- validate # validate the corpus
dotnet run .ci/kac.cs -- index # regenerate indexes and generated blocks
dotnet run .ci/kac.cs -- checks # list the checks
dotnet run .ci/kac-tests.cs # run the test suiteTo start your own corpus: clone, delete the type folders you don't want, rewrite the root pages' examples in your own
domain, and start adding records. Keep .ci/ and knowledge-as-code/schema/ as they are — those are the half you want
to receive updates to.
<type>.md # what the type is, why it exists, how to contribute — one per type
<type>/
├── INDEX.md # GENERATED from frontmatter
├── template.md # what humans and agents copy
└── <records>.md
knowledge-as-code/ # the system's own documentation
├── taxonomy.md # the seventeen types and where things go
├── metadata.md # the frontmatter fields
├── contributing.md # how a contribution is made and reviewed
├── automation.md # what is generated, validated and scheduled
├── manifest.yaml # which files are shared, which are local
├── mechanism.lock # this corpus's sync state
└── schema/ # the machine-readable schema — the source of truth
.ci/ # kac, its tests and fixtures
Adding a knowledge type is adding a YAML file to schema/, not editing the tool.
This framework is designed to be copied, not depended on. An organisation adopting it gets its own cut, free to diverge, with no runtime dependency on this repository and nothing to remove if they later want to go their own way.
The cost of that is drift, which is what the manifest is for. Every file resolves to exactly one layer — synced,
forked, generated, local or ignored — and each layer has a rule about what divergence means. mechanism.lock
records which version of the shared layer a given corpus is on, and any deviation it has deliberately accepted.
Stated openly, because they are load-bearing:
- Azure DevOps wiki is the primary publishing target. Frontmatter renders as a metadata table there,
.orderdrives navigation, and/-rooted links resolve from the repo root. Everything degrades to plain markdown elsewhere, but the sharp edges were filed against ADO. - Seventeen types is a lot. It is the most likely thing to be wrong here, and the mitigation is a decision table plus a standing willingness to merge types that aren't earning their place.
- Trust matters more than coverage. The failure mode of a wiki is not too little content, it is content nobody believes. Generated indexes, validated links and immutable decisions all serve that.
Released under the MIT licence, so that any organisation adopting this keeps an unencumbered copy.