docs: extend AGENTS.md with conventions mined from PR reviews - #12352
Draft
julian-risch wants to merge 3 commits into
Draft
docs: extend AGENTS.md with conventions mined from PR reviews#12352julian-risch wants to merge 3 commits into
julian-risch wants to merge 3 commits into
Conversation
Our AGENTS.md documents the mechanics -- hatch, tests, mypy, release notes -- but none of the judgement reviewers actually apply. That knowledge lived only in review comments, so agents rediscovered it one review round at a time. This adds 122 rules mined with pydantic/braindump from 2,746 review comments written by the deepset team between 2025-07-01 and today, clustered and deduplicated across PRs so that only repeatedly-enforced conventions survive. Because the corpus is mostly Haystack 2.x era, rules were filtered against the current tree before inclusion: a git diff of v2.31.0..HEAD identifies the 75 symbols removed in 3.0, and any rule whose text depends on one is dropped or rewritten to its 3.x equivalent. No rule naming a removed API survives except the handful that deliberately warn against it. Each <!-- rule:N --> marker traces back to its source review comments. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Review feedback on the single-file version:
- Nested layout, as braindump generates it. Rules about tests, release notes and
the docs site now live next to the code they govern, so agents load them only
when work touches those directories. The root file drops 4,993 -> 2,789 tokens
(-45%) with more relevant guidance loaded per session, not less.
- CLAUDE.md now imports AGENTS.md via '@AGENTS.md'. Claude Code reads CLAUDE.md,
not AGENTS.md, and the previous prose ('read the AGENTS.md file...') only worked
if the model chose to act on it. The import inlines the content at session start.
Each directory with an AGENTS.md gets the same one-line CLAUDE.md, since nested
memory files are picked up lazily.
- Dropped the inline <!-- rule:N --> markers, ~11% of every file for traceability
nothing reads at runtime.
Rules removed:
- 'Use typing.Union[...] instead of | unions until Python 3.10+ is required'.
This was wrong and contradicted the rule three lines above it: requires-python
is already >=3.10, and 106 modules use PEP 604 unions against 12 using Optional[.
The staleness gate could not catch it -- it diffs symbols, and this is a
convention change with no symbol footprint.
- 'Revert review-rejected changes exactly', 'Compute values once per function and
reuse them', 'Delete lines explicitly marked to remove' -- generic developer
hygiene carrying no project-specific information.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
julian-risch
force-pushed
the
docs/agents-md-from-pr-reviews
branch
from
August 15, 2026 08:06
d535e11 to
0d8185a
Compare
…d rules The <!-- braindump:begin/end --> comments existed so the mined block could be replaced in place on a re-run. That anchor now lives in the generator instead, so the shipped files carry no scaffolding. Clustering preserves whichever example the source review comments happened to discuss, which leaves some rules reading as if they only apply to one class or path. Generalised, with the specific case kept only where it is illustrative: - 'preserve all runtime config, including Watsonx max_retries, ...' -> every constructor argument that affects runtime behaviour must round-trip. - 'use WATSONX_API_KEY for Watsonx components' -> default each Secret from the provider's conventional env var. WATSONX_API_KEY is one of ~10 such variables in this repo (COHERE_API_KEY, NVIDIA_API_KEY, JINA_API_KEY, ...). - 'preserve Elasticsearch bulk write/delete try/except behavior' -> preserve documented bulk write/delete error behaviour. DocumentStoreError is used by 17 document stores, not just Elasticsearch. - 'update ... Google GenAI model names and RagasEvaluator ragas.metrics.collections usage' -> refresh docstrings, cookbooks and integration docs when model names or provider APIs change. - 'especially in integrations/mcp/src/haystack_integrations/tools/mcp/' -> dropped the path; the warm_up() rule is repo-wide. - 'Assert ... in DocumentSplitter tests' and the RecursiveDocumentSplitter overlap rule -> stated for splitters generally; core ships 11 splitter classes. - Test-layout and pipeline-components docs rules trimmed to the convention. Removed: 'Update integrations/amazon_bedrock/tests/ with generator changes', which is entirely about one integration, and 'Label agents-1 docs sections clearly', which is vague and pinned to a Docusaurus slug. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Related Issues
Proposed Changes:
Our
AGENTS.mddocuments the mechanics — hatch, tests, mypy, release notes — but none of the judgement reviewers actually apply. That knowledge lives only in review comments, so contributor agents rediscover it one review round at a time.This adds 117 rules mined with pydantic/braindump (see Scaling open source with AI) from 2,746 PR review comments written by 14 deepset reviewers between 2025-07-01 and 2026-08-14. The hand-written sections of
AGENTS.mdare untouched; the mined rules follow underneath.Layout. Rules are split by scope rather than piled into one file, so agents load them lazily — only when work touches that directory:
AGENTS.mdtest/AGENTS.mddocs-website/docs/AGENTS.mdreleasenotes/notes/AGENTS.mddocs-website/AGENTS.mdhaystack/hooks/compaction/AGENTS.mdCLAUDE.mdbecomes a one-line@AGENTS.mdimport, and each directory with anAGENTS.mdgets the same. Claude Code readsCLAUDE.md, notAGENTS.md(docs), so the import is what puts the guidance in context. Codex and Cursor readAGENTS.mddirectly, so it stays the single source of truth.Verified with canary fixtures (
claude -p, file tools disabled so the model can only answer from loaded context):CLAUDE.md=@AGENTS.mdAGENTS.mdalone, noCLAUDE.mdAGENTS.mdon its ownCLAUDE.md= the old prose, tools disabledsub/CLAUDE.md=@AGENTS.md, cwd at root, after readingsub/thing.pysub/For fairness: with
Readenabled the old prose form did work — the model went and readAGENTS.mdin 3/3 runs. The import's advantage is that it is deterministic and costs no tool-call round-trip, not that the old form was broken.Pipeline: download → extract (1 LLM call per comment) → embed & cluster → dedupe → place → group → generate. 2,643 candidate generalisations collapsed into 442 deduplicated rules, of which 117 survived scoring and review. Rules seen in only one PR are penalised, so what remains is what reviewers say repeatedly.
Handling the 3.0 boundary. The corpus has to span 13 months to be large enough — only ~220 team review comments exist since 3.0 shipped on 2026-07-20 — so most of it is 2.x-era, and a naive run would tell agents to use
OpenAIGenerator. Rules were therefore filtered against the current tree before inclusion, deterministically rather than by asking a model:v2.31.0..HEADovergit ls-files(not the filesystem — the deleted component directories still exist on disk holding__pycache__) yields 75 removed symbols: 45 that moved tohaystack-core-integrations, 30 gone entirely.AsyncPipeline.stream()-style APIs, define, document and test the exact error semantics…" → "ForPipelinestreaming APIs, …".ToolInvokerandAsyncPipelineappear exactly twice in the file — in the two rules that warn against them.Five rules removed and nine generalised on review. Clustering preserves whichever example the source review comments happened to discuss, so several rules read as though they only applied to one class or path — e.g. "preserve all runtime config, including Watsonx
max_retries", or an assertion stated only forDocumentSplitterwhen core ships 11 splitter classes. Those now state the convention, keeping the specific case only where it illustrates it.Four of the removals were about rule quality rather than scope. One was a genuine defect: "Use
typing.Union[...]instead of|unions until Python3.10+is required" contradicted the rule three lines above it and is factually wrong —requires-pythonis already>=3.10, and 106 modules use PEP 604 unions against 12 usingOptional[. The staleness gate could not catch it: it diffs symbols, and this is a convention change with no symbol footprint. The other three ("Revert review-rejected changes exactly", "Compute values once per function", "Delete lines explicitly marked to remove") carry no project-specific information.How did you test it?
Markdown-only change, so no test suite applies. Verified instead:
ToolInvokerandAsyncPipelinein the two deliberate warnings.Notes for the reviewer
Checklist
I have added unit tests and updated the docstrings.— documentation-only change.docs:.I have added a release note file— not user-facing;AGENTS.mdis contributor documentation.🤖 Generated with Claude Code