gravitee-api-management
AGENTS.md469 starsChanged 5 months agoApache-2.0View on GitHub
Plan non-trivial work before editing (see Planning), implement test-first (see Test-Driven Development), and self-review before finishing against the repository's review instructions (.github/instructions/code-review.instructions.md and the other files there that apply to your change); review others' changes against the same files. Where your tooling has its own process, follow it — it must still produce those three. Surface your assumptions and name competing interpretations rather than picking one silently; ask when the ask is unclear. For a hard bug or regression, build…
- Reads credentials
Where files are headingNew AGENTS.md files have more rules about keeping secrets out of the code, and fewer about code style.
Of the AGENTS.md files we read, the 31,542 first seen in the last six months, against the older ones: the kind of rule that gained most share, and the kind that lost most. About files like this in general, not this one, and an estimate, since a kind is a pattern in the words.
In this repository31 other files it gives its agents.
- .ai/AGENTS.mdAGENTS.md
- gravitee-apim-common/AGENTS.mdAGENTS.md
- gravitee-apim-console-webui/AGENTS.mdAGENTS.md
- gravitee-apim-definition/AGENTS.mdAGENTS.md
- gravitee-apim-distribution/AGENTS.mdAGENTS.md
- gravitee-apim-gateway/AGENTS.mdAGENTS.md
- gravitee-apim-plugin/AGENTS.mdAGENTS.md
- gravitee-apim-portal-webui/AGENTS.mdAGENTS.md
- gravitee-apim-portal-webui-next/AGENTS.mdAGENTS.md
- gravitee-apim-reporter/AGENTS.mdAGENTS.md
- gravitee-apim-repository/AGENTS.mdAGENTS.md
- gravitee-apim-rest-api/AGENTS.mdAGENTS.md
- .ai/CLAUDE.mdCLAUDE.md
- CLAUDE.mdCLAUDE.md
- gravitee-apim-common/CLAUDE.mdCLAUDE.md
- gravitee-apim-console-webui/CLAUDE.mdCLAUDE.md
- gravitee-apim-definition/CLAUDE.mdCLAUDE.md
- gravitee-apim-distribution/CLAUDE.mdCLAUDE.md
- gravitee-apim-gateway/CLAUDE.mdCLAUDE.md
- gravitee-apim-plugin/CLAUDE.mdCLAUDE.md
- gravitee-apim-portal-webui/CLAUDE.mdCLAUDE.md
- gravitee-apim-portal-webui-next/CLAUDE.mdCLAUDE.md
- gravitee-apim-reporter/CLAUDE.mdCLAUDE.md
- gravitee-apim-repository/CLAUDE.mdCLAUDE.md
- gravitee-apim-rest-api/CLAUDE.mdCLAUDE.md
- .cursor/rules/graphene.mdCursor rule
- .cursor/rules/graphene-snippets/context-sidebar-detail-page.tsxCursor rule
- .cursor/rules/graphene-snippets/creation-wizard-page.tsxCursor rule
- .cursor/rules/graphene-snippets/data-table-list-page.tsxCursor rule
- .cursor/rules/graphene-snippets/json-schema-form-simple.tsxCursor rule
- .cursor/rules/graphene-snippets/json-schema-form-with-meta.tsxCursor rule
The file
Show its rules and text
We split this AGENTS.md into the rules it gives an agent
23 rules. About 0 are common, 16 are distinctive, and 7 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈16
Distinctive · estimate
This author's own choices. Worth a look.
7
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 25
Don't delete pre-existing dead code unless asked.
- Distinctive: line 37
No dead code: after a change, remove the fields, methods, imports, and parameters it left unused.
- Distinctive: line 42
Ask of every comment, in order:
- Distinctive: line 53
Prefer deep modules — a simple interface hiding substantial behaviour — over shallow pass-throughs.
- Distinctive: line 60
Prefer small, logically-scoped commits over one large commit.
- Very specific: line 62
Never bypass hooks (--no-verify) or skip signing unless explicitly asked.
- Distinctive: line 63
Create new commits rather than amending.
- Distinctive: line 67
Use US English for comments, log messages, and user-facing strings (UI copy, API error messages, operator-facing documentation).
- Very specific: line 76
Never commit, print, log, return, paste, or summarise secrets, credentials, tokens, private keys, real .env values, or unnecessary …
- Distinctive: line 80
Do not disable, skip, silence, or loosen security checks, tests, scanners, audit logging, redaction, or CI enforcement unless explicitly …
- Distinctive: line 83
If a change intentionally accepts a security risk, state the risk, the mitigation, and the owner.
- Distinctive: line 87
Write the failing test before the production code: RED → GREEN → REFACTOR.
- Distinctive: line 89
Use real instances over mocks for pure logic (no network, DB, or filesystem).
- Very specific: line 104
Use gravitee-apim-bom for dependency alignment in Maven projects that belong to this product.
- Distinctive: line 123
Layering: keep definition and plugin handler separate from Gateway execution and from Console / Portal UI — do not reach from management …
- Very specific: line 127
When adding or changing HTTP endpoints under gravitee-apim-rest-api/:
- Distinctive: line 140
Do not hand-write DTOs that duplicate generated models or start from JAX-RS before generation has run.
- Very specific: line 145
Local verification: after building standalone Gateway and REST API distributions (gravitee-apim-distribution), copy the zip into both …
- Very specific: line 152
Use specific, actionable keys ("CORS_PREFLIGHT_FAILED") and messages that tell the operator what condition or limit was hit.
- Distinctive: line 171
Stop and name the owned files the task would touch, and why.
- Distinctive: line 172
Leave them unchanged; finish the rest of the task if it stands on its own.
- Distinctive: line 173
Add an Automation API / CRD impact section to the PR description listing the owned files and the change they need, and tell the person to …
- Very specific: line 197
Before working on files under any of these directories, read that directory's AGENTS.md first: gravitee-apim-common/, …
≈ “Common” is an estimate: at least 1 in 5 of the 40,246 AGENTS.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
<!--
Generated by gravitee-ai. Do not edit directly.
Edit the source rules and re-run: gbuddy setup
Source rules:
- context/rules/global/agentic-workflow.md
- context/rules/global/debugging.md
- context/rules/global/engineering.md
- context/rules/global/git.md
- context/rules/global/language.md
- context/rules/global/planning.md
- context/rules/global/security.md
- context/rules/global/tdd.md
- context/rules/products/apim.md
- .ai/rules/apim-automation-api.md
- .ai/rules/apim-two-reactors.md
-->Agentic Workflow
Plan non-trivial work before editing (see Planning), implement test-first (see Test-Driven Development), and self-review before finishing against the repository's review instructions (.github/instructions/code-review.instructions.md and the other files there that apply to your change); review others' changes against the same files. Where your tooling has its own process, follow it — it must still produce those three. Surface your assumptions and name competing interpretations rather than picking one silently; ask when the ask is unclear.
Surgical changes
- Touch only what the task requires; don't refactor, reformat, or "improve" unrelated code. Match the existing style even where you would choose differently.
- Don't delete pre-existing dead code unless asked.
- Surface unrelated issues you notice instead of silently fixing them in the same change.
Debugging
For a hard bug or regression, build a fast, deterministic pass/fail loop that reproduces the reported failure before hypothesising — raise a flaky failure's reproduction rate until it is debuggable, minimise the failing case, and test one instrumented hypothesis at a time — and if you genuinely cannot build a loop, say so and ask for an environment or artifact instead of guessing. Fix the root cause, not the symptom, and turn the reproduction into a permanent test (see Test-Driven Development); a debugging skill, where one is installed, carries the method: a ranked list of ways to construct the loop, and how to sharpen it.
Engineering Conventions
Clean code
- Explicit imports — no fully-qualified names in bodies.
- No dead code: after a change, remove the fields, methods, imports, and parameters it left unused.
- Validate and fail loudly at system boundaries (user input, external APIs, parsing, real I/O). Inside trusted internal code, don't add handling for scenarios that genuinely can't happen — and never use that as a reason to skip boundary handling.
Comments
Ask of every comment, in order:
- Does it restate what the code does? Rename or extract instead — the code is the problem.
- Does it defend the change rather than explain the code? It belongs in the commit message.
- Does it explain why the code is as it is — a constraint, an invariant, an alternative that looks right and is wrong? Keep it, as briefly as it can be said.
On code you are changing, delete any comment that answers yes to 1 or 2; one that answers no to all three was not worth writing. Public-API documentation (javadoc, docstrings) follows its own standard and is out of scope here.
Design
- Apply SOLID — single responsibility, open/closed, Liskov substitution, interface segregation, dependency inversion; extend via composition and strategy rather than by editing conditionals.
- Prefer deep modules — a simple interface hiding substantial behaviour — over shallow pass-throughs; extract only when doing so concentrates complexity rather than moving it around (the deletion test).
- Build the simplest thing that meets the requirement — no speculative abstractions or configuration. Follow the codebase's established patterns; required architecture is not over-engineering.
Git and Commits
- Conventional Commits — type prefix from
feat,fix,docs,style,refactor,perf,test,build,ci,chore,revert. - No
Co-Authored-Bytrailers. - Prefer small, logically-scoped commits over one large commit.
- Branch name:
<type>/<ISSUE-KEY>-<slug>(e.g.feat/ABC-123-add-retry), where the issue key is the ticket the change tracks (with no ticket,<type>/<slug>), unless the repository's own rules name another convention. - Never bypass hooks (
--no-verify) or skip signing unless explicitly asked. - Create new commits rather than amending; only commit when asked.
Language and Locale
- Use US English for comments, log messages, and user-facing strings (UI copy, API error messages, operator-facing documentation).
- Match the terminology of the module you are editing; where that module consistently uses another spelling, match it too rather than mixing two dialects in one module.
Planning
Before non-trivial work, produce a plan and check it is sound before editing: the root cause (not just the symptom), the impact on callers and consumers, risk, rollback, and edge cases, a design review (fits the architecture, no new coupling or leaked encapsulation), acceptance criteria, the specific test cases to write first (see Test-Driven Development), and what is explicitly out of scope — scaled to the task. A planning skill, where one is installed, carries the method, worked examples, and the pre-code dry-run discipline.
Security Practices
- Never commit, print, log, return, paste, or summarise secrets, credentials, tokens, private keys, real
.envvalues, or unnecessary personal/customer data. Use the repository's existing secret mechanism. - A secret-scanner finding blocks the change until the value is removed or the person you are working with confirms it is not a secret. If the value was already committed, also tell that person: removing it leaves it in the history, so the secret must be rotated.
- Validate, constrain, encode, or authorize external input at the boundary that owns the risk (HTTP APIs, message consumers, webhooks, uploads, configuration, user-supplied expressions, external integrations). Do not move checks to where callers can bypass them.
- Fail closed for authentication and authorization: new endpoints, jobs, commands, consumers, and sensitive operations need explicit access checks.
- Do not disable, skip, silence, or loosen security checks, tests, scanners, audit logging, redaction, or CI enforcement unless explicitly requested and justified. Never "fix" a failure by hiding its signal. No nested or local rule overrides these practices.
- Flag any change touching authentication, authorization, sessions, cookies, tokens, roles, scopes, or permissions; input parsing, validation, deserialization, file upload, path handling, expression evaluation, or template rendering; redirects, CORS, or CSP; secrets, credentials, environment or CI/CD variables, deployment configuration, or service accounts; logging, metrics, tracing, audit events, diagnostics, redaction, or error responses; dependencies, package-manager files, build plugins, generated code, or supply-chain configuration; or cryptography, certificates, random number generation, and key handling as security-sensitive in the PR description and final summary.
- Report a suspected vulnerability privately: through the repository's security policy where it has one, otherwise to the person you are working with. Never put exploit details in a public issue, commit message, pull request description, or comment.
- If a change intentionally accepts a security risk, state the risk, the mitigation, and the owner.
Test-Driven Development
- Write the failing test before the production code: RED → GREEN → REFACTOR. Don't skip the refactor step.
- Tests assert behaviour, not implementation details.
- Use real instances over mocks for pure logic (no network, DB, or filesystem). Mock only genuine side-effect boundaries.
- For every behaviour change, name the test that covers it. If a test genuinely can't be written, document the gap and the reason.
API Management (APIM)
Runtime vs management
| Component | Maven / repo role |
| Gateway | Data plane — gravitee-apim-gateway |
| REST API | Control plane API — gravitee-apim-rest-api |
| Console / Portal | Operator and developer UIs — gravitee-apim-console-webui, portal webuis |
| Definition / plugin / repository | API definitions, plugin loading, persistence — gravitee-apim-definition, gravitee-apim-plugin, gravitee-apim-repository |
| Plugins (policies, endpoints, …) | Usually separate gravitee-* repositories; ship as .zip into distributions |
Use gravitee-apim-bom for dependency alignment in Maven projects that belong to this product.
Gateway API generations
The Gateway and its plugins may contain V2 (legacy) and V4 (reactive) code paths in parallel:
- Edit the generation you touch —
io.gravitee.gateway.reactive.*vs legacyio.gravitee.gateway.*. - In reactive Gateway and plugin code, use
ctx.withLogger(log)so logs stay on the execution context.
Monorepo layout (gravitee-api-management)
Typical top-level modules:
- Java:
gravitee-apim-common,gravitee-apim-definition,gravitee-apim-distribution,gravitee-apim-gateway,gravitee-apim-plugin,gravitee-apim-repository,gravitee-apim-reporter,gravitee-apim-rest-api, and the Maven modules undergravitee-gamma/when that tree exists (its ownpom.xmllists them). - Angular:
gravitee-apim-console-webui,gravitee-apim-portal-webui-next,gravitee-apim-webui-libs/*.
Optional gravitee-gamma/ trees are Gamma management plugins on the Management API — they are not Gateway runtime; the product: gamma rules apply only when this repo's .ai/manifest.yaml declares gamma.
- Local full stack: service layout, ports, and compose definitions live in
CONTRIBUTING.adoc, section AI Agent Context (Docker Compose Full Stack) — do not invent alternatives. - Layering: keep definition and plugin handler separate from Gateway execution and from Console / Portal UI — do not reach from management resources or UI code into Gateway internals.
Management API: API-first (OpenAPI before JAX-RS)
When adding or changing HTTP endpoints under gravitee-apim-rest-api/:
| Area | Module path (under gravitee-apim-rest-api/) | OpenAPI spec(s) |
| Management API v2 | gravitee-apim-rest-api-management-v2/gravitee-apim-rest-api-management-v2-model (JAX-RS resources: the sibling -rest module) | src/main/resources/openapi/openapi-*.yaml (split by area) |
| Kafka Explorer | gravitee-apim-rest-api-kafka-explorer | src/main/resources/openapi/openapi-kafka-explorer.yaml |
| Portal API | gravitee-apim-rest-api-portal/gravitee-apim-rest-api-portal-rest | src/main/resources/portal-openapi.yaml |
| Automation API | gravitee-apim-rest-api-automation/gravitee-apim-rest-api-automation-rest | src/main/resources/open-api.yaml |
- Edit the correct OpenAPI file (paths, operations,
components.schemas). - Compile the module so
openapi-generator-maven-plugingenerates models (generateModels=true,generateApis=false):mvn -pl gravitee-apim-rest-api/<module> -am compile—-ambuilds upstream modules first, so it works on a fresh checkout. - Implement or update JAX-RS resources and mappers using the generated
io.gravitee.rest.api.*.model.*types.
Do not hand-write DTOs that duplicate generated models or start from JAX-RS before generation has run.
External plugins
- Package:
target/gravitee-<type>-<name>-<version>.zip. - Local verification: after building standalone Gateway and REST API distributions (
gravitee-apim-distribution), copy the zip into both standaloneplugins/directories (Gateway and Management API) before exercising management + runtime together.
Operator-visible Gateway behaviour
Policy and connector diagnostics (Diagnostic, warnWith, interruptWith) surface in the Console — treat keys and messages as product UX, not only log lines.
- On reactive paths,
ctx.interruptWith()stops the request flow;ctx.warnWith()reports without interrupting. Attach.cause(e)to theExecutionFailureorExecutionWarnwhen an exception is available. - Use specific, actionable keys (
"CORS_PREFLIGHT_FAILED") and messages that tell the operator what condition or limit was hit.
Automation API, CRD and Terraform Ownership
The Automation API, the CRD import/export path and the Terraform export are a public contract consumed by the Kubernetes operator (GKO) and the Terraform provider. An Automation PUT replaces the whole definition, so a field dropped on the write or the read path resets user configuration on every apply. This surface is owned by @gravitee-io/gko and @gravitee-io/tech-lead.
Owned surface:
| Area | Paths |
| Automation API | everything under gravitee-apim-rest-api/gravitee-apim-rest-api-automation/ — the open-api.yaml spec, mappers, resources, HRID helpers, Gamma automation ports |
| CRD models and use cases | under gravitee-apim-rest-api/, every class whose name contains CRD and every model/crd/ package — core models, Import*/Validate*/Export* CRD use cases and domain services, the hand-written Management API v2 *CRD* classes and mappers, ApiCRDEntity |
| CRD endpoints | _import/crd and _export/crd in Management API v2; crd and import-crd in Management API v1 |
| CRD and Terraform export UI | gravitee-apim-console-webui/src/management/api/general-info/api-general-info-export-v4-dialog/ |
CODEOWNERS requests the owning teams on the automation module, the *CRD* classes, the model/crd/ packages and the export dialog. The CRD endpoint methods sit in shared resource classes, so only this rule and the review rule cover them.
Do not create, edit, rename or delete a file on the owned surface unless the person you are working with confirms the owning team requested the change; when they do, the PR description says so in one line under Automation API / CRD impact. Otherwise, before editing:
- Stop and name the owned files the task would touch, and why.
- Leave them unchanged; finish the rest of the task if it stands on its own.
- Add an Automation API / CRD impact section to the PR description listing the owned files and the change they need, and tell the person to raise it with the owning team.
The same hand-off applies when a change outside the surface alters what the surface exposes: a v4 API definition model (gravitee-apim-definition), a Management API v2 schema property or enum value, or a repository entity field surfaced through Management API v2. Do not mirror it into the Automation API or the CRD classes; record it in the PR description's impact section. The owning team's mirroring procedure is .ai/guides/automation-api-sync.md.
Dry run. GKO's admission webhook admits a resource on the answer of a dry run (dryRun=true on an Automation PUT or on _import/crd), then reconciles it with the same request without dryRun. Never give a dry run validation of its own: put every check the write runs, the service's own checks included, in one method that both the dry run and the write call, and skip only the write and its side effects (deployment, events, audit). Test it by sending the same invalid request with and without dryRun and expecting the same error.
APIM Two Maven Reactors
This repository holds two independent reactors:
- the product reactor, at the root — the engine and the libraries;
- the distribution reactor, under
gravitee-apim-distribution/— the assembly that produces the Docker images, the bundle and the RPM. It is not a module of the root pom.
Consequences for any Maven command:
- A root
mvn clean installbuilds the engine and stops there. It does not refreshtarget/distribution, the folder run configurations use asGRAVITEE_HOME. mvn -pl gravitee-apim-distribution/…from the root fails with Could not find the selected project in the reactor. Use-f gravitee-apim-distribution/pom.xml; inside that reactor,-plpaths are relative to it.- Building the distribution takes two phases: install the engine first, then assemble against it.
task build-quickdoes both. - After a
clean installfails or is interrupted (especially with-T, parallel reactor builds), a later scopedmvn test/mvn -pl <module> testwithoutcleansilently compiles against staletarget/classesleft by modules that never finished rebuilding — producing "cannot find symbol"/"constructor cannot be applied" errors that look like a broken annotation processor (e.g. Lombok) but aren't. Re-run a fullclean installcovering every changed reactor module before trusting a scoped test run.
The distribution assembles the pinned released core unless -Dapim.core.version=<root triplet> is passed. Leaving it out does not fail — it produces a distribution without the change under test. task build-distribution passes it for you, and task which-engine prints which core actually got bundled.
Modules
Before working on files under any of these directories, read that directory's AGENTS.md first: gravitee-apim-common/, gravitee-apim-console-webui/, gravitee-apim-definition/, gravitee-apim-distribution/, gravitee-apim-distribution/gravitee-apim-distribution-integration-tests/, gravitee-apim-gateway/, gravitee-apim-plugin/, gravitee-apim-portal-webui/, gravitee-apim-portal-webui-next/, gravitee-apim-reporter/, gravitee-apim-repository/, gravitee-apim-rest-api/, gravitee-apim-webui-libs/gravitee-dashboard/, gravitee-apim-webui-libs/gravitee-kafka-explorer/, gravitee-apim-webui-libs/gravitee-markdown/, gravitee-gamma/gravitee-gamma-control-plane-webui/, gravitee-gamma/gravitee-gamma-definition-model/, gravitee-gamma/gravitee-gamma-module-apim/, gravitee-gamma/gravitee-gamma-module-platform/, gravitee-gamma/gravitee-gamma-module-portals/, gravitee-gamma/gravitee-gamma-plugin/, gravitee-gamma/gravitee-gamma-rest-api/, .ai/, gravitee-apim-rest-api/gravitee-apim-rest-api-automation/.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

