Every codebase has context that lives in engineers' heads: why Postgres instead of MySQL,
what you must never log, which layer owns what.
CONTEXT.yaml makes it explicit.
ktext generates, validates, and scores it.
go install github.com/arithmetike/ktext/cmd/ktext@latest The problem
When a new engineer joins, or an AI agent is spun up to work on a project, they work without the institutional knowledge your team takes for granted. They make reasonable guesses, or spend time or tokens looking for config files, documentation, ADRs, or comments that may or may not be there. This leads to mistakes, inefficiency, and risk.
CONTEXT.yaml captures what matters in a structured file both humans and tools can read: constraints, decisions, risks, and conventions.
Never log raw card data or PII in any request handler
Use PostgreSQL for all persistent state
Migration rollback untested beyond 2 versions
How it works
01 / init
Reads your README, Makefile, package manifests, ADRs, and directory layout. Walks you through each discovered field so you can confirm or correct.
02 / validate
Scores all eight sections out of 100. Reports what is missing and what to fix. Exits 1 below threshold so you can gate on it in CI.
03 / export
Renders CONTEXT.yaml as compact XML for direct injection into LLM context windows, or as JSON for scripts and pipelines.
The standard
An agent reading your codebase cold will spend tokens on config files, grep for conventions, and still miss things. Give it CONTEXT.yaml and it starts with the full picture.
No database, no server, no account. It lives at the root of your repo, versioned with your code. Export to compact XML for efficient injection into any LLM context window.
<context name="my-service" type="service" status="active">
<purpose>Handles payment processing for the checkout flow.</purpose>
<constraints>
<c>Never log raw card data or PII in any request handler</c>
<c>Always validate input at the service boundary before domain logic</c>
</constraints>
<decisions>
<d title="Use PostgreSQL for all persistent state">Need transactional integrity and JSONB support</d>
</decisions>
<risks>
<r severity="high">Migration rollback untested beyond 2 schema versions</r>
</risks>
<commands>
<cmd desc="build the service binary">make build</cmd>
<cmd desc="run unit and integration tests">make test</cmd>
</commands>
</context> ktext: "1.0.0"
identity:
name: my-service
url: https://github.com/org/my-service
type: service
status: active
purpose: Handles payment processing for the checkout flow.
constraints:
- content: Never log raw card data or PII in any request handler
why: PCI compliance
- content: Always validate input at the service boundary before domain logic
why: Defense in depth
decisions:
- title: Use PostgreSQL for all persistent state
rationale: Need transactional integrity and JSONB support for flexible metadata
status: accepted
date: "2024-03"
conventions:
- rule: Run all DB queries through the repository layer, no raw SQL in handlers
why: Keeps the domain layer testable and persistence swappable
risks:
- content: Migration rollback untested beyond 2 schema versions
severity: high
mitigation: Add rollback smoke test to CI before next release
dependencies:
- name: PostgreSQL
url: https://www.postgresql.org
why: Primary data store, transactions and JSONB
- name: Redis
url: https://redis.io
why: Session cache and rate-limit counters
working:
commands:
- command: make build
description: build the service binary
- command: make test
description: run unit and integration tests
- command: make migrate
description: apply pending database migrations
structure:
- path: internal/payments/
description: payment processing logic and provider integrations
- path: internal/repository/
description: all database access, no SQL outside this package
notes:
- Run migrations before starting the server locally
- Set STRIPE_WEBHOOK_SECRET in .env.local for webhook testing
ownership:
team: platform
escalation: https://github.com/org/my-service/issues Quality scoring
Each section is scored for presence, completeness, and language quality. Vague entries score low and surface as fixes.
Be careful with logging
Never write sensitive fields to application logs. Use the redact() helper before passing data to the logger.
CI integration
ktext validate exits 1 below your threshold. One step in CI and context rot becomes a failing check.
- name: Validate CONTEXT.yaml
run: |
go install github.com/arithmetike/ktext/cmd/ktext@latest
ktext validate -threshold 80 Install, run ktext init, and you'll have a scored CONTEXT.yaml ready to go!