299 lines
16 KiB
Markdown
299 lines
16 KiB
Markdown
# AgenticCode
|
||
|
||
## 0. Hard Rules
|
||
|
||
* **NEVER ask questions in response text.** Every question to the user MUST go through the `AskUserQuestion` tool. No
|
||
exceptions. If you need to ask something, use `AskUserQuestion`. If you need clarification, use `AskUserQuestion`. If
|
||
you need a decision, use `AskUserQuestion`. The tool provides a freetext option automatically — use it.
|
||
* **Never assume anything about the user's intent.** Ask questions and wait for the user to clarify.
|
||
* **Always use agentic code** see x-docs/agent-api-usage-ac-implementation.md to understand the code, get an overview
|
||
and
|
||
if somethinmg is missing or not working, report it directly. Also. find identifier via agentic code. if agentic code
|
||
is not running, report it.
|
||
* **NEVER start Docker yourself — the human starts it.** If you need the server/Neo4j for analysis and
|
||
`http://localhost:8787` is unreachable, **stop and ask the user to run `./manage-ac.sh deploy`** (via
|
||
`AskUserQuestion`, per the rule above). Do not run `./manage-ac.sh deploy`, `docker compose up/start/restart`, or
|
||
otherwise bring containers up on your own initiative — not to "just check something", not because it is
|
||
faster. Starting the stack is the human's call, like committing. The same goes for stopping or restarting
|
||
it: ask first. You may *read* container state (`docker ps`, logs) freely.
|
||
* **Clean up what you start.** Any long-running probe you launch (`cypher-shell`, background Bash, a query
|
||
against Neo4j) must be stopped before you report done. `TaskStop` kills the *client*, not the JVM behind
|
||
a `docker exec` — verify with `ps` on the host **and** inside the container, then say so. Never report
|
||
"all shells stopped" from the task list alone.
|
||
* If agentic code is not ingested, refresh it again (`ac refresh` / `POST /api/projects/ac/refresh`)
|
||
* After implementation do a refresh again to get the latest changes.
|
||
* **A deep refresh is long and mutates the graph.** Do not abort one halfway: the earlier enrichment steps
|
||
are already committed, so the graph is left partially updated and every later query silently answers from
|
||
it. If one must be stopped, say plainly that the graph is now in a half-updated state.
|
||
* **Keep the REST API and `ac-cli` in sync.** Every REST endpoint added or changed in
|
||
`ac-code-server/.../api/*Resource.java` MUST have a matching `ac-cli` command, delivered in the same change. Treat
|
||
REST + CLI as one unit of work — neither is "done" without the other.
|
||
## 1. Core Rules
|
||
|
||
- Never assume. Always read files first with tools.
|
||
- Make all assumptions explicit and visible.
|
||
- Prioritize good structure, modularization, and maintainability.
|
||
- Keep solutions simple — only as abstract as necessary.
|
||
- Validate state before and after changes using terminal commands.
|
||
- Remove dead/unreachable code immediately (ask first if unsure).
|
||
- Be willing to backtrack if heading in the wrong direction.
|
||
- Trivial tasks: Ask "Trivial? Direct edit or full workflow?"
|
||
- Never run `git commit` (or `git push`) without the user explicitly asking for it in that turn. A prior commit approval
|
||
does not carry over to later changes.
|
||
- **The human decides what to commit and when.** Committing is a human decision, not yours. Do not stage, group, or
|
||
propose commits on your own initiative, and do not nudge toward committing. You may prepare a suggested commit message
|
||
when asked, but the act — and its timing and scope — is the human's call alone.
|
||
- All features must be tracked in `x-docs/roadmap.md`. Once a feature has been implemented, mark it `[x]` and add a
|
||
timestamp (date) indicating when it was completed.
|
||
- For **every feature** that changes API behavior or what an agent can query, you MUST update
|
||
`x-docs/agent-api-usage-ac-implementation.md` to reflect it (new/changed endpoints, response fields, semantics) —
|
||
treat
|
||
this doc
|
||
update as part of the feature's Definition of Done, not an optional follow-up.
|
||
- Never add a `Co-Authored-By:` line (or any AI-attribution trailer) to commit messages.
|
||
- **Dogfooding: use AgenticCode itself for static analysis of this repo whenever possible.** The
|
||
server runs at `http://localhost:8787` with this repo already ingested as project `ac`. Prefer it
|
||
over grep/Explore for call graphs, callers/callees, DB access, dataflow, and module overviews — it's
|
||
exactly the tool this project builds, so using it here is both faster and the best test of its own
|
||
output. Usage guide: `x-docs/agent-api-usage-ac-implementation.md`. Re-ingest after code changes
|
||
(`ac refresh` / `POST /api/projects/ac/refresh`, or `--deep`/`?deep=true` for a full field-level
|
||
pass) before trusting query results.
|
||
- **Tool priority: REST API first, then the `ac` CLI, then grep/Explore.** Query the REST endpoints
|
||
(`GET /api/projects/ac/modules/{name}/...`) before anything else. The `ac <command>` CLI (`ac callers`,
|
||
`ac callees`,
|
||
`ac call-tree`, `ac context`, `ac db-accesses`, `ac refresh`, ...) is a convenience wrapper over the same REST API,
|
||
useful for quick manual checks. **If the server is unavailable** (`http://localhost:8787`
|
||
unreachable), **ask the user to run `./manage-ac.sh deploy`** — never start it yourself (see Hard Rules).
|
||
**Only when it still can't answer the question** (info the API doesn't expose, or the analysis needs
|
||
exact source text/comments/formatting) fall back to normal code analysis (Read/Grep/Explore agent)
|
||
exactly as you would on any other codebase.
|
||
- **If a needed capability is missing from the API/CLI** (not just unreachable, but the question is
|
||
one none of them can answer at all), don't silently fall back to grep and move on — after finishing
|
||
the task with the grep-based fallback, use `AskUserQuestion` to tell the user what was missing and
|
||
ask whether it should be added as a feature in `x-docs/roadmap.md`.
|
||
|
||
## 2. Mandatory 4-Phase Workflow
|
||
|
||
``0. **Clarify Intent** -Assess if the user's request is fully clear.
|
||
- **Clear**: State your understanding and proceed.
|
||
- **Unclear**: Use `AskUserQuestion` tool with concrete options. Repeat until unambiguous.
|
||
1. **PROPOSAL** – Clear plan + impact. Wait for `OK PROPOSAL`.
|
||
2. **VALIDATE** – Brutal self-critique (NullAway, layering, regressions). Wait for `OK VALIDATE`.
|
||
3. **IMPLEMENT** – One unit at a time. Show exact diff only.
|
||
4. **VERIFICATION** – Run relevant tests. Suggest a commit message, but do not commit unless asked (see Core Rules).``
|
||
|
||
Quarkus-based server for parsing, storing, and agentically querying source code (Natural/Software AG and Java).
|
||
Programs are parsed into a unified AST, persisted as a graph in Neo4j, enriched with semantic information, and exposed via an agent-optimized API.
|
||
|
||
## Architecture Overview
|
||
|
||
```
|
||
Parser Layer → Unified AST → Neo4j Graph DB → Enrichment → Agentic API (REST)
|
||
```
|
||
|
||
- **Natural Parser**: custom implementation (no OSS parser available for Software AG Natural)
|
||
- **Java Parser**: JavaParser library
|
||
- **Graph Store**: Neo4j — nodes for modules, functions, variables, data structures, DB accesses
|
||
- **Enrichment**: call graph, identifier index, data structures, ADABAS/SQL access patterns
|
||
- **API**: Quarkus REST (JAX-RS), optimized for AI agent tool use
|
||
|
||
## Tech Stack
|
||
|
||
| Component | Technology |
|
||
|----------------|------------------------------------------------|
|
||
| Server | Quarkus (latest stable) |
|
||
| Language | Java 21 (Virtual Threads enabled) |
|
||
| Graph DB | Neo4j 5.x (via neo4j-java-driver) |
|
||
| REST | Quarkus RESTEasy Reactive (JAX-RS) |
|
||
| JSON | Jackson (quarkus-jackson) |
|
||
| Natural Parser | Custom impl in `ac-parser-natural` module |
|
||
| Java Parser | JavaParser (com.github.javaparser) |
|
||
| Tests | JUnit 5 + RestAssured + Testcontainers (Neo4j) |
|
||
| Build | Maven (multi-module) |
|
||
| Config | `application.properties` (dev/prod profiles) |
|
||
|
||
## Project Structure
|
||
|
||
```
|
||
agenticcode/
|
||
├── CLAUDE.md
|
||
├── pom.xml # Root POM (multi-module)
|
||
├── ac-code-server/ # Quarkus application
|
||
│ ├── src/main/java/de/agenticcode/
|
||
│ │ ├── api/ # JAX-RS Resources
|
||
│ │ ├── service/ # Business logic
|
||
│ │ └── enrichment/ # Enrichment pipelines
|
||
│ └── src/main/resources/
|
||
│ └── application.properties
|
||
├── ac-parser-natural/ # Natural parser module
|
||
│ └── src/main/java/de/agenticcode/parser/natural/
|
||
├── ac-parser-java/ # Java parser module
|
||
│ └── src/main/java/de/agenticcode/parser/java/
|
||
├── ac-parser-core/ # Shared AST schema + interfaces
|
||
│ └── src/main/java/de/agenticcode/ast/
|
||
│ ├── model/ # AstNode, AstEdge, NodeType, EdgeType
|
||
│ └── spi/ # LanguageParser interface
|
||
├── ac-neo4j-store/ # Neo4j persistence + queries
|
||
│ └── src/main/java/de/agenticcode/graph/
|
||
└── docs/
|
||
├── ast-schema.md # Neo4j node/edge types with Cypher examples
|
||
├── natural-grammar.md # Natural language constructs and parser decisions
|
||
├── api-endpoints.md # Full API reference
|
||
└── enrichment-pipelines.md # Enrichment logic and pipeline design
|
||
```
|
||
|
||
## Build & Run
|
||
|
||
Maven settings: `.mvn/maven.config` (gitignored, machine-local) points `-s` at
|
||
`~/.m2/settings_my.xml` — the working repository configuration, since the default Maven settings
|
||
point at an internal artifactory not reachable from this environment. Plain `mvn ...` picks it up
|
||
automatically; no need to pass `-s` explicitly.
|
||
|
||
```bash
|
||
# Full build
|
||
mvn clean install
|
||
|
||
# Dev mode (hot reload)
|
||
cd ac-code-server && mvn quarkus:dev
|
||
|
||
# Native build (GraalVM)
|
||
mvn package -Pnative
|
||
|
||
# Run all tests (includes Testcontainers Neo4j)
|
||
mvn test
|
||
|
||
# Test a single module
|
||
mvn test -pl ac-parser-natural
|
||
```
|
||
|
||
Requirements: Java 21+, Maven 3.9+, Docker (for Testcontainers).
|
||
|
||
```bash
|
||
# Start Neo4j locally for dev — for the human to run, not the agent (see Hard Rules)
|
||
docker run -p 7474:7474 -p 7687:7687 \
|
||
-e NEO4J_AUTH=neo4j/agenticcode \
|
||
neo4j:5
|
||
```
|
||
|
||
## Code Conventions
|
||
|
||
### General
|
||
- Use Java 21 features: Records for DTOs/value objects, Sealed Classes for AST node types, Pattern Matching
|
||
- Non-null is the default (enforced by NullAway, packages annotated `@NullMarked`). Avoid `Optional` for fields, parameters, and most return types — use `@org.jspecify.annotations.Nullable` only where a value can genuinely be absent. Prefer empty collections over `Optional<List<T>>`.
|
||
- Immutable by default: prefer Records over mutable classes
|
||
- Logging: `org.jboss.logging.Logger` (Quarkus standard) — no `System.out`
|
||
|
||
### Naming
|
||
- Packages: `com.agenticcode.<module>.<layer>` (all lowercase)
|
||
- Parser classes: `NaturalParser`, `JavaParser` (implement `LanguageParser`)
|
||
- API classes: `ModuleResource`, `AnalysisResource` (JAX-RS Resources)
|
||
- Service classes: `AstIngestService`, `CallGraphService`, `EnrichmentService`
|
||
- Neo4j classes: `GraphRepository`, `CypherQueryBuilder`
|
||
|
||
### Quarkus Specifics
|
||
- CDI: `@ApplicationScoped` for services, `@RequestScoped` for stateful request context
|
||
- All configuration via `@ConfigProperty` — never hardcoded values
|
||
- Reactive where appropriate: `Uni<T>` / `Multi<T>` (Mutiny) for Neo4j calls
|
||
- Implement health checks: `@Liveness`, `@Readiness`
|
||
|
||
### AST / Graph
|
||
|
||
- Node types are defined as `enum NodeType` in `ac-parser-core` — never use raw strings
|
||
- Edge types are defined as `enum EdgeType` in `ac-parser-core` — never use raw strings
|
||
- Every node must have: `id` (UUID), `sourceFile`, `language`, `startLine`, `endLine`
|
||
- Cypher queries do not belong inline in service classes — put them in a `CypherQueries` constants class
|
||
|
||
## Unified AST Schema (Neo4j)
|
||
|
||
Node types (`NodeType` enum):
|
||
- `MODULE` — a Natural source file or Java class
|
||
- `FUNCTION` — Natural subroutine or Java method
|
||
- `VARIABLE` — local variable or parameter
|
||
- `DATA_STRUCTURE` — Natural `DEFINE DATA` block or Java DTO
|
||
- `DB_TABLE` — ADABAS view or SQL table
|
||
|
||
Edge types (`EdgeType` enum):
|
||
- `CONTAINS` — module contains function
|
||
- `CALLS` — function calls another function (call graph)
|
||
- `READS` / `WRITES` — function reads/writes a variable or DB table
|
||
- `USES_TYPE` — function or variable references a data structure
|
||
|
||
Full schema with Cypher examples: `@docs/ast-schema.md`
|
||
|
||
## API Design Principles
|
||
|
||
The API is designed primarily for AI agent tool use:
|
||
- Responses are concise and machine-readable JSON
|
||
- Each endpoint does exactly one thing — no overloading
|
||
- Errors return structured JSON: `{ "error": "...", "code": "...", "details": {} }`
|
||
- Pagination via `limit` + `offset` (default: limit=50)
|
||
- Priority endpoints to implement first:
|
||
- `GET /api/modules/{name}/callers` — who calls this module?
|
||
- `GET /api/modules/{name}/callees` — what does this module call?
|
||
- `GET /api/modules/{name}/db-accesses` — DB tables and access mode (READ/WRITE)
|
||
- `GET /api/search/identifier?name=...` — find an identifier across all modules
|
||
- `POST /api/ingest` — parse and ingest source code into the graph
|
||
|
||
Endpoint structure: `@docs/api-endpoints.md`
|
||
|
||
## Natural Parser: Key Constructs
|
||
|
||
**When implementing or extending `NaturalParser`, always use
|
||
`@ac-parser-natural/src/main/resources/natural-grammar.md` as the authoritative
|
||
reference** for Natural language syntax, statement variants, and edge cases.
|
||
|
||
The following Natural language constructs must be recognized (priority order):
|
||
|
||
1. `DEFINE DATA LOCAL/PARAMETER/GLOBAL` — data structure declarations
|
||
2. `PERFORM <subroutine>` — internal subroutine call (call graph)
|
||
3. `CALLNAT '<module>'` — external module call (call graph)
|
||
4. `READ/FIND/STORE/UPDATE/DELETE ... <view>` — ADABAS DB access
|
||
5. `DEFINE SUBROUTINE` / `END-SUBROUTINE` — function boundaries
|
||
6. `IF/ELSE/END-IF`, `FOR/END-FOR`, `REPEAT/END-REPEAT` — control flow
|
||
7. `MOVE`, `ASSIGN`, `COMPUTE` — variable assignments
|
||
|
||
Parser decisions and edge cases: `@docs/natural-grammar.md`
|
||
|
||
## Enrichment Pipelines
|
||
|
||
Enrichment runs as a separate phase after ingest:
|
||
|
||
```
|
||
Ingest → AST in Neo4j → EnrichmentPipeline.run() → enriched edges + properties
|
||
```
|
||
|
||
- `CallGraphEnricher`: resolves `PERFORM`/`CALLNAT` → `CALLS` edges
|
||
- `DbAccessEnricher`: extracts `READ`/`FIND`/`STORE` → `READS`/`WRITES` edges to `DB_TABLE`
|
||
- `IdentifierIndexEnricher`: indexes all variable nodes for cross-module search
|
||
- `DataStructureEnricher`: links `DEFINE DATA` blocks to the functions that use them
|
||
|
||
All enrichers implement `de.agenticcode.enrichment.spi.GraphEnricher` (single `enrich(String moduleId)` method).
|
||
|
||
Details: `@docs/enrichment-pipelines.md`
|
||
|
||
## Testing
|
||
|
||
- Unit tests: pure Java logic, no container, no Neo4j
|
||
- Integration tests: `@QuarkusTest` + Testcontainers Neo4j (annotated `@NaturalParserIT`)
|
||
- Parser tests: fixture files in `src/test/resources/fixtures/natural/` and `.../java/`
|
||
- No `Thread.sleep()` in tests — use Awaitility
|
||
|
||
```bash
|
||
# Unit tests only
|
||
mvn test -Dtest="*Test"
|
||
|
||
# Integration tests only
|
||
mvn test -Dtest="*IT"
|
||
```
|
||
|
||
## Key Decisions (ADR Summary)
|
||
|
||
| Decision | Rationale |
|
||
|---|---|
|
||
| Quarkus over Spring | Native build support, fast startup, CDI standard |
|
||
| Neo4j over relational DB | Call graphs and traversals are naturally graph problems |
|
||
| Multi-module Maven | Parsers are independently testable and replaceable |
|
||
| Custom Natural parser | No OSS parser available for Software AG Natural |
|
||
| JavaParser over tree-sitter | Mature Java library, type-safe AST API |
|
||
|