ktext
MIT Licensed · open standard · no strings attached

Project context,
machine-readable.

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

Context lives in engineers' heads.
Agents and new hires don't have that.

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.

constraints PCI compliance

Never log raw card data or PII in any request handler

decisions accepted

Use PostgreSQL for all persistent state

risks high

Migration rollback untested beyond 2 versions

How it works

Three commands.

01 / init

$ ktext init

Scan and generate

Reads your README, Makefile, package manifests, ADRs, and directory layout. Walks you through each discovered field so you can confirm or correct.

02 / validate

$ ktext validate

Score quality

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

$ ktext export xml

Export anywhere

Renders CONTEXT.yaml as compact XML for direct injection into LLM context windows, or as JSON for scripts and pipelines.

The standard

One file.
Everything an agent needs.

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.

$ ktext export xml
<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>
~50
lines
replaces the toil of codebase exploration
<2k
tokens
for the full file as XML
~80%
less context overhead
more tokens for actual work
Full schema reference →
CONTEXT.yaml
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

Context, not empty content.
Quality matters.

Each section is scored for presence, completeness, and language quality. Vague entries score low and surface as fixes.

✗ low score

Be careful with logging

✓ high score

Never write sensitive fields to application logs. Use the redact() helper before passing data to the logger.

How scoring works →
CONTEXT.yaml
100 / 100
constraints
20/20
identity
15/15
decisions
15/15
conventions
15/15
risks
10/10
dependencies
10/10
working
10/10
ownership
5/5
✓ PASS threshold 80

CI integration

Keep quality from slipping.

ktext validate exits 1 below your threshold. One step in CI and context rot becomes a failing check.

.github/workflows/context.yml
- name: Validate CONTEXT.yaml
  run: |
    go install github.com/arithmetike/ktext/cmd/ktext@latest
    ktext validate -threshold 80

Start in seconds.

Install, run ktext init, and you'll have a scored CONTEXT.yaml ready to go!