Skip to content

Contributing

Kritarth-Dandapat edited this page Jul 10, 2026 · 1 revision

Contributing / Development

Working conventions for anyone (human or agent) making changes to context-kernel. This mirrors the repo's own CLAUDE.md, expanded with the current build status and repository layout.

Hard rules (never violate)

  • content/ is sacred and gitignored. It holds the owner's real curated context. Never commit it. Never let an automated process edit it. Only content.example/ (fake templates) is committed.
  • No curated-write tool. MCP exposes read tools plus one append-only write tool (append_journal). Nothing an agent can call may modify curated context. Promotion is a local, human-run script. See Security-Model for how this is enforced in code, not just by convention.
  • Two tokens, two scopes. READ_TOKEN serves context; WRITE_TOKEN gates journal writes. The read token must never reach write tools. Use constant-time token comparison.
  • Secrets stay in Cloudflare. Never hardcode tokens or KV namespace IDs. wrangler.toml (the real one) and .dev.vars are gitignored; only wrangler.toml.example is committed.
  • No personal data in URLs, query strings, logs, or cache keys.
  • Verify moving APIs against live docs. MCP transport and Cloudflare's remote-MCP + Claude connector auth story change often. Confirm the current shape before implementing; do not guess an API.

Stack

  • Runtime: Cloudflare Workers (a V8 isolate). Keep dependencies minimal.
  • Storage: Cloudflare KV — see Architecture for the full key scheme.
  • Language: TypeScript.
  • Protocol: remote MCP over HTTP, via the Cloudflare Agents SDK's createMcpHandler.

Commands

npm run typecheck
npm test
npm run build      # content/*.md -> artifacts/kv-bulk.json + meta.json
npm run dev        # wrangler dev, reads .dev.vars

Every change must end green on npm run typecheck && npm test && npm run build.

Repository layout

context-kernel/
  content.example/          # committed template sections
  content/                  # gitignored; owner's real curated context (not in this repo's git history)
  src/
    worker.ts               # MCP server entry (Cloudflare Worker)
    mcp/
      tools.ts              # tool definitions + handlers
      auth.ts               # token gate, constant-time compare
    kv.ts                   # KV key helpers
    types.ts
    ulid.ts                 # journal entry IDs
  scripts/
    generate-artifacts.ts   # content/*.md -> artifacts/kv-bulk.json + meta.json
    promote.ts               # interactive journal-review + promotion helper
  artifacts/                 # gitignored, generated by the build step
  test/
    auth.test.ts
    tools.test.ts
    generate.test.ts
    journal.test.ts
  .claude/
    agents/
      context-promoter.md    # subagent that runs the promotion review
      mcp-tester.md          # subagent that smoke-tests deployed tools
  skill/
    context-kernel/          # thin personal skill (see status below)
  CLAUDE.md
  README.md
  HANDOFF.md                 # full build brief; the source this wiki is synthesized from
  wrangler.toml.example
  .gitignore
  package.json
  tsconfig.json

Build phases and current status

The project was built in the phase order below (see HANDOFF.md §8 for the original plan). As of this writing:

Phase What it covers Status
1 Scaffold + tooling: package.json, tsconfig.json, .gitignore, wrangler example, empty content.example/ templates, test runner. Done
2 Artifact generator: scripts/generate-artifacts.ts reads content/*.md, produces artifacts/kv-bulk.json + meta.json with a content hash. Done, tested (test/generate.test.ts)
3 Auth gate: src/mcp/auth.ts, constant-time token comparison, unit tests for read/write/deny. Done, tested (test/auth.test.ts)
4 MCP server, read tools: src/worker.ts + get_context / list_sections / get_meta. Done
5 Write tools + journal: append_journal / list_journal, ULID keys, index, write-token enforcement. Done, tested (test/tools.test.ts, test/journal.test.ts)
6 Promotion script: scripts/promote.ts — pull journal:*, print entries, let the owner mark entries handled; owner edits content/ by hand. Stub only — the file exists but is a TODO(Phase 6) placeholder
7 Personal skill: skill/context-kernel/SKILL.md — instruct Claude to call get_context early in a session. Not started — skill/context-kernel/ exists but is empty
8 Docs + GitHub hygiene: README, CLAUDE.md, verify content/, artifacts/, .dev.vars, real wrangler.toml are gitignored; no personal data committed. Largely done — README, CLAUDE.md, HANDOFF.md, and a LICENSE file are all present

Each phase is meant to end green on npm run typecheck && npm test && npm run build, in small, reviewable commits — one phase at a time, not batched together.

Testing conventions

Handler logic is factored so it's unit-testable without a live Worker or MCP transport:

  • src/mcp/auth.ts exports plain async functions (scopesForToken, authorize) that take tokens and a small AuthEnv shape as plain parameters — no dependency on the Workers runtime.
  • src/mcp/tools.ts exports each tool's handler body (handleGetContext, handleAppendJournal, etc.) separately from the server.registerTool wiring, so tests can call a handler directly against a fake KVNamespace without spinning up an MCP client/transport.

Follow this pattern for new tools: write the handler as a plain function taking (ctx, args), test it directly, then wire it into registerReadTools/registerWriteTools as a thin adapter.

Style

  • Small, reviewable commits, one build phase at a time.
  • Prose in docs and READMEs: clear and plain. No em-dashes in owner-facing docs (owner preference) — this applies to wiki pages too.
  • Do not add dependencies without a reason noted in the commit message. Runtime dependencies are intentionally minimal (@modelcontextprotocol/sdk, agents, zod) since this runs in a V8 isolate.

When in doubt

Raise it as an open question (see Design-Decisions's "open questions" section) rather than deciding silently. The owner's stated priority is that the curation gate and the read/write split are preserved above all else — see Security-Model for why that boundary exists and how it's enforced.

Clone this wiki locally