Slate — context control plane for AI-assisted repos. Generates concise Markdown context beside the code, detects stale knowledge after changes, and scores what is safe to trust.
Project description
Slate — Context Control Plane for AI-Assisted Repos
Slate keeps AI and humans aligned with the current state of a codebase. It generates a small set of concise Markdown context files beside the code, detects which of them a code change may have invalidated, and surfaces what is safe to trust before the next AI action — so every session starts from reality instead of guesswork.
The single source of truth for product and architecture decisions is slate-product-doc.md — read §3 (wedge), §7 (context layer design), and §10 (build vs vibecode rules) before touching anything.
How it works
cd your-repo
slate init # scan the repo, generate the context layer
git add -A && git commit -m "add context layer"
# ... code changes land ...
slate status # which context docs are now suspect?
○ .slate/modules.md stale 2 watched path(s) changed since 3f2c91a
↳ src/billing/tax.py
slate diff # what changed vs. what each doc claims + sync preview
slate sync # regenerate the auto-blocks, re-anchor to HEAD
slate verify # 0.00–1.00 trust score per doc
slate read # the ordered "first read" path for an AI session
Beyond the core loop:
slate sync --prose # opt-in: LLM-drafted orientation paragraph above the
# scanned facts (needs ANTHROPIC_API_KEY; the facts and
# all trust math stay deterministic)
slate watches --apply # propose watch globs from import graphs + doc references
slate hook install # pre-push gate: refuses to push a stale context layer
slate fleet ~/code # freshness roll-up across many repos
Every context doc carries freshness metadata (sync anchor commit + content digest + watch globs) in its frontmatter and is always in one of three states:
| Status | Meaning |
|---|---|
fresh |
nothing watched changed since the doc was synced — or something did, but the doc provably still checks out (a fresh scan generates the same facts, and no hand-written claim references a changed path) |
stale |
watched code changed (committed or uncommitted) in a way the doc can't be proven to survive — verify before acting |
needs-verification |
the freshness anchor is gone and the content digest can't vouch for the doc — treat as a rumor |
Two properties keep the signal honest in real workflows: stale means "sync
would actually change something" — an edit inside a watched tree that doesn't
alter what the doc claims stays fresh (content-verified), so the flag never
becomes ritual noise. And squash-merges/rebases don't nuke the layer: when the
commit anchor dies, the content digest proves the watched files still match
the last sync and the doc stays fresh (a slate sync re-anchors it).
What it generates
AGENTS.md routing + trust protocol at the repo root (read first)
.slate/read-next.md current focus — the smallest useful context for the task at hand
.slate/architecture.md what the system is and its invariants
.slate/modules.md where things live (scanned module map)
.slate/workflows.md how to build, test, run (scanned commands)
.slate/decisions.md why things are the way they are (append-only log)
Generated docs contain a marked auto-block that slate sync rewrites from a
deterministic repo scan; everything outside the block is human-owned and
survives every sync. read-next.md and decisions.md are fully human-owned —
Slate only tracks their freshness (slate mark attests them).
Install
pip install -e . # Python ≥ 3.11, zero runtime dependencies
slate --version
Requires a git repository — Slate anchors freshness to git history.
Does it actually beat "just ask the AI to write .md files"?
Measured on this repo itself (benchmarks/RESULTS.md,
reproduce with python benchmarks/benchmark.py):
- Session start: an agent ingests 2,066 tokens via
slate_readvs ~20,600 rediscovering the repo by hand (10×) or ~54,700 for a full repo dump (26.5×) — with trust labels attached, which the baselines can't provide at any price. - Staying true: replaying this repo's real history, 50% of commits invalidated at least one context doc. Manually maintained .md files rot silently on every one of those; Slate flagged each and healed it with a ~45 ms, 0-token deterministic sync (vs an estimated ~111K tokens of model traffic to do the same maintenance by prompting).
- Every Slate operation is sub-second, local, and free — status, scores, scan, sync, and the full MCP round-trip.
Wire it into your coding agent (MCP)
Slate ships an MCP server so your AI agent runs Slate itself — no more manually running commands and pasting output into the chat:
slate agent enable claude # Claude Code (.mcp.json) — or: cursor, all
slate agent access full # optional: let the agent maintain the layer too
Restart the agent session; it now has these tools:
| Tool | Access | What the agent does with it |
|---|---|---|
slate_read |
read | session start: the ordered context set with trust labels + scores |
slate_status / slate_verify / slate_diff |
read | mid-task: is this doc still safe? what exactly broke? |
slate_sync |
full | session end: regenerate auto-blocks, re-anchor freshness |
slate_update_focus |
full | session end: rewrite read-next's "Current focus" for the next session |
slate_mark / slate_append_decision |
full | attest human docs / record decisions worth keeping |
Consent works in two layers, Claude Code-style. Your editor prompts per
tool call (until you always-allow a tool there). Underneath, Slate's own
access mode is the hard ceiling: it defaults to read-only — the mutating
tools aren't even exposed — and slate agent access full (or the
"Slate: Agent Access" command in VS Code) unlocks them. The mode lives in
.slate/agent-access, so committing it makes it team policy, and toggling
it takes effect without restarting the agent.
Integrations
- GitHub PR bot — action.yml is a reusable composite action:
it checks the consumer repo's context layer on every PR and posts (and
edits in place) a comment listing which docs the PR invalidates, with
trust scores. Two lines in a consumer workflow:
uses: gurbirdhaliwal/slate@v0.2.0after afetch-depth: 0checkout. - VS Code extension — integrations/vscode/:
trust badges in the file tree, a status-bar roll-up, and one-click sync.
Plain JS, no build step; renders
slate status --json, never computes. - pre-commit framework — .pre-commit-hooks.yaml
(
id: slate-context, runs at pre-push); orslate hook installfor the same gate without the framework. - PyPI releases — pushing a
v*tag builds and publishes via release.yml (PyPI trusted publishing; one-time project setup on pypi.org required).
Repository layout
slate/ the CLI package (stdlib only, by design)
├── cli.py argparse entry point (all commands, --json contracts)
├── scanner.py deterministic repo scan (languages, modules, commands)
├── generator.py scan -> Markdown context layer, auto-block rewriting
├── freshness.py the freshness engine: fresh / stale / needs-verification
├── verify.py verification score (reference validity + watch quiet + drift)
├── diffs.py slate diff: change kinds, broken claims, sync preview
├── imports.py watch inference from import graphs + doc references
├── llm.py opt-in prose writer (urllib, injectable transport)
├── hooks.py pre-push freshness gate installer
├── context.py doc registry, frontmatter stamping, auto-block markers
├── frontmatter.py tiny hand-rolled YAML-subset frontmatter (no deps)
├── globs.py watch-pattern matching with ** semantics
└── gitutil.py git plumbing (change detection anchors)
integrations/
├── github/ PR bot script used by the root action.yml
└── vscode/ editor extension (plain JS, no build step)
tests/ pytest suite — runs against real throwaway git repos
.github/workflows/ ci.yml (tests + dogfood + PR bot) · release.yml (PyPI)
docs/github-setup.md one-time repo config (branch ruleset)
Development
make install # venv + editable install with dev deps
make test # pytest (31 tests, real git repos in tmpdirs)
make demo # throwaway repo walking the core loop end to end
make dogfood # slate status on this repo's own context layer
Verifying a change
make test— the freshness engine and verification scoring are the hand-code-carefully core (§10); both are covered by tests that build real git repos.make demo— eyeball the actual CLI output on a fresh repo.- CI also runs
slate status --ciagainst this repo's own context layer: if your change touches watched code, runslate syncand commit the doc updates with it.
The rules that matter (§10)
Hand-code (a false "fresh" destroys the product's promise): the freshness derivation, watch-glob matching, git change detection, verification scoring, frontmatter round-tripping, and the auto-block boundary logic. Vibecode freely: doc templates, CLI presentation, scanner heuristics for new languages/build tools.
Current state (Phases 1–3 built)
Working end to end: init → generated context layer with freshness
frontmatter → status/verify/read/diff → sync/mark, plus the
pre-push hook, watch inference, opt-in LLM prose, the PR bot action, the
VS Code extension, and fleet. Dogfooded on this repo (see
AGENTS.md and .slate/); CI runs the tests, the
freshness gate, and the PR bot.
Remaining one-time setup (needs account owner): create the slate-context
project + trusted publisher on pypi.org, then push a v0.2.0 tag; publish
the VS Code extension to the marketplace if wanted (works from a local VSIX
today). Phase 4 (team dashboards, merge policies, hosted bot) is not built.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file slate_context-0.3.0.tar.gz.
File metadata
- Download URL: slate_context-0.3.0.tar.gz
- Upload date:
- Size: 77.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e46307341284409e9eb4636c30fa400ff385ac3eeb4d388a3bae2397ddc73988
|
|
| MD5 |
645de7c1f7ea2fa1e46dfa1f5aded0fe
|
|
| BLAKE2b-256 |
b41b8b2691413202a74696590f6b5e68d277bb2589a73f8e9b3b5e6fa2b8240f
|
File details
Details for the file slate_context-0.3.0-py3-none-any.whl.
File metadata
- Download URL: slate_context-0.3.0-py3-none-any.whl
- Upload date:
- Size: 65.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7991fa5cd3e5a6e0afd16615cda43cf95553e0aa15ffb2b4f5de2090efa9c8ac
|
|
| MD5 |
7d694b2f50a707e20395d575f6d3d8c7
|
|
| BLAKE2b-256 |
f02c6cfc65dc447718e2738cb447ab8d57cc1210c5093e43e24d9aade95bb7a0
|