Repository navigation
docs(agents): walk into package registrations when re-deriving #271 - #790
Conversation
AGENTS.md tells you to re-derive the single-serving-instance blocker list by walking every AddSingleton/AddHostedService under `src/`. That walk is structurally blind to a package's own registration extension: only the one-line call site lives in `src/`, and it looks like any other registration. Surfaced designing MCP support (#770). `WithHttpTransport` registers three singletons and an AddHostedService, unconditionally, from one call. Two of three independent reviewers followed the documented walk correctly and still concluded it adds no hosted service; only the one who read the package source got it right. The outcome was benign — the service is inert under SessionMode.Stateless — but that is luck, not method. Per the repo's own rule that two misses of the same shape mean the method is wrong, the defect is the walk's SCOPE. Adds the package step and a graphify recipe that answers it mechanically, with the two caveats that matter: read the version from packages.lock.json (the graph is of published source at a tag, not the restored assembly), and it needs the package to have public source. The stronger fix — a test asserting IHostedService descriptors against a reviewed inventory, which would catch a package UPGRADE changing registrations — is named in the decision record and left open.
|
@coderabbitai review Docs-only: an Two things worth your attention specifically:
|
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (2)
Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review. 📝 WalkthroughWalkthroughThe deployment-invariant guidance now includes service registrations made inside package extensions. The decision record documents package-source inspection, version matching, and a proposed service-collection test. ChangesPackage registration coverage
Priority: ⬇️ Low Estimated code review effort: 1 (Trivial) | ~5 minutes Change: Other · Severity of issue fixed: Low Merge Risk: ⚪ Minimal · up to This PR clarifies how to inspect package registrations without changing runtime behavior. No merge-blocking risk remains. 🚥 Pre-merge checks | ✅ 7✅ Passed checks (7 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
echo '--- PR diff: AGENTS.md and decision record ---'
git diff --unified=80 'origin/HEAD...HEAD' -- AGENTS.md docs/decisions/271-single-serving-instance.md || \
git diff --unified=80 HEAD^ HEAD -- AGENTS.md docs/decisions/271-single-serving-instance.md
echo '--- Current AGENTS.md relevant section ---'
rg -n -C 12 'single-serving|AddSingleton|AddHostedService|WithHttpTransport|package' AGENTS.md || true
echo '--- Current decision record relevant section ---'
rg -n -C 15 'How this list was derived|WithHttpTransport|IdleTrackingBackgroundService|published source|packages.lock' docs/decisions/271-single-serving-instance.md || true
base='https://raw.githubusercontent.com/modelcontextprotocol/csharp-sdk/v2.2.0'
echo '--- HttpMcpServerBuilderExtensions.cs at v2.2.0 ---'
curl --fail --silent --show-error \
"$base/src/ModelContextProtocol.AspNetCore/HttpMcpServerBuilderExtensions.cs" | \
nl -ba | sed -n '20,50p'
echo '--- IdleTrackingBackgroundService.cs at v2.2.0 ---'
curl --fail --silent --show-error \
"$base/src/ModelContextProtocol.AspNetCore/IdleTrackingBackgroundService.cs" | \
nl -ba | sed -n '1,220p'Length of output: 88916 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo '--- ModelContextProtocol.AspNetCore lock entries ---'
rg -n -C 5 '"ModelContextProtocol\.AspNetCore"' -g 'packages.lock.json' .
echo '--- WithHttpTransport call sites in source ---'
rg -n -C 8 '\.WithHttpTransport\s*\(' src
echo '--- PR changed files and whitespace check ---'
git diff --name-status 'origin/HEAD...HEAD' || git diff --name-status HEAD^ HEAD
git diff --check 'origin/HEAD...HEAD' || git diff --check HEAD^ HEAD
echo '--- HTTP transport mode configuration around call site ---'
rg -n -C 12 'HttpServerSessionMode|SessionMode|McpServer' srcLength of output: 956
I verified both package-source claims against
The revised ✅ Action performedReview finished.
|
PR #790 merged the AGENTS.md walk-scope amendment, so three places in this record that described it as raised-but-open are now wrong in the same way CodeRabbit caught last round: a document asserting a follow-up is pending when it has shipped. Rebased onto main so the claim is checkable against the merged wording.
🤖 I have created a release *beep* *boop* --- ## [0.1.1](v0.1.0...v0.1.1) (2026-09-12) ### Bug fixes * **dashboard:** give recent sales real columns and make both charts readable ([#781](#781)) ([7193ebe](7193ebe)) * **dashboard:** tell a day with no entry from a day that laid no eggs ([#791](#791)) ([48c10e5](48c10e5)) ### Documentation * **agents:** walk into package registrations when re-deriving [#271](#271) ([#790](#790)) ([5fab974](5fab974)) * **mcp:** record the MCP server design and what the spike got wrong ([#785](#785)) ([3fe5a7f](3fe5a7f)), closes [#770](#770) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). Co-authored-by: cluckwork-lockfix[bot] <309265648+cluckwork-lockfix[bot]@users.noreply.github.com>
AGENTS.mdtells you to re-derive the #271 single-serving-instance blocker list by walking everyAddSingleton/AddHostedServiceundersrc/. That walk cannot see a whole class of registration, and the wording currently reads as if it can.The gap
A NuGet package's own
IServiceCollectionextension registers services that never appear undersrc/. Only the one-line call site does, and it looks like any other registration.Surfaced while designing MCP support (#770).
ModelContextProtocol.AspNetCore'sWithHttpTransportregisters, unconditionally, from one call:Three singletons and a hosted service.
AGENTS.md's stated count ("19AddSingletoncall sites and 1AddHostedService") would stay unchanged while the live registrations changed.Two of three independent reviewers followed the documented walk correctly and still concluded "HTTP transport adds no
AddHostedService". Only the one who read the package source got it right. That is the tell: the method, not the reviewers.The outcome in #770 was benign —
IdleTrackingBackgroundService.StartAsyncreturns early underSessionMode.Stateless, so it is registered but inert, and the blocker list genuinely did not change. That is luck, not method.AGENTS.md's own rule says two misses of the same shape mean the method is wrong; this is a third shape, and it is the one the current wording cannot catch by construction.What changes
AGENTS.md— the walk now explicitly includes what each packageAdd*/With*extensionProgram.cscalls registers internally, with the recipe to answer it.docs/decisions/271-single-serving-instance.md— the narrative, added to the existing "How this list was derived, because it was twice derived wrongly" section, which is where it belongs.The recipe, tested
Output, verbatim — exactly the four registrations, with line numbers:
graphify merge-graphsalso works for cross-repo traversal (verified: 25,319 nodes, nodes namespacedrepo::/csharp-sdk::), but is not needed for the enumeration step and is not part of the documented recipe.Two caveats kept in the text deliberately
Both are load-bearing and easy to drop on a re-tell:
packages.lock.jsonrather than typing a branch, or the graph faithfully describes code that is not what restores.What this does NOT claim
No current blocker is missing and #271 is not violated. The walk was re-run for #770 and its conclusion held. The claim is narrower: the walk's scope cannot see this class of registration, so that conclusion holding was not guaranteed by the method.
Still open, deliberately not in this PR
The stronger fix is a test that builds the real service collection and asserts
IHostedServicedescriptors and singleton lifetimes against a reviewed inventory — the only form that catches a package upgrade changing registrations under an unchanged call site, which neither prose nor an on-demand graph query will. It has its own design question (what the inventory is keyed by — and perAGENTS.md, not byfile:line), so it is named in the decision record and left for a follow-up rather than bolted on here.Closes #786
Summary by CodeRabbit