Tighten comments and fold the README client-quirks section
The comment cut from DebugLogger was stale: the server serves real
data, so the fictional-card rationale no longer held.
Assisted-by: GLM-5.3 via pi
diff --git a/README.md b/README.md
index 5f82b7d..56e791b 100644
--- a/README.md
+++ b/README.md
@@ -111,6 +111,14 @@ Three properties are load-bearing in non-obvious ways, documented in
client asks for — displayname, privileges, owner, quotas, push transports,
me-card, principal-URL, the multiget/query advertisements — is optional.
+sabre/dav's [notes on the macOS Address Book client][sabre-osx] are the best
+single source of client quirks beyond this list, and they explain several
+failures that look like protocol bugs but are not. See `docs/macos-contacts.md`
+for the details worth keeping close, including how to turn on the client's own
+debug logging.
+
+[sabre-osx]: https://sabre.io/dav/clients/osx-addressbook/
+
## Protocol references
CardDAV is a stack of extensions rather than a single specification, so
@@ -151,15 +159,6 @@ CalendarServer, which is archived but still the only written source:
[ctag]: https://github.com/apple/ccs-calendarserver/blob/master/doc/Extensions/caldav-ctag.txt
[pubsub]: https://github.com/apple/ccs-calendarserver/blob/master/doc/Extensions/caldav-pubsubdiscovery.txt
-## What macOS Contacts needs
-
-sabre/dav's [notes on the macOS Address Book client][sabre-osx] are the best
-single source of client quirks, and they explain several failures that look
-like protocol bugs but are not. See `docs/macos-contacts.md` for the details
-worth keeping close, including how to turn on the client's own debug logging.
-
-[sabre-osx]: https://sabre.io/dav/clients/osx-addressbook/
-
## Reference implementations
`servers/` holds compose files for CardDAV servers to compare against, each
diff --git a/config.ru b/config.ru
index afdbb86..8e2d59f 100644
--- a/config.ru
+++ b/config.ru
@@ -24,7 +24,6 @@ ProTacts::Web.store = ProTacts::Store.at(config.database_path)
Sentry.init do |sentry|
sentry.dsn = config.sentry_dsn
- # Get breadcrumbs from logs
sentry.breadcrumbs_logger = [:sentry_logger, :http_logger]
# On: request bodies are worth having on a 404, and nothing else this
@@ -37,7 +36,6 @@ Sentry.init do |sentry|
# locally either way, see ProTacts::UnhandledRequests.
sentry.before_send = ProTacts::SentryScrubber
- # Trace all the things!
sentry.traces_sample_rate = 1.0
end
diff --git a/lib/pro_tacts/debug_logger.rb b/lib/pro_tacts/debug_logger.rb
index b1c2d6e..2a4b8e0 100644
--- a/lib/pro_tacts/debug_logger.rb
+++ b/lib/pro_tacts/debug_logger.rb
@@ -10,9 +10,7 @@ module ProTacts
# Every line is prefixed ">>" (request) or "<<" (response) so multi-line
# XML/vCard bodies stay readable.
#
- # Off by default because it logs contact data. The only card right now is
- # fictional, so the debug path stays verbose while the normal one-line path
- # (Roda's common_logger) can be narrowed later without losing this.
+ # Off by default because it logs contact data.
class DebugLogger
# @rbs @app: Rack::_App
# @rbs @logger: Logger
diff --git a/lib/pro_tacts/store.rb b/lib/pro_tacts/store.rb
index bf26539..3a19f40 100644
--- a/lib/pro_tacts/store.rb
+++ b/lib/pro_tacts/store.rb
@@ -217,9 +217,7 @@ module ProTacts
# What is stored is the card minus its birthday, which moves into
# the birthdays table — vCard 3.0 cannot carry a partial date, so
# no stored card carries the model's BDAY and every read composes
- # it back in (docs/plans/2026-08-31-partial-birthdays.md). The
- # Contact this returns is the composed one, and the logged etag is
- # its hash, so a client's token describes the card it downloads.
+ # it back in (docs/plans/2026-08-31-partial-birthdays.md).
#
# The strings are UTF-8 by contract, and the adapter holds the store
# to it: the sqlite3 gem encodes every bound value to UTF-8, so a
diff --git a/lib/pro_tacts/web.rb b/lib/pro_tacts/web.rb
index a458215..ad20b54 100644
--- a/lib/pro_tacts/web.rb
+++ b/lib/pro_tacts/web.rb
@@ -220,7 +220,6 @@ module ProTacts
# 10.2, and the 207 body it returns section 13.
depth = request.env.fetch("HTTP_DEPTH", "infinity")
- # Check if this is an etag-only request (Depth:1 listing)
etag_only = body.include?("getetag") && !body.include?("displayname") && !body.include?("resourcetype")
# Etag-only asks want the members; the collection self-entry