docs(src): one-line XML docs, no docs on internal members #184
No reviewers
Labels
No labels
breaking-change
bug
documentation
duplicate
enhancement
good first issue
help wanted
performance
question
wontfix
No milestone
No project
No assignees
4 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Grandiras/ATProto.NET!184
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "debloat-f-docs"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Part of #180 (pass F: XML docs).
What changed
Applies the lean doc rule ("Keep CS1591 everywhere. Apply the lean doc rule instead") across
src/**, outside the files Pass D (shared primitives) owns.src/ATProtoNet/Lexicon/**(models and clients). Collapsed 475 multi-line<summary>blocks that were just word-wrapped prose into the single physical line the rest of the codebase already uses for one-thought summaries (matching the convention inAtProtoClient.cs,Http/*.cs, etc.). The 4 blocks with genuine multi-paragraph<para>rationale (the chat client class docs) were left alone. Also fixed 53 public property docs that were pure restatements of the declared name ("The actors.","The name.", …): the ~31 that are the wire-facing twin of aCursorPage<T>.Itemsoverride now say"This page's X."(real information the name/type didn't carry — that it's paginated); the rest got a one-line, context-specific description (e.g."The list's display name.","The list the page's members belong to.").Internal/private XML docs, everywhere in scope. Found and processed 574
///doc blocks on members whose effective accessibility is internal or private — includingpublic/protectedmembers of aninternal/privateenclosing type, which the compiler also doesn't require docs for. ~93 were pure boilerplate ("Request body for X.", "Response from X.", with nothing else) and were deleted outright; the rest were converted to plain//comments, stripping the XML tags to plain prose (<see cref>/<paramref>/<c>unwrapped,<param>/<returns>/<exception>folded into labeled lines) so the rationale survives without pretending to be public API documentation. Bare<inheritdoc/>with no other content was dropped entirely (7 cases —Validate()overrides and similar).This pass is intentionally conservative about what counts as internal: a scanner tracks brace-depth and container kind (interface/enum members are implicitly public and were left alone; class/struct/record members with no explicit modifier are implicitly private) so
publicmembers nested in aninternaltype are caught without false-flagging real public API or interface/enum members.Duplicated rationale outside Pass D's files. Checked that Pass A's stream-contract consolidation (
EventStreamLoop/StreamConsumerOptions) and Pass B's replay-store consolidation (IJtiReplayStore) are intact — they are, and nothing needed redoing. Found and fixed one more case:MessageRecordEmbedView.Record(chat.bsky) repeatedRecordEmbedView.Record's (app.bsky) sentence verbatim, since both wrap the exact sameEmbeddedRecordViewunion; it now uses<inheritdoc cref="RecordEmbedView.Record"/>, a pattern already used elsewhere in this codebase (PdsAdminClient.cs,XrpcClient.cs).What was left alone, and why
With*PdsAsyncextension methods share a couple of sentences inside otherwise-different<remarks>paragraphs; two stream consumers'LastSeqproperties are identical). These weren't extracted:<inheritdoc>'spathfilter would fragment already-careful prose for a few lines saved.LastSeqproperties each contain a self-referencing<see cref="ConsumeAsync"/>— using<inheritdoc>across the two sibling classes would carry acrefthat the compiler pre-resolves to the source type's method, silently pointing at the wrong type in generated docs. Not worth the correctness risk for two short properties.Unknown*union variant boilerplate, sibling<param>docs,DbContextconstructor boilerplate) is either the established per-type pattern for CS1591 (each type needs its own summary; the interface it implements,IUnknownUnionVariant, is a Pass D file) or standard per-overload/per-context<param>text that isn't practically shareable through XML doc tooling.~200 lineestimate for the Lexicon summary collapse turned out low once "leftover docs that restate names" was in scope too; the actual change is larger (net ~2000 fewer doc/comment lines) because it also covers the client-method and class-level summaries, not just DTO properties, and because the internal/private sweep (item 2) touched far more ofsrc/**than justLexicon/.Verification
git diff -U0 origin/main, and for every changed line in a.csfile requires it to be blank,//,/*,*/, or inside a block comment. Result: 0 non-comment changed lines across all three commits.loc.py origin/main HEAD: code lines unchanged (26,951 → 26,951, confirming comment-only). XML-doc lines 14,694 → 11,415 (−3,279). Plain//comment lines 871 → 2,159 (+1,288, from the internal/private conversions). Net doc+comment lines: 15,565 → 13,574 (−1,991).dotnet build -p:EnableSourceControlManagerQueries=false— 0 warnings, 0 errors (CS1591 still an error and satisfied).dotnet test tests/ATProtoNet.Tests/ -p:EnableSourceControlManagerQueries=false— 5000 passed, 0 failed, 5 skipped (Aspire manifest tests, pre-existing skip condition), run in Release-equivalent config both mid-pass and at the end.Deferred
Nothing from this pass's assigned scope was deferred. The near-duplicates noted above under "what was left alone" were evaluated and deliberately not touched, not skipped for lack of time.
🤖 Generated with Claude Code
🤖 Reviewing this PR — the review will link the full session transcript.
📜 Live transcript — updating every ~5 minutes while the review runs.
⏳ Held on the OpenCode Go window — the 5-hour window is at 0% (the bot holds at 95%).
This continues automatically after the window resets (2026-09-27T21:56:02.846Z) — nothing to re-trigger.
Comment-only check, run by the orchestrator over
git diff -U0 origin/main...HEAD -- '*.cs': 5,591 changed lines, 0 outside comments or blank lines. No non-.cs files changed. Release build: 0 warnings, with CS1591 still an error and satisfied. 5,000 unit tests pass.@claude /review, please. The diff is large but touches comments only (checked above), so please don't read all of it. Spot-check a sample of files for three things:
//. Look atRepo/,Streaming/,Auth/andServer/internals.<inheritdoc>or<see cref>targets that resolve to the wrong member.🤖 Reviewing this PR — follow along in the action run; the reply will link the full session transcript.
📜 Live transcript — updating every ~5 minutes while the task runs.
💬 Verdict: comment — notes only, nothing blocking.
This is a large, mechanical, comment/doc-only pass, and the diff shown is consistent with that claim: every hunk touches only
///XML doc blocks being either collapsed to one line (public Lexicon members, not shown in this truncated diff) or converted to plain//comments (internal/private members). The internal/private detection logic described (tracking brace depth and container kind) appears correctly applied to the samples visible here — e.g.KeyedLock<TKey>.Lease.Dispose()/DisposeAsync()andSessionManager.BeforeSendAsync/TryRecoverAsynccorrectly lose their bare<inheritdoc/>because the enclosing types are internal, so CS1591 never required docs there.One small inconsistency: in
src/ATProtoNet/Auth/OAuth/DPoP.cs, the conversion strips<see cref>and<c>tags into plain prose everywhere, but leaves<see href="...">...</see>tags un-stripped in two places, producing raw pseudo-XML inside a plain//comment (worse than the original doc, which at least rendered as a link, and inconsistent with the PR's own stated tag-handling rules). Not a functional issue, just a leftover from the conversion script not handling thehrefvariant of<see>.Nothing else in the visible diff looks like an accidental code change, a misattributed doc comment, or a case where a doc that should have been public documentation got stripped as if internal. Given this is verified comment-only (per the PR's own script and
loc.py), the CHANGELOG exemption for comment-only changes applies correctly.⏱ 0m 53s · 1 turns · tokens: 72.9k in / 4.9k out (+23.9k cache-read)
📜 Full session transcript
@ -6,31 +6,27 @@ using System.Text.Json;namespace ATProtoNet.Auth.OAuth;The
<see href="...">RFC 9449</see>tag is left intact inside a plain//comment instead of being unwrapped to plain text, unlike<see cref>/<c>elsewhere in this same conversion pass (e.g. theThumbprintdoc just below strips<c>crv</c>etc. but leaves its own<see href="...">RFC 7638</see>untouched too). Minor, but produces a comment with stray markup rather than the plain prose the rest of the pass aims for.@claude /review, please re-review. A new commit fixes your note: the two
<see href="…">RFC …</see>tags left in plain//comments inDPoP.csnow read "RFC 9449 (https://…)". A repo-wide grep finds no other XML markup (<see,<c>,<paramref) in//comments, and the change is still comment-only.🤖 Reviewing this PR — follow along in the action run; the reply will link the full session transcript.
📜 Live transcript — updating every ~5 minutes while the task runs.
✅ Verdict: approve — no blocking issues found.
Re-review after new commits. The one issue I flagged in my previous pass —
<see href="...">RFC 9449</see>/<see href="...">RFC 7638</see>left as raw unstripped markup inside plain//comments insrc/ATProtoNet/Auth/OAuth/DPoP.cs— is fixed by commit7f8d686("unwrap the RFC links left as markup in converted comments"): both now read as plain prose with the URL in parentheses, e.g.RFC 9449 (https://www.rfc-editor.org/rfc/rfc9449), consistent with how<see cref>/<c>are handled elsewhere in the same pass.The rest of the diff continues the same mechanical, comment/doc-only pattern as before: multi-line
<summary>/<remarks>/<param>XML doc blocks on internal/private members (including public members of internal enclosing types, e.g.AtProtoPdsContainerResourceBase.Hostname,KeyedLock<TKey>.Lease,SessionManager) are converted to plain//prose, with<param>/<returns>/<exception>folded into labeled lines. Bare<inheritdoc/>is correctly dropped only where the enclosing type is internal (KeyedLock<TKey>.Lease.Dispose/DisposeAsync,SessionManager.BeforeSendAsync/TryRecoverAsync), matching the stated brace-depth/container-kind scanner logic. I didn't spot any place where genuinely public API documentation got miscategorized as internal, or where a doc's meaning changed during the conversion.No remaining issues from my prior pass; nothing new stood out as a correctness or content problem in this batch.
⏱ 0m 54s · 12 turns · tokens: 80.2k in / 5.1k out (+1133.7k cache-read)
📜 Full session transcript