


Change and Test Code in a Large Multi-Package Monorepo
Use when an AI works in a big framework repository with many packages. It maps the code before editing, keeps builds current, picks tests that match the CI mode, fixes CI failures before review comments, keeps secrets out of logs, and checks each change before calling it done.
To use this AI rule
## Find Packages and Entry Points Before Editing
- Identify the workspace layout, published packages, native components, test suites, examples, documentation, and maintenance scripts.
- Locate the primary package's source tree, compiled output, command-line entry points, server entry points, and build entry point.
- Trace the relevant entry point before changing behavior; do not infer ownership from a filename alone.
- Before editing a nested file, read every applicable `README.md` from the repository root through the target directory.
- Treat generated output and dependency directories as search-only evidence. Change their source or generator instead of editing generated files directly.
## Keep Build Output Current and Choose a Focused or Full Build
- After switching branches or bootstrapping an uncertain workspace, run the complete bootstrap build so dependent package outputs are current.
- For iterative source or integration-test work, start the package's watch build before editing unless it is already running.
- A docs-only change, read-only investigation, or CI-only analysis may skip watch mode, but record the reason.
- Use the focused package build when changes stay inside one package. Use the full build when work crosses packages or changes native code.
- For type errors, prefer the dedicated type check over a full build when it provides equivalent evidence.
- Stop any watch process you started after the task is complete.
## Pick Tests That Match Development or Production Mode
- Choose the test command that exactly matches development or production behavior and the intended bundler or runtime implementation.
- Rebuild the affected source before running integration tests; stale compiled output invalidates the result.
- Run the narrowest relevant test file or name pattern first, then expand only when the failure or change surface requires it.
- Reproduce CI with the same command, mode, feature flags, and environment-variable names. Small mode differences can change resolution and snapshots.
- Do not substitute a convenient unit test for an integration test when package resolution, bundling, startup, or browser behavior is part of the claim.
- When feature flags implicitly enable a behavior, test the normal suite with that flag instead of relying only on legacy dedicated suites.
## Write Tests That Wait for Conditions Instead of Fixed Sleeps
- Use the repository's test generator, including its non-interactive arguments, so fixtures and harness configuration follow local conventions.
- Prefer condition-based retry helpers with assertions over fixed sleeps. Fixed delays are slow and remain race-prone.
- Replace deprecated polling helpers with the supported retry-and-assert pattern.
- Prefer real fixture directories over large inline file maps so tests resemble actual projects and remain maintainable.
- For mode-specific tests, perform the mode guard before manually starting a server when the harness requires deferred startup.
- Control prefetching and navigation state inside the test's synchronization boundary; avoid history actions that restore cached state and trigger uncontrolled work.
## Save Test and Build Output Instead of Rerunning It
- Capture a test or build's complete output once, then search and summarize the saved output instead of rerunning the same suite with different filters.
- For files larger than roughly 500 lines, search for relevant symbols first and read only the surrounding ranges.
- Search generated directories only when necessary to confirm emitted behavior; do not browse them as primary source.
- Batch related edits before running the next build, and use the fastest check that proves the current hypothesis.
- Cache remote status responses during one investigation and analyze the saved response from multiple angles rather than fetching it repeatedly.
- Preserve the exact failing output, command, mode, and environment as evidence for the next diagnostic step.
## Reproduce CI Failures and Fix Them Before Review Comments
- Use the repository's status-analysis tool when one exists, and identify whether the current branch or an explicit change request is being examined.
- Address blocking failures in this order unless evidence dictates otherwise: build, formatting or lint, types, then tests.
- Treat failures as real until disproven. Known flaky behavior is context for investigation, not permission to dismiss a failure.
- Reproduce with the same CI mode and environment flags, especially when different bundlers or runtime paths are available.
- For module-resolution or build-graph failures, run the normal mode-specific integration command so the real package graph is exercised.
- Separate CI failures from review comments, resolve the blocking execution evidence first, and retain a concise record of what was reproduced.
## Wire Feature Flags Through Both Build and Runtime Code
- Add a new feature flag to its public type, validation schema, and build-time injection point when user-bundled code consumes it.
- If precompiled runtime code consumes the flag, also wire the runtime value through each relevant server or worker path.
- Do not assume build-time injection for user code controls precompiled runtime internals.
- Keep conditional module loads inside compile-time `if`/`else` branches so dead-code elimination can remove unreachable dependencies.
- In restricted runtimes, force flags guarding unsupported platform imports to `false`.
- Keep runtime-specific imports in their designated entry module and expose required behavior through that module's public facade.
- Use a dedicated runtime signal to distinguish a live development server from a debug build; a generic environment label may describe both.
- Flag any new nonstandard inbound request header for security review unless the entry layer strips or authenticates it.
## Keep Secrets Out of Logs and Stop When Authentication Fails
- Treat environment-variable values as sensitive unless they are documented test-mode flags.
- Never print, paste, commit, or place tokens, keys, cookies, or secret values in shared logs, review text, or examples.
- Mirror CI variable names and modes without inlining their values. If a required secret is absent, stop and ask for it through the approved channel.
- Use placeholders when documenting setup, and never commit local secret files.
- If source-control authentication fails because a signing agent, key provider, or hardware-backed credential is unavailable, stop and ask the user to unlock it.
- Do not change remote protocols or addresses, repeat the failing operation, or attempt an alternate authentication workaround without explicit approval.
## Check Permission Before Posting Change Requests or Comments
- Before creating or editing a remote change request, issue, discussion, or comment, determine whether the contribution comes from an internal branch or an external fork.
- Verify the repository's contribution policy and the user's authorization before writing on their behalf.
- If authorization is insufficient, do not impersonate a maintainer or publish full remote content. Offer technical facts, review user-written text, and point to the user-controlled submission path.
- Apply documented exceptions narrowly and only after their conditions are verified.
- Keep newly created change requests in draft state unless the user explicitly decides they are ready for review.
- Remote writes require explicit scope; local analysis and reproduction do not imply permission to publish.
## Split Work Into Small Steps and Check Each One
- Split a large task into small steps whose outputs can be checked independently.
- Verify each step before moving to the next with the method that matches its risk: inspection, formatting, lint, types, unit tests, integration tests, build, or runtime observation.
- When the correct verification method is unclear, ask before claiming the step is complete.
- Before committing, run the same formatter and linter configuration used by the repository's commit hook on the changed files.
- Review the final diff for unrelated edits, generated noise, secret material, and missing tests or documentation.
- Do not report completion without naming the evidence that supports the changed behavior.
## Catch Stale Native Binaries and Mismatched Snapshots
- Source-map lookup may require an explicit runtime flag, and source paths can differ between compilers; test the known path forms.
- Account for the current working directory when comparing stack traces from tests and production.
- After branch changes, suspect stale native binaries when behavior contradicts the source; refresh the dependency-managed artifact through the approved bootstrap path.
- For an internal compiler error, remove only the affected incremental compilation cache and retry once before escalating.
- Use the official formatter for native-language code, and prefer repository-rooted imports except inside tightly scoped inline test modules.
- Snapshot output can vary by flags and runtime implementation, so update snapshots only under the exact environment used by the target CI job.
- In documentation code blocks, recount displayed lines after edits and confirm every highlight points to the intended statement.
