<feed xmlns='http://www.w3.org/2005/Atom'>
<title>domain-dig.git/DomainDig/DomainViewModel+Widget.swift, branch chore/owner-record-id-reveal</title>
<subtitle>local-first ios domain inspection toolkit. dns, tls, rdap, audit.
</subtitle>
<id>http://git.krz.sh/krz/domain-dig.git/atom?h=chore%2Fowner-record-id-reveal</id>
<link rel='self' href='http://git.krz.sh/krz/domain-dig.git/atom?h=chore%2Fowner-record-id-reveal'/>
<link rel='alternate' type='text/html' href='http://git.krz.sh/krz/domain-dig.git/'/>
<updated>2026-07-22T20:04:32+00:00</updated>
<entry>
<title>feat(a11y): seeded audit fixtures; fix dense-row reflow they exposed (#21)</title>
<updated>2026-07-22T20:04:32+00:00</updated>
<author>
<name>Christian Cleberg</name>
<email>hello@cleberg.net</email>
</author>
<published>2026-07-22T05:47:12+00:00</published>
<link rel='alternate' type='text/html' href='http://git.krz.sh/krz/domain-dig.git/commit/?id=7f917e98b929dcf0f7901d0bc4eb05e04db3aa0c'/>
<id>urn:sha1:7f917e98b929dcf0f7901d0bc4eb05e04db3aa0c</id>
<content type='text'>
The dense rows and portfolio sections never rendered in the audit — the
test simulator has no tracked domains or batch results — so five phases
of row treatment shipped unmeasured. Driving the add-domain UI was tried
earlier and rejected (keyboard contamination, persistent state), so this
adds DOMAIN_DIG_SEED_FIXTURES: DEBUG-only launch argument, same pattern
as DOMAIN_DIG_FORCE_PRO_PLUS, seeding four tracked domains and four
batch results chosen to exercise every badge path, including a failed
lookup and a stress-length domain name.

Fixtures are strictly in-memory. persistTrackedDomains, refreshWidgetData
(App Group file), refreshPersistedData, and refreshMonitoringState are
all guarded while fixtures are active — the last one mattered: it runs
right after seeding in the app task and was reloading the empty disk
over the fixtures, which initially made the seeded watchlist audit pass
by silently auditing the empty state.

Four new audit tests cover the seeded Dashboard, Tracked Domains, and
batch results at default and AccessibilityXXXL.

What they found was real. At XXXL the watchlist row rendered the domain
as "hea lt…" while the Registered badge wrapped one character per line
into a screen-height capsule. Fixes, verified by before/after
screenshots and the XXXL audits dropping to 7-8 findings per screen:

- AppStatusBadgeView gets .fixedSize() — a capsule badge must never
  letter-wrap; taking natural width instead forces the row layout to its
  stacked alternative.
- WatchlistRowView, BatchResultRowView, and PortfolioExpiryRow headers
  use ViewThatFits: domain-beside-badge while it genuinely fits, badge
  below the domain at accessibility sizes. Domain titles get
  fixedSize(horizontal: false, vertical: true) so they wrap rather than
  report a single-line ideal width to ViewThatFits and truncate.
- The watchlist monitoring metadata strip (three texts abreast) stacks
  vertically when it no longer fits instead of wrapping mid-word.

Known and deliberate: the seeded default-size audits still report a
contrast/dynamicType wave attributed to "unknown element". Bisecting the
row and badge accessibility modifiers showed most of it is an audit
artifact on children-ignored content (the same rows measure 6-7:1 and
render correctly); the artifact classes get characterised suppressions
when enforcement lands, not blanket ones.
</content>
</entry>
<entry>
<title>Complete v4.5.0: Run Sweep intent, detail deep link, and portfolio widget</title>
<updated>2026-07-17T05:31:57+00:00</updated>
<author>
<name>Christian Cleberg</name>
<email>hello@cleberg.net</email>
</author>
<published>2026-07-17T05:27:45+00:00</published>
<link rel='alternate' type='text/html' href='http://git.krz.sh/krz/domain-dig.git/commit/?id=d3a27d06809e6744c092f9bed4bf0537843d0210'/>
<id>urn:sha1:d3a27d06809e6744c092f9bed4bf0537843d0210</id>
<content type='text'>
Finishes the v4.5.0 "Home Screen &amp; Shortcuts reach" scope that the tag shipped
partially:

- Add RunSweepIntent (opens the app and runs refreshAllTrackedDomains via the
  in-process router) and expose it in DomainDigShortcuts.
- Extend the domaindig:// scheme with `sweep` and `domain` (detail) actions;
  route .detail to present TrackedDomainDetailView and .sweep to refresh the
  watchlist. Move DomainDigDeepLink into Shared/ so the widget can build links.
- Add a WidgetKit extension (DomainDigWidgetExtension) with small/medium/large
  Portfolio widgets showing health counts, per-domain status, and certificate
  countdowns; tapping a domain deep-links into its detail.
- Share portfolio state via an App Group (group.net.cleberg.DomainDig): the app
  writes a DomainDigWidgetData snapshot on launch/foreground and on watchlist
  changes and reloads timelines; the widget reads the same store.
</content>
</entry>
</feed>
