Skip to content

fix(templates): dial the number the sheet printed, not one like it - #659

Merged
DemchaAV merged 3 commits into
feature/template-promotionfrom
refactor/contact-uri-sweep
Sep 7, 2026
Merged

DemchaAV merged 3 commits into
feature/template-promotionfrom
refactor/contact-uri-sweep

Conversation

@DemchaAV

@DemchaAV DemchaAV commented Sep 3, 2026

Copy link
Copy Markdown
Owner

Stacked on chore/one-contact-uri (#658) — merge that first.

Why

#658 gave the rule one home. It did not find all the places that had it.

The rule is that a printed telephone number and the number a device dials are
different strings. #658 collapsed three named helper classes; thirteen presets
were still carrying the same rule written inline, where a search for the class
names could not see it. Five of the thirteen did not drop the parenthesised
trunk prefix:

design prints linked should link
CharcoalGold, NavySidebar, ProfessionalSidebar, SerifHeadline +44 (0)20 7946 0832 tel:+4402079460832 tel:+442079460832
ConsultingInvoice +44 (0)20 7946 0832 tel:+44(0)2079460832 tel:+442079460832

The first four kept the trunk zero, which a caller abroad omits — the target
reaches nobody. ConsultingInvoice removed spaces and nothing else, so the
printed brackets went into the target and it was not a dialable number at all.
One printed number, five different answers, decided by which design its owner
picked.

What

All thirteen copies are gone. The other eight were already producing the right
target, in eight separate places — four spelling the regex out inline, four
naming a constant for it — and that duplication is as much what this removes as
the five that got it wrong.

The same sweep removes three copies of the scheme-prefixing rule for a printed
website. ContactUri gains web: the target form of webLink, the way tel
is of telLink. Two call sites take a plain String, so webLink could not
serve them.

The Consulting closing moves from the target form to telLink. It hands its
phone field straight to a link constructor, and a contact line reading
"ask reception" carries no digits: the old copy made a junk target out of it,
the target form answers null, and only the link form turns that into no link
rather than a page that refuses to compose. Every other rewritten site was
already null-tolerant.

Nothing on any page moves. A link annotation is not ink, and no fixture
prints a trunk prefix, so no pixel baseline and no layout snapshot changes.
What changes is where the link goes when a caller's own number carries one.

Tests

CvPresetDialTargetTest asks all ten promoted CV designs the same question:
render a contact block whose number carries a trunk prefix, read the tel:
targets back out of the file.

This is the check the private copies never had. Two designs had a test naming a
trunk prefix and both handled one; the other eight asserted their dial target
with a number carrying none. So every copy agreed with its own test, and four
still built a target no caller could reach. Proved fails-closed by removing the
trunk-prefix rule from ContactUri and watching all ten go red.

ConsultingInvoiceSmokeTest asks the same of the invoice design that was
furthest out, giving the masthead and the closing prose different numbers so
that neither site can answer for the other.

Reactor gate green, 1249 tests, no baseline moved; javadoc gate green; API
surface regenerated in the same change.

DemchaAV and others added 2 commits September 3, 2026 08:18
…ble one

The rule that a printed telephone number and the number a device dials are
different strings was written three times — ContactUri in the CV presets,
InvoiceUri in the invoice presets, ProposalUri in the proposal presets — and
where the three overlapped they were byte-identical, down to the regex and
its comment.

They are now one helper, core.identity.ContactUri, beside the contact-block
and link records it serves: tel, telLink, mailLink, webLink, channelLink.
Twenty-three preset files call it and the three copies are gone.

It is public because the three families are three packages and a helper
shared between them cannot be package-private. It is not marked experimental,
because the shape is not a guess: three independent implementations had
already agreed on it.

Every method answers null rather than throwing, which the proposal copy had
already learned and the other two had not: a notice, a name or a line of
prose can reach a channel field, DocumentLinkOptions refuses a string that is
not a URI, and a contact line is not the place to find that out.

Nothing renders differently. A link annotation is not ink, so every pixel
baseline in the suite passes untouched — the reactor gate ran the visual
tests and moved no baseline.

Tests: the CV suite's ContactUriTest moves to the shared package and gains
what the other two copies contributed — an address, a site with and without a
scheme, a channel read from its own shape, a site carrying digits that is not
mistaken for a number, and prose in a channel field losing its link rather
than the page. Ten cases. Reactor gate green, 1238 tests.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
A printed telephone number and the number a device dials are different
strings. That conversion had been given one home, core.identity.ContactUri,
but thirteen presets still carried their own private copy of it, written
inline rather than named, and five of the copies did not drop the
parenthesised trunk prefix. A sheet printing +44 (0)20 7946 0832 linked
tel:+4402079460832 -- a number that reaches nobody from abroad -- in
CharcoalGold, NavySidebar, ProfessionalSidebar and SerifHeadline, and
ConsultingInvoice was further out still: its copy removed spaces and
nothing else, so the printed brackets went into the target and the link
was not a dialable number at all.

All thirteen are gone. The other eight were already producing the right
target, in eight separate places -- four spelling the regex out inline and
four naming a constant for it -- and that duplication is as much what this
removes as the five that got it wrong. The same sweep removes three copies
of the scheme-prefixing rule for a printed website, which ContactUri gains
as web: the target form of webLink, the way tel is of telLink.

The Consulting closing moves to telLink at the same time. It hands its
phone field straight to a link constructor, and a contact line reading "ask
reception" carries no digits: the old copy made a junk target out of it,
the target form answers null, and only the link form turns that into no
link rather than a page that refuses to compose.

Nothing on any page moves. A link annotation is not ink, and no fixture
prints a trunk prefix, so no pixel baseline and no layout snapshot changes;
what changes is where the link goes when a caller's own number carries one.

Tests: CvPresetDialTargetTest asks all ten promoted CV designs the same
question -- render a contact block whose number carries a trunk prefix,
read the tel: targets back out of the file. This is the check the private
copies never had: two designs had a test naming a trunk prefix and both
handled one, while the other eight asserted their dial target with a number
carrying none, so every copy agreed with its own test and four still built
a target no caller could reach. Proved fails-closed by removing the
trunk-prefix rule from ContactUri and watching all ten go red.
ConsultingInvoiceSmokeTest asks the same of the invoice design, giving the
masthead and the closing prose different numbers so neither site can answer
for the other.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@DemchaAV
DemchaAV changed the base branch from chore/one-contact-uri to feature/template-promotion September 7, 2026 07:33
… refactor/contact-uri-sweep

# Conflicts:
#	CHANGELOG.md
#	knowledge/api/templates.json
#	knowledge/api/templates.md
@DemchaAV
DemchaAV merged commit 6407b73 into feature/template-promotion Sep 7, 2026
12 checks passed
@DemchaAV
DemchaAV deleted the refactor/contact-uri-sweep branch September 7, 2026 07:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant