comments: cite the argument instead of re-deriving it
The stray first: a comment written for the fold round trip sat one test
too low, over the parameter round trip, since the commit that added
both. It moves onto its own test, now saying whose folds those are, and
the parameter test keeps its name, which was always the whole of it.

The rest is the AGENTS.md rule applied where it had slipped -- two
copies of an argument drift apart, so the second one cites:

- web/contacts.rb said apply_edit was private "for the same reason
  write_card is one" and then gave the reason in full anyway.
- test_store.rb copied Store#report_unrecognized_bday_line's opening
  sentence. It now says what its five BDAY lines are for, which nothing
  else does: two components out of range, two spellings the grammar
  does not take, and one hung off a property group.
- test_format.rb repeated test_contact.rb's helper comment, which
  already cites Contact's class comment.
- test_vcard.rb and test_web.rb repeated, near-verbatim, the arguments
  on VCard.split_raw_components and the sync-collection branch.
- admin/layout.rb re-derived docs/DESIGN.md's no-webfont rule before
  getting to the part only it knows: the Google Fonts link that was
  there, and the woff2s that were never added.
- Two test comments in test_contacts_pages.rb restated both their test
  names and ContactsShow's reasoning, so they are gone.

Verified with steep (clean) and a prism parse of every Ruby file, and
every method a new comment cites was checked to exist. The suite still
needs Ruby 4, which this container does not have.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UXvcTFuXPr8ecpyD99h33M
change
commit b2dc7dcf4464e005d69e1be26cc3bc8e4921ad89
author Claude <noreply@anthropic.com>
date
parent 7ff5b05c
diff --git a/lib/pro_tacts/admin/contacts_show.rb b/lib/pro_tacts/admin/contacts_show.rb
index 773ddb1..d6a35a7 100644
--- a/lib/pro_tacts/admin/contacts_show.rb
+++ b/lib/pro_tacts/admin/contacts_show.rb
@@ -76,7 +76,8 @@ module ProTacts
                   # the avatar is the row's visual anchor, not a caption.
                   render Avatar.new(contact: @contact, size: "xl") if @contact.photo
                 end
-                # Never empty: the groups row is always there.
+                # Never empty, #groups_row standing unconditionally
+                # for the reason it gives, so no guard around it.
                 dl(class: "detail-grid") { rows }
               end
             end
diff --git a/lib/pro_tacts/admin/layout.rb b/lib/pro_tacts/admin/layout.rb
index 8b1900e..b342e26 100644
--- a/lib/pro_tacts/admin/layout.rb
+++ b/lib/pro_tacts/admin/layout.rb
@@ -50,14 +50,11 @@ module ProTacts
             meta(charset: "utf-8")
             meta(name: "viewport", content: "width=device-width, initial-scale=1")
             title { "pro-tacts — #{@title}" }
-            # No webfont. --gl-font-mono names IBM Plex Mono first and
-            # falls back through ui-monospace to the platform's own
-            # (tokens.css), so a face this app does not ship is a
-            # preference the browser honors when the reader happens to
-            # have it, not a download. What was here before was a
-            # remote Google Fonts stylesheet, and the self-hosted
-            # woff2s meant to replace it were never added — the
-            # @font-face rules pointed at three files that 404ed.
+            # No webfont (docs/DESIGN.md), so there is no font link
+            # among these. What was here before was a remote Google
+            # Fonts stylesheet, and the self-hosted woff2s meant to
+            # replace it were never added — the @font-face rules
+            # pointed at three files that 404ed.
             link(rel: "stylesheet", href: "/vendor/gloss/tokens.css")
             link(rel: "stylesheet", href: "/vendor/gloss/base.css")
             link(rel: "stylesheet", href: "/vendor/gloss/components.css")
diff --git a/lib/pro_tacts/web/contacts.rb b/lib/pro_tacts/web/contacts.rb
index b7f95f1..bc6ab0d 100644
--- a/lib/pro_tacts/web/contacts.rb
+++ b/lib/pro_tacts/web/contacts.rb
@@ -118,11 +118,10 @@ module ProTacts
       )
     end
 
-    # The whole of the edit POST, a private method for the same reason
-    # write_card is one: a Roda route block cannot return early, so each
-    # refusal is a value the block ends with rather than a branch it
-    # exits. The checks run in write_card's order — the request's own
-    # validity first, the conditionals on stored state after.
+    # The whole of the edit POST, a private method for the reason
+    # Web#write_card is one, and its checks in the same order: the
+    # request's own validity first, the conditionals on stored state
+    # after.
     #: (untyped r, String id) -> String?
     def apply_edit(r, id)
       contact = store.contact(id)
diff --git a/test/pro_tacts/admin/test_contacts_pages.rb b/test/pro_tacts/admin/test_contacts_pages.rb
index 8edd47c..cdbbbbb 100644
--- a/test/pro_tacts/admin/test_contacts_pages.rb
+++ b/test/pro_tacts/admin/test_contacts_pages.rb
@@ -494,8 +494,6 @@ class AdminContactsPagesTest < Minitest::Test
     end
   end
 
-  # A value with no TYPE parameter still gets a key — the fallback
-  # names the kind of value, so every row in the grid is labeled.
   def test_show_labels_untyped_values_with_the_property_name
     untyped = ADA.sub("TEL;TYPE=mobile:", "TEL:").sub("EMAIL;TYPE=home:", "EMAIL:")
 
@@ -733,9 +731,6 @@ class AdminContactsPagesTest < Minitest::Test
 
   ## Photos
 
-  # No picture, no avatar: an initials circle beside the name in
-  # type-h2 would repeat what the name already says, so a contact
-  # without a photo renders the header as the name alone.
   def test_show_without_a_picture_renders_no_avatar
     with_contacts({"ada" => ADA}) do
       get "/contacts/ada"
diff --git a/test/pro_tacts/admin/test_format.rb b/test/pro_tacts/admin/test_format.rb
index 937656c..db00a82 100644
--- a/test/pro_tacts/admin/test_format.rb
+++ b/test/pro_tacts/admin/test_format.rb
@@ -8,10 +8,8 @@ class FormatTest < Minitest::Test
   CARD = "BEGIN:VCARD\r\nVERSION:3.0\r\nFN:Ada Lovelace\r\nN:Lovelace;Ada;;;\r\n" \
     "UID:ada\r\nEND:VCARD\r\n"
 
-  # The production shapes: a modeled birthday passes a BDAY-free card
-  # beside a Birthday, a fallback case passes a card carrying an
-  # unmodeled BDAY beside nil, and inheritance defaults to none (see
-  # Contact).
+  # The production shapes, as Contact's class comment lays them out.
+  # Nothing on these screens is in a group, so inheritance is none.
   def contact(bytes = CARD, id: "aiden", birthday: nil, inherited: [])
     ProTacts::Contact.new(id:, stored: ProTacts::VCard.new(bytes), birthday:, inherited:)
   end
diff --git a/test/pro_tacts/test_store.rb b/test/pro_tacts/test_store.rb
index e2c166c..4727cfc 100644
--- a/test/pro_tacts/test_store.rb
+++ b/test/pro_tacts/test_store.rb
@@ -882,9 +882,11 @@ class StoreTest < Minitest::Test
     end
   end
 
-  # The arrival report: a submitted BDAY the model does not take is
-  # unexpected input, and storing it verbatim would be the last anyone
-  # heard of it.
+  # Both ways a BDAY misses the reader, and the one that is neither: a
+  # component out of range (month 13, day 32), a spelling its grammar
+  # does not take (undashed, unpadded — see Birthday's patterns), and a
+  # BDAY the card hangs off a property group. Why it reports rather
+  # than stores quietly is Store#report_unrecognized_bday_line.
   def test_an_unrecognized_bday_arriving_is_reported
     ["BDAY:1985-13", "BDAY:--0432", "BDAY:19850412", "BDAY:1985-4", "item1.BDAY:1985-04-12"].each do |line|
       with_store({}) do |store|
diff --git a/test/pro_tacts/test_vcard.rb b/test/pro_tacts/test_vcard.rb
index 0ff5c70..d278b7b 100644
--- a/test/pro_tacts/test_vcard.rb
+++ b/test/pro_tacts/test_vcard.rb
@@ -54,10 +54,9 @@ class VCardTest < Minitest::Test
     assert_equal ["Smith; Jr.", "John"], ProTacts::VCard.split_components("Smith\\; Jr.;John")
   end
 
-  # The writer's splice: the same split with the escaping left alone,
-  # so components rejoin byte for byte — unescape-then-re-escape is
-  # not byte-stable (unescape leaves an unrecognized escape like "\\x"
-  # alone, and escape would double its backslash).
+  # The third component is the case the byte-stability argument on
+  # VCard.split_raw_components turns on: an escape neither half of the
+  # pair recognizes, which a round trip through them would corrupt.
   def test_split_raw_components_leaves_each_component_escaped
     assert_equal ["Smith\\; Jr.", "John", "a\\xb"],
       ProTacts::VCard.split_raw_components("Smith\\; Jr.;John;a\\xb")
diff --git a/test/pro_tacts/test_web.rb b/test/pro_tacts/test_web.rb
index 6a0dda4..8ee22c4 100644
--- a/test/pro_tacts/test_web.rb
+++ b/test/pro_tacts/test_web.rb
@@ -886,11 +886,9 @@ class WebTest < Minitest::Test
     end
   end
 
-  # RFC 6578 section 3.2: the delta since the client's token, one
-  # response per net-changed member, and a DAV:sync-token naming the
-  # state the answer reaches. The warm-sync ask is etag-only; a changed
-  # etag sends the client back through multiget, so no address-data
-  # here.
+  # The warm sync, whose shape the REPORT route's sync-collection
+  # branch argues in full (web/dav.rb): RFC 6578 section 3.2, etags
+  # only, address-data never.
   def test_sync_collection_reports_the_delta_since_the_token
     with_contacts({"aiden" => "Aiden"}) do |store|
       request "/dav/addressbook/", method: "REPORT", input: sync_collection(issued_token(0))
diff --git a/test/pro_tacts/vcard/test_parser.rb b/test/pro_tacts/vcard/test_parser.rb
index 49d30d0..8ad9a40 100644
--- a/test/pro_tacts/vcard/test_parser.rb
+++ b/test/pro_tacts/vcard/test_parser.rb
@@ -356,6 +356,10 @@ class VCardParserTest < Minitest::Test
     folded
   end
 
+  # Folding and unfolding are inverses on a rendered line, which is what
+  # makes an index rebuilt from stored cards agree with what was served.
+  # The folds are the client's — nothing here writes one — so this is
+  # the read holding up its end of a round trip it only ever finishes.
   def test_an_escaped_and_folded_value_parses_back
     Hegel.test do |tc|
       value = tc.draw(text(max_size: 300))
@@ -367,8 +371,6 @@ class VCardParserTest < Minitest::Test
     end
   end
 
-  # Folding and unfolding are inverses on a rendered line, which is what
-  # makes an index rebuilt from stored cards agree with what was served.
   def test_a_parameter_value_survives_a_round_trip
     token = from_regex("[A-Za-z0-9-]{1,20}", fullmatch: true)
     Hegel.test do |tc|