


Edit a Multi-Module Backend and Frontend Repo Without Breaking the Build
Use when an AI edits a repo where the API, backend, and frontend live together. It reads each module's rules, keeps both sides in sync, regenerates the API client instead of hand-editing it, runs tests that fit the change, and asks before migrations or new dependencies.
To use this AI rule
## Start at the Repo Root and Load the Rules of Every Affected Module
Open and orchestrate the project from the repository root, even when a task appears limited to one subproject. Treat root-level agent instructions as the baseline and nested instruction files as additive local rules.
Before editing, identify every module the task can affect and load the instruction file for each one. A task that crosses modules must obey all relevant local rules, not only the file nearest to the first proposed change.
## Map What Each Module Owns and Change Backend and Frontend Together
Maintain an ownership map for the major areas:
- the public API module owns extension points, service contracts, and security abstractions;
- the backend application owns business logic, reactive services, routing, security, migrations, and packaging;
- the frontend workspace owns administrative and user interfaces, shared packages, and the generated API client;
- dependency-platform modules own constraints for the application and downstream extensions;
- developer documentation owns human-facing architecture and workflow guidance.
Treat backend and frontend changes as one full-stack task whenever contracts, payloads, authentication, navigation, or user experience cross the boundary. Keep public contracts, backend handlers, and frontend usage synchronized in the same change.
## Regenerate the API Client When the API Changes, Never Hand-Edit It
Assess frontend impact whenever public request or response types, routes, router contracts, API schema annotations, generated schemas, authentication, or session behavior changes. Regenerate the API description and client through the repository’s prescribed commands after updating the source contract.
Never edit generated client files directly. Correct the contract or generator input, regenerate the output, and review the resulting diff. Ask before making destructive changes to generated output or altering a public API that downstream consumers may depend on.
## Check How Frontend Output Is Packaged into the Backend Build
Understand how frontend output enters the deployable backend artifact. If the backend build embeds the compiled interface into application resources, every frontend output change also affects the backend packaging path and must be verified there.
Run cross-stack orchestration from the root so backend compilation, interface packaging, and tests use the same dependency graph. Treat build-time downloads, preset extensions, and copied distribution assets as part of the build contract rather than incidental files.
## Take Versions and Formatting Rules from Their Designated Files
Read dependency versions, the project version, language release, plugin versions, and frontend dependencies from their designated catalogs, properties files, build scripts, and package manifests. Do not hard-code a version that already has an authoritative source.
Use the configured formatter and linter as the source of truth for indentation, line width, and supported syntax. Honor the declared language release, including release 21 when specified, and keep root-level formatting rules in the scope where the build expects them.
## Keep Blocking I/O Out of Reactive Code and Keep Database Files in Place
Do not introduce blocking input or output into reactive execution paths, even when virtual threads are enabled elsewhere. Preserve the project’s selected migration engine instead of silently substituting another one, and keep dialect-specific migrations in their designated database directories.
Keep extension schemas, runtime JSON data, profile-specific configuration, and the overridable work directory in their owning locations. Use absolute file paths for embedded file-backed databases; a relative URI can create stray directories under the application module and change which database is opened.
## Pick Tests and Checks Based on Which Side of the Stack Changed
Select checks according to the actual scope:
- backend-only changes require repository formatting and the affected backend tests;
- frontend-only changes require frontend formatting, type checking, linting, and relevant unit tests;
- contract changes require API description generation, client regeneration, frontend validation, and backend tests;
- cross-stack changes require verification of the final packaged artifact as well as both sides of the contract.
Run the focused checks first, then broaden as needed. Add or update tests for every changed behavior, and do not submit work while required continuous-integration checks remain failing.
## Check the Right Upstream Before Pushing and Stage Only the Task's Files
Identify the current repository and inspect its remotes before pushing or opening a review. Target the correct upstream for that checkout; using the upstream of a related public or proprietary repository can be expensive to unwind.
Create work from the intended upstream base and use the repository’s branch conventions, such as `upgrade/gradle-X`, `feat/name`, `fix/name`, or `improvement/name`. Stage only the files belonging to the task; never use `git add -A` or `git add .` when build output or database artifacts may exist.
If a stale worktree locks the main branch, inspect the worktree list and remove only the confirmed stale entry explicitly. Do not use a broad cleanup as a substitute for identifying the exact lock owner.
## Ask Before Migrations or New Dependencies, and Never Commit Secrets
Use three levels of control:
- always work from the root, load every applicable nested rule, stage files explicitly, regenerate derived clients from source, add tests for changed behavior, and disclose AI-assisted material in the review description;
- ask before changing public APIs, adding build or package dependencies, writing database migrations, modifying security configuration or continuous-integration workflows, or destructively replacing generated output;
- never commit secrets, hard-code authoritative versions, add blocking operations to reactive paths, edit generated clients directly, or open a review without confirming the correct upstream.
These boundaries apply even when the implementation itself is straightforward. Ease of coding does not reduce compatibility, security, data, or release risk.
## Avoid Known Build Traps Like Relative Database Paths
Preserve known tool-specific invariants:
1. File-backed embedded database locations must resolve to absolute filesystem paths; relative path forms can create stray module directories and cause the application to open the wrong database.
2. A build-wrapper upgrade requires both the versioned wrapper command and a second wrapper-generation command; running only the first leaves generated wrapper files inconsistent.
3. Keep repository-wide miscellaneous formatting configuration at the root when moving it into an application submodule would combine incompatible formatter tasks and trigger implicit-dependency validation errors in build-tool version 9.x.
Record these pitfalls near the authoritative build guidance and verify them whenever the affected configuration changes.
