vcard, contact: trim what the new comments say
Fourteen lines of comment stood above a three-line find,
re-arguing the layering the class comment had already signed.
The rules stay — a name without case, the first value of a repeat —
the case for them goes to the review, and of_line keeps its own seat.

Assisted-by: Claude Opus 5 via Claude Code

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015WjrPJFvetad8vvCHqjujh
change
commit 565d2642d390a3130508f533bdd82ff9555132c5
author Claude <noreply@anthropic.com>
date
parent fbd9c823
diff --git a/lib/pro_tacts/contact.rb b/lib/pro_tacts/contact.rb
index 8d7a359..1c90f4a 100644
--- a/lib/pro_tacts/contact.rb
+++ b/lib/pro_tacts/contact.rb
@@ -341,20 +341,9 @@ module ProTacts
       }
     end
 
-    # The rows a repeatable property reads as: the lines naming it,
-    # in the card's own order, each folded by the block into a typed
-    # value, with the nils dropped. Two absences arrive as one that
-    # way, which is what every one of these accessors wants — a line
-    # that would not read is a row no form can address, and a line
-    # the block finds nothing in (a blank value, an ADR blank
-    # throughout) is a row with nothing to show; neither is an error,
-    # and a card is served from its bytes either way. The unreadable
-    # line stays enumerable in VCard#lines regardless.
-    #
-    # The block takes the parsed property and the line it came from,
-    # because a row carries both: the property for what it says, the
-    # line for the address a save names the row by
-    # (docs/plans/2026-09-05-web-card-editor.md).
+    # The rows a repeatable property reads as: each line naming it
+    # folded by the block, which takes the property and the line it
+    # came from and answers nil for a row with nothing to show.
     #: [T] (String name) { (VCard::Parser::Property, VCard::Parser::Line) -> T? } -> Array[T]
     def rows(name)
       of_line(name).filter_map { |line|
@@ -363,9 +352,11 @@ module ProTacts
       }
     end
 
-    # The lines naming `name`, parsed beside their bytes — the walk
-    # #rows reads over, and the one accessor-facing read that hands
-    # back the lines that would not parse along with the rest.
+    # The lines naming `name`, parsed beside their bytes — the walk the
+    # provenance-carrying accessors read from, so a row can carry the
+    # line it was read from as its address. A line that would not
+    # read is a row no form can address and no accessor reads; it
+    # stays enumerable in VCard#lines, served from its bytes.
     #: (String name) -> Array[VCard::Parser::Line]
     def of_line(name)
       vcard.lines.select { it.names?(name) }
@@ -402,12 +393,8 @@ module ProTacts
       Address.new(po_box:, extended:, street:, locality:, region:, postal_code:, country:, type: type_of(property), line:)
     end
 
-    # A row's type parameter (RFC 2426 section 3.3.1), the first of
-    # them where a card lists several — which one that is, and that a
-    # name matches without case, is the grammar's and so
-    # Property#parameter's. What is this layer's is the downcase: the
-    # spelling is the card's, `WORK` and `work` label the same row,
-    # and a screen shows one of them.
+    # The first of a row's TYPE parameters (RFC 2426 section 3.3.1),
+    # downcased: the spelling is the card's, and a screen shows one.
     #: (VCard::Parser::Property property) -> String?
     def type_of(property)
       property.parameter("TYPE")&.downcase
diff --git a/lib/pro_tacts/vcard/parser.rb b/lib/pro_tacts/vcard/parser.rb
index 9d6010e..9932bff 100644
--- a/lib/pro_tacts/vcard/parser.rb
+++ b/lib/pro_tacts/vcard/parser.rb
@@ -90,20 +90,10 @@ module ProTacts
         #: () -> Array[String]
         def components = VCard.split_components(value)
 
-        # The named parameter's first value, or nil when the property
-        # carries none. Names compare without case, RFC 2426 section 4
-        # making them case-insensitive, and the first value is the
-        # answer because a parameter can repeat: section 3.3.1's
-        # `TYPE=work;TYPE=voice` and `TYPE=work,voice` are the same
-        # thing and both arrive as two pairs, so a caller wanting all
-        # of them reads `parameters` itself.
-        #
-        # Lookup, not meaning: that a parameter name is
-        # case-insensitive and that a repeat is a second value are
-        # the grammar's rules, which is what keeps this on the shallow
-        # side of the line the class comment draws. Which parameters a
-        # property may carry, and what any of them says, stays the
-        # caller's.
+        # The named parameter's first value, or nil for a property
+        # carrying none. Names match without case (RFC 2426 section
+        # 4); the first value, because a repeat arrives as two pairs
+        # (see above) and a caller wanting both reads `parameters`.
         #: (String name) -> String?
         def parameter(name)
           parameters.find { |parameter, _| parameter.casecmp?(name) }&.last
diff --git a/test/pro_tacts/vcard/test_parser.rb b/test/pro_tacts/vcard/test_parser.rb
index 23f3ba2..3fb7962 100644
--- a/test/pro_tacts/vcard/test_parser.rb
+++ b/test/pro_tacts/vcard/test_parser.rb
@@ -371,8 +371,7 @@ class VCardParserTest < Minitest::Test
   ## Parameters
 
   # A name matches without case (RFC 2426 section 4), and a parameter
-  # a card lists several values for answers with the first of them —
-  # both spellings of the repeat reaching here as the same two pairs.
+  # listing several values answers with the first of them.
   def test_a_parameter_reads_by_name_without_case
     property = properties(card("TEL;type=WORK,voice:+1-555-1234")).fetch(0)