Query Interface Specification

ACP Version: 1.0.0 Document Version: 1.0.0 Last Updated: 2024-12-18 Status: Draft


Table of Contents

  1. Overview
  2. jq Queries
  3. CLI Queries
  4. MCP Server Interface
  5. Programmatic Access
  6. Query Patterns
  7. 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:

InterfaceUse CaseConformance Level
jqAd-hoc queries, scripting, universal accessLevel 1+
CLIDeveloper tooling, automationLevel 2+
MCPAI assistant integrationLevel 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.json

Output:

[
  "src/auth/session.ts",
  "src/auth/jwt.ts",
  "src/utils/helpers.ts"
]

Get File Metadata

jq '.files["src/auth/session.ts"]' .acp.cache.json

Output:

{
  "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.json

Output:

{
  "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.json

Output:

"restricted"

Get All Frozen Files

jq '.constraints.by_lock_level.frozen[]' .acp.cache.json

Output:

"src/config/production.ts"
"src/security/keys.ts"

Get All Restricted Files

jq '.constraints.by_lock_level.restricted' .acp.cache.json

Output:

[
  "src/auth/session.ts",
  "src/billing/payment.ts"
]

Get Full Constraints for a File

jq '.constraints.by_file["src/auth/session.ts"]' .acp.cache.json

Output:

{
  "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.json

Output:

["authentication", "billing", "database", "api"]

Get Domain Details

jq '.domains["authentication"]' .acp.cache.json

Output:

{
  "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.json

Output:

"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.json

Output:

[
  "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.json

Output:

[
  "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.json

Output:

"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.json

Get All Async Functions

jq '.symbols | to_entries | map(select(.value.async == true)) | .[].key' .acp.cache.json

Get Exported Symbols Only

jq '.symbols | to_entries | map(select(.value.exported == true)) | .[].value.name' .acp.cache.json

Find Files in a Layer

jq '.files | to_entries | map(select(.value.layer == "service")) | .[].key' .acp.cache.json

2.6 Statistics Queries

Get Codebase Stats

jq '.stats' .acp.cache.json

Output:

{
  "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.json

Output:

[
  {"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.json

2.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.json

Find 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.json

Get 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.json

3. 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 validateSession

Output:

{
  "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.ts

Query 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:authMiddleware

Query 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:findSession

List Domains

acp query domains

Output:

authentication: 5 files, 23 symbols
billing: 8 files, 45 symbols
database: 12 files, 67 symbols
api: 15 files, 89 symbols

Query Domain

acp query domain <name>

Example:

acp query domain authentication

Show Statistics

acp query stats

Output:

Files: 127
Symbols: 523
Lines: 15420
Coverage: 45.2%
Domains: 4
Layers: 6

3.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.ts

Output:

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 --json

Output:

{
  "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:

FlagFormat
--jsonJSON (default for programmatic use)
--prettyPretty-printed JSON (default for terminal)
--tableTabular format
--plainPlain 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 URIDescription
acp://cacheFull codebase cache
acp://varsVariable definitions
acp://constraintsConstraints 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:

ParameterTypeRequiredDescription
typestringYesQuery type (see below)
namestringConditionalSymbol, file, or domain name
patternstringConditionalSearch pattern

Query Types:

TypeDescriptionRequired Parameters
symbolGet symbol detailsname
fileGet file metadataname
domainGet domain infoname
callersGet callers of symbolname
calleesGet callees of symbolname
searchSearch symbols and filespattern
statsGet 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:

ParameterTypeRequiredDescription
filestringYesFile 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_levelAI Behavior
frozenMUST NOT modify; refuse the request
restrictedMUST explain changes and get approval first
approval-requiredSHOULD ask for approval for significant changes
tests-requiredMUST include tests with changes
docs-requiredMUST update documentation
normalMay modify freely
experimentalMay modify aggressively

acp_expand

Expand variable references to their full values.

Parameters:

ParameterTypeRequiredDescription
textstringYesText containing $VAR references
modestringNoExpansion mode (default: summary)

Modes:

ModeDescription
summaryShort summary (default)
fullComplete JSON
inlineInline replacement
annotatedShows 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:

ParameterTypeRequiredDescription
actionstringYesAction to perform
dataobjectConditionalAction-specific data

Actions:

ActionDescriptionData Fields
startBegin new sessionproblem, hypothesis
attemptLog an attemptsession_id, description, files
resultRecord outcomesession_id, attempt_id, success, notes
revertMark as revertedsession_id, attempt_id
resolveClose sessionsession_id, resolution
statusGet session statussession_id

acp_hack

Track temporary/experimental code.

Parameters:

ParameterTypeRequiredDescription
actionstringYesAction to perform
dataobjectConditionalAction-specific data

Actions:

ActionDescriptionData Fields
markMark code as hackfile, line, reason, ticket, expires
listList all hacksfile (optional), expired_only (optional)
revertRemove hack markerid
cleanupFind 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 constraints

6.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 authentication

6.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.json

6.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.json

7. Performance Considerations

7.1 Cache Size Guidelines

Codebase SizeTypical Cache SizeLoad Time
Small (<100 files)<100 KB<10ms
Medium (100-1000 files)100 KB - 1 MB10-100ms
Large (1000-10000 files)1 MB - 10 MB100ms-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 --slurp for multiple queries
  • Consider jq with -c for compact output in scripts

7.3 Staleness Handling

Queries return stale data if the cache is outdated. Implementations SHOULD:

  1. Check generated_at against source file modification times
  2. Compare git_commit with current HEAD
  3. Warn users if cache appears stale
  4. Provide --force flag to rebuild cache

Appendix A: jq Quick Reference

Common Patterns

GoalQuery
List all filesjq '.files | keys'
Get file infojq '.files["path/to/file.ts"]'
List all symbolsjq '.symbols | keys'
Get symbol infojq '.symbols["qualified:name"]'
List domainsjq '.domains | keys'
Get domain filesjq '.domains["name"].files'
Find callersjq '.graph.reverse["symbol"]'
Find calleesjq '.graph.forward["symbol"]'
Get frozen filesjq '.constraints.by_lock_level.frozen'
Check lock leveljq '.constraints.by_file["path"].lock_level'
Get statsjq '.stats'

Filtering Patterns

GoalQuery
Files by languagejq '.files | to_entries | map(select(.value.language == "typescript"))'
Symbols by typejq '.symbols | to_entries | map(select(.value.type == "function"))'
Exported onlyjq '.symbols | to_entries | map(select(.value.exported))'
Async functionsjq '.symbols | to_entries | map(select(.value.async))'
By name patternjq '.symbols | to_entries | map(select(.key | contains("validate")))'

Appendix B: Related Documents


End of Query Interface Specification