Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions .claude/CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Claude Instructions — agent-kernel

Read `AGENTS.md` before making any changes. It is the canonical source of truth
for all shared rules, conventions, and documentation pointers.

## Explore before acting

- Read `AGENTS.md` and the relevant `docs/agent-context/` file for the topic
before proposing changes.
- Check existing code patterns in the target area. Do not infer repo-wide
conventions from a single file.
- When path-specific conventions exist (see Code conventions in `AGENTS.md`),
follow them exactly.

## Implement safely

- Preserve invariants. Consult `docs/agent-context/invariants.md` before any
change that touches security, tokens, policy, or the firewall.
- Use only the conventions documented in `AGENTS.md`. Do not invent new ones.
- Use `make ci` as the single validation command. Do not guess alternatives.
- Do not "clean up" or "simplify" code unless the change was requested. Hidden
constraints may exist.

## Validate before completing

- Run `make ci` and confirm it passes.
- If a public API, workflow, invariant, or convention changed, update the
relevant canonical doc in the same changeset.
- Verify that every changed docstring matches the final implementation.
- Check for dead code: unused parameters, fixtures, or helpers.

## Handle contradictions

When docs contradict code or each other:
1. Code is authoritative over docs.
2. Canonical shared docs (`AGENTS.md`, `docs/agent-context/`) are authoritative
over tool-specific files.
3. Surface the contradiction explicitly. Do not silently pick one side.
4. Fix stale docs in the same changeset when possible.

## Capture lessons

When a mistake or unexpected pattern is discovered during work:
1. Determine if it generalizes — would it recur in a similar task?
2. If yes, identify the canonical home using the workflow in
`docs/agent-context/lessons-learned.md`.
3. Treat candidate lessons as provisional. Do not promote a fresh observation
into durable guidance from a single incident.

## Update order

1. Update canonical shared docs (`AGENTS.md`, `docs/agent-context/`) first.
2. Update tool-specific files (this file, `.github/copilot-instructions.md`)
second.
3. If a Claude-specific rule becomes shared and durable, promote it into
canonical docs and remove it from `.claude/`.
53 changes: 53 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Copilot Instructions — agent-kernel

> Canonical rules: `AGENTS.md`. This file projects review-critical rules that
> must be visible during GitHub PR review.

## Review checklist

Flag these in every PR — CI does not catch them:

- Docstrings and descriptions must match actual implementation.
- No security bypass vectors: whitespace-only justification, truncated JSON, bare `int()` on untrusted input.
- No dead code: unused parameters, fixtures, or helpers.
- No backward-compat breaks: adding required methods to an existing Protocol breaks downstream.
- Naming consistent: use capability, principal, grant, Frame — never synonyms.

Canonical checklist: `docs/agent-context/review-checklist.md`

## Code and docs reviewed together

- PRs that change public APIs, workflows, invariants, review rules, or path conventions must include doc updates.
- If a docstring changed, verify it matches the final code.
- Code is authoritative over docs. Fix stale docs in the same PR.
- Surface contradictions explicitly. Do not silently work around them.

## Invariants

Non-negotiable. Violations silently degrade security:

- Firewall always mediates: `RawResult → Frame`. Never bypass.
- Token verification before every invocation. Never skip.
- Non-admin principals never get `raw` response mode.
- Policy rule ordering is security-critical — a rule placed before sensitivity checks creates a silent bypass.
- New `SensitivityTag` values need a matching policy rule, or the tag is silently ignored.

Full list: `docs/agent-context/invariants.md`

## Convention discipline

- Follow conventions in `AGENTS.md`. Do not invent new ones.
- `make ci` is the single pre-push command. Do not guess alternatives.
- Custom exceptions from `errors.py` only. Never raise bare `ValueError`/`KeyError` to callers (catching stdlib internally to remap is fine).
- No new dependencies without justification.

## Canonical sources

| Topic | File |
|-------|------|
| All shared rules | `AGENTS.md` |
| Hard invariants | `docs/agent-context/invariants.md` |
| Full review checklist | `docs/agent-context/review-checklist.md` |
| Workflows & commands | `docs/agent-context/workflows.md` |
| Recurring mistakes | `docs/agent-context/lessons-learned.md` |
| Architecture intent | `docs/agent-context/architecture.md` |
133 changes: 119 additions & 14 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,38 +1,143 @@
# AGENTS.md — AI Agent Instructions

This file provides instructions for AI coding agents (Copilot, Cursor, etc.) working in this repository.
This is the canonical source of truth for AI coding agents working in this repository.
Tool-specific instruction files (`.github/copilot-instructions.md`, `.claude/CLAUDE.md`)
reference this file and add only tool-specific guidance.

## Repo layout

```
src/agent_kernel/ — library source (one module per concern, ≤300 lines each)
tests/ — pytest test suite
examples/ — runnable demos (no internet required)
docs/ — architecture and security documentation
src/agent_kernel/ — library source (one module per concern, ≤300 lines each)
drivers/ — capability drivers (one file per driver)
firewall/ — context firewall (redaction, summarization, budgets)
tests/ — pytest suite (one test file per module)
examples/ — runnable demos (prefer offline; network OK with fallback)
docs/ — reference documentation
docs/agent-context/ — deeper agent guidance (architecture, workflows, invariants)
```

## Weaver ecosystem

agent-kernel is part of the **Weaver ecosystem**:
- [weaver-spec](https://github.com/dgenio/weaver-spec) — formal specification with invariants
- [contextweaver](https://github.com/dgenio/contextweaver) — context compilation library
- ChainWeaver — orchestration layer

This repo must conform to weaver-spec invariants. Key invariants (all equally critical):
- **I-01**: Every tool output must pass through a context boundary before reaching the LLM.
- **I-02**: Context boundaries must enforce budgets (size, depth, field count).
- **I-06**: Tokens must bind principal + capability + constraints; no reuse across principals.

Full spec: [dgenio/weaver-spec](https://github.com/dgenio/weaver-spec)

## Domain vocabulary

Use these terms consistently. Never substitute synonyms:

| Term | Means | Not |
|------|-------|-----|
| capability | a registered, auditable action | tool, function, API |
| principal | the identity invoking a capability | agent, user, caller |
| grant | a policy-approved token issuance | permission, access |
| Frame | the bounded, redacted result returned to the LLM | response, output |

## Quality bar

- `make ci` must pass before every commit.
- `make ci` must pass before every push. It runs: `fmt → lint → type → test → example`.
- All public interfaces need type hints and docstrings.
- Use custom exceptions from `errors.py` — never bare `ValueError` or `KeyError`.
- Never raise bare `ValueError` or `KeyError` to callers. Use custom exceptions from `errors.py`. Catching stdlib exceptions internally to remap them is fine.
- Error messages are part of the contract — tests must assert both exception type and message.
- Keep modules ≤ 300 lines. Split if needed.
- No randomness in matching, routing, or summarization (deterministic outputs).
- No randomness in matching, routing, or summarization. Deterministic outputs always.
- No new dependencies without justification. The dep list is intentionally minimal (`httpx` only).

## Security rules

- Never log or print secret key material.
- HMAC secrets come from `AGENT_KERNEL_SECRET` env var; fall back to a random dev secret with a logged warning.
- Tokens are tamper-evident (HMAC-SHA256) but not encrypted — document this.
- Confused-deputy prevention: tokens bind to `principal_id + capability_id + constraints`.
- HMAC secrets come from `AGENT_KERNEL_SECRET` env var; fallback to a random dev secret with a logged warning.
- Tokens are HMAC-signed but **not encrypted**. Never store secrets in token payloads.
- Confused-deputy prevention: tokens bind `principal_id + capability_id + constraints`.
- Never bypass token verification before capability invocation.
- Firewall always transforms `RawResult → Frame`. Raw driver output never reaches the LLM.
- Non-admin principals never get `raw` response mode. The Firewall downgrades to `summary`.
- No duplicate capability IDs in the registry.

See [docs/agent-context/invariants.md](docs/agent-context/invariants.md) for the full "never do" list and security traps.

## Code conventions

**All modules (`src/agent_kernel/`):**
Relative imports. Dataclasses with `slots=True`. Protocols for interfaces.
`__all__` in every `__init__.py`. Google-style docstrings.
`CamelCase` for classes, `snake_case` for functions. Error classes end with `Error`.

**Drivers (`drivers/`):**
One file per driver. `Driver` Protocol in `base.py`. Async `execute()` method.
Driver classes end with `Driver`. Use `DriverError` for exceptions.

**Firewall (`firewall/`):**
Pure functions for redaction and summarization. `Firewall` class in `transform.py` orchestrates.
Use `FirewallError` for exceptions.

**Tests (`tests/`):**
Every module has a corresponding test file (`kernel.py` → `test_kernel.py`).
Conftest fixtures only for cross-test reuse (≥2 test files). Local helpers otherwise.

## Adding a new capability driver
**Examples (`examples/`):**
Prefer offline. Network examples OK only with a clear fallback.

## Workflow

- One logical change per PR. Squash-merge. Conventional commit titles (`feat:`, `fix:`, `test:`, `docs:`).
- `make ci` is the single authoritative pre-push command.
- Update `CHANGELOG.md` in the same PR when adding features or fixes.
- Code is authoritative over docs. Fix stale docs when you spot discrepancies.

See [docs/agent-context/workflows.md](docs/agent-context/workflows.md) for full details.

## Adding a capability driver

1. Implement the `Driver` protocol in `src/agent_kernel/drivers/`.
2. Register it with `StaticRouter` or implement a custom `Router`.
3. Add integration tests in `tests/test_drivers.py`.

## Adding a new policy rule
See [docs/integrations.md](docs/integrations.md) for MCP and HTTP examples.

## Adding a policy rule

1. Add the rule to `DefaultPolicyEngine.evaluate()` in `policy.py`.
2. Cover it with a test in `tests/test_policy.py`.
2. **Placement matters:** rules are evaluated in order. A new rule placed before sensitivity checks silently bypasses them.
3. If adding a new `SensitivityTag`, you must also add a corresponding policy rule — otherwise the tag is silently ignored.
4. Cover it with a test in `tests/test_policy.py`.

## Review checklist (beyond `make ci`)

Before submitting a PR, verify:
- [ ] Docstrings and descriptions match the actual implementation.
- [ ] Security edge cases handled (whitespace-only justification, truncated JSON, bare `int()` on untrusted input).
- [ ] No dead or unused code (parameters, fixtures, helpers).
- [ ] No backward compatibility breaks (e.g., adding required methods to a Protocol).
- [ ] Naming consistent across docs and code (use capability, principal, grant, Frame — never synonyms).

See [docs/agent-context/review-checklist.md](docs/agent-context/review-checklist.md) for the full checklist.

## Documentation map

| Topic | Canonical source |
|-------|-----------------|
| Architecture & design intent | [docs/agent-context/architecture.md](docs/agent-context/architecture.md) |
| Components & API reference | [docs/architecture.md](docs/architecture.md) |
| Security model & threats | [docs/security.md](docs/security.md) |
| Hard invariants & forbidden shortcuts | [docs/agent-context/invariants.md](docs/agent-context/invariants.md) |
| Workflow rules & commands | [docs/agent-context/workflows.md](docs/agent-context/workflows.md) |
| Recurring mistakes | [docs/agent-context/lessons-learned.md](docs/agent-context/lessons-learned.md) |
| Review & self-check | [docs/agent-context/review-checklist.md](docs/agent-context/review-checklist.md) |
| Driver integration patterns | [docs/integrations.md](docs/integrations.md) |
| Capability design conventions | [docs/capabilities.md](docs/capabilities.md) |
| Context firewall details | [docs/context_firewall.md](docs/context_firewall.md) |

## Update policy

Code is authoritative. When docs contradict code, fix the docs.
Each topic has one canonical source (see table above). Update the canonical source;
do not create parallel guidance elsewhere.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]

### Added
- Agent-facing documentation system: `docs/agent-context/` (architecture, workflows, invariants, lessons-learned, review-checklist).
- `.github/copilot-instructions.md` — review-critical projections for GitHub Copilot.
- `.claude/CLAUDE.md` — Claude-specific operating instructions.
- PyPI publish workflow (`.github/workflows/publish.yml`) with Trusted Publisher (OIDC) (#37).
- `RELEASE.md` documenting the full release process.
- `[project.urls]` in `pyproject.toml` (Homepage, Repository, Documentation, Changelog).
- Optional dependency groups: `mcp` and `otel` in `pyproject.toml`.

### Changed
- Rewrote `AGENTS.md` with full domain vocabulary, security rules, code conventions, documentation map, and weaver-spec references.
- Renamed PyPI package from `agent-kernel` to `weaver-kernel` to align with Weaver ecosystem.
- Added `workflow_call` trigger to CI workflow so publish workflow can reuse it as a gate.

Expand Down
50 changes: 50 additions & 0 deletions docs/agent-context/architecture.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Architecture — Agent Context

> Canonical source for architectural intent and design tradeoffs.
> For component API details, see [../architecture.md](../architecture.md).
> For hard invariants, see [invariants.md](invariants.md).

## Intent

agent-kernel is a **capability-based security kernel** for AI agents operating in large
tool ecosystems (MCP, HTTP APIs, internal services). It sits between the LLM and raw tool
execution, enforcing least-privilege, confused-deputy prevention, and context firewalling.

The architecture optimizes for:
- **Security over convenience** — every capability invocation requires a scoped, signed token.
- **Bounded LLM context** — the Firewall always transforms raw output into a bounded Frame.
- **Auditability** — every action is traced; no silent execution.
- **Determinism** — no randomness in matching, routing, or summarization.

## Major boundaries

1. **Kernel ↔ Drivers**: The Kernel never exposes raw driver output. The Firewall always
mediates. This boundary enforces weaver-spec I-01.

2. **PolicyEngine ↔ Kernel**: Policy decisions are made *before* token issuance, not at
execution time. The token carries the approved constraints. This prevents
time-of-check/time-of-use gaps.

3. **TokenProvider ↔ Kernel**: Tokens are verified on every `invoke()`, not just at
issuance. This prevents replayed, expired, or tampered tokens from executing.

4. **Registry ↔ Router**: The registry owns capability metadata; the router maps
capabilities to drivers. They are deliberately separate so that routing changes
don't affect policy or capability definitions.

## Key tradeoffs

| Decision | Why | Consequence |
|----------|-----|-------------|
| Tokens signed, not encrypted | Simplicity; avoids key management complexity | Payloads are readable — never store secrets in them |
| Keyword-based capability search | Deterministic; no external service dependency | Less flexible than semantic search; relies on good tagging |
| Firewall is mandatory | Prevents accidental context blowup and data leakage | All output is bounded; debugging requires admin `raw` mode |
| Single dep (`httpx` only) | Minimal attack surface for a security kernel | Adding a dependency requires justification |

## Things not to simplify

- **Do not bypass the Firewall** to "improve performance." It enforces I-01 and I-02.
- **Do not merge PolicyEngine and TokenProvider.** Policy decides; tokens carry the
decision. Merging them creates confused-deputy vulnerabilities.
- **Do not make the Router stateful.** Routing is a pure mapping. Stateful routing
introduces ordering dependencies and non-determinism.
Loading