Spec Files, Hook Receipts, and Agent Plugins
A field note on Spec Kit, Cursor plugins, Graft, Mole, Opencomplai, and the contract layer forming around agent workflows.
Agent workflows are growing an extension layer.
The better projects I checked did not ask me to trust a larger prompt. They moved agent behavior into artifacts a team can inspect: spec files, plugin manifests, code graphs, hook receipts, budget ledgers, quote checks, and compliance reports.
That is the right direction. An agent that can run longer needs a narrower contract around each step, not a more dramatic persona.
The useful layer sits around the agent: files that define intent, manifests that describe capabilities, hooks that refresh evidence, budgets that bound work, gates that fail builds, and receipts that explain the run.
My Trial Bench
I used a Windows 11 laptop with PowerShell, Node 24, npm 11, uv, Python 3.11/3.12, and Go 1.25. I did not run paid model calls. I did not install editor extensions into a real profile. I cloned the repos, ran help/build/test commands, and read the source where the smoke tests exposed a boundary.
The checks favored boring truth: can the package explain itself, can the manifest parse, can tests cover the core path, and does failure name the missing dependency?
| Project | Check | Result | Read |
|---|---|---|---|
| Spec Kit | uv run specify --help, targeted pytest | CLI help worked. 21 passed, 12 skipped. | Strong artifact workflow: constitution, spec, plan, tasks, implementation. |
| Cursor plugins | manifest parse | 31 marketplace entries, 31 plugin manifests, 0 missing names. | Good schema layer for agent capabilities, but repo lacks a single root validator command. |
| Graft | npm install, npm test | Build produced viewer and grammar query assets. 659 tests, 655 pass, 4 skipped. | Best engineering signal in this set: graph retrieval, drift checks, hooks, MCP tools. |
| Mole | go test ./... | Exit 1. Many packages passed, but Windows, sandbox, chmod, and SQLite cleanup failures appeared. | Useful design for budgeted research, not yet smooth across local enviroments. |
| Opencomplai | workspace CLI build, core tests | CLI build failed on missing checker-local.html. Core subset: 46 passed. | Compliance core has real tests. Packaging has a sharp broken edge. |
I left out broad skill catalogs and agent wrapper repos that did not expose a tight runtime contract. A repo with many prompts and no testable boundary is a prompt pile.
Spec Files as Agent State
Spec Kit has a simple idea with strong operational shape: keep the "what", "why", plan, and task breakdown as repo-local artifacts before an agent writes code.
The CLI installed from the checkout and printed a real command surface:
uv run specify --help
Usage: specify [OPTIONS] COMMAND [ARGS]...
Commands:
init Initialize a new Specify project.
check Check that all required tools are installed.
version Display version and system information.
self Manage the specify CLI itself...
extension Manage spec-kit extensions
integration Manage coding agent integrations
event Manage and execute event-driven commands
preset Manage spec-kit presets
bundle Discover, install, and author Spec Kit bundles
workflow Manage and run automation workflows
The package metadata tells you the product shape. The wheel force-includes templates, command files, scripts, bundled extensions, workflows, presets, and a catalog snapshot:
templates/spec-template.md
templates/plan-template.md
templates/tasks-template.md
templates/commands
scripts/bash
scripts/powershell
scripts/python
extensions/git
extensions/agent-context
workflows/speckit
presets/lean
bundles/catalog.community.json
That matters for teams. A spec workflow that downloads half its behavior during init creates a review hole. Spec Kit tries to package the workflow with the CLI, so the generated project matches the installed version.
I ran a small pytest set with the right Python entrypoint:
uv run --with pytest --with typer --with rich --with click \
python -m pytest tests/test_cli_version.py \
tests/test_commands_package.py \
tests/test_extension_add_path_traversal.py
21 passed, 12 skipped in 1.01s
The skipped tests were platform dependent symlink/path hardening cases. The passing tests covered version output, command imports, init registration, default integration resolution, and fallback URL extension safety.
The init source also takes URL extension installs serious enough: non-interactive URL extension installs default to denied unless the user passes a trust override. That is the right default for agent workflows. A spec extension can write commands that the model will later treat as instructions.
Spec Kit still has product smell. The README has a lot of process language, and the project name can tempt teams into making ceremony. The engineering value is narrower: it turns agent intent into versioned files before the model touches implementation.
Plugin Manifests Need Schema, Not Vibes
Cursor plugins show the same move from prompt text to contracts. The repo is a marketplace-style tree. Each plugin carries a .cursor-plugin/plugin.json manifest, and the root marketplace lists plugin sources.
I did not install the plugins. I parsed the local manifests:
{
"marketplacePlugins": 31,
"pluginManifests": 31,
"missingName": 0,
"sampleNames": [
"agent-compatibility",
"cli-for-agent",
"continual-learning",
"create-plugin",
"cursor-sdk",
"cursor-team-kit",
"docs-canvas",
"orchestrate"
]
}
The schema is the part worth reading. It allows a plugin to declare commands, agents, skills, rules, hooks, variables, and MCP servers. The manifest rejects unknown top-level fields with additionalProperties: false, and the plugin name must match a lowercase identifier pattern.
{
"required": ["name"],
"additionalProperties": false,
"properties": {
"commands": "glob pattern(s) or path(s) to command files",
"agents": "glob pattern(s) or path(s) to agent definition files",
"skills": "glob pattern(s) or path(s) to skill files",
"rules": "glob pattern(s) or path(s) to rule files",
"hooks": "Path to a hooks configuration file, or an inline hooks object",
"mcpServers": "MCP server configuration"
}
}
That contract is more useful than another list of "AI workflows". Agent extension systems need explicit nouns:
| Manifest noun | Risk it names |
|---|---|
commands | prompt files that change model behavior |
skills | bundled instructions and scripts |
rules | policy that may oversteer generated code |
hooks | code that runs around tool use |
mcpServers | external capability and data egress |
variables | user-provided config and secrets-adjacent values |
The missing piece is a root validation CLI. I could parse JSON and inspect the schema, but I did not find a single repo-level npm test or validate all manifests command at the root. A marketplace repo should make this boring:
validate marketplace.json
validate every plugin.json against schemas/plugin.schema.json
ensure every source path exists
ensure declared globs match files
ensure every MCP server has a clear auth boundary
Schema is the start. CI needs to enforce it.
Graft Treats Context as a Hooked Graph
Graft gave the strongest signal. It builds a repo context graph as local generated files, wires agent hosts through hooks and MCP, and answers questions from structural code evidence instead of sending the agent through raw grep.
Install ran a build:
npm install
> @nanonets/graft@0.11.0 postinstall
> node scripts/postinstall.mjs
> @nanonets/graft@0.11.0 prepare
> npm run build
viewer bundle -> dist/viewer/
grammar queries -> dist/graph/queries/ (12 .scm)
added 46 packages, and audited 47 packages in 32s
1 high severity vulnerability
The audit warning needs attention. A context tool that agents run inside repos should keep its dependency story clean.
The test suite was strong:
npm test
tests 659
pass 655
fail 0
skipped 4
duration_ms 89558.2886
The passing cases covered ask indexing, sidecar freshness, graph rebuilds, duplicate symbol IDs, worktree seeding, workspace federation, path normalization, MCP tool aliases, graph-rank, call tracing, repo maps, grep grouping by enclosing symbol, UTF-16 input, and hook wiring across hosts.
The MCP tool names explain the product better than the README headline:
graft_find_code
graft_file_api
graft_check_freshness
graft_trace_calls
graft_find_all
graft_repo_map
That is a good roster. The tools return file and line spans, call edges, drift status, grouped search results, and repo orientation. The source also refreshes the graph before answering most tools:
Freshness first: an answer that cites file:line has to be about
the code as it is right now, including edits nobody has committed.
That line is the contract. If an agent reads stale context, it can produce a correct-looking patch against code that no longer exists. Graft makes freshness a hook-level concern.
I also like the failure posture. Unknown symbols return a soft error with "check spelling or run graft build". Old tool names still map to new ones, so saved prompts do not break. Generated graph files stay ignored and each teammate can rebuild locally. The tests cover those small edges.
The product risk sits in scope and host wiring. Graft can write repo-local files and machine-wide host config. The test suite names that distinction, and the CLI supports --dry-run, --no-global, and explicit agent selection. That is the right shape. Users still need to read the plan before letting a context hook edit ~/.codex or another agent home.
Mole Has Receipts, But Windows Found the Gaps
Mole is a deep research agent with an enforced budget, verified quotes, and a privacy boundary for local data. The repo has much more code than the star count suggests: budget ledgers, connector ingestion, sandbox checks, fetch guards, academic tools, verifier prompts, dataset scoring, and an MCP server.
The full test command failed on my machine:
go test ./...
# github.com/lajosdeme/mole/internal/daemon
internal\daemon\daemon.go:157:34: undefined: syscall.Stat_t
internal\daemon\daemon.go:417:34: undefined: syscall.Stat_t
FAIL github.com/lajosdeme/mole/cmd/mole [build failed]
More failures followed:
--- FAIL: TestRegistryRoundTrip
registry mode = 0666, want 0600
--- FAIL: TestARuntimeReplyIsReadCorrectly/podman
no container runtime found (podman: not on PATH; docker: not on PATH)
--- FAIL: TestTheBudgetCeilingIsTheDaemonsNotTheCallers
TempDir RemoveAll cleanup: ... t.db: The process cannot access the file
because it is being used by another process.
That is not a pass. It is still useful evidence.
The failures say the project cares about real boundaries. The registry test expects 0600 because the registry lists which local files a research tool can inspect. The sandbox tests expect Docker or Podman because code execution should not run naked. The daemon build assumes Unix file metadata. The SQLite cleanup failure shows a Windows file-handle problem.
The connector tests were worth reading. They assert behavior, not config strings:
| Connector test concern | Why it is good |
|---|---|
read-only DB handle refuses DROP, DELETE, UPDATE, INSERT | SQL generated by a model cannot mutate user data if a guard misses. |
PRAGMA query_only = 0 does not make writes succeed | The VFS read-only mode matters more than a SQL-level setting. |
| CSV type inference reads every row | A sampled first row would round later decimals. |
| hostile CSV headers cannot author SQL | File headers are untrusted input. |
| free-text columns get value ranges withheld | A "top values" list over notes can become row leakage. |
registry file mode should be 0600 | Local connector paths count as sensitive data. |
Mole has the kind of tests I want in an agent research tool. It also has a local enviroment story to clean up. On Windows, the project should either mark unsupported packages with build tags or fail early with a clear platform message. Sandbox tests should skip with a prerequisite note when Docker and Podman are absent, unless the project intends the dev machine to have one.
Opencomplai Turns Compliance into a Build Gate
Opencomplai attacks a different part of the agent stack: AI compliance checks as code. The repo has Python packages for core assessment, CLI, SDK, risk engine, evidence vault, doc generator, and egress proxy.
The first-run CLI path broke:
uv run opencomplai --help
Failed to build `opencomplai-cli`
FileNotFoundError: Forced include not found:
packages\cli\src\opencomplai_cli\data\checker-local.html
I confirmed the file was missing:
Test-Path packages\cli\src\opencomplai_cli\data\checker-local.html
False
That is a real packaging defect. A compliance CLI cannot fail before --help because a bundled HTML file is missing from the tree.
The core package looked better. I ran a focused test set:
uv run --with pytest python -m pytest \
tests/test_ai_usage_gate.py \
tests/test_compliance_checker_golden.py \
tests/test_manifest_parsers.py
46 passed in 1.22s
Those tests cover AI usage gating, golden compliance classifications, and package manifest parsers for Go, Cargo, Maven, Gradle, Pipfile, and npm lockfile shapes.
The scan engine also has the right internal pieces:
repo inventory
-> feature extraction
-> detector registry
-> evidence fusion
-> declared category derivation
-> discrepancy comparison
-> severity classification
-> input_digest + report_hash
I care about report_hash and input_digest here. Compliance checks that emit mutable prose are weak. A scan result needs a hash over inputs, config, detector versions, evidence, and output so a team can prove what the gate saw.
The AI usage gate tests show a practical false-positive problem:
APIRouter -> rejected
ASGITransport in a biometric test file -> rejected
openai import -> accepted
client.chat.completions.create -> accepted
bare score() without ML context -> rejected
predict_proba with sklearn context -> accepted
That is the kind of boring detector work compliance tools need. If the scanner flags every score() helper, reviewers will ignore it. If it misses OpenAI calls and model inference calls, the gate is theater.
The packaging failure keeps Opencomplai off the "drop into CI now" list for me. The core still has value. It treats AI compliance as a repo scan plus evidence object, not as a policy PDF someone updates after release.
The Contract Pattern
The projects differ in surface area, but the valuable parts share one contract shape:
| Layer | Artifact | Good behavior |
|---|---|---|
| intent | spec, plan, task files | The agent starts from reviewed state, not a chat blur. |
| extension | plugin manifest and schema | Capabilities have names, globs, variables, hooks, and MCP boundaries. |
| context | graph files and freshness checks | File/line answers track current code, not stale index bytes. |
| research | budget ledger and quote verifier | Long-running work spends from a cap and cites checked evidence. |
| compliance | scan report and hashes | CI can fail on risk evidence and prove which input produced it. |
The anti-pattern also repeats:
| Smell | Why I cut or downgraded it |
|---|---|
| giant prompt packs | No boundary between instruction, policy, and executable behavior. |
| no first-run command | A teammate cannot check the thing without becoming an archaeologist. |
| no tests around the core claim | The README sells behavior the repo does not pin. |
| hidden platform assumptions | Windows or Linux users find out only after a long install. |
| compliance without hashes | The report cannot become a build artifact you can audit later. |
An agent platform can start small. It needs files and receipts before it needs an enterprise control plane.
A Minimal Extension Receipt
For coding agents, I would record one JSON object per extension action:
{
"run_id": "agent_run_2026_08_15_001",
"extension": "graft",
"capability": "graft_trace_calls",
"inputs": {
"symbol": "validateUser",
"direction": "in",
"depth": 2
},
"context_artifact": {
"type": "code_graph",
"path": "graft/wiring.json",
"freshness": "rebuilt_before_answer",
"digest": "sha256:..."
},
"policy": {
"machine_wide_writes": false,
"network": "none",
"secrets": "not_requested"
},
"result": {
"exit": 0,
"files_referenced": [
"src/auth/session.ts:44",
"src/api/users.ts:91"
]
}
}
That record is small enough for a local file and structured enough for CI, review UI, or a future agent handoff. It tells a reviewer which extension ran, what evidence it used, whether it touched machine-wide state, and which files it cited.
Spec files, manifests, hooks, budgets, and compliance reports all become better when they end in a receipt like that.
Close
The useful agent extension layer looks less like an app store and more like build tooling.
Spec Kit turns intent into files. Cursor plugins put agent capabilities behind manifests. Graft keeps code context fresh and queryable. Mole shows how research agents can carry budgets, quote checks, and privacy tests, even though my Windows run found rough edges. Opencomplai pushes AI compliance toward scan artifacts and hashes, while its CLI packaging needs repair.
I would spend engineering time on this layer. Not on more agent names. Not on bigger prompt catalogs. On contracts a teammate can inspect before an agent gets more permission.