chore(agents): consolidate agent context and compress instruction files - #5195
Conversation
Replace AGENT.md and .cursor/rules with a single AGENTS.md entry point plus CODEMAP.md, and cut duplicated guidance out of the instruction files. The same six non-negotiables were restated across seven files, so editing one .tsx under packages/ loaded ~36.8KB of instructions to say them four times over. Now ~28.7KB: generic React/Vitest material dropped, Fusion-specific patterns kept. Also corrects rules that were actively wrong: - vite plugins were documented as `fusion-framework-vite-plugin-*`; every one of them is `@equinor/`-scoped - the documented pre-PR gate `pnpm -w check` runs biome only, silently skipping fusion-lint; now `pnpm lint` - documentation.instructions.md applied to `**/*.md`, firing its retrieval-corpus rules on changesets and agent files Adds `pnpm verify:agent-context` plus a CI job so CODEMAP.md cannot drift from the real workspace, and contributing/fusion-lint.md for lint knowledge that previously lived only in agent memory. No changeset: nothing under packages/* or cookbooks/* is touched.
|
There was a problem hiding this comment.
Pull request overview
This PR consolidates AI agent guidance into a single entry point (AGENTS.md) and a new repository map (CODEMAP.md), removing duplicated/overlapping instruction sources and adding CI/script verification to keep the agent context accurate over time.
Changes:
- Introduces
AGENTS.md+CODEMAP.mdas the primary routing/orientation docs, and removes the legacyAGENT.mdand.cursor/rules/*delegation files. - Adds
pnpm verify:agent-contextplus a validating script and CI workflow to detect drift in the agent context inputs. - Tightens/retargets several instruction files (e.g.,
applyTonarrowing for documentation rules, updated validation gates topnpm lint) and adds contributor guidance forfusion-lint.
Reviewed changes
Copilot reviewed 30 out of 31 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| package.json | Adds verify:agent-context script for validating agent context drift. |
| contributing/fusion-lint.md | Adds contributor-facing documentation for fusion-lint behavior and how to satisfy rules. |
| CODEMAP.md | Adds repository topology, package map, routing hints, and canonical commands for agents/contributors. |
| AGENTS.md | Adds a single “entry point” doc that routes agents to the right instruction files. |
| AGENT.md | Removes the legacy agent entry point to eliminate duplication/drift. |
| .vscode/extensions.json | Adds shared extension recommendations (Biome, Fusion lint VS Code extension, Vitest, etc.). |
| .gitignore | Updates VS Code ignore rules to allow committing .vscode/extensions.json. |
| .github/workflows/copilot-setup-steps.yml | Adds a workflow to pre-provision Copilot agent environments (install/build). |
| .github/workflows/agent-context.yml | Adds CI verification for CODEMAP/instruction drift on relevant PR changes. |
| .github/scripts/verify-agent-context.mjs | Adds a script that validates CODEMAP/package map/instruction frontmatter/script references. |
| .github/prompts/release-recovery.prompt.md | Adds/updates a release recovery prompt for partial publish scenarios. |
| .github/prompts/changeset.prompt.md | Adds a prompt for authoring changesets based on branch diff. |
| .github/instructions/workflow-contribution.instructions.md | Updates workflow contribution guidance (notably the validation gate). |
| .github/instructions/testing.instructions.md | Compresses testing guidance and adds single-project run instructions. |
| .github/instructions/react.instructions.md | Compresses React guidance while retaining Fusion-specific patterns. |
| .github/instructions/pull-requests.instructions.md | Updates PR validation checklist to use pnpm lint. |
| .github/instructions/monorepo-structure.instructions.md | Updates monorepo structure docs and corrects Vite plugin naming/scoping guidance. |
| .github/instructions/documentation.instructions.md | Narrows applyTo to consumer-facing markdown (excludes internal md like changesets/instructions). |
| .github/instructions/cookbooks.instructions.md | Adds cookbook-specific rules (structure, linting exceptions, required checks). |
| .github/instructions/code-review.instructions.md | Adds explicit code review scope/cost rules for PR reviews. |
| .github/instructions/code-generation.instructions.md | Removes duplicated “non-negotiables” and keeps TS-specific guidance + fusion-lint intent rules. |
| .github/copilot-instructions.md | Compresses global Copilot instructions to only non-negotiables + routing pointers. |
| .cursor/rules/*.mdc | Removes Cursor-specific duplicated/delegation rule files. |
| .cursor/commands/dependabot.md | Removes Cursor command stub (delegation now via GitHub instructions). |
Suppressed comments (5)
CODEMAP.md:105
- The CLI plugin package map paths omit the
packages/prefix (e.g.cli-plugins/ai-base), but these packages live underpackages/cli-plugins/*. Update these entries to the real workspace paths.
| `@equinor/fusion-framework-cli-plugin-ai-base` | `cli-plugins/ai-base` | Shared AI plugin base |
| `@equinor/fusion-framework-cli-plugin-ai-chat` | `cli-plugins/ai-chat` | Interactive AI chat command |
| `@equinor/fusion-framework-cli-plugin-ai-index` | `cli-plugins/ai-index` | Embedding and chunking for the retrieval index |
| `@equinor/fusion-framework-cli-plugin-copilot` | `cli-plugins/copilot` | Copilot SDK evaluation plugin |
CODEMAP.md:75
- The React package map paths omit the
packages/prefix (e.g.react/framework), but the workspace usespackages/react/*. This will send readers/agents to the wrong location. Update these paths topackages/react/....
| `@equinor/fusion-framework-react` | `react/framework` | React framework provider and root hooks |
| `@equinor/fusion-framework-react-app` | `react/app` | React application host |
| `@equinor/fusion-framework-react-module` | `react/modules/module` | Hooks for consuming modules |
| `@equinor/fusion-framework-react-module-bookmark` | `react/modules/bookmark` | Bookmark hooks |
| `@equinor/fusion-framework-react-module-context` | `react/modules/context` | Context hooks |
CODEMAP.md:93
- The Utils package map paths omit the
packages/prefix (e.g.utils/observable), but the workspace usespackages/utils/*. This makes the code map’s paths invalid. Update these rows topackages/utils/....
| `@equinor/fusion-observable` | `utils/observable` | RxJS-based observable primitives and state |
| `@equinor/fusion-query` | `utils/query` | Reactive fetching and caching |
| `@equinor/fusion-log` | `utils/log` | Logging utilities |
| `@equinor/fusion-imports` | `utils/imports` | Import resolution helpers |
| `@equinor/fusion-load-env` | `utils/load-env` | `.env` loading |
CODEMAP.md:115
- The Vite plugin package map paths omit the
packages/prefix (e.g.vite-plugins/spa), but these packages live underpackages/vite-plugins/*. Update these rows so the code map points at real directories.
| `@equinor/fusion-framework-vite-plugin-spa` | `vite-plugins/spa` | SPA build/dev plugin |
| `@equinor/fusion-framework-vite-plugin-api-service` | `vite-plugins/api-service` | Service-discovery proxy and mocking |
| `@equinor/fusion-framework-vite-plugin-markdown` | `vite-plugins/markdown` | Markdown `?raw` imports |
| `@equinor/fusion-framework-vite-plugin-raw-imports` | `vite-plugins/raw-imports` | Generic `?raw` imports |
| `@equinor/fusion-framework-vite-plugin-routes-dsl` | `vite-plugins/routes-dsl` | `import.meta.resolve()` transform for route DSL |
CODEMAP.md:126
- The linting package map paths omit the
packages/prefix (e.g.linting/cli), but these packages live underpackages/linting/*. This makes the code map paths invalid. Update these rows topackages/linting/....
| `@equinor/fusion-lint` | `linting/cli` | `fusion-lint` CLI |
| `@equinor/fusion-framework-lint-core` | `linting/core` | Rule engine and diagnostic types |
| `@equinor/fusion-framework-lint-rules` | `linting/rules` | tree-sitter powered Fusion rules |
| `@equinor/fusion-framework-lint-config` | `linting/config` | Recommended presets |
| `@equinor/fusion-framework-lint-lsp` | `linting/lsp` | Language server |
| `fusion-ts-lint-vscode` | `linting/vscode` | VS Code extension |
The package map listed paths relative to `packages/` (`modules/http`), relying on the section heading for context. The CLI/tooling table mixed both styles in adjacent rows. Fully qualifying them also brings all ~50 paths under the existence check in verify-agent-context.mjs, which only inspects `packages/...` and `cookbooks/...` strings. They were previously invisible to CI; a typo now fails the build.
The repo's own non-negotiable is "pnpm only", but three documented commands used `npx vitest` or `npm view`. Verified both replacements work: `pnpm exec vitest run --project '*lint-core*'` runs 30 tests, `pnpm view <pkg> version` returns from the registry. Also corrects the project filter placeholder. Vitest project names are `<package-name>@<version>`, so a bare `'<name>'` never matches — it needs a glob.
Coverage Report
File CoverageNo changed files found. |
Why is this change needed?
Agent guidance had accumulated in three places at once —
AGENT.md,.cursor/rules/*.mdc, and.github/instructions/*— with the same rules restated in each. The six non-negotiables (noany, explicit return types, TSDoc on exports, scoped imports, pnpm only, function components with loading/error) appeared in seven files. Editing a single.tsxunderpackages/loaded ~36.8KB of instructions in order to say those six things four times over.Three of the rules had also drifted into being wrong, which is worse than verbose — an agent that follows a wrong rule writes broken code confidently.
What is the current behavior?
AGENT.mdand.cursor/rules/*duplicate.github/instructions/*, and drift independently.monorepo-structure.instructions.mddocuments vite plugins asfusion-framework-vite-plugin-*. Every one of them is@equinor/-scoped, so an agent following it writes an unresolvable import.pnpm test && pnpm build && pnpm -w check.checkisbiome checkonly, so the documented gate silently skipsfusion-lint.documentation.instructions.mdusesapplyTo: "**/*.md", firing its "write for the retrieval corpus, use exact exported symbol names" rules on changesets and on the agent instruction files themselves — where that advice does not apply.CODEMAP.mddid not exist, so agents fell back to whole-workspace semantic search to answer "where does this live".What is the new behavior?
AGENTS.mdroutes to the instruction file matching the files being touched.AGENT.mdand.cursor/rules/*are removed.CODEMAP.mddocuments the package map, task routing, and commands.useState,.mapwithkey, Arrange/Act/Assert); Fusion-specific patterns are kept in full — lazy providers,useObservableState+useMemo(EMPTY), theStyledobject, framework hooks, the context-throw pattern.pnpm verify:agent-contextplus a CI job fail the build ifCODEMAP.mddrifts from the real workspace.contributing/fusion-lint.mdcapturesfusion-lintbehaviour that previously existed only as agent tribal knowledge.What is the intended behavior or invariant?
Each rule is stated once, in the most specific file whose
applyTomatches. The global non-negotiables live in.github/copilot-instructions.md; per-domain files cover only what is specific to their domain and point at the global set rather than restating it.CODEMAP.mdstays in sync with the workspace by CI, not by good intentions.Does this PR introduce a breaking change?
No, for consumers. For contributors,
.cursor/rules/*are removed — Cursor readsAGENTS.md, which is the cross-tool standard and now the single source. Flagging it explicitly since it affects anyone who relied on the Cursor-specific rules.Impact assessment:
packages/*orcookbooks/*is touched; this is repo-internal markdown, CI, and one root script, whichworkflow-contribution.instructions.mdexplicitly exempts.Review guidance:
react.instructions.md(12.8KB → 7.9KB) andcode-generation.instructions.md(10.0KB → 6.8KB). I removed material a competent model already knows and kept anything Fusion-specific. If you think a deleted section was load-bearing, say so — that is the subjective part..cursor/removal is the other call worth a second opinion..gitignorenow uses.vscode/*with a!.vscode/extensions.jsonnegation. The directory-level.vscodepattern prevented git from descending far enough for a negation to work, so extension recommendations never reached anyone.verify-agent-context.mjswas tested in both directions: it passes clean, and injecting a wrong package count intoCODEMAP.mdproducesdeclares 99 framework packages but the workspace has 58.Additional context
Net effect on the always-on context budget: editing a
.tsxunderpackages/now loads ~28.7KB instead of ~36.8KB (−22%). Editing internal markdown loads ~5KB less, sincedocumentation.instructions.mdno longer fires there.Noticed but deliberately not fixed here, since it needs a changeset:
packages/utils/observable/package.jsonstill declares"lint": "eslint --ext .ts,.tsx,.js src/". There is no ESLint in this repo.Checklist
pnpm verify:agent-contextpasses,biome checkclean, both new workflows parse