Query Interface Specification
ACP Version: 1.0.0 Document Version: 1.0.0 Last Updated: 2024-12-18 Status: Draft
Table of Contents
- Overview
- jq Queries
- CLI Queries
- MCP Server Interface
- Programmatic Access
- Query Patterns
- Performance Considerations
1. Overview
1.1 Purpose
The query interface provides flexible ways to access ACP metadata from the cache file. Queries enable:
- AI Context Retrieval — Get relevant code information for AI prompts
- Constraint Checking — Verify rules before modifying code
- Navigation — Find related code across domains and call graphs
- Analysis — Understand codebase structure and statistics
1.2 Query Methods
ACP supports three query interfaces:
| Interface | Use Case | Conformance Level |
|---|---|---|
| jq | Ad-hoc queries, scripting, universal access | Level 1+ |
| CLI | Developer tooling, automation | Level 2+ |
| MCP | AI assistant integration | Level 3 |
1.3 Cache Structure Reference
Queries operate on the cache file structure:
{
"version": "1.0.0",
"generated_at": "2024-12-18T15:30:00Z",
"project": { ... },
"stats": { ... },
"files": { "<path>": { ... } },
"symbols": { "<qualified_name>": { ... } },
"graph": { "forward": { ... }, "reverse": { ... } },
"domains": { "<name>": { ... } },
"constraints": { "by_file": { ... }, "by_lock_level": { ... } }
}1.4 Conformance
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.
2. jq Queries
The cache is standard JSON, directly queryable with jq.
2.1 Basic Queries
List All Files
jq '.files | keys' .acp.cache.jsonOutput:
[
"src/auth/session.ts",
"src/auth/jwt.ts",
"src/utils/helpers.ts"
]Get File Metadata
jq '.files["src/auth/session.ts"]' .acp.cache.jsonOutput:
{
"path": "src/auth/session.ts",
"module": "Session Service",
"summary": "User session management",
"lines": 245,
"language": "typescript",
"domains": ["authentication"],
"layer": "service",
"stability": "stable"
}Get Symbol Details
jq '.symbols["src/auth/session.ts:SessionService.validateSession"]' .acp.cache.jsonOutput:
{
"name": "validateSession",
"qualified_name": "src/auth/session.ts:SessionService.validateSession",
"type": "method",
"file": "src/auth/session.ts",
"lines": [45, 89],
"signature": "(token: string) => Promise<Session | null>",
"summary": "Validates JWT and returns session",
"exported": true,
"async": true
}2.2 Constraint Queries
Check File Lock Level
jq '.constraints.by_file["src/auth/session.ts"].lock_level' .acp.cache.jsonOutput:
"restricted"Get All Frozen Files
jq '.constraints.by_lock_level.frozen[]' .acp.cache.jsonOutput:
"src/config/production.ts"
"src/security/keys.ts"Get All Restricted Files
jq '.constraints.by_lock_level.restricted' .acp.cache.jsonOutput:
[
"src/auth/session.ts",
"src/billing/payment.ts"
]Get Full Constraints for a File
jq '.constraints.by_file["src/auth/session.ts"]' .acp.cache.jsonOutput:
{
"lock_level": "restricted",
"lock_reason": "Security critical",
"style": "google-typescript",
"quality": ["security-review"]
}2.3 Domain Queries
List All Domains
jq '.domains | keys' .acp.cache.jsonOutput:
["authentication", "billing", "database", "api"]Get Domain Details
jq '.domains["authentication"]' .acp.cache.jsonOutput:
{
"name": "authentication",
"description": "User authentication and session management",
"files": ["src/auth/session.ts", "src/auth/jwt.ts"],
"symbols": [
"src/auth/session.ts:SessionService.validateSession",
"src/auth/jwt.ts:verifyToken"
]
}Get Files in a Domain
jq '.domains["authentication"].files[]' .acp.cache.jsonOutput:
"src/auth/session.ts"
"src/auth/jwt.ts"2.4 Call Graph Queries
Get What a Function Calls (Callees)
jq '.graph.forward["src/auth/session.ts:SessionService.validateSession"]' .acp.cache.jsonOutput:
[
"src/auth/jwt.ts:verifyToken",
"src/db/sessions.ts:findSession"
]Get What Calls a Function (Callers)
jq '.graph.reverse["src/auth/jwt.ts:verifyToken"]' .acp.cache.jsonOutput:
[
"src/auth/session.ts:SessionService.validateSession",
"src/api/middleware.ts:authMiddleware"
]2.5 Search and Filter Queries
Find Symbols by Name Pattern
jq '.symbols | to_entries | map(select(.key | contains("validate"))) | .[].key' .acp.cache.jsonOutput:
"src/auth/session.ts:SessionService.validateSession"
"src/utils/validation.ts:validateEmail"Get All TypeScript Files
jq '.files | to_entries | map(select(.value.language == "typescript")) | .[].key' .acp.cache.jsonGet All Async Functions
jq '.symbols | to_entries | map(select(.value.async == true)) | .[].key' .acp.cache.jsonGet Exported Symbols Only
jq '.symbols | to_entries | map(select(.value.exported == true)) | .[].value.name' .acp.cache.jsonFind Files in a Layer
jq '.files | to_entries | map(select(.value.layer == "service")) | .[].key' .acp.cache.json2.6 Statistics Queries
Get Codebase Stats
jq '.stats' .acp.cache.jsonOutput:
{
"files": 127,
"symbols": 523,
"lines": 15420,
"annotation_coverage": 45.2
}Count Symbols by Type
jq '.symbols | to_entries | group_by(.value.type) | map({type: .[0].value.type, count: length})' .acp.cache.jsonOutput:
[
{"type": "function", "count": 234},
{"type": "method", "count": 189},
{"type": "class", "count": 67},
{"type": "const", "count": 33}
]Count Files by Language
jq '.files | to_entries | group_by(.value.language) | map({language: .[0].value.language, count: length})' .acp.cache.json2.7 Advanced Queries
Get Full Call Chain (2 Levels Deep)
jq --arg sym "src/auth/session.ts:SessionService.validateSession" '
.graph.forward[$sym] as $callees |
[$callees[] | . as $c | {callee: $c, calls: .graph.forward[$c]}]
' .acp.cache.jsonFind Unrestricted Files in Security Domain
jq '
.domains["authentication"].files as $auth_files |
.constraints.by_file | to_entries |
map(select(.key | IN($auth_files[]))) |
map(select(.value.lock_level == "normal" or .value.lock_level == null)) |
.[].key
' .acp.cache.jsonGet Summary Report
jq '{
project: .project.name,
files: .stats.files,
symbols: .stats.symbols,
domains: (.domains | keys),
frozen_count: (.constraints.by_lock_level.frozen | length),
restricted_count: (.constraints.by_lock_level.restricted | length)
}' .acp.cache.json3. CLI Queries
Level 2+ implementations SHOULD provide a command-line interface for queries.
3.1 Query Subcommands
Query Symbol
acp query symbol <name>Example:
acp query symbol validateSessionOutput:
{
"name": "validateSession",
"qualified_name": "src/auth/session.ts:SessionService.validateSession",
"type": "method",
"file": "src/auth/session.ts",
"lines": [45, 89],
"signature": "(token: string) => Promise<Session | null>",
"summary": "Validates JWT and returns session"
}Query File
acp query file <path>Example:
acp query file src/auth/session.tsQuery Callers
acp query callers <symbol>Example:
acp query callers "src/auth/jwt.ts:verifyToken"Output:
src/auth/session.ts:SessionService.validateSession
src/api/middleware.ts:authMiddlewareQuery Callees
acp query callees <symbol>Example:
acp query callees "src/auth/session.ts:SessionService.validateSession"Output:
src/auth/jwt.ts:verifyToken
src/db/sessions.ts:findSessionList Domains
acp query domainsOutput:
authentication: 5 files, 23 symbols
billing: 8 files, 45 symbols
database: 12 files, 67 symbols
api: 15 files, 89 symbolsQuery Domain
acp query domain <name>Example:
acp query domain authenticationShow Statistics
acp query statsOutput:
Files: 127
Symbols: 523
Lines: 15420
Coverage: 45.2%
Domains: 4
Layers: 63.2 Constraints Command
The acp constraints command is specifically designed for checking constraints before modifications.
Check File Constraints
acp constraints <path>Example:
acp constraints src/auth/session.tsOutput:
File: src/auth/session.ts
Lock Level: restricted
Lock Reason: Security critical
Style: google-typescript
Quality Requirements:
- security-review
⚠ This file requires approval before modification.Check with JSON Output
acp constraints src/auth/session.ts --jsonOutput:
{
"file": "src/auth/session.ts",
"lock_level": "restricted",
"lock_reason": "Security critical",
"style": "google-typescript",
"quality": ["security-review"],
"can_modify": false,
"approval_needed": true
}3.3 Direct jq Passthrough
Some implementations MAY support direct jq expression passthrough:
acp query '.domains | keys'
acp query '.constraints.by_lock_level.frozen'3.4 Output Formats
Implementations SHOULD support multiple output formats:
| Flag | Format |
|---|---|
--json | JSON (default for programmatic use) |
--pretty | Pretty-printed JSON (default for terminal) |
--table | Tabular format |
--plain | Plain text, one item per line |
4. MCP Server Interface
Level 3 implementations MUST provide an MCP (Model Context Protocol) server interface for AI assistant integration.
4.1 Resources
MCP resources expose ACP data for AI consumption:
| Resource URI | Description |
|---|---|
acp://cache | Full codebase cache |
acp://vars | Variable definitions |
acp://constraints | Constraints summary |
acp://file/{path} | Specific file metadata |
acp://symbol/{qualified_name} | Specific symbol metadata |
acp://domain/{name} | Specific domain metadata |
4.2 Tools
MCP tools enable AI assistants to query and interact with ACP:
acp_query
Query the codebase index.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
type | string | Yes | Query type (see below) |
name | string | Conditional | Symbol, file, or domain name |
pattern | string | Conditional | Search pattern |
Query Types:
| Type | Description | Required Parameters |
|---|---|---|
symbol | Get symbol details | name |
file | Get file metadata | name |
domain | Get domain info | name |
callers | Get callers of symbol | name |
callees | Get callees of symbol | name |
search | Search symbols and files | pattern |
stats | Get codebase statistics | (none) |
Example Calls:
// Get symbol details
acp_query({ type: "symbol", name: "validateSession" })
// Get domain info
acp_query({ type: "domain", name: "authentication" })
// Find callers
acp_query({ type: "callers", name: "src/auth/jwt.ts:verifyToken" })
// Search for symbols
acp_query({ type: "search", pattern: "validate" })
// Get stats
acp_query({ type: "stats" })acp_constraints
Check constraints before modifying a file. AI assistants SHOULD always call this before modifying any file.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
file | string | Yes | File path to check |
Response:
{
"file": "src/auth/session.ts",
"lock_level": "restricted",
"lock_reason": "Security critical",
"style": "google-typescript",
"behavior": "conservative",
"quality": ["security-review"],
"can_modify": {
"allowed": true,
"approval_needed": true,
"requirements": ["Explain changes before making them"]
}
}AI Behavior Based on Response:
lock_level | AI Behavior |
|---|---|
frozen | MUST NOT modify; refuse the request |
restricted | MUST explain changes and get approval first |
approval-required | SHOULD ask for approval for significant changes |
tests-required | MUST include tests with changes |
docs-required | MUST update documentation |
normal | May modify freely |
experimental | May modify aggressively |
acp_expand
Expand variable references to their full values.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
text | string | Yes | Text containing $VAR references |
mode | string | No | Expansion mode (default: summary) |
Modes:
| Mode | Description |
|---|---|
summary | Short summary (default) |
full | Complete JSON |
inline | Inline replacement |
annotated | Shows both variable and expansion |
Example:
acp_expand({
text: "Check $SYM_VALIDATE_SESSION for the bug",
mode: "summary"
})Response:
{
"original": "Check $SYM_VALIDATE_SESSION for the bug",
"expanded": "Check validateSession (src/auth/session.ts:45-89) - Validates JWT tokens for the bug",
"variables_found": ["SYM_VALIDATE_SESSION"],
"variables_resolved": ["SYM_VALIDATE_SESSION"],
"variables_unresolved": []
}acp_debug
Manage debugging sessions for reversible troubleshooting.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
action | string | Yes | Action to perform |
data | object | Conditional | Action-specific data |
Actions:
| Action | Description | Data Fields |
|---|---|---|
start | Begin new session | problem, hypothesis |
attempt | Log an attempt | session_id, description, files |
result | Record outcome | session_id, attempt_id, success, notes |
revert | Mark as reverted | session_id, attempt_id |
resolve | Close session | session_id, resolution |
status | Get session status | session_id |
acp_hack
Track temporary/experimental code.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
action | string | Yes | Action to perform |
data | object | Conditional | Action-specific data |
Actions:
| Action | Description | Data Fields |
|---|---|---|
mark | Mark code as hack | file, line, reason, ticket, expires |
list | List all hacks | file (optional), expired_only (optional) |
revert | Remove hack marker | id |
cleanup | Find expired hacks | (none) |
4.3 MCP Server Configuration
Claude Desktop Configuration Example:
{
"mcpServers": {
"acp": {
"command": "acp-mcp-server",
"args": ["--dir", "/path/to/your/project"]
}
}
}Or with Node.js:
{
"mcpServers": {
"acp": {
"command": "node",
"args": ["/path/to/acp-mcp-server/dist/index.js", "--dir", "/path/to/project"]
}
}
}5. Programmatic Access
5.1 JavaScript/TypeScript
import { readFileSync } from 'fs';
// Load cache
const cache = JSON.parse(readFileSync('.acp.cache.json', 'utf-8'));
// Query symbol
function getSymbol(name: string) {
return Object.values(cache.symbols).find(s => s.name === name);
}
// Get callers
function getCallers(qualifiedName: string): string[] {
return cache.graph.reverse[qualifiedName] || [];
}
// Check constraints
function canModify(filePath: string): { allowed: boolean; reason?: string } {
const constraints = cache.constraints.by_file[filePath];
if (!constraints) return { allowed: true };
if (constraints.lock_level === 'frozen') {
return { allowed: false, reason: constraints.lock_reason };
}
return { allowed: true };
}
// Get domain files
function getDomainFiles(domain: string): string[] {
return cache.domains[domain]?.files || [];
}5.2 Python
import json
# Load cache
with open('.acp.cache.json') as f:
cache = json.load(f)
# Query symbol
def get_symbol(name: str):
for sym in cache['symbols'].values():
if sym['name'] == name:
return sym
return None
# Get callers
def get_callers(qualified_name: str) -> list:
return cache['graph']['reverse'].get(qualified_name, [])
# Check constraints
def can_modify(file_path: str) -> tuple[bool, str | None]:
constraints = cache['constraints']['by_file'].get(file_path)
if not constraints:
return True, None
if constraints.get('lock_level') == 'frozen':
return False, constraints.get('lock_reason')
return True, None
# Get domain files
def get_domain_files(domain: str) -> list:
return cache['domains'].get(domain, {}).get('files', [])5.3 Rust
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Deserialize)]
struct Cache {
files: HashMap<String, FileEntry>,
symbols: HashMap<String, SymbolEntry>,
graph: CallGraph,
domains: HashMap<String, DomainEntry>,
constraints: ConstraintIndex,
}
impl Cache {
fn get_symbol(&self, name: &str) -> Option<&SymbolEntry> {
self.symbols.values().find(|s| s.name == name)
}
fn get_callers(&self, qualified_name: &str) -> Vec<&str> {
self.graph.reverse
.get(qualified_name)
.map(|v| v.iter().map(|s| s.as_str()).collect())
.unwrap_or_default()
}
fn can_modify(&self, file_path: &str) -> (bool, Option<&str>) {
match self.constraints.by_file.get(file_path) {
Some(c) if c.lock_level == Some("frozen".into()) => {
(false, c.lock_reason.as_deref())
}
_ => (true, None)
}
}
}6. Query Patterns
6.1 AI Workflow Pattern
Standard pattern for AI assistants working with ACP:
1. RECEIVE task from user
2. QUERY relevant context:
- acp_query(type="domain", name=<relevant_domain>)
- acp_query(type="search", pattern=<keywords>)
3. CHECK constraints before any modification:
- acp_constraints(file=<target_file>)
4. RESPECT constraint response:
- If frozen: refuse modification
- If restricted: explain changes, request approval
- If tests-required: include tests
5. PROCEED with task respecting constraints6.2 Navigation Pattern
Finding related code:
# Start with a symbol
acp query symbol validateSession
# Find what it calls
acp query callees "src/auth/session.ts:SessionService.validateSession"
# Find what calls it
acp query callers "src/auth/session.ts:SessionService.validateSession"
# Explore the domain
acp query domain authentication6.3 Audit Pattern
Checking codebase security posture:
# Find all frozen files
jq '.constraints.by_lock_level.frozen' .acp.cache.json
# Find restricted files without lock reasons
jq '.constraints.by_file | to_entries | map(select(.value.lock_level == "restricted" and .value.lock_reason == null)) | .[].key' .acp.cache.json
# Find files in auth domain without constraints
jq --argjson auth_files '["src/auth/session.ts", "src/auth/jwt.ts"]' '
.constraints.by_file | keys as $constrained |
$auth_files | map(select(. as $f | $constrained | index($f) | not))
' .acp.cache.json6.4 Impact Analysis Pattern
Understanding change impact:
# Find all callers (direct)
jq '.graph.reverse["src/auth/jwt.ts:verifyToken"]' .acp.cache.json
# Find all callers (2 levels)
jq '
.graph.reverse["src/auth/jwt.ts:verifyToken"] as $direct |
$direct + [$direct[] as $d | .graph.reverse[$d][]] | unique
' .acp.cache.json7. Performance Considerations
7.1 Cache Size Guidelines
| Codebase Size | Typical Cache Size | Load Time |
|---|---|---|
| Small (<100 files) | <100 KB | <10ms |
| Medium (100-1000 files) | 100 KB - 1 MB | 10-100ms |
| Large (1000-10000 files) | 1 MB - 10 MB | 100ms-1s |
| Very Large (>10000 files) | >10 MB | >1s |
7.2 Query Optimization
For frequent queries:
- Load cache once, reuse in memory
- Index by frequently-queried fields
- Use streaming parsers for very large caches
For jq:
- Avoid repeated file reads
- Use
--slurpfor multiple queries - Consider
jqwith-cfor compact output in scripts
7.3 Staleness Handling
Queries return stale data if the cache is outdated. Implementations SHOULD:
- Check
generated_atagainst source file modification times - Compare
git_commitwith current HEAD - Warn users if cache appears stale
- Provide
--forceflag to rebuild cache
Appendix A: jq Quick Reference
Common Patterns
| Goal | Query |
|---|---|
| List all files | jq '.files | keys' |
| Get file info | jq '.files["path/to/file.ts"]' |
| List all symbols | jq '.symbols | keys' |
| Get symbol info | jq '.symbols["qualified:name"]' |
| List domains | jq '.domains | keys' |
| Get domain files | jq '.domains["name"].files' |
| Find callers | jq '.graph.reverse["symbol"]' |
| Find callees | jq '.graph.forward["symbol"]' |
| Get frozen files | jq '.constraints.by_lock_level.frozen' |
| Check lock level | jq '.constraints.by_file["path"].lock_level' |
| Get stats | jq '.stats' |
Filtering Patterns
| Goal | Query |
|---|---|
| Files by language | jq '.files | to_entries | map(select(.value.language == "typescript"))' |
| Symbols by type | jq '.symbols | to_entries | map(select(.value.type == "function"))' |
| Exported only | jq '.symbols | to_entries | map(select(.value.exported))' |
| Async functions | jq '.symbols | to_entries | map(select(.value.async))' |
| By name pattern | jq '.symbols | to_entries | map(select(.key | contains("validate")))' |
Appendix B: Related Documents
- Cache Format — Cache file structure
- Variables — Variable expansion
- Constraints — Constraint definitions
- Introduction — Overview and workflows
- Terminology — Definitions
End of Query Interface Specification