From 593bdb17d4f946a2675af0f51d0319106bf3183f Mon Sep 17 00:00:00 2001 From: Jorijn van der Graaf Date: Tue, 18 Aug 2026 14:52:49 +0200 Subject: [PATCH] 112 tested --- shared/interfaces/Catcrafts.Shared-Content.cppm | 11 +++++++---- shared/interfaces/Catcrafts.Shared-Model.cppm | 9 +++++---- shared/interfaces/Catcrafts.Shared-Views.cppm | 3 +-- styles/styles.css | 5 +++-- tests/ShouldSellTheShopFront/main.cpp | 6 +++++- tests/ShouldShipContent/main.cpp | 10 +++++++--- 6 files changed, 28 insertions(+), 16 deletions(-) diff --git a/shared/interfaces/Catcrafts.Shared-Content.cppm b/shared/interfaces/Catcrafts.Shared-Content.cppm index 02419b6..b3413fd 100644 --- a/shared/interfaces/Catcrafts.Shared-Content.cppm +++ b/shared/interfaces/Catcrafts.Shared-Content.cppm @@ -73,10 +73,13 @@ export const std::vector& Products() { p.image = "/fp6-pmos.jpg"; p.summary = "The Fairphone (Gen. 6), reflashed by Catcrafts to run postmarketOS with the patches and IMS/VoLTE implementation Catcrafts maintains. All of that software is open source. You can download it and flash a Fairphone yourself, and you are welcome to. What you pay for here is the thing open source doesn't come with: real support. A phone that arrives working, and one email address that answers for it. Not a forum, not a git issue, but support like any other manufacturer offers. And the margin funds the development itself."; p.warranty = "Two years from Catcrafts, worldwide, one counter: every claim goes to Catcrafts, whatever turns out to be broken. The software (postmarketOS, the patches, imsd) is Catcrafts' own work and is fixed by Catcrafts with updates, delivered over the air. Even a phone that no longer boots is normally recovered in place: as long as fastboot still comes up, Catcrafts walks you through reflashing it over a USB cable in minutes. Only a phone that shows nothing at all, not even fastboot, travels for a software fault. For a hardware fault Catcrafts takes the phone back and handles the manufacturer's process, including the temporary reflash to stock Android it requires, and returns it running postmarketOS. When a phone does have to travel, warranty shipping is paid by Catcrafts, both directions, worldwide. User inflicted damage, including software faults caused by relocking the bootloader do not fall under this policy. The full terms are on the terms page."; - // The one claim on this page that is about safety rather than - // features. It stays until emergency calling has been verified on a - // real network — removing it is a decision, not a cleanup. - p.safetyNote = "Emergency calling (112/911) is implemented in imsd, including carrier-broadcast emergency numbers, but not yet verified against a live network."; + // No safety note. There was one — the emergency-calling caveat — and + // it came off on 2026-08-18, when imsd placed calls to 112 on a live + // network in a test session approved by TB112 (the Dutch 1-1-2 + // operator). That verification is exactly what the caveat was waiting + // for, so the claim it hedged is now a plain fact and the warning box + // would only mislead. The field stays in the model for the next real + // safety claim; leaving it empty is the decision, not an oversight. p.variants = { // supplier €513.30 incl VAT { "green", "Forest Green", 51330 + kMarkupMinor }, diff --git a/shared/interfaces/Catcrafts.Shared-Model.cppm b/shared/interfaces/Catcrafts.Shared-Model.cppm index 2f8f1ab..3f8af79 100644 --- a/shared/interfaces/Catcrafts.Shared-Model.cppm +++ b/shared/interfaces/Catcrafts.Shared-Model.cppm @@ -226,10 +226,11 @@ export struct Product { std::string image; std::string summary; std::string warranty; - // Rendered as a prominent warning box when non-empty. Exists for exactly - // one thing today: the emergency-calling caveat — the single claim on the - // page that is about safety rather than features, which is why it gets a - // warning box instead of a table row. + // Rendered as a prominent warning box when non-empty. No product sets it + // today: it existed for the emergency-calling caveat, which came off once + // 112 was verified on a live network. It stays because the next safety + // claim — something about safety rather than features — belongs in a + // warning box above the fold, not in a spec-table row. std::string safetyNote; std::vector specs; diff --git a/shared/interfaces/Catcrafts.Shared-Views.cppm b/shared/interfaces/Catcrafts.Shared-Views.cppm index 2b660ce..b5d0a99 100644 --- a/shared/interfaces/Catcrafts.Shared-Views.cppm +++ b/shared/interfaces/Catcrafts.Shared-Views.cppm @@ -1279,8 +1279,7 @@ export RenderedPage RenderProduct(const Product& product, R"(

Specifications

)" R"(

The hardware is a stock Fairphone )" R"((Gen. 6), unmodified. Fairphone's spec sheet is this product's spec sheet, )" - R"(and all of it works under postmarketOS. The one caveat is the )" - R"(emergency-calling warning above.

)" + R"(and all of it works under postmarketOS.

)" R"({}
)" R"()", Join(specRows)); diff --git a/styles/styles.css b/styles/styles.css index c667618..7aa0797 100644 --- a/styles/styles.css +++ b/styles/styles.css @@ -964,8 +964,9 @@ treatment it replaces, which read as the wrong category for the work. border-bottom: 1px solid var(--border); } - /* The emergency-calling note on the product page. Warn colours rather than - danger: it flags an unverified path, not a known-broken one. */ + /* A product's safety note. Warn colours rather than danger: the box flags a + caveat, not a known-broken feature. Unused since the emergency-calling + caveat came off — kept with the renderer that would use it again. */ .notice--warn { color: var(--warn); border-color: color-mix(in oklab, var(--warn) 40%, transparent); diff --git a/tests/ShouldSellTheShopFront/main.cpp b/tests/ShouldSellTheShopFront/main.cpp index 2617594..dfc654e 100644 --- a/tests/ShouldSellTheShopFront/main.cpp +++ b/tests/ShouldSellTheShopFront/main.cpp @@ -66,7 +66,11 @@ int main(int argc, char** argv) { // The image file itself is Caddy's to serve (static asset), so its // presence is asserted against the repo, not this server. Check(std::filesystem::exists("images/fp6-pmos.jpg"), "product photo exists in the repo"); - srv.BodyHas("/shop/fp6-pmos", "not yet verified", "emergency-calling caveat is on the page"); + // 112 was verified against a live network on 2026-08-18, so the caveat + // that used to sit above the spec sheet is gone from the served page and + // must not creep back in. + srv.BodyLacks("/shop/fp6-pmos", "not yet verified", + "no unverified-emergency-calling caveat on the page"); srv.BodyLacks("/shop", "reservation", "no reservation copy survives on /shop"); srv.BodyLacks("/shop/fp6-pmos", "Reserve one", "no reservation form survives"); diff --git a/tests/ShouldShipContent/main.cpp b/tests/ShouldShipContent/main.cpp index 7ae8a2a..6be84de 100644 --- a/tests/ShouldShipContent/main.cpp +++ b/tests/ShouldShipContent/main.cpp @@ -89,9 +89,13 @@ void CatalogueContract() { Check(MaxUnitsFor(ladder, pr.shipWeightGrams) == 14, "content: and caps one parcel at fourteen units"); } - Check(pr.safetyNote.find("112") != std::string::npos - && pr.safetyNote.find("not yet verified") != std::string::npos, - "content: emergency-calling safety warning present and honest"); + // This used to assert the emergency-calling caveat was present. It + // came off on 2026-08-18, when imsd called 112 over a live network in + // an approved test session, so the assertion inverts: the page must + // not go back to telling buyers that path is unverified. A future + // safety claim may fill this field again — it just cannot be that one. + Check(pr.safetyNote.find("not yet verified") == std::string::npos, + "content: no stale unverified-emergency-calling caveat"); Check(pr.warranty.find("TODO") == std::string::npos && pr.warranty.size() > 100, "content: warranty is written, not a placeholder"); // The product page's schema.org record must parse with our own