Ownware
Home›Deliora›Test run
Deliora · Test run · run 2026-09-06

Deliora Test run, as shipped in the download

3,112 checks passed, 0 failed, when the suite that ships in the zip was run on 2026-09-06 with php tests/run.php. Run it yourself after you download.

== 0. launch-mode flags ship OFF on a fresh install ==
  PASS  fresh install: demos_live defaults to 0 (got 0, want 0)
  PASS  fresh install: sales_live defaults to 0 (got 0, want 0)

== 1. helpers ==
  PASS  e() escapes for view context (got '<b>"x"</b>', want '<b>"x"</b>')
  PASS  clip caps to width (got 190, want 190)
  PASS  clip passes short values (got 'abc', want 'abc')
  PASS  clamp_int caps range (got 2000000000, want 2000000000)
  PASS  clamp_int floor (got -2000000000, want -2000000000)
  PASS  clamp_int non-numeric -> 0 (got 0, want 0)
  PASS  fmt_money USD (got '$49.00', want '$49.00')
  PASS  fmt_money unknown code suffixes (got '49.00 SEK', want '49.00 SEK')
  PASS  now_utc format

== 2. safe markdown renderer (escape-first) ==
  PASS  heading rendered as h2
  PASS  subheading rendered as h3
  PASS  bold rendered
  PASS  list rendered
  PASS  paragraph rendered
  PASS  script tag escaped
  PASS  img/onerror escaped
  PASS  raw HTML never passes through bold
  PASS  heading content escaped
  PASS  list content escaped
  PASS  quote attribute breakout escaped
  PASS  table rendered with thead
  PASS  table body cell inline-rendered
  PASS  separator row not rendered as cells
  PASS  blockquote rendered
  PASS  ordered list rendered
  PASS  hr rendered
  PASS  code span rendered
  PASS  italic rendered
  PASS  table cell XSS escaped
  PASS  code span in table escaped
  PASS  blockquote XSS escaped
  PASS  ordered-list XSS escaped
  PASS  code span shields markdown and html
  PASS  bold not applied inside code
  PASS  legacy constructs unchanged

== 3. Payments demo contract (crypto module boundary) ==
  PASS  demo fixture parses
  PASS  type normalized (got 'paid', want 'paid')
  PASS  order_ref kept (got 'ord_123', want 'ord_123')
  PASS  buyer email lowercased (got 'buyer@x.com', want 'buyer@x.com')
  PASS  currency uppercased (got 'USD', want 'USD')
  PASS  amount_cents int (got 4900, want 4900)
  PASS  items mapped (got array (
  0 => 
  array (
    'sku' => 'invoicer-pro',
    'tier' => 'single',
  ),
), want array (
  0 => 
  array (
    'sku' => 'invoicer-pro',
    'tier' => 'single',
  ),
))
  PASS  refunded event parses without items (got 'refunded', want 'refunded')
  PASS  unknown type -> other (got 'other', want 'other')
  PASS  garbage body -> null
  PASS  missing order_ref -> null
  PASS  bad email -> null
  PASS  paid with no items -> null
  PASS  provider mismatch -> null (demo body to lemonsqueezy endpoint)
  PASS  LS: forged signature -> null
  PASS  Stripe: bogus/stale signature -> null
  PASS  unknown provider -> null
  PASS  LS: valid signature -> normalized paid event
  PASS  LS: tampered signature -> null
  PASS  LS: wrong secret -> null
  PASS  LS: UUID identifier preferred over numeric data.id as order_ref
  PASS  LS: empty identifier falls back to data.id (refund keeps matching old rows)
  PASS  LS O13: a PAID order with no identifier never takes the sequential data.id as its ref
  PASS  LS O13: that derived ref is deterministic, so an LS resend stays idempotent
  PASS  Stripe: valid signature -> normalized paid event
  PASS  Stripe: stale timestamp -> null
  PASS  Stripe: tampered payload -> null
  PASS  module HAS real HMAC verification (not a stub)

== 4. Licensing (real HMAC, DB-bound tamper-evidence) ==
  PASS  sign() returns a real OWX key (not DEMO), fits 80 chars
  PASS  sign -> insert -> verify returns the row grant
  PASS  verify with WRONG secret -> null
  PASS  verify detects a tampered DB grant -> null
  PASS  verify unissued real-format key -> null
  PASS  verify demo-format key (never issued) -> null
  PASS  verify garbage -> null
  PASS  verify with no secret -> null
  PASS  200 keys for identical claims are unique (random nonce) (got 200, want 200)
  PASS  module HAS real HMAC signing (not a stub)

== 5. FULL webhook → fulfillment loop ==
  PASS  W16-6: the two download fixtures are shutdown-guarded, not only cleaned inline
  PASS  W16-6: data/files carries no orphaned test_*.zip from an earlier aborted run
  PASS  paid webhook -> 200 (got 200, want 200)
  PASS  one item fulfilled (got 1, want 1)
  PASS  customer upserted
  PASS  order created paid
  PASS  order amount stored (got 4900, want 4900)
  PASS  order provider stored (got 'demo', want 'demo')
  PASS  one order item (got 1, want 1)
  PASS  license issued (real signed key that verifies)
  PASS  license active (got 'active', want 'active')
  PASS  activation limit from settings (got 3, want 3)
  PASS  download token issued (48 hex)
  PASS  download max_uses from settings (got 5, want 5)
  PASS  download expiry ≈ 72h from settings
  PASS  fulfillment email in outbox (demo mode, not sent)
  PASS  email points at the Lemon Squeezy receipt for the licence, and never carries a second key
  PASS  email contains download link
  PASS  DUPLICATE order_ref -> 200 (got 200, want 200)
  PASS  duplicate flagged (got true, want true)
  PASS  duplicate: NO double fulfillment (orders/items/licenses/downloads/outbox all unchanged) (got array (
  0 => 1,
  1 => 1,
  2 => 1,
  3 => 1,
  4 => 1,
), want array (
  0 => 1,
  1 => 1,
  2 => 1,
  3 => 1,
  4 => 1,
))
  PASS  multi-item order fulfills both (got 2, want 2)
  PASS  two licenses on multi order (got 2, want 2)
  PASS  two downloads on multi order (got 2, want 2)
  PASS  unknown sku -> 200 (got 200, want 200)
  PASS  unknown sku -> 0 fulfilled (got 0, want 0)
  PASS  unknown sku order still recorded
  PASS  pipeline: non-demo provider with stub -> 400 (fail closed) (got 400, want 400)
  PASS  pipeline: demo webhook rejected while real provider active (got 400, want 400)
  PASS  rejected webhook wrote NOTHING
  PASS  refund -> 200 (got 200, want 200)
  PASS  order marked refunded (got 'refunded', want 'refunded')
  PASS  ALL its licenses revoked (got 2, want 2)
  PASS  refund again idempotent -> 200 (got 200, want 200)
  PASS  refund of unknown ref -> 200 no-op

== 6. download tokens ==
  PASS  refunded order download -> 410 (got 410, want 410)
  PASS  valid token -> 200 (got 200, want 200)
  PASS  resolved path is inside data/files
  PASS  attachment filename derived from slug+tier+version
  PASS  used_count incremented (got 1, want 1)
  PASS  used_count capped at max_uses (atomic) (got 5, want 5)
  PASS  exhausted token -> 410 (got 410, want 410)
  PASS  expired token -> 410 (got 410, want 410)
  PASS  expired token consumed no use (got 0, want 0)
  PASS  garbage token -> 404 (got 404, want 404)
  PASS  well-formed unknown token -> 404 (got 404, want 404)
  PASS  edition without a file -> 404 (got 404, want 404)
  PASS  path-traversal download_file -> 404 (basename + realpath guard) (got 404, want 404)

== 7. license API ==
  PASS  check valid
  PASS  check wrong sku (got 'sku_mismatch', want 'sku_mismatch')
  PASS  check garbage key (got 'invalid_key', want 'invalid_key')
  PASS  check non-demo-format key (got 'invalid_key', want 'invalid_key')
  PASS  activate consumes a slot
  PASS  re-activate SAME domain idempotent (no slot consumed)
  PASS  normalized variants map to the same domain (still no slot)
  PASS  limit reached exactly
  PASS  over limit rejected
  PASS  same-domain still fine at limit (idempotent)
  PASS  domain normalization (got 'foo-bar.com', want 'foo-bar.com')
  PASS  invalid domain -> empty (got '', want '')
  PASS  activate with invalid domain (got 'invalid_domain', want 'invalid_domain')
  PASS  admin activation reset frees the slot (got 1, want 1)
  PASS  check on revoked (got 'revoked', want 'revoked')
  PASS  activate on revoked (got 'revoked', want 'revoked')
  PASS  reissue creates a NEW key
  PASS  old key revoked by reissue (got 'revoked', want 'revoked')
  PASS  old key now fails check (got 'revoked', want 'revoked')
  PASS  new key valid with a fresh activation budget
  PASS  Licensing::verify returns claims from the DB row

== 8. CSV formula-injection guard (numeric-aware) ==
  PASS  =-formula neutralized (got '\'=1+2', want '\'=1+2')
  PASS  @-formula neutralized (got '\'@SUM(A1)', want '\'@SUM(A1)')
  PASS  +cmd neutralized (got '\'+cmd', want '\'+cmd')
  PASS  +1 numeric -> KEPT (got '+1', want '+1')
  PASS  -text neutralized (got '\'-abc', want '\'-abc')
  PASS  negative number KEPT (got '-45.00', want '-45.00')
  PASS  leading TAB neutralized (got '\'	X', want '\'	X')
  PASS  leading CR neutralized + quoted
  PASS  plain value untouched (got 'Ava T', want 'Ava T')
  PASS  comma value quoted (got '"a,b"', want '"a,b"')
  PASS  quote value escaped (got '"say ""hi"""', want '"say ""hi"""')
  PASS  export header row (got 'name,amount', want 'name,amount')
  PASS  CRLF endings
  PASS  formula neutralized in real export
  PASS  negative amount preserved in export
  PASS  empty export -> empty string (got '', want '')

== 9. clip/clamp on write paths (MySQL strict-mode defense) ==
  PASS  customer email clipped to 190 (got 190, want 190)
  PASS  customer name clipped to 190 (got 190, want 190)
  PASS  webhook order_ref clipped to 190 (got 190, want 190)
  PASS  webhook currency clipped to 8 (got 8, want 8)
  PASS  webhook sku clipped to 80 (got 80, want 80)
  PASS  webhook amount clamped inside INT (got 2000000000, want 2000000000)
  PASS  100KB description survives clip(200000) intact

== 10. buyer-portal magic links ==
  PASS  unknown email -> true (no enumeration)
  PASS  …and no token row created (got 0, want 0)
  PASS  buyer with orders -> true
  PASS  portal token created (48 hex, 1h expiry)
  PASS  magic link is in the outbox email
  PASS  consume returns the customer id
  PASS  token is single-use
  PASS  expired magic link rejected
  PASS  garbage magic link rejected
  PASS  invalid email -> true, silent

== 11. per-IP rate limiter ==
  PASS  61st hit from same IP+bucket blocked
  PASS  different IP unaffected
  PASS  different bucket unaffected

== 12. Mailer message building (no socket) ==
  PASS  From header present
  PASS  To header present
  PASS  Subject header present
  PASS  MIME text/plain utf-8
  PASS  dot-stuffing applied
  PASS  CRLF stripped from To (header injection)
  PASS  CRLF stripped from Subject (header injection)
  PASS  encodeHeader UTF-8 -> RFC 2047 (got '=?UTF-8?B?Q2Fmw6k=?=', want '=?UTF-8?B?Q2Fmw6k=?=')
  PASS  send refuses when unconfigured (no socket)
  PASS  send refuses invalid recipient before any socket
  PASS  sendMail in demo/provider-demo mode -> outbox only, never a socket

== 13. auth + csrf ==
  PASS  stored hash verifies
  PASS  wrong password rejected
  PASS  empty stored csrf token can never match (bypass killed)
  PASS  non-matching token rejected by hash_equals
  PASS  matching token accepted

== 14. security hardening regressions ==
  PASS  csrf_check rejects empty stored token (hash_equals empty-token bypass)
  PASS  installer rejects empty install token (_it bypass)
  PASS  settings_save blocks writes in public demo mode
  PASS  settings view never echoes smtp_pass value
  PASS  settings view never echoes ls_webhook_secret value
  PASS  settings view never echoes stripe_webhook_secret value
  PASS  webhook handler NEVER echoes the raw body
  PASS  webhook exceptions leak no details (generic 500)
  PASS  download response sets nosniff + attachment
  PASS  image serve sets nosniff + whitelisted mime
  PASS  demo session cookie is None + Secure + Partitioned (CHIPS)
  PASS  buyer session cookie is HttpOnly + Lax + Secure-on-HTTPS
  PASS  session cookie named deliora
  PASS  dev router denies config.php / data / .sqlite
  PASS  .htaccess denies config.php / sqlite / demo marker
  PASS  .htaccess denies data/ (the deliverables live there)
  PASS  no error_log of credentials anywhere in mail/domain layer
  PASS  secrets never in Deliora logs: raw body never persisted
  PASS  MEDIUMTEXT used for big columns on MySQL
  PASS  license column avoids MySQL reserved word `key`
  PASS  portable UTC timestamps (no SQLite datetime() in domain/controllers)
  PASS  front controller catches boot errors (no stack traces)
  PASS  SaaS boot shim present verbatim
  PASS  license API rate-limited per IP
  PASS  portal + demo-checkout rate-limited
  PASS  licenseGate compares sku with hash_equals (constant time)
  PASS  installer generates license_secret + demo provider default
  PASS  CSV exports go through the guarded toCsv

== 15. schema migration v1.0 -> v1.1 ==
  PASS  install() left the v1.1 landing columns present
  PASS  install() left settings site_url + demo_base present
  PASS  comparisons + demo_clicks tables exist
  PASS  legacy shape reproduced (columns gone)
  PASS  migrate() restores landing columns
  PASS  migrate() restores settings columns + new tables
  PASS  old->new migration keeps every product row (got 2, want 2)
  PASS  old->new migration keeps row data intact (got 'Invoicer Pro', want 'Invoicer Pro')
  PASS  migrate() is idempotent (re-runs are no-ops, no throw)

== 16. Storefront helpers ==
  PASS  break-even ceil: 12900/6200 -> 3 (got 3, want 3)
  PASS  break-even ceil: 9900/900 -> 11 (got 11, want 11)
  PASS  break-even exact: 7900/7900 -> 1 (got 1, want 1)
  PASS  break-even guard: monthly 0 -> 0 (got 0, want 0)
  PASS  featuresFrom parses valid list
  PASS  featuresFrom garbage -> [] (got array (
), want array (
))
  PASS  featuresFrom wrong shape -> [] (got array (
), want array (
))
  PASS  featuresFrom skips titleless items (got 1, want 1)
  PASS  faqFrom parses valid list
  PASS  faqFrom garbage -> [] (got array (
), want array (
))
  PASS  validateFeaturesJson: empty + valid -> null
  PASS  validateFeaturesJson: broken JSON -> friendly error
  PASS  validateFeaturesJson: missing title -> item-numbered error
  PASS  validateFaqJson: missing answer -> friendly error
  PASS  sentence leaves an existing full stop alone (got 'Self-hosted invoicing.', want 'Self-hosted invoicing.')
  PASS  sentence adds one when missing (got 'Self-hosted invoicing.', want 'Self-hosted invoicing.')
  PASS  sentence respects a question mark (got 'Ready?', want 'Ready?')
  PASS  sentence respects an ellipsis (got 'Own it once…', want 'Own it once…')
  PASS  sentence leaves empty empty (got '', want '')
  PASS  sentence trims before deciding (got 'Tagline.', want 'Tagline.')
  PASS  the alternatives page never double-punctuates a tagline
  PASS  priceTextCurrency euro sign (got 'EUR', want 'EUR')
  PASS  priceTextCurrency EUR word (got 'EUR', want 'EUR')
  PASS  priceTextCurrency dollars (got 'USD', want 'USD')
  PASS  priceTextCurrency pound sign (got 'GBP', want 'GBP')
  PASS  priceTextCurrency GBP word (got 'GBP', want 'GBP')
  PASS  priceTextCurrency real Papertrail text (got 'GBP', want 'GBP')
  PASS  priceTextCurrency A$ is AUD (got 'AUD', want 'AUD')
  PASS  priceTextCurrency C$ is CAD (got 'CAD', want 'CAD')
  PASS  priceTextCurrency quote-gated falls back (got 'USD', want 'USD')
  PASS  priceTextCurrency empty falls back (got 'USD', want 'USD')
  PASS  a GBP price renders with a pound sign, not a dollar sign
  PASS  detector and renderer agree on the currency set
  PASS  vs-calc.js SYM covers every currency the detector returns
  PASS  siteBase trims trailing slash (got 'https://ownware.example', want 'https://ownware.example')
  PASS  canonical builds off site_url (got 'https://ownware.example/p/foo', want 'https://ownware.example/p/foo')
  PASS  demoTarget: product demo_url wins (got 'https://direct.example/x', want 'https://direct.example/x')
  PASS  demoTarget: template substitutes {slug} (got 'https://foo.demo.ownware.example', want 'https://foo.demo.ownware.example')
  PASS  demoTarget: non-http scheme rejected
  PASS  demoTarget: nothing configured -> null
  PASS  demo click upsert: ONE row, count incremented to 2
  PASS  demo click: second product gets its own row (got 2, want 2)

== 17. landing page render (XSS + SEO + JSON-LD) ==
  PASS  landing renders (non-empty, has storefront chrome)
  PASS  NO raw <script>alert survives ANY injected field
  PASS  product name escaped in h1
  PASS  feature title + blurb escaped
  PASS  FAQ rendered as details/summary (no JS accordion)
  PASS  pain + limitations escaped through md_render
  PASS  thanks: no false email promise when SMTP unset
  PASS  thanks: promises the email only when SMTP configured
  PASS  claim: offers the email-verified recovery route
  PASS  claim: posts to itself with a CSRF field
  PASS  claim: promises no key on the page itself (email-verified only)
  PASS  claim: points the buyer at spam before support
  PASS  claim route is registered GET+POST
  PASS  exactly one h1 (sane heading hierarchy) (got 1, want 1)
  PASS  canonical link off site_url
  PASS  meta description + og:title + twitter card present
  PASS  demo CTA present (demo_base template active)
  PASS  vs cross-link ABSENT with no comparison rows
  PASS  JSON-LD block present
  PASS  JSON-LD decodes to a schema.org @graph
  PASS  graph Product node: matching Offer (49.00 USD, InStock) + raw product name
  PASS  FREE product JSON-LD: SoftwareApplication with $0 offer, never a bare Product node
  PASS  offerMerchantFields default: shippingDetails + declared no-returns policy
  PASS  graph BreadcrumbList: Home › product, 2 positioned items ending at /p/xss-probe
  PASS  graph FAQPage: built from the REAL FAQ (question present, Answer typed), no raw <script> leaked
  PASS  faq source: the shared Q&A file returns categories
  PASS  /faq renders the Q&A (its canonical home)
  PASS  the help widget no longer inlines the generic answers into a page
  PASS  comparisons schema carries the per-competitor substance columns
  PASS  alternativesGrouped exposes the substance fields to the templates
  PASS  comparisons carries the source_dead flag
  PASS  UPGRADE PATH: migrate() re-adds the comparison-facts columns on an existing install
  PASS  UPGRADE PATH: alternativesGrouped() runs after the re-migration
  PASS  /faq is reachable from the site chrome, not just the widget (no orphan pages)
  PASS  /faq.json serves the same categories the widget renders
  PASS  home page now carries canonical + og:title + meta description (was missing entirely)
  PASS  home JSON-LD: Organization + WebSite graph, WebSite publisher-linked to the Organization

== 18. vs page render (cited rows ONLY) ==
  PASS  vs page renders with priced competitor (escaped) + price text
  PASS  vs page REFUSES the row with empty source_url
  PASS  vs page skips inactive rows
  PASS  quote-gated row renders qualitatively (name, no calculator entry)
  PASS  visible citation footnote: date + source link
  PASS  break-even line rendered with the right month count (ceil(4900/6200)=1), singular
  PASS  break-even never renders the "1 months" grammar defect
  PASS  calculator markup: data-own-cents from the edition
  PASS  calculator option carries the cited monthly cents
  PASS  calculator script included
  PASS  vs page links back to the landing page
  PASS  landing now cross-links the vs page (rows exist)
  PASS  vs page with zero renderable rows -> 404 page
  PASS  quote-gated-only vs page: NO calculator markup at all

== 18b. /alternatives — competitor-keyed inversion of /vs ==
  PASS  competitorSlug "When I Work" -> when-i-work (got 'when-i-work', want 'when-i-work')
  PASS  competitorSlug "Bill.com" -> bill-com (got 'bill-com', want 'bill-com')
  PASS  competitorSlug collapses/trims junk (got 'zoho-expense', want 'zoho-expense')
  PASS  competitorSlug all-punct -> "" (got '', want '')
  PASS  alternativesGrouped includes cited priced + quote-gated competitors
  PASS  alternativesGrouped enforces the honesty invariant (drops empty-source + inactive)
  PASS  alternativeBySlug(priced) -> product + break-even ceil(4900/6200)=1
  PASS  alternativeBySlug(quote-gated) -> no break-even (null monthly)
  PASS  alternativeBySlug(missing) -> null
  PASS  alternatives page ESCAPES the competitor name (no raw script)
  PASS  alternatives page renders break-even + the cited source link, singular
  PASS  alternatives page never renders the "1 months" grammar defect
  PASS  alternatives page cross-links the product + its /vs page
  PASS  alternatives page for an uncited competitor -> 404 (never surfaces)
  PASS  alternatives index lists cited, hides uncited

== 18c. /self-hosted — category & use-case landing pages ==
  PASS  selfhostedPages: 28 pages (>= the 14 shipped 2026-08), each fully formed (slug/label/h1/intro/slugs)
  PASS  selfhostedPages h1s carry the category keyword phrase
  PASS  productsBySlugs: active products only, with min price from editions
  PASS  productsBySlugs preserves caller order + drops unknowns
  PASS  selfhostedBySlug(unknown) -> null
  PASS  selfhostedPagesFor maps a product to its landing pages (pure map, no DB)
  PASS  /self-hosted hub renders with h1 + alternatives cross-link
  PASS  /self-hosted hub carries canonical + ItemList JSON-LD
  PASS  category page with no live products -> 404 (honesty: never an empty landing page)
  PASS  sitemap includes the /self-hosted hub + all 28 landing pages

== 18d. price-recheck — honest freshness (dates only, never prices) ==
  PASS  normalize folds tags/entities/unicode-dashes/whitespace/case
  PASS  quoteFragments splits the " ... " citation separator
  PASS  quoteStillPresent needs EVERY fragment (normalized match)
  PASS  recheck dry-run: 2 cited rows, 1 confirmed, 1 stale, dates untouched
  PASS  recheck --apply: confirmed row date bumped, stale row untouched, report stored
  PASS  recheck fetch-failure: rows counted, nothing flagged stale, no date moves (blocked vendor is not evidence)
  PASS  recheck reports a cited vendor that now answers on a different host
  PASS  recheck reports NO move when every citation lands where it pointed
  PASS  a moved citation is reported, never rewritten (the stored URL is untouched)

== 19. sitemap + robots ==
  PASS  sitemap is valid XML (simplexml parses)
  PASS  sitemap contains home + landing + vs URLs and EXCLUDES the private /portal (GSC 2026-07-29)
  PASS  sitemap entries carry lastmod
  PASS  sitemap includes the /alternatives hub + a cited competitor page
  PASS  inactive product excluded from sitemap
  PASS  vs URL only for products WITH citable rows (+ the static /vs/cloud page)
  PASS  robots.txt allows all + sitemap line

== 20. savings-calculator JS (source-level) ==
  PASS  vs-calc.js exists, is vanilla JS (no PHP, no frameworks)
  PASS  vs-calc.js writes via textContent ONLY (no innerHTML injection surface)
  PASS  vs-calc.js braces/parens balanced
  PASS  node not available in this container - syntax proven by balanced-brace check above (node --check run in CI/dev)

== 21. admin guards: csrf + validation ==
  PASS  admin_landing_save requires login + csrf_check
  PASS  admin_comparison_create requires login + csrf_check
  PASS  admin_comparison_update requires login + csrf_check
  PASS  admin_comparison_delete requires login + csrf_check
  PASS  settings save validates site_url + demo_base schemes
  PASS  comparison input: EMPTY source_url rejected with friendly error
  PASS  comparison input: non-http source rejected
  PASS  comparison input: valid row passes, blank cents -> NULL
  PASS  comparison input: clip to column widths (190/300/500)
  PASS  comparison input: cents clamped inside INT (got 2000000000, want 2000000000)
  PASS  landing input: broken features JSON -> friendly error
  PASS  landing input: FAQ missing answer -> friendly error
  PASS  landing input: bad demo URL -> friendly error
  PASS  landing input: valid payload passes; 150KB pain_md survives clip(200000)

== 22. bundles schema migration (additive + idempotent) ==
  PASS  install() left bundles + bundle_items + order_items.bundle_id present
  PASS  pre-bundles shape reproduced
  PASS  migrate() restores bundles + bundle_items + order_items.bundle_id
  PASS  bundles migration keeps every order_items row (got 3, want 3)
  PASS  bundles migrate() is idempotent (re-runs are no-ops, no throw)

== 23. suite fulfillment: 1 checkout -> N licenses + N downloads + 1 order ==
  PASS  suite SKU namespace parses (got 'toolkit', want 'toolkit')
  PASS  non-suite SKUs stay out of the namespace
  PASS  components = each product's PRIMARY (cheapest) edition, in sort order
  PASS  suite webhook -> 200 (got 200, want 200)
  PASS  suite expands: 2 components fulfilled (got 2, want 2)
  PASS  ONE order, paid, at the SUITE price
  PASS  2 order items, each tagged with the bundle (suite badge source)
  PASS  suite items carry the PRODUCT sku (not the suite sku)
  PASS  2 licenses issued under the one order (got 2, want 2)
  PASS  each suite license is a real signed key that verifies
  PASS  suite licenses work with the license API per PRODUCT sku
  PASS  2 download tokens issued under the one order (got 2, want 2)
  PASS  ONE outbox email lists EVERY included product
  PASS  …and never a second licence key, for any product in the suite
  PASS  …and each product's download link
  PASS  …and names the suite
  PASS  DUPLICATE suite webhook -> 200 + duplicate flag
  PASS  duplicate suite: identical state (orders/items/licenses/downloads/outbox unchanged) (got array (
  0 => 4,
  1 => 5,
  2 => 6,
  3 => 7,
  4 => 6,
), want array (
  0 => 4,
  1 => 5,
  2 => 6,
  3 => 7,
  4 => 6,
))
  PASS  suite refund -> 200 (got 200, want 200)
  PASS  suite order marked refunded (got 'refunded', want 'refunded')
  PASS  refund revokes ALL N suite licenses (got 2, want 2)
  PASS  unknown suite -> 200, order recorded, 0 fulfilled
  PASS  mixed order fulfills suite components + the plain item (3 licenses)
  PASS  mixed order: plain item stays untagged, suite items tagged

== 24. suite savings math is computed LIVE (never hardcoded) ==
  PASS  suiteTotals: sum of members' single prices (4900+5900) (got 10800, want 10800)
  PASS  suiteTotals: savings vs the 8900 suite price (got 1900, want 1900)
  PASS  suiteTotals: member count (got 2, want 2)
  PASS  …and the suite math CHANGES on the next read (data layer)
  PASS  suite page renders the LIVE figures ($128.00 separately, save $39.00)
  PASS  price restored -> page recomputes ($108.00 separately, save $19.00)

== 24b. cross-sell band: best suite per member product, live math, ONE band ==
  PASS  bestSuiteFor: member product -> its active suite with LIVE totals attached
  PASS  bestSuiteFor: product in NO active bundle -> null (no band data)
  PASS  member landing renders the band: BETTER TOGETHER eyebrow + names + live figures
  PASS  band is link-only: "See the suite" -> /s/{slug}; NO buy CTA inside the band
  PASS  …and the band math CHANGES at the data layer (sum 12800, save 3900 — never stored)
  PASS  …and the rendered band recomputes on the next request ($128.00 separately — save $39.00)
  PASS  product in TWO active suites -> the bigger absolute saving wins (2900 > 1900)
  PASS  multi-suite member renders a band for EVERY topic suite it belongs to, best saving FIRST (contract changed 2026-08-30: one band hid the Front-Desk Suite from half its members)
  PASS  deactivated bundle drops out of the ranking (band falls back to the active suite)

== 25. suite landing page (XSS + JSON-LD + structure) ==
  PASS  suite page renders (storefront chrome)
  PASS  NO raw <script>alert survives ANY injected bundle field
  PASS  suite name escaped in h1
  PASS  exactly one h1 on the suite page (got 1, want 1)
  PASS  per-product cards link to their /p/ pages
  PASS  combined honest-limitations note carries the members' limitations (escaped)
  PASS  suite FAQ present (details/summary, no JS)
  PASS  Buy CTA points at the suite checkout path
  PASS  suite JSON-LD decodes to schema.org Product
  PASS  suite JSON-LD Offer price = the BUNDLE price
  PASS  suite JSON-LD url is the canonical /s/ page
  PASS  deactivated suite -> 404 page (nothing leaks)

== 26. storefront suites strip + sitemap ==
  PASS  home renders the Suites strip with the suite (escaped) + live savings
  PASS  strip links to the /s/ landing page
  PASS  sitemap includes the /s/ suite pages
  PASS  sitemap is still valid XML with suites
  PASS  deactivated suite drops out of the sitemap
  PASS  deactivated suite drops off the home strip too

== 27. bundles admin: input clip/clamp + csrf + immutable slug ==
  PASS  bundle input: valid payload passes
  PASS  bundle slug sanitized to SKU-safe form (got 'my-suite', want 'my-suite')
  PASS  bundle input clipped to column widths (190/255/190/300/8)
  PASS  bundle price clamped inside INT (got 2000000000, want 2000000000)
  PASS  bundle items: only REAL product ids survive; sort clamped
  PASS  bundle input: no real products -> friendly error; missing slug -> error
  PASS  admin_bundle_create requires login + csrf_check
  PASS  admin_bundle_update requires login + csrf_check
  PASS  admin_bundle_delete requires login + csrf_check
  PASS  suite slug is IMMUTABLE on update (input without slug; UPDATE never touches slug)
  PASS  sold suites are protected from deletion (deactivate instead)

== 28. ownware.io storefront seed (dev tree only - excluded from dist) ==
  PASS  seed is idempotent (second run: identical row counts) (got array (
  'products' => 55,
  'editions' => 107,
  'comparisons' => 196,
  'bundles' => 15,
  'bundle_items' => 146,
  'guides' => 114,
), want array (
  'products' => 55,
  'editions' => 107,
  'comparisons' => 196,
  'bundles' => 15,
  'bundle_items' => 146,
  'guides' => 114,
))
  PASS  reseed PRESERVES launch flags when ON (live store never un-launched)
  PASS  reseed PRESERVES launch flags when OFF (staging stays dark)
  PASS  seed created all 27 storefront products (got 27, want 27)
  PASS  seed created the 4 products added on 2026-07-07 (got 4, want 4)
  PASS  the products added on 2026-07-07: demo_urls follow the live <slug>.ownware.io scheme
  PASS  prices on the 2026-08-20 bands: cashora $59 / permora $89 (kept) / certora $79 / commissa $69 (kept) (got array (
  0 => 5900,
  1 => 8900,
  2 => 7900,
  3 => 6900,
), want array (
  0 => 5900,
  1 => 8900,
  2 => 7900,
  3 => 6900,
))
  PASS  the products added on 2026-07-07 now carry comparison rows, and EVERY row is source-cited (zero-fab)
  PASS  the products added on 2026-07-07: features/faq JSON parse (5+/4+ entries) and theme colors are valid 6-hex
  PASS  /p/permora renders: brand + tracked live-demo button (/demo/permora)
  PASS  premium prices: rentara $119 (comp-pinned 2026-07-06) (got 11900, want 11900)
  PASS  premium prices: fixora $129 / specta $99 / deliora $99 / saas-kit $79 (got array (
  0 => 12900,
  1 => 9900,
  2 => 9900,
  3 => 7900,
), want array (
  0 => 12900,
  1 => 9900,
  2 => 9900,
  3 => 7900,
))
  PASS  every seeded comparison row carries a source_url (zero uncited) (got 0, want 0)
  PASS  rentara has the Buildium row with the verified $62 figure
  PASS  deliora fee-model rows (Gumroad, Lemon Squeezy) are NULL-cents — subscription rivals added 2026-08-31 carry real monthly prices
  PASS  quote-gated categories seeded without numbers (menura/packora)
  PASS  complia: every priced row carries a source URL (the number came from the vendor, never from us)
  PASS  seed set the storefront settings (site_url; demo_base EMPTY — demos are explicit per product)
  PASS  seed created all 6 themed suites (active) (got 6, want 6)
  PASS  suite 'compliance': price 29900, all 5 members present
  PASS  suite 'compliance': INVARIANT price < sum of singles (43500) AND > any single (11900)
  PASS  suite 'restaurant-ops': price 14900, all 3 members present
  PASS  suite 'restaurant-ops': INVARIANT price < sum of singles (26700) AND > any single (9900)
  PASS  suite 'field-service': price 36900, all 5 members present
  PASS  suite 'field-service': INVARIANT price < sum of singles (46500) AND > any single (12900)
  PASS  suite 'property': price 14900, all 2 members present
  PASS  suite 'property': INVARIANT price < sum of singles (20300) AND > any single (11900)
  PASS  suite 'ai-documents': price 19900, all 5 members present
  PASS  suite 'ai-documents': INVARIANT price < sum of singles (40500) AND > any single (9900)
  PASS  suite 'front-desk': price 15900, all 4 members present
  PASS  suite 'front-desk': INVARIANT price < sum of singles (26600) AND > any single (7900)
  PASS  property suite math: 11900 + 8400 = 20300 separately -> save 5400 (computed live)
  PASS  seeding twice leaves suite membership identical (wholesale replace)
  PASS  seed created the 5 launch guides, all PUBLISHED (got 5, want 5)
  PASS  run-twice: guide count equals the seed lists exactly (upsert by slug, no duplicates) (got 132, want 132)
  PASS  t2: jobora is a listed, active product
  PASS  t2: jobora single-tier price (got 12900, want 12900)
  PASS  t2: jobora has an extended tier too
  PASS  t2: jobora points at its own live demo host (got 'https://jobora.ownware.io', want 'https://jobora.ownware.io')
  PASS  t2: warrantora is a listed, active product
  PASS  t2: warrantora single-tier price (got 7900, want 7900)
  PASS  t2: warrantora has an extended tier too
  PASS  t2: warrantora points at its own live demo host (got 'https://warrantora.ownware.io', want 'https://warrantora.ownware.io')
  PASS  t2: at least the eleven cited comparison rows across the two products (now 12)
  PASS  t2: every row carries a live source, a verbatim quote, a date and the substance fields (got array (
), want array (
))
  PASS  t2: every cited competitor has an /alternatives page offering the right product (got array (
), want array (
))
  PASS  hub: the gym-studio page exists with products
  PASS  hub: gym-studio resolves to the Studio Suite (largest member overlap, whole-catalog bundles excluded)
  PASS  hub: its alternatives list carries the gym rivals we have pages for (glofox, mindbody, pushpress)
  PASS  hub: two priciest USD rivals with year-one = monthly × 12, dated and sourced
  PASS  hub: at least one guide mentions a gym-studio product
  PASS  hub page renders the suite card, the rented-year lines and the alternatives strip
  PASS  hub view carries no typed dollar figure
  PASS  /for/{vertical} is routed to the vertical page and /for to the index
  PASS  llms.txt lists every /self-hosted vertical and category page (was 0 lines)
  PASS  L1.2: the Field-Service Suite exists in the seed
  PASS  L1.2: field-service picks two USD rivals, priciest first, year = 12 × monthly, sourced + dated
  PASS  L1.2: the suite page renders the rented-year block with the rival names
  PASS  L1.2: a suite whose rivals are usage-priced or non-USD simply shows no block (never an invented figure)
  PASS  L1.2: the whole-catalog bundles show NO rented-year block (two-of-a-hundred would be selective)
  PASS  L1.2: suite view still carries no typed dollar figure
  PASS  L2.8: the product page links each cited competitor's /alternatives page
  PASS  L2.8: the alternatives page links the product's suite
  PASS  L2.8: guideAlternatives resolves comparison pages ONLY for the products a guide links (capped at 8)
  PASS  L2.8: the field-service guide renders its related-comparisons box
  PASS  /alternatives/servicetitan resolves to jobora with a sourced, dated row
  PASS  /alternatives/fieldpulse resolves to jobora with a sourced, dated row
  PASS  /alternatives/fieldedge resolves to jobora with a sourced, dated row
  PASS  /alternatives/service-fusion resolves to jobora with a sourced, dated row
  PASS  /alternatives/kickserv resolves to jobora with a sourced, dated row
  PASS  /alternatives/shopify-pos resolves to vendra with a sourced, dated row
  PASS  /alternatives/erply resolves to vendra with a sourced, dated row
  PASS  /alternatives/hike-pos resolves to vendra with a sourced, dated row
  PASS  /alternatives/korona-pos resolves to vendra with a sourced, dated row
  PASS  /alternatives/zen-planner resolves to gymora with a sourced, dated row
  PASS  /alternatives/pushpress resolves to gymora with a sourced, dated row
  PASS  /alternatives/wodify resolves to gymora with a sourced, dated row
  PASS  /alternatives/booksy resolves to slotly with a sourced, dated row
  PASS  /alternatives/emaint resolves to fixora with a sourced, dated row
  PASS  /alternatives/fmx resolves to fixora with a sourced, dated row
  PASS  /alternatives/facilio resolves to fixora with a sourced, dated row
  PASS  /alternatives/hippo-cmms-eptura resolves to fixora with a sourced, dated row
  PASS  /alternatives/azuga resolves to fleetora with a sourced, dated row
  PASS  /alternatives/fleet-complete resolves to fleetora with a sourced, dated row
  PASS  /alternatives/mariana-tek resolves to gymora with a sourced, dated row
  PASS  /alternatives/fresha resolves to slotly with a sourced, dated row
  PASS  /alternatives/vagaro resolves to slotly with a sourced, dated row
  PASS  /alternatives/workiz resolves to jobora with a sourced, dated row
  PASS  /alternatives/tradogram resolves to approva with a sourced, dated row
  PASS  /alternatives/payhip resolves to deliora with a sourced, dated row
  PASS  /alternatives/sendowl resolves to deliora with a sourced, dated row
  PASS  /alternatives/sellfy resolves to deliora with a sourced, dated row
  PASS  /alternatives/bonsai resolves to invora with a sourced, dated row
  PASS  /alternatives/honeybook resolves to invora with a sourced, dated row
  PASS  /alternatives/invoicely resolves to invora with a sourced, dated row
  PASS  /alternatives/sortly resolves to restock with a sourced, dated row
  PASS  /alternatives/zoho-inventory resolves to restock with a sourced, dated row
  PASS  /alternatives/skiplino resolves to tokora with a sourced, dated row
  PASS  quote-gated rows carry NULL cents — no invented monthly figure
  PASS  non-USD rows (Fresha EUR, Vagaro GBP, Shopify POS EUR) carry NULL cents — no FX baked into a page
  PASS  Wodify is cited at its standing $199 per location, not the August promo
  PASS  Lightspeed Retail row names X-Series and was re-read today at the same $89
  PASS  t2: both guides seeded (got 2, want 2)
  PASS  t2: both guides are published and date every figure they quote (got array (
), want array (
))
  PASS  flagship guide: all 5 verified comp figures present, each with source link + checked-2026-07-05 framing
  PASS  flagship guide: 3-year totals are exact arithmetic on the cited figures (62/135/79/159/199 × 36)
  PASS  seed carries the per-competitor substance (who_should_stay filled on 80+ rows)
  PASS  seed carries the Avalara correction ($699/state/yr), dated to its most recent read
  PASS  seed carries the ContractWorks source_dead fix (withdrawn pricing page)
  PASS  storefront copy denies no feature the catalog actually ships ()
  PASS  seed PRESERVES editions.version (release script is the authority)
  PASS  seed PRESERVES editions.price_cents + currency (the shop is the authority on price)
  PASS  LS custom-data: sku+tier appended to a bare checkout URL
  PASS  LS custom-data: appended with & when the URL already has a query
  PASS  LS custom-data: idempotent — appending twice does not duplicate
  PASS  LS custom-data: empty tier normalizes to single
  PASS  every guide is substantial (330–1400 words) and links into the store (/p or /s)
  PASS  flagship guide page renders with sources linked + related-product pills from its body links
  PASS  dated guide carries its authoring date from the seed, not deploy day
  PASS  reseed HEALS a wrongly-stamped created_at back to the seed date
  PASS  reseed does NOT touch an unchanged guide (updated_at sentinel survives change-detection)
  PASS  guidesMentioning finds the CMMS teardown for fixora
  PASS  product page renders the "Covered in these guides" band with a guide link
  PASS  publish gate: the de-linked AI-Act guide publishes; the CRA guide is unaffected
  PASS  publish gate: a guide whose product IS listed publishes normally (not a blanket)
  PASS  publish gate: a body with no store link at all cannot publish either
  PASS  publish gate: the listed corpus is untouched by it
  PASS  publish gate: every published guide links only to products that are listed and active
  PASS  seed set explicit demo_url on all 27 apps (25 bare host · slotly + saas-kit → their console)
  PASS  seed gave all 27 a VALID 6-hex theme_color (got 0, want 0)
  PASS  seed gave all 27 a manifest with a real banner + >=3 existing shots (got 0, want 0)
  PASS  rentara manifest is exactly what the shipped tree holds (idempotent reseed source)
  PASS  rentara landing: hero banner image served via /shot/ route
  PASS  rentara landing: derived accent scoped inline
  PASS  rentara landing: all 4 shots render, twice in gallery + once in JSON-LD (got 12, want 12)
  PASS  rentara still ships 4 gallery shots in its manifest (got 4, want 4)
  PASS  rentara landing: prominent demo button through the tracked /demo/ redirect
  PASS  bestSuiteFor(rentara) -> Property Suite with live totals (20300 sum, 5400 saved)
  PASS  rentara landing: cross-sell band — Property Suite, 2 tools for $149.00 ($203.00 separately — save $54.00)
  PASS  OS-only product (votera): NO cross-sell band (the whole-catalog flagship never upsells), page intact
  PASS  suite page shows its own banner beside the hero
  PASS  every member card opens with the product's shipped banner
  PASS  an unknown or malformed suite slug has no banner
  PASS  every real suite ships a banner (thirteen: ten workflow suites + the whole-catalog two + Back-Office)
  PASS  exactly 3 ACTIVE of the classic 27 sit outside every focused suite — certora, deliora, secreta (2026-08-30 ruling: the Back-Office Suite took invora + approva; nexura is unlisted 2026-08-24 and must stay uncounted — this goes red if it reactivates without a suite) (got 3, want 3)
  PASS  saas-kit landing: demo button present, pointing at the guided tour
  PASS  vendra landing (sales live, post-Codester): NO Codester anywhere; unwired edition shows notify capture, not a dead Buy
  PASS  vendra landing: price is $59.00 (2026-08-20 register band), never the stale $34.00
  PASS  vendra landing: live demo links to the verified external host, not the dead /demo/ route or the .demo.ownware.io template
  PASS  home grid links a card for EVERY active one of the 27 products (got array (
), want array (
))
  PASS  home grid does NOT card unlisted nexura
  PASS  home keeps the 5-suite strip above the curated catalog sections
  PASS  home shows exactly 59 Try-demo buttons (37 + 11 added on 2026-08-22 in the catalog + the same 11 in the what's-new band — nexura unlisted 2026-08-24, aiactora unlisted 2026-09-06) (got 59, want 59)
  PASS  home cards carry banner thumbnails + accent scoping + a "View details" funnel button (all 27 identical)
  PASS  sample products without shipped images fall back to monogram/uploaded cover (no broken img)
  PASS  the rack carries the real dashboards (fixora / menura / invora shots among them)
  PASS  carousel: exactly 8 curated slides, anchors → 1.1 flagships → AI showpieces, in order (got array (
  0 => 'invora',
  1 => 'slotly',
  2 => 'vendra',
  3 => 'rentara',
  4 => 'fixora',
  5 => 'specta',
  6 => 'menura',
  7 => 'extracta',
), want array (
  0 => 'invora',
  1 => 'slotly',
  2 => 'vendra',
  3 => 'rentara',
  4 => 'fixora',
  5 => 'specta',
  6 => 'menura',
  7 => 'extracta',
))
  PASS  carousel: 8 <article class="slide"> entries (nothing else in the track) (got 8, want 8)

== T6 unit 3 (2026-08-31): the answer to github.com, on the 11 gap pages + 14 hubs ==
  PASS  repo_answer.php prose contains NO typed number — price and count are derived
  PASS  the gap set is the ten products the audit found absent (aiactora unlisted 2026-09-06) (got 10, want 10)
  PASS  repo answer renders on all 10 gap product pages with the right price (aiactora unlisted 2026-09-06) (got 10, want 10)
  PASS  repo answer is absent from /p/invoicer-pro (outside the audit gap set)
  PASS  repo answer renders on all 28 /self-hosted hubs with a derived count (got 28, want 28)
  PASS  T6 unit 3 total coverage: every gap page + every hub (got 38, want 38)
  PASS  the catalogue slug set was read from the seed (not guessed)
  PASS  llms.txt carries a line for every active catalogue product (got 49, want 49)
  PASS  every catalogue product line in llms.txt names a cited competitor
  PASS  cashora cites Pleo from a real source URL
  PASS  certora cites Certifier from a real source URL
  PASS  permora cites PermitFlow from a real source URL

== 29. presentation: theme accents + shipped gallery ==
  PASS  install() left theme_color + images_json present
  PASS  pre-presentation shape reproduced
  PASS  migrate() restores theme_color + images_json (additive, data kept)
  PASS  presentation migrate() is idempotent (re-runs are no-ops, no throw)
  PASS  themeColor: valid hex normalized lowercase (got '#21b5cb', want '#21b5cb')
  PASS  themeColor: 3-hex / no-# / css-injection / attr-breakout / null all rejected
  PASS  themeStyle: invalid input -> empty string (no style attribute emitted) (got '', want '')
  PASS  themeStyle: exactly four derived accent vars, ALL locked to 6-hex values
  PASS  themeBlend midpoint math (got '#808080', want '#808080')
  PASS  storeImages: ONLY the existing whitelisted image survives (missing / traversal / .php dropped)
  PASS  storeImages: garbage JSON -> empty manifest (got array (
  'banner' => NULL,
  'shots' => 
  array (
  ),
), want array (
  'banner' => NULL,
  'shots' => 
  array (
  ),
))
  PASS  shotPath maps the manifest path onto the nosniff route (got 'shot/zz-test-probe/shot-01.jpg', want 'shot/zz-test-probe/shot-01.jpg')
  PASS  shotPath stamps a real image with its mtime
  PASS  landing scopes the VALIDATED accent inline
  PASS  gallery renders ONLY the existing file via /shot/ (missing + traversal entries absent)
  PASS  demo button hidden when demo_url empty and no demo_base template
  PASS  INVALID stored theme_color never reaches the page (no accent vars, no attribute breakout)
  PASS  demo button reappears via the demo_base template (tracked /demo/ redirect)
  PASS  store_asset_serve: nosniff + realpath jail + whitelisted mime (source level)

== 30. launch-mode flags: coming-soon gating + notify waitlist ==
  PASS  pre-flags shape reproduced
  PASS  migrate() restores demos_live + sales_live + notify_signups
  PASS  flags migrate() is idempotent (re-runs are no-ops, no throw)

== notify double opt-in ==
  PASS  signup mints a 48-hex confirm token
  PASS  row starts UNconfirmed
  PASS  confirm by token succeeds
  PASS  row is now confirmed
  PASS  re-click is idempotent (still true, timestamp unchanged)
  PASS  garbage token rejected
  PASS  duplicate signup keeps the ORIGINAL token (no token churn)
  PASS  pre-opt-in row (empty token) gets a token minted on re-signup
  PASS  confirm route is registered
  PASS  welcome mail carries the confirm link

== deal-code redemption ==
  PASS  gate: /redeem is OFF while no codes exist
  PASS  normalize: lowercase/spaces/junk collapse to canonical code
  PASS  gate: codes seeded switches /redeem ON
  PASS  unknown code refused
  PASS  invalid email refused
  PASS  unfulfillable sku refused as config (code NOT burned)
  PASS  valid redeem succeeds via normalized input (lowercase in, RD- ref out)
  PASS  redeem created a paid $0 appsumo order
  PASS  redeem issued exactly one license + one download
  PASS  code row marked redeemed with buyer email + order id
  PASS  same code + same email re-surfaces the SAME order (idempotent, no new fulfillment)
  PASS  same code + DIFFERENT email refused
  PASS  redeem routes registered
  PASS  follow-up: fresh redemption (today) is NOT yet eligible
  PASS  follow-up: 8-day-old redemption IS eligible exactly once
  PASS  follow-up: refunded order is excluded (never ask a refunder for a review)
  PASS  follow-up: marked rows never re-send
  PASS  follow-up: script ships + sends exactly one mail, no drip
  PASS  gate: back OFF after cleanup (buyer stores never expose /redeem by accident)

== Own It 2.0 ==
  PASS  v2: tables + columns migrated
  PASS  v2: mintKey stores only the hash; revocation kills lookup
  PASS  v2: TOTP verify + drift + recovery consume-once
  PASS  v2: outbound webhook delivery logged with failure detail
  PASS  v2: routes registered (owner api, 2fa, security, backup, import, healthz)
  PASS  v2: login intercepted (2FA + rate limit) and fulfillment fires owner events
  PASS  v2: admin dark mode scoped away from the storefront + theme assets ship
  PASS  restored flag columns default OFF (got array (
  0 => 0,
  1 => 0,
), want array (
  0 => 0,
  1 => 0,
))
  PASS  home OFF: "Demo — coming soon" chips + ZERO internal /demo/ hrefs; grid never sells (no Codester links, cards funnel through "View details")
  PASS  home OFF (dev tree): live Try-demo links only for the external quartet, only to their verified hosts; cards present
  PASS  vendra landing (sales OFF, post-Codester): NO Codester, NO on-site /buy/, notify capture present, price still $59.00
  PASS  landing OFF: demo chip present, NO /demo/ href anywhere
  PASS  landing OFF: hero shows "Available soon — get notified", no Buy/own-it CTAs
  PASS  landing OFF: notify form carries csrf + honeypot + the product slug
  PASS  cross-sell band under sales_live=0: still renders, links ONLY the (gated) suite page
  PASS  vs page OFF: comparisons + citations + calculator STILL render
  PASS  vs page OFF: Buy CTAs replaced by get-notified, demo link replaced by chip
  PASS  suite page OFF: live savings math kept, /buy-suite/ gone, notify form with suite slug
  PASS  /demo/{slug} with demos_live=0 -> 404 page, NO redirect
  PASS  …and NO click row was recorded (got 3, want 3)
  PASS  /buy/{id} with sales_live=0 -> 404 page (no provider hand-off)
  PASS  /checkout/demo/{id} gated -> 404 (fake fulfillment unreachable from public UI)
  PASS  /buy-suite/{id} + /checkout/suite/{id} gated -> 404
  PASS  ALL six checkout entry handlers call the sales gate FIRST (source level)
  PASS  webhook endpoint is NOT gated by the launch flags (existing buyers/refunds)
  PASS  notifySignup stores a validated row (lowercased email)
  PASS  duplicate signup is a silent success and stays ONE row (idempotent)
  PASS  same email may follow a DIFFERENT product / the whole store
  PASS  invalid email rejected, nothing stored
  PASS  product_slug sanitized to SKU alphabet + clipped to 80
  PASS  notify endpoint: csrf + per-IP rate limit + honeypot drop (source level)
  PASS  notify CSV export goes through the guarded _csv_out/toCsv path
  PASS  notify export cells stay formula-guarded (numeric-aware)
  PASS  flags ON + wired edition: demo link + Buy button + own-it-once hero restored, notify UI gone
  PASS  home ON: live Try-demo links return, chips gone
  PASS  suite ON: Buy-the-suite CTA back, notify form gone
  PASS  payment webhook fulfills normally under both flags OFF
  PASS  /license/check unaffected by the flags
  PASS  buyer re-download still serves under both flags OFF (got 200, want 200)
  PASS  buyer portal still lists the order, key, and download link under both flags OFF

== 31. storefront narrative, title dedupe, favicon, editorial skin scope ==
  PASS  home <title> is the full SEO title, store name once (no "Store · Store")
  PASS  non-home pages keep "Page · Store" titles
  PASS  product pages keep their SEO title (name — tagline)
  PASS  assets/favicon.png ships (non-empty PNG)
  PASS  storefront layout links rel=icon + apple-touch-icon
  PASS  admin layout links the favicon too (source level)
  PASS  home narrative: hero → #idea → #compare → #pillars → #complete → #catalog → grid, in order
  PASS  rent-vs-own comparison renders (both columns + the illustrative range, no invented stats)
  PASS  three self-hosted pillars render
  PASS  storefront layout links store.css + carries body.storefront
  PASS  Signal CSS carries the approved token set (light-first + dark) and the legacy aliases read it
  PASS  editorial CSS: self-hosted fonts (no hotlink), mono accents, tag.soon chip, reduced-motion
  PASS  no glass surfaces outside the flagship block: backdrop blur ONLY on the sticky header; no feTurbulence; the glow radial is bounded
  PASS  the flagship exemption is one marked block, present once, and the only place feTurbulence appears
  PASS  no admin or data-grid selectors in store.css
  PASS  home hero is the Signal hero (sig-hero + Machine SVG + rack), no glass class anywhere
  PASS  the rack renders: 30+ dashboard cards, 7 chips, filter input, both detail links
  PASS  Signal brand: wordmark link in the header, brand block in the footer columns, no blue dot
  PASS  admin stylesheet + admin layout stay skin-free (no backdrop-filter, store.css not linked)
  PASS  portal + admin views carry no glass class and no backdrop-filter
  PASS  storefront views carry no glass class either (editorial system replaced it)

== 32. guides engine: migrate, CRUD guards, published-only, XSS, links, JSON-LD, sitemap, nav ==
  PASS  install() left the guides table present
  PASS  legacy shape reproduced (guides table gone)
  PASS  migrate() restores the guides table with the full column set
  PASS  guides migration is idempotent (re-runs are no-ops, no throw)
  PASS  guide input: slug sanitized, title→190, description→300, body→200000, published=1
  PASS  guide input: unchecked publish box stays a draft (0) (got 0, want 0)
  PASS  admin_guide_create requires login + csrf_check
  PASS  admin_guide_update requires login + csrf_check
  PASS  admin_guide_delete requires login + csrf_check
  PASS  guides index: published guide listed (escaped), draft invisible
  PASS  guides index: canonical + storefront chrome
  PASS  draft guide page -> 404 view, nothing leaks
  PASS  guide body renders escape-first: NO script/onerror survives any field
  PASS  markdown structure renders: # -> h2, ## -> h3, bold, list
  PASS  exactly one h1 on a guide page (got 1, want 1)
  PASS  internal /p link renders as an anchor; external https link carries rel=noopener
  PASS  javascript: scheme is REFUSED — stays literal escaped text, never an href
  PASS  JSON-LD Article decodes with headline + canonical url + dates
  PASS  related band: ACTIVE linked product gets a pill; inactive linked product does not
  PASS  guide page ends with the store CTA block
  PASS  storefront nav + footer both link the guides index
  PASS  sitemap lists /guides + the published guide, never the draft
  PASS  sitemap is still valid XML with guides
  PASS  unpublishing 404s the page AND removes it from the sitemap
  PASS  with zero published guides the /guides index drops out of the sitemap too

== PWA ==
  PASS  pwaManifest() returns the required fields
  PASS  manifest name follows store_name setting (falls back to Deliora)
  PASS  manifest URLs are RELATIVE (subpath-install safe)
  PASS  manifest icons exist on disk (192 + 512 + apple-touch)
  PASS  sw.js never caches non-GET
  PASS  sw.js never caches page navigations
  PASS  sw.js cache versioned + purges old caches
  PASS  offline fallback ships
  PASS  both layouts (admin + store) link the manifest + register the SW
  PASS  the /manifest.json ROUTE is registered
  PASS  bin/broadcast.php loads StoreApi + OutWebhook (Deliora.php calls both)
  PASS  bin/demo.php loads StoreApi + OutWebhook (Deliora.php calls both)
  PASS  bin/export-ls-descriptions.php loads StoreApi + OutWebhook (Deliora.php calls both)
  PASS  bin/flush-outbox.php loads StoreApi + OutWebhook (Deliora.php calls both)
  PASS  bin/list-stats.php loads StoreApi + OutWebhook (Deliora.php calls both)
  PASS  bin/ownware-deliverable.php loads StoreApi + OutWebhook (Deliora.php calls both)
  PASS  bin/ownware-release.php loads StoreApi + OutWebhook (Deliora.php calls both)
  PASS  bin/ownware-seed.php loads StoreApi + OutWebhook (Deliora.php calls both)
  PASS  bin/ownware-store.php loads StoreApi + OutWebhook (Deliora.php calls both)
  PASS  bin/redeem-codes.php loads StoreApi + OutWebhook (Deliora.php calls both)
  PASS  bin/review-followup.php loads StoreApi + OutWebhook (Deliora.php calls both)
  PASS  bin/wire-extended-variants.php loads StoreApi + OutWebhook (Deliora.php calls both)
  PASS  bin/wire-oya-checkouts.php loads StoreApi + OutWebhook (Deliora.php calls both)
  PASS  bin/wire-oya-release.php loads StoreApi + OutWebhook (Deliora.php calls both)
  PASS  bin/wire-single-checkouts.php loads StoreApi + OutWebhook (Deliora.php calls both)
  PASS  bin/wire-suite-checkouts.php loads StoreApi + OutWebhook (Deliora.php calls both)

== v3 ==
  PASS  v3: dropped v3 tables restored by migrate()
  PASS  v3: role/active/branding/token/oidc columns present
  PASS  v3: settings singleton ensured with EXPLICIT id=1
  PASS  v3: index.php migrates at boot
  PASS  v3: 8 shared cores byte-identical to the reference copy (Ical N/A by design)
  PASS  W16-8: the dev tree runs the REAL byte-identity branch, never the buyer-zip skip
  PASS  v3: healthz/ping/openapi all say 3.1.1
  PASS  v3: sw cache is static-v3.1.1
  PASS  v3: README has New in 3.0 + API.md has the MCP section
  PASS  v3: backup redaction widened + shared (export uses DELIORA_BACKUP_REDACT, scheduled too)
  PASS  v3: GET /mcp transport-hint route registered
  PASS  v3: requireKey checks u.active (deactivated users keys die)
  PASS  v3: deploy kit filled (deliora/acme/8090, no placeholders)
  PASS  v3: kit healthcheck is the json_decode probe with $$ escape
  PASS  v3: mint core refuses unknown sku by name
  PASS  v3: invite token verifies + expiry honoured
  PASS  v3: last-admin guard math
  PASS  nav: every sidebar link is highlighted by the page it opens
  PASS  nav: no page highlights a sidebar item that does not exist
  PASS  ip: a direct visitor's forged headers are ignored
  PASS  ip: behind a trusted proxy the forwarded visitor is used
  PASS  ip: CF-Connecting-IP wins over the X-Forwarded-For chain
  PASS  ip: the chain is read right-to-left, past trusted hops
  PASS  ip: a Cloudflare edge is not a trusted proxy by default
  PASS  ip: CIDR maths (v4 boundaries + v6, no cross-family match)
  PASS  urls: a cron never derives a base path from its own script name
  PASS  urls: a cron-built URL keeps the host and path separate
  PASS  urls: a cron uses the canonical site_url when one is configured
  PASS  urls: cron-built download links are absolute and correct
  PASS  urls: a malformed site_url is ignored rather than emitted
  PASS  urls: an ordinary web request is unaffected

== UI kit v1.0 (2026-08-19): admin on the kit, resend delivery, dashboard ==
  PASS  resend: fixture order fulfilled
  PASS  resend: a paid order re-sends its delivery email (outbox +1) with a fresh download link and no second licence key
  PASS  resend: an expired download link is re-minted (a usable token exists again)
  PASS  resend: a refunded order is refused with a sentence
  PASS  resend: unknown order is refused
  PASS  routes: POST admin/orders/{id}/resend registered → admin_order_resend (csrf + flash + redirect)
  PASS  kit: admin layout loads kit css+js + admin.css, grouped nav (≥4 groups), theme toggle, who-line; storefront layout untouched (style.css + store.css, no kit)
  PASS  kit: admin.css is an app layer with light + dark accent; no theme.js; versioned assets; revalidating worker; bundled fonts only
  PASS  dashboard: first-run checklist from the database (editions / files / provider / mail / orders), needs-action for unfulfilled orders, 30-day revenue sparkline
  PASS  order record: rail (customer, emails, portal), licence cards with reissue/revoke/free-seat, usable/expired download rows, resend button
  PASS  licences list: table with search + status counts; products/customers lists link into records

== v3.1: promo pass-through ==
  PASS  promo: the LS checkout URL carries the provider discount code (never repriced on-box)
  PASS  promo: an invalid code is IGNORED, never emitted
  PASS  promo: demo checkout stays untouched (no provider = no code)
  PASS  promo: settings save validates the code alphabet and the product page shows the banner only when set
  PASS  scope: api_keys gains a scope column defaulting to full — an upgrade never loosens
  PASS  scope: requireKey reads the key scope and refuses a write on a read-only key
  PASS  scope: mintKey persists the chosen scope, and anything but read is full access
  PASS  scope: /mcp hands the key scope to the core, which refuses write tools per tool
  PASS  scope: the key form lets an administrator mint a read-only key

== nexura unlisted (operator ruling 2026-08-24) ==
  PASS  nexura: in the curation deactivation list (deploy runs curation after every seed)
  PASS  nexura: NOT in any suite seed (was Compliance Suite; suite ships 6 tools now)
  PASS  nexura: test instance mirrors curation (nexura-only) before active-state invariants

== /pricing: the page AI agents were guessing at (2026-08-24) ==
  PASS  pricing: route + controller exist and every figure is read from the DB (no typed prices)
  PASS  pricing: every guessed 404 spelling now lands — /plans, /plan, /prices, /plans-pricing, /pricing-plans
  PASS  pricing: per-product guesses land on the product page, unknown slugs on /pricing
  PASS  pricing: unwired products say "Available soon", never a stale price (same rule as llms.txt)
  PASS  pricing: in the sitemap and named in llms.txt Reference

== citable Observatory + guide capture (2026-08-23) ==
  PASS  observatory.csv: route registered and the exporter neutralizes leading =+-@ (external vendor text)
  PASS  observatory page: quote-gated means the price TEXT says so, never a missing normalized figure (the 7shifts CAD trap)
  PASS  observatory page: copy-paste citation + CSV and JSON download links
  PASS  sitemap: observatory entry carries lastmod = newest verified date, not an undated URL
  PASS  llms.txt: names the CSV download beside the JSON API
  PASS  guide capture: form posts to /notify with guide-<slug> tag, honeypot intact, csrf present
  PASS  notify handler: guide-<slug> errors bounce back to the guide, published-only

== conversion pass P2-P4 (2026-08-23) ==
  PASS  trust block: refund, tests-in-box and continuity lines at the buy button, source line stack-aware (OYA is Node)
  PASS  ladder line: Cloud says SELECTED apps (it does not host all 51) with the 12-month licence fact
  PASS  listedon partial: shared, honours a caller skip list, and reads it from legal.local
  PASS  post-Codester rule: this deployment excludes Codester on product pages
  PASS  listedon partial: no directory name is hard-coded in the shipped view
  PASS  listedon callers: both includes are guarded (the partial is not in a buyer zip)
  PASS  suites hero: no suite slug is hard-coded in the shipped view
  PASS  suites hero: a store naming both gets hero + alternative
  PASS  suites hero: a store naming only the first gets a hero and no alternative
  PASS  suites hero: a buyer store naming none gets no hero — every suite falls to the list
  PASS  suites hero: THIS deployment still names its two suites
  PASS  /security: no deployment fact is hard-coded in the shipped view
  PASS  /security: all three deployment facts read from legal.local
  PASS  /security: each fallback tells the operator which key to set, and claims nothing
  PASS  /security: THIS deployment still states all three
  PASS  source-layout details: read-before-you-buy tree, skipped for oya

== undeliverable editions (2026-08-30: a paid product whose edition had no file) ==
  PASS  an edition with no file at all is reported
  PASS  an edition naming a file that is not on disk is reported too — the same 404 to a buyer
  PASS  an edition whose file is present is NOT reported
  PASS  an INACTIVE product is not reported — nobody can buy it
  PASS  the setup checklist is green only when EVERY sellable edition can be delivered
  PASS  the dashboard warning is fed by the same check as the checklist

== /suites, /contact, /p/<x>-suite, bare /<slug>: what the first buyer's AI agent 404'd on (2026-08-30) ==
  PASS  routes registered: /suites, /bundles, /contact, /products, /apps
  PASS  bare /{slug} is the LAST GET route registered — every explicit route above it still wins
  PASS  aliases are 301s (permanent addresses, not temporary detours)
  PASS  /suites is in the sitemap and named in llms.txt Reference
  PASS  /suites view carries no typed price or saving — every figure comes from suiteTotals()
  PASS  /support carries the #contact anchor /contact redirects to
  PASS  /privacy, /terms, /refunds redirect into /legal at anchors the page really has
  PASS  /openapi.json redirects to the spec route that exists (/api/openapi.json)
  PASS  the four aliases are registered before the bare-slug catch-all
  PASS  bare /<product-slug> resolves to its /p/ page (got '/p/gw-probe', want '/p/gw-probe')
  PASS  bare /<suite-slug> resolves to its /s/ page (got '/s/gw-field', want '/s/gw-field')
  PASS  bare /<suite>-suite resolves to the suite (the agent guessed /p/field-service-suite) (got '/s/gw-field', want '/s/gw-field')
  PASS  suite_slug_for strips a -suite suffix and a suite- prefix (got 'gw-field', want 'gw-field')
  PASS  an unknown bare slug resolves to nothing (ordinary 404, no guessing)
  PASS  a slug with path characters never resolves (no open redirect)
  PASS  uppercase is tolerated (agents and humans type it)
  PASS  /suites lists the probe suite with its /s/ link and its member product
  PASS  /suites shows the live saving for the probe suite ($59 parts vs $49 suite = $10)
  PASS  an INACTIVE product no longer resolves from its bare slug
  PASS  an INACTIVE suite no longer resolves (neither bare nor -suite form)

== suites: every topic suite on the product page, and the suite page answers what the buyer asked (2026-08-30) ==
  PASS  suitesFor returns BOTH topic suites of a dual-membership product (got 2, want 2)
  PASS  suitesFor orders by live saving, best first ($59-$39 beats $59-$49) (got 'gs-beta', want 'gs-beta')
  PASS  the product page names BOTH suites (was: only bestSuiteFor, the second silently dropped)
  PASS  the suite page states what runs it (PHP 8, MySQL/SQLite) — the buyer question it did not answer
  PASS  the suite page states data ownership and source (never phones home, full source)
  PASS  the suite page carries the two FAQ answers the first buyer needed (already own one / start with one)
  PASS  suite page: a per-member demo link renders only through the same demosLive gate as the product page

== typed prices that drifted from the store (found by the growth wave, 2026-08-30) ==
  PASS  the Ownware OS guide no longer sells the OS at $499 or $999 (it is $1,299) nor claims 37 apps
  PASS  the OS + OYA bundle copy carries no typed "$499 + $249 = $699" arithmetic
  PASS  llms.txt derives the Observatory vendor count from the DB (it read "~74" while the dataset held 110)
  PASS  QuotaPath is cited with its platform fee ($525/month governs for five users or fewer), not $105 for three seats
  PASS  Qminder is cited at its month-to-month price ($869) with the annual figure beside it, not the annual-equivalent as monthly

== typed catalog counts (the OS guide's 37/38 were not alone — sweep 2026-08-30) ==
  PASS  the OS guide no longer claims one of the apps is free (Tokora is $69) nor counts 38
  PASS  the 3.1 release notes no longer say "across all 37"
  PASS  /affiliates derives the tool count from the DB instead of a typed "30+ tools"
  PASS  /affiliates renders the live active-product count

== short product names in buttons and running text (2026-08-30) ==
  PASS  shortName cuts at the em-dash (got 'Fixora', want 'Fixora')
  PASS  shortName cuts at the en-dash (got 'Examplia', want 'Examplia')
  PASS  shortName cuts at a colon (got 'Approva', want 'Approva')
  PASS  shortName leaves a plain name alone (got 'Menura', want 'Menura')
  PASS  alternatives page: the CTA and running text use the short name, the product list keeps the full one

== L1.3 + L5.20 (2026-08-31): gap pages carry the buyer's phrase; llms Optional; press traction block; derived press desc ==
  PASS  gap page opens with the buyer's phrase: self-hosted invoicing software — one time payment
  PASS  gap page opens with the buyer's phrase: self-hosted CMMS maintenance software you buy once
  PASS  gap page opens with the buyer's phrase: self-hosted fixed asset depreciation register
  PASS  gap page opens with the buyer's phrase: self-hosted purchase order approval system
  PASS  gap page opens with the buyer's phrase: Self-hosted review request automation
  PASS  gap page opens with the buyer's phrase: self-hosted visitor sign-in system for reception
  PASS  gap page opens with the buyer's phrase: self-hosted helpdesk request tracker, small business
  PASS  llms.txt has an Optional section holding the guides, after Reference
  PASS  press: SEO description is derived (no typed "37" or "$34–$129")
  PASS  press: the dated traction block renders and never annualises

== L1.4 (2026-08-31): agent-readiness surfaces — /status /changelog /security /docs /for-agents /llms-full.txt ==
  PASS  route /status → status_page registered
  PASS  route /changelog → changelog_page registered
  PASS  route /security → security_page_public registered
  PASS  route /docs → docs_page registered
  PASS  route /for-agents → for_agents_page registered
  PASS  /status renders the live checks and the catalog counts
  PASS  /changelog lists current versions read from editions
  PASS  /security names the report address and the merchant-of-record fact
  PASS  /docs and /for-agents share one surface list (llms.txt, openapi, observatory present on both)
  PASS  /for-agents documents the guessed addresses and how to verify
  PASS  llms-full.txt carries one section per active product with its URL and price
  PASS  view status.php carries no typed dollar figure
  PASS  view changelog.php carries no typed dollar figure
  PASS  view docs.php carries no typed dollar figure
  PASS  view for_agents.php carries no typed dollar figure
  PASS  view repo_answer.php carries no typed dollar figure
  PASS  the six agent pages are in the sitemap and llms.txt Reference names all six surfaces

== Release package 2 (2026-09-02): /badge + /your-ai-can-vet-us ==
  PASS  /badge renders through the public layout with its canonical
  PASS  /your-ai-can-vet-us renders through the public layout with its canonical
  PASS  badge asset runs-on-ownware.svg exists and is well-formed SVG
  PASS  badge asset runs-on-ownware.svg carries no script, no external reference, no comment
  PASS  /badge shows runs-on-ownware.svg and its embed code linking to https://ownware.io
  PASS  badge asset runs-on-ownware-dark.svg exists and is well-formed SVG
  PASS  badge asset runs-on-ownware-dark.svg carries no script, no external reference, no comment
  PASS  /badge shows runs-on-ownware-dark.svg and its embed code linking to https://ownware.io
  PASS  /badge says what the mark does NOT claim (no certification, licence independent)
  PASS  /your-ai-can-vet-us carries the receipt '/connect-your-ai'
  PASS  /your-ai-can-vet-us carries the receipt '/legal'
  PASS  /your-ai-can-vet-us carries the receipt '/support'
  PASS  /your-ai-can-vet-us carries the receipt '/.well-known/security.txt'
  PASS  /your-ai-can-vet-us carries the receipt '/contact'
  PASS  /your-ai-can-vet-us carries the receipt '/suites'
  PASS  /your-ai-can-vet-us carries the receipt '/api/openapi.json'
  PASS  /your-ai-can-vet-us carries the receipt '/for-agents'
  PASS  /your-ai-can-vet-us carries the receipt 'POST /mcp'
  PASS  /your-ai-can-vet-us carries the receipt 'read-only'
  PASS  /your-ai-can-vet-us: the MCP receipts name a REAL demo host from the database
  PASS  view vet_us.php hard-codes no absolute host — every URL comes from $B() or $demoHost
  PASS  /your-ai-can-vet-us counts are read from the DB (app count = active products minus oya + saas-kit)
  PASS  /your-ai-can-vet-us: the flagship row renders for the product legal.local names
  PASS  /your-ai-can-vet-us: with no demo host the MCP rows are skipped, not printed empty
  PASS  /your-ai-can-vet-us: with no flagship product the sealed-mode row is skipped
  PASS  /your-ai-can-vet-us: the generic receipts still render for a store with neither
  PASS  /your-ai-can-vet-us holds the customer story as an HTML comment placeholder only — no link, no slug
  PASS  view badge.php carries no typed dollar figure
  PASS  view vet_us.php carries no typed dollar figure
  PASS  agent_surfaces() lists your-ai-can-vet-us, so /docs, /for-agents and llms.txt all carry it
  PASS  llms.txt points at /your-ai-can-vet-us
  PASS  /for-agents points at /your-ai-can-vet-us
  PASS  agent_surfaces() reads the suite count from the DB (no typed "twelve")
  PASS  sitemap carries /badge and /your-ai-can-vet-us
  PASS  portal offers the badge once, only to buyers with purchases, with no obligation
  PASS  the badge and vet pages use no class the other brand's stylesheet defines (fingerprint firewall)

== Release package 3 (2026-09-02): guide seed set 9 + footer/press addendum ==
  PASS  seed set 9 holds exactly 10 guides, all published, all dated 2026-09-02
  PASS  seed set 9 is registered in ownware-seed.php
  PASS  set 9 never mentions the other brand and spells licence the British way
  PASS  guide property-management-software-pricing-one-time-vs-subscription is seeded, published, with its real created_at
  PASS  guide property-management-software-pricing-one-time-vs-subscription: every internal link resolves (9 links)
  PASS  guide property-management-software-pricing-one-time-vs-subscription renders with its title and at least one related product
  PASS  guide what-property-management-software-actually-costs-self-hosted is seeded, published, with its real created_at
  PASS  guide what-property-management-software-actually-costs-self-hosted: every internal link resolves (13 links)
  PASS  guide what-property-management-software-actually-costs-self-hosted renders with its title and at least one related product
  PASS  guide rentara-pricing-what-119-buys-and-what-it-does-not-do is seeded, published, with its real created_at
  PASS  guide rentara-pricing-what-119-buys-and-what-it-does-not-do: every internal link resolves (7 links)
  PASS  guide rentara-pricing-what-119-buys-and-what-it-does-not-do renders with its title and at least one related product
  PASS  guide iauditor-alternative-for-hospitality is seeded, published, with its real created_at
  PASS  guide iauditor-alternative-for-hospitality: every internal link resolves (10 links)
  PASS  guide iauditor-alternative-for-hospitality renders with its title and at least one related product
  PASS  guide hotel-inspection-checklists-form-app-vs-register is seeded, published, with its real created_at
  PASS  guide hotel-inspection-checklists-form-app-vs-register: every internal link resolves (8 links)
  PASS  guide hotel-inspection-checklists-form-app-vs-register renders with its title and at least one related product
  PASS  guide self-hosted-booking-simple-to-use-with-an-api is seeded, published, with its real created_at
  PASS  guide self-hosted-booking-simple-to-use-with-an-api: every internal link resolves (10 links)
  PASS  guide self-hosted-booking-simple-to-use-with-an-api renders with its title and at least one related product
  PASS  guide best-self-hosted-booking-software-the-direct-answer is seeded, published, with its real created_at
  PASS  guide best-self-hosted-booking-software-the-direct-answer: every internal link resolves (5 links)
  PASS  guide best-self-hosted-booking-software-the-direct-answer renders with its title and at least one related product
  PASS  guide workforce-suite-rota-timesheet-leave-onboarding-training is seeded, published, with its real created_at
  PASS  guide workforce-suite-rota-timesheet-leave-onboarding-training: every internal link resolves (17 links)
  PASS  guide workforce-suite-rota-timesheet-leave-onboarding-training renders with its title and at least one related product
  PASS  guide field-service-suite-quote-to-job-van-kit-and-inspections is seeded, published, with its real created_at
  PASS  guide field-service-suite-quote-to-job-van-kit-and-inspections: every internal link resolves (18 links)
  PASS  guide field-service-suite-quote-to-job-van-kit-and-inspections renders with its title and at least one related product
  PASS  guide restaurant-ops-suite-food-safety-diary-menu-and-reviews is seeded, published, with its real created_at
  PASS  guide restaurant-ops-suite-food-safety-diary-menu-and-reviews: every internal link resolves (14 links)
  PASS  guide restaurant-ops-suite-food-safety-diary-menu-and-reviews renders with its title and at least one related product
  PASS  guide property-management-software-pricing-one-time-vs-subscription is on the guides index, in the sitemap and in the JSON feed
  PASS  guide what-property-management-software-actually-costs-self-hosted is on the guides index, in the sitemap and in the JSON feed
  PASS  guide rentara-pricing-what-119-buys-and-what-it-does-not-do is on the guides index, in the sitemap and in the JSON feed
  PASS  guide iauditor-alternative-for-hospitality is on the guides index, in the sitemap and in the JSON feed
  PASS  guide hotel-inspection-checklists-form-app-vs-register is on the guides index, in the sitemap and in the JSON feed
  PASS  guide self-hosted-booking-simple-to-use-with-an-api is on the guides index, in the sitemap and in the JSON feed
  PASS  guide best-self-hosted-booking-software-the-direct-answer is on the guides index, in the sitemap and in the JSON feed
  PASS  guide workforce-suite-rota-timesheet-leave-onboarding-training is on the guides index, in the sitemap and in the JSON feed
  PASS  guide field-service-suite-quote-to-job-van-kit-and-inspections is on the guides index, in the sitemap and in the JSON feed
  PASS  guide restaurant-ops-suite-food-safety-diary-menu-and-reviews is on the guides index, in the sitemap and in the JSON feed
  PASS  set 9 cites Buildium as the comparisons row states it ($62/month, read 2026-09-03)
  PASS  set 9 cites DoorLoop as the comparisons row states it ($69.00/mo billed yearly, read 2026-09-03)
  PASS  set 9 cites TenantCloud as the comparisons row states it ($15.00/mo billed annually, read 2026-09-03)
  PASS  set 9 cites AppFolio as the comparisons row states it (50-unit minimum, read 2026-09-03)
  PASS  set 9 cites Hemlane as the comparisons row states it ($28 platform fee, read 2026-09-03)
  PASS  set 9 cites SafetyCulture as the comparisons row states it ($24/seat/month, read 2026-09-03)
  PASS  set 9 cites FoodDocs as the comparisons row states it ($79 per site/month, read 2026-09-03)
  PASS  set 9 cites Calendly as the comparisons row states it ($10/seat/mo, read 2026-09-03)
  PASS  set 9 cites Acuity as the comparisons row states it ($16/mo billed annually, read 2026-09-03)
  PASS  set 9 cites SimplyBook as the comparisons row states it (11.9/mo billed annually, read 2026-07-05)
  PASS  set 9 prices rentara at the live single-licence price
  PASS  set 9 prices inspectora at the live single-licence price
  PASS  set 9 prices safora at the live single-licence price
  PASS  set 9 prices slotly at the live single-licence price
  PASS  set 9 prices leavora at the live single-licence price
  PASS  set 9 prices rostera at the live single-licence price
  PASS  set 9 prices clockora at the live single-licence price
  PASS  set 9 prices onboardora at the live single-licence price
  PASS  set 9 prices trainora at the live single-licence price
  PASS  set 9 prices jobora at the live single-licence price
  PASS  set 9 prices fixora at the live single-licence price
  PASS  set 9 prices fleetora at the live single-licence price
  PASS  set 9 prices lendra at the live single-licence price
  PASS  set 9 prices menura at the live single-licence price
  PASS  set 9 prices revup at the live single-licence price
  PASS  set 9 prices the property suite at the live bundle price
  PASS  set 9 prices the workforce suite at the live bundle price
  PASS  set 9 prices the field-service suite at the live bundle price
  PASS  set 9 prices the restaurant-ops suite at the live bundle price
  PASS  set 9 prices the studio suite at the live bundle price
  PASS  set 9 suite arithmetic ($385 / $465 / $267 separately) equals the sum of live single prices
  PASS  footer Help column carries "Your AI can vet us" on every public page
  PASS  /press links the badge page under "Images you can use."

== Package 4 phase B, batch 1 (2026-09-02): back-catalogue retrofit ==
  PASS  retrofit b1: cmms-cost-teardown is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b1: cmms-cost-teardown — every internal link resolves (10)
  PASS  retrofit b1: cmms-cost-teardown — no absolute ownware.io link left where an internal one belongs, no AmE 'license' in prose
  PASS  retrofit b1: cmms-cost-teardown — no stale observatory count
  PASS  retrofit b1: what-a-cafe-pays-for-software-every-year is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b1: what-a-cafe-pays-for-software-every-year — every internal link resolves (9)
  PASS  retrofit b1: what-a-cafe-pays-for-software-every-year — no absolute ownware.io link left where an internal one belongs, no AmE 'license' in prose
  PASS  retrofit b1: what-a-cafe-pays-for-software-every-year — no stale observatory count
  PASS  retrofit b1: saas-rent-index-2026 is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b1: saas-rent-index-2026 — every internal link resolves (9)
  PASS  retrofit b1: saas-rent-index-2026 — no absolute ownware.io link left where an internal one belongs, no AmE 'license' in prose
  PASS  retrofit b1: saas-rent-index-2026 — no stale observatory count
  PASS  retrofit b1: the-fee-stack-nobody-reads is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b1: the-fee-stack-nobody-reads — every internal link resolves (7)
  PASS  retrofit b1: the-fee-stack-nobody-reads — no absolute ownware.io link left where an internal one belongs, no AmE 'license' in prose
  PASS  retrofit b1: the-fee-stack-nobody-reads — no stale observatory count
  PASS  retrofit b1: what-a-gym-pays-for-software-every-year is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b1: what-a-gym-pays-for-software-every-year — every internal link resolves (15)
  PASS  retrofit b1: what-a-gym-pays-for-software-every-year — no absolute ownware.io link left where an internal one belongs, no AmE 'license' in prose
  PASS  retrofit b1: what-a-gym-pays-for-software-every-year — no stale observatory count
  PASS  retrofit b1: consignment-software-the-split-has-to-be-exact is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b1: consignment-software-the-split-has-to-be-exact — every internal link resolves (5)
  PASS  retrofit b1: consignment-software-the-split-has-to-be-exact — no absolute ownware.io link left where an internal one belongs, no AmE 'license' in prose
  PASS  retrofit b1: consignment-software-the-split-has-to-be-exact — no stale observatory count
  PASS  retrofit b1: saas-minimum-spend-small-business-trap is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b1: saas-minimum-spend-small-business-trap — every internal link resolves (6)
  PASS  retrofit b1: saas-minimum-spend-small-business-trap — no absolute ownware.io link left where an internal one belongs, no AmE 'license' in prose
  PASS  retrofit b1: saas-minimum-spend-small-business-trap — no stale observatory count
  PASS  retrofit b1: stop-paying-for-deputy-self-hosted-rota is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b1: stop-paying-for-deputy-self-hosted-rota — every internal link resolves (12)
  PASS  retrofit b1: stop-paying-for-deputy-self-hosted-rota — no absolute ownware.io link left where an internal one belongs, no AmE 'license' in prose
  PASS  retrofit b1: stop-paying-for-deputy-self-hosted-rota — no stale observatory count
  PASS  retrofit b1: small-landlord-locked-out-property-software is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b1: small-landlord-locked-out-property-software — every internal link resolves (7)
  PASS  retrofit b1: small-landlord-locked-out-property-software — no absolute ownware.io link left where an internal one belongs, no AmE 'license' in prose
  PASS  retrofit b1: small-landlord-locked-out-property-software — no stale observatory count
  PASS  retrofit b1: what-a-freelancer-pays-for-software-every-year is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b1: what-a-freelancer-pays-for-software-every-year — every internal link resolves (9)
  PASS  retrofit b1: what-a-freelancer-pays-for-software-every-year — no absolute ownware.io link left where an internal one belongs, no AmE 'license' in prose
  PASS  retrofit b1: what-a-freelancer-pays-for-software-every-year — no stale observatory count
  PASS  retrofit b1: contract-renewal-tracker-self-hosted is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b1: contract-renewal-tracker-self-hosted — every internal link resolves (8)
  PASS  retrofit b1: contract-renewal-tracker-self-hosted — no absolute ownware.io link left where an internal one belongs, no AmE 'license' in prose
  PASS  retrofit b1: contract-renewal-tracker-self-hosted — no stale observatory count
  PASS  retrofit b1: document-extraction-break-even-volume is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b1: document-extraction-break-even-volume — every internal link resolves (6)
  PASS  retrofit b1: document-extraction-break-even-volume — no absolute ownware.io link left where an internal one belongs, no AmE 'license' in prose
  PASS  retrofit b1: document-extraction-break-even-volume — no stale observatory count
  PASS  retrofit b1: stop-paying-gumroad-10-percent is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b1: stop-paying-gumroad-10-percent — every internal link resolves (5)
  PASS  retrofit b1: stop-paying-gumroad-10-percent — no absolute ownware.io link left where an internal one belongs, no AmE 'license' in prose
  PASS  retrofit b1: stop-paying-gumroad-10-percent — no stale observatory count
  PASS  retrofit b1: salon-clinic-software-stack-what-to-own is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b1: salon-clinic-software-stack-what-to-own — every internal link resolves (11)
  PASS  retrofit b1: salon-clinic-software-stack-what-to-own — no absolute ownware.io link left where an internal one belongs, no AmE 'license' in prose
  PASS  retrofit b1: salon-clinic-software-stack-what-to-own — no stale observatory count
  PASS  retrofit b1: timesheet-software-without-per-seat-pricing is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b1: timesheet-software-without-per-seat-pricing — every internal link resolves (10)
  PASS  retrofit b1: timesheet-software-without-per-seat-pricing — no absolute ownware.io link left where an internal one belongs, no AmE 'license' in prose
  PASS  retrofit b1: timesheet-software-without-per-seat-pricing — no stale observatory count
  PASS  retrofit b1: eu-data-residency-buyers-guide is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b1: eu-data-residency-buyers-guide — every internal link resolves (15)
  PASS  retrofit b1: eu-data-residency-buyers-guide — no absolute ownware.io link left where an internal one belongs, no AmE 'license' in prose
  PASS  retrofit b1: eu-data-residency-buyers-guide — no stale observatory count
  PASS  retrofit b1: quote-gated-pricing-what-it-costs-you is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b1: quote-gated-pricing-what-it-costs-you — every internal link resolves (5)
  PASS  retrofit b1: quote-gated-pricing-what-it-costs-you — no absolute ownware.io link left where an internal one belongs, no AmE 'license' in prose
  PASS  retrofit b1: quote-gated-pricing-what-it-costs-you — no stale observatory count
  PASS  retrofit b1: haccp-logbook-per-seat-vs-per-site is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b1: haccp-logbook-per-seat-vs-per-site — every internal link resolves (8)
  PASS  retrofit b1: haccp-logbook-per-seat-vs-per-site — no absolute ownware.io link left where an internal one belongs, no AmE 'license' in prose
  PASS  retrofit b1: haccp-logbook-per-seat-vs-per-site — no stale observatory count
  PASS  retrofit b1: fleet-software-cost-teardown is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b1: fleet-software-cost-teardown — every internal link resolves (5)
  PASS  retrofit b1: fleet-software-cost-teardown — no absolute ownware.io link left where an internal one belongs, no AmE 'license' in prose
  PASS  retrofit b1: fleet-software-cost-teardown — no stale observatory count
  PASS  retrofit b1: bank-statement-converter-who-sees-your-statements is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b1: bank-statement-converter-who-sees-your-statements — every internal link resolves (5)
  PASS  retrofit b1: bank-statement-converter-who-sees-your-statements — no absolute ownware.io link left where an internal one belongs, no AmE 'license' in prose
  PASS  retrofit b1: bank-statement-converter-who-sees-your-statements — no stale observatory count
  PASS  retrofit b1: what-currency-are-you-actually-billed-in is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b1: what-currency-are-you-actually-billed-in — every internal link resolves (4)
  PASS  retrofit b1: what-currency-are-you-actually-billed-in — no absolute ownware.io link left where an internal one belongs, no AmE 'license' in prose
  PASS  retrofit b1: what-currency-are-you-actually-billed-in — no stale observatory count
  PASS  retrofit b1: visitor-management-cost-what-a-reception-book-rents-for is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b1: visitor-management-cost-what-a-reception-book-rents-for — every internal link resolves (8)
  PASS  retrofit b1: visitor-management-cost-what-a-reception-book-rents-for — no absolute ownware.io link left where an internal one belongs, no AmE 'license' in prose
  PASS  retrofit b1: visitor-management-cost-what-a-reception-book-rents-for — no stale observatory count
  PASS  retrofit b1: agency-stack-when-free-is-the-right-answer is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b1: agency-stack-when-free-is-the-right-answer — every internal link resolves (10)
  PASS  retrofit b1: agency-stack-when-free-is-the-right-answer — no absolute ownware.io link left where an internal one belongs, no AmE 'license' in prose
  PASS  retrofit b1: agency-stack-when-free-is-the-right-answer — no stale observatory count
  PASS  retrofit b1: inspection-software-cost-teardown-per-user-forever is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b1: inspection-software-cost-teardown-per-user-forever — every internal link resolves (8)
  PASS  retrofit b1: inspection-software-cost-teardown-per-user-forever — no absolute ownware.io link left where an internal one belongs, no AmE 'license' in prose
  PASS  retrofit b1: inspection-software-cost-teardown-per-user-forever — no stale observatory count
  PASS  retrofit b1: timetastic-alternative-self-hosted-leave is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b1: timetastic-alternative-self-hosted-leave — every internal link resolves (10)
  PASS  retrofit b1: timetastic-alternative-self-hosted-leave — no absolute ownware.io link left where an internal one belongs, no AmE 'license' in prose
  PASS  retrofit b1: timetastic-alternative-self-hosted-leave — no stale observatory count
  PASS  retrofit b1: the-five-year-math-honestly is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b1: the-five-year-math-honestly — every internal link resolves (6)
  PASS  retrofit b1: the-five-year-math-honestly — no absolute ownware.io link left where an internal one belongs, no AmE 'license' in prose
  PASS  retrofit b1: the-five-year-math-honestly — no stale observatory count
  PASS  retrofit b1: equipment-checkout-self-hosted-honest-comparison is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b1: equipment-checkout-self-hosted-honest-comparison — every internal link resolves (6)
  PASS  retrofit b1: equipment-checkout-self-hosted-honest-comparison — no absolute ownware.io link left where an internal one belongs, no AmE 'license' in prose
  PASS  retrofit b1: equipment-checkout-self-hosted-honest-comparison — no stale observatory count
  PASS  retrofit b1: fixed-asset-depreciation-register-self-hosted is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b1: fixed-asset-depreciation-register-self-hosted — every internal link resolves (5)
  PASS  retrofit b1: fixed-asset-depreciation-register-self-hosted — no absolute ownware.io link left where an internal one belongs, no AmE 'license' in prose
  PASS  retrofit b1: fixed-asset-depreciation-register-self-hosted — no stale observatory count
  PASS  retrofit b1: self-hosted-expense-claims-not-expense-tracking is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b1: self-hosted-expense-claims-not-expense-tracking — every internal link resolves (6)
  PASS  retrofit b1: self-hosted-expense-claims-not-expense-tracking — no absolute ownware.io link left where an internal one belongs, no AmE 'license' in prose
  PASS  retrofit b1: self-hosted-expense-claims-not-expense-tracking — no stale observatory count
  PASS  retrofit b1: inventory-forecasting-show-me-the-formula is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b1: inventory-forecasting-show-me-the-formula — every internal link resolves (5)
  PASS  retrofit b1: inventory-forecasting-show-me-the-formula — no absolute ownware.io link left where an internal one belongs, no AmE 'license' in prose
  PASS  retrofit b1: inventory-forecasting-show-me-the-formula — no stale observatory count
  PASS  retrofit b1: pos-subscription-plus-processing-fee-stack is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b1: pos-subscription-plus-processing-fee-stack — every internal link resolves (6)
  PASS  retrofit b1: pos-subscription-plus-processing-fee-stack — no absolute ownware.io link left where an internal one belongs, no AmE 'license' in prose
  PASS  retrofit b1: pos-subscription-plus-processing-fee-stack — no stale observatory count
  PASS  retrofit b1: menu-digitisation-the-job-nobody-prices is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b1: menu-digitisation-the-job-nobody-prices — every internal link resolves (5)
  PASS  retrofit b1: menu-digitisation-the-job-nobody-prices — no absolute ownware.io link left where an internal one belongs, no AmE 'license' in prose
  PASS  retrofit b1: menu-digitisation-the-job-nobody-prices — no stale observatory count
  PASS  retrofit b1: gym-software-two-of-three-hide-the-price is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b1: gym-software-two-of-three-hide-the-price — every internal link resolves (6)
  PASS  retrofit b1: gym-software-two-of-three-hide-the-price — no absolute ownware.io link left where an internal one belongs, no AmE 'license' in prose
  PASS  retrofit b1: gym-software-two-of-three-hide-the-price — no stale observatory count
  PASS  retrofit b1: self-hosted-dsar-portal-gdpr-requests is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b1: self-hosted-dsar-portal-gdpr-requests — every internal link resolves (10)
  PASS  retrofit b1: self-hosted-dsar-portal-gdpr-requests — no absolute ownware.io link left where an internal one belongs, no AmE 'license' in prose
  PASS  retrofit b1: self-hosted-dsar-portal-gdpr-requests — no stale observatory count
  PASS  retrofit b1: purchase-approval-the-shelf-between-499-and-an-erp is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b1: purchase-approval-the-shelf-between-499-and-an-erp — every internal link resolves (7)
  PASS  retrofit b1: purchase-approval-the-shelf-between-499-and-an-erp — no absolute ownware.io link left where an internal one belongs, no AmE 'license' in prose
  PASS  retrofit b1: purchase-approval-the-shelf-between-499-and-an-erp — no stale observatory count
  PASS  retrofit b1: self-host-on-shared-hosting is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b1: self-host-on-shared-hosting — every internal link resolves (4)
  PASS  retrofit b1: self-host-on-shared-hosting — no absolute ownware.io link left where an internal one belongs, no AmE 'license' in prose
  PASS  retrofit b1: self-host-on-shared-hosting — no stale observatory count
  PASS  retrofit b1: what-a-cafe-pays-for-software-every-year types safora at the live single price
  PASS  retrofit b1: what-a-cafe-pays-for-software-every-year types rostera at the live single price
  PASS  retrofit b1: what-a-cafe-pays-for-software-every-year types leavora at the live single price
  PASS  retrofit b1: what-a-gym-pays-for-software-every-year types gymora at the live single price
  PASS  retrofit b1: what-a-gym-pays-for-software-every-year types waiverly at the live single price
  PASS  retrofit b1: what-a-gym-pays-for-software-every-year types lendra at the live single price
  PASS  retrofit b1: consignment-software-the-split-has-to-be-exact types consigna at the live single price
  PASS  retrofit b1: stop-paying-for-deputy-self-hosted-rota types rostera at the live single price
  PASS  retrofit b1: small-landlord-locked-out-property-software types rentara at the live single price
  PASS  retrofit b1: what-a-freelancer-pays-for-software-every-year types invora at the live single price
  PASS  retrofit b1: what-a-freelancer-pays-for-software-every-year types clockora at the live single price
  PASS  retrofit b1: what-a-freelancer-pays-for-software-every-year types slotly at the live single price
  PASS  retrofit b1: cmms-cost-teardown types fixora at the live single price
  PASS  retrofit b1: saas-minimum-spend-small-business-trap types extracta at the live single price
  PASS  retrofit b1: saas-rent-index-2026 types expensa at the live single price
  PASS  retrofit b1: saas-rent-index-2026 types assetora at the live single price
  PASS  retrofit b1: café one-time total = rota + leave + logbook from the DB ($247)
  PASS  retrofit b1: gym one-time total = gymora + rostera + waiverly + leavora from the DB ($316)
  PASS  retrofit b1: freelancer stack = invora + clockora + slotly from the DB ($267)
  PASS  retrofit b1: rent-index own-once column = seven live licences ($583) and the five-year gap follows
  PASS  retrofit b1: Deputy guide names the Rostera price in the honest section ($69)
  PASS  retrofit b1: cmms-cost-teardown cites Fiix as the record states ($45) with the vendor URL in the body
  PASS  retrofit b1: cmms-cost-teardown cites MaintainX as the record states ($20) with the vendor URL in the body
  PASS  retrofit b1: cmms-cost-teardown cites UpKeep as the record states ($24) with the vendor URL in the body
  PASS  retrofit b1: cmms-cost-teardown cites Limble as the record states (No public price) with the vendor URL in the body
  PASS  retrofit b1: what-a-cafe-pays-for-software-every-year cites FoodDocs as the record states ($79 per site/month) with the vendor URL in the body
  PASS  retrofit b1: what-a-cafe-pays-for-software-every-year cites SafetyCulture as the record states ($24/seat/month) with the vendor URL in the body
  PASS  retrofit b1: what-a-cafe-pays-for-software-every-year cites Deputy as the record states (Lite $5) with the vendor URL in the body
  PASS  retrofit b1: what-a-cafe-pays-for-software-every-year cites Timetastic as the record states ($1.50/user/month) with the vendor URL in the body
  PASS  retrofit b1: what-a-cafe-pays-for-software-every-year cites Zoho Expense as the record states ($4/user/month) with the vendor URL in the body
  PASS  retrofit b1: what-a-cafe-pays-for-software-every-year cites Square POS as the record states ($49/mo) with the vendor URL in the body
  PASS  retrofit b1: what-a-gym-pays-for-software-every-year cites GymMaster as the record states ($89/month) with the vendor URL in the body
  PASS  retrofit b1: what-a-gym-pays-for-software-every-year cites Cheqroom as the record states (184 per admin) with the vendor URL in the body
  PASS  retrofit b1: what-a-gym-pays-for-software-every-year cites Smartwaiver as the record states ($19/mo) with the vendor URL in the body
  PASS  retrofit b1: what-a-gym-pays-for-software-every-year cites WaiverForever as the record states ($19/mo) with the vendor URL in the body
  PASS  retrofit b1: what-a-gym-pays-for-software-every-year cites Mindbody as the record states (EUR 99/month) with the vendor URL in the body
  PASS  retrofit b1: what-a-gym-pays-for-software-every-year cites Glofox as the record states (No public price) with the vendor URL in the body
  PASS  retrofit b1: consignment-software-the-split-has-to-be-exact cites ConsignCloud as the record states ($139/month) with the vendor URL in the body
  PASS  retrofit b1: consignment-software-the-split-has-to-be-exact cites SimpleConsign as the record states ($159/mo) with the vendor URL in the body
  PASS  retrofit b1: small-landlord-locked-out-property-software cites TenantCloud as the record states ($15.00/mo) with the vendor URL in the body
  PASS  retrofit b1: small-landlord-locked-out-property-software cites Rentec Direct as the record states ($25/month) with the vendor URL in the body
  PASS  retrofit b1: small-landlord-locked-out-property-software cites Buildium as the record states ($62/month) with the vendor URL in the body
  PASS  retrofit b1: small-landlord-locked-out-property-software cites DoorLoop as the record states ($69.00/mo) with the vendor URL in the body
  PASS  retrofit b1: small-landlord-locked-out-property-software cites Hemlane as the record states ($28 platform fee) with the vendor URL in the body
  PASS  retrofit b1: small-landlord-locked-out-property-software cites AppFolio as the record states (50-unit minimum) with the vendor URL in the body
  PASS  retrofit b1: what-a-freelancer-pays-for-software-every-year cites FreshBooks as the record states ($23.00/mo) with the vendor URL in the body
  PASS  retrofit b1: what-a-freelancer-pays-for-software-every-year cites Harvest as the record states ($9/seat/month) with the vendor URL in the body
  PASS  retrofit b1: what-a-freelancer-pays-for-software-every-year cites Calendly as the record states ($10/seat/mo) with the vendor URL in the body
  PASS  retrofit b1: what-a-freelancer-pays-for-software-every-year cites Setmore as the record states ($5/user/month) with the vendor URL in the body
  PASS  retrofit b1: what-a-freelancer-pays-for-software-every-year cites Wave as the record states ($19/mo) with the vendor URL in the body
  PASS  retrofit b1: what-a-freelancer-pays-for-software-every-year cites Acuity as the record states ($16/mo billed annually) with the vendor URL in the body
  PASS  retrofit b1: stop-paying-for-deputy-self-hosted-rota cites Deputy as the record states (Core $6.50) with the vendor URL in the body
  PASS  retrofit b1: saas-minimum-spend-small-business-trap cites Vacation Tracker as the record states (EUR 50/month minimum) with the vendor URL in the body
  PASS  retrofit b1: saas-minimum-spend-small-business-trap cites Veryfi (OCR as the record states ($500+/mo) with the vendor URL in the body
  PASS  retrofit b1: the-fee-stack-nobody-reads cites Wave as the record states (Pro $19/mo) with the vendor URL in the body
  PASS  retrofit b1: the-fee-stack-nobody-reads cites Smartwaiver as the record states (Business $155/mo) with the vendor URL in the body
  PASS  retrofit b1: the-fee-stack-nobody-reads cites FreshBooks as the record states (Lite $23.00/mo) with the vendor URL in the body
  PASS  retrofit b1: saas-rent-index-2026 cites Concord as the record states ($499) with the vendor URL in the body
  PASS  retrofit b1: saas-rent-index-2026 cites QuotaPath as the record states ($525/month platform fee) with the vendor URL in the body
  PASS  retrofit b1: saas-rent-index-2026 cites Clockify as the record states ($5.49) with the vendor URL in the body
  PASS  retrofit b1: saas-rent-index-2026 cites AssetTiger as the record states (30-day free trial up to 250 assets) with the vendor URL in the body
  PASS  retrofit w3-1: the CMMS teardown dates its re-read at all four vendors
  PASS  retrofit w3-1: the teardown no longer credits only MaintainX with a free tier, and says who the meter skips
  PASS  depth-2: the teardown names Fiix's operator-access licence and what it does to the seat count
  PASS  retrofit w3-1: UpKeep Premium and Limble's quote-gated tier names reached the page
  PASS  retrofit w3-1: the teardown reads as British English
  PASS  retrofit w3-2: the Gumroad guide dates its 3 September re-check of the two sources that answered
  PASS  retrofit w3-2: the EDD paragraph names the tiers that do NOT include the licensing API
  PASS  retrofit w3-2: the figures that refused a re-read keep their original dates, unaltered
  PASS  retrofit w3-2: the Gumroad guide keeps the British licence and never the American spelling
  PASS  retrofit w3-3: the shared-hosting guide names the shared host's four plans as read on 5 September
  PASS  retrofit w3-3: the price range keeps the 10 August machine-read date it was actually read on
  PASS  retrofit w3-3: the guide spells catalogue the way the body copy does
  PASS  retrofit w3-4: the rent index dates the 3 September re-read of all ten headline vendors
  PASS  retrofit w3-4: the minimum count matches the rows that actually carry a floor
  PASS  retrofit w3-4: Deputy's minimum is still quoted in the vendor's own words
  PASS  depth-2: the consignment guide carries SimpleConsign's intro rates and its own unrendered-source note
  PASS  depth-2: the gym guide names every source it could not re-read, and refuses the staging price
  PASS  depth-2: the fee stack explains both dates it could not refresh
  PASS  depth-2: the rent-index stack is ten priced rows, no strays
  PASS  retrofit w3-4: the headline totals follow the vendors, with the seat ruling still open
  PASS  retrofit w3-5: the Deputy guide records both re-reads and still quotes the floor exactly
  PASS  depth-2: the Deputy guide turns its own lens on the $49 base fee
  PASS  depth-2 u9: the eleventh unit is priced, and it is not $3
  PASS  depth-2 u9: the ten-unit ceiling is counted at both vendors that impose it
  PASS  depth-2 u9: Hemlane's unresolved card is published as unresolved, both readings costed
  PASS  depth-2 u9: a cloud-host page that will not render its price does not get a fresher date
  PASS  depth-2 u10: the sixth client is priced from the tier above
  PASS  depth-2 u10: the promo state is recorded, and its own banner arithmetic checks out
  PASS  depth-2 u10: the free tiers the guide had missed are named with their real caps
  PASS  depth-2 u10: the unsupported Calendly claim is withdrawn, not quietly reworded
  PASS  depth-2 u10: Wave Pro's waived transactions are costed from the two printed rates
  PASS  depth-2 u11: Concord's surcharge ladder is read in the direction it actually runs
  PASS  depth-2 u11: the third re-read of Concord is dated and its result stated
  PASS  depth-2 u11: ContractWorks is an acquired product linking to its own deleted price page
  PASS  depth-2 u11: Gatekeeper's published meter is quoted, and it meters third parties
  PASS  depth-2 u12: the Parseur row is re-sourced to the pricing page, and the old page named
  PASS  depth-2 u12: the free-tier doubt is resolved where it was raised
  PASS  depth-2 u12: Mindee's three non-reconciling figures are all printed
  PASS  depth-2 u12: the two missing free tiers are recorded with their printed limits
  PASS  depth-2 u12: Veryfi's 1-cent discount is shown RAISING the break-even volume
  PASS  depth-2 u13: Gumroad's rate is shown as flat at every size, in its own words
  PASS  depth-2 u13: Stripe's two surcharges are quoted and compounded correctly
  PASS  depth-2 u13: the international row lands on the Lemon Squeezy figure, and says so
  PASS  depth-2 u13: the Lemon Squeezy 403 is disclosed rather than papered over
  PASS  depth-2 u13: EDD's renewal rule and site limits are quoted
  PASS  depth-2 u14: the localised pricing page is disclosed, and not converted
  PASS  depth-2 u14: the booking ALLOWANCE, not the price, is what rules out the cheap tier
  PASS  depth-2 u14: both waiver vendors refusing a read is recorded, with the irony named
  PASS  depth-2 u14: Expensify's $5 is shown as the NEW-customer price it actually is
  PASS  depth-2 u14: Square's unreadable plans are held, and the tier that DID render is new
  PASS  depth-2 u14: Deputy's minimum re-confirmed today, and it still bites a four-person salon
  PASS  depth-2 u15: the kiosk seat class is published, and costed against our own product
  PASS  depth-2 u15: the entry-tier contradiction is corrected and the correction disclosed
  PASS  depth-2 u15: Clockify's monthly ladder is carried, and the bundle labelled as a bundle
  PASS  depth-2 u15: Harvest's advertised annual discount is checked against its own arithmetic
  PASS  depth-2 u16: only the verified statutory text is published, on calendar days
  PASS  depth-2 u16: the whistleblowing price quoted is the band that actually has the duty
  PASS  depth-2 u16: Enzuzo's free tier is recorded even though it competes with us
  PASS  depth-2 u16: the two quote-gated vendors are recorded by what they offer instead
  PASS  depth-2 u17: the headline count is what the ledger actually holds, recomputed
  PASS  depth-2 u17: the share is stated as a range, so a rounding boundary cannot falsify the title
  PASS  depth-2 u17: a price in another currency is no longer counted as a hidden price
  PASS  depth-2 u17: Mindbody's move INTO full gating is recorded, floor and all
  PASS  depth-2 u17: Cheqroom read at last, and its published ladder is still uncomputable
  PASS  depth-2 u18: the free tier's seat count is stated, and the table is qualified by it
  PASS  depth-2 u18: the per-seat vendor also sells per-site, and the guide admits the wrinkle
  PASS  depth-2 u18: FoodDocs' full ladder and its unlimited-users promise are quoted
  PASS  depth-2 u19: the vehicle minimum is priced for the fleet too small to meet it
  PASS  depth-2 u19: the free plan and the annual rate the August read had missed
  PASS  depth-2 u19: Fleetio has a ceiling as well as a band, and both are stated
  PASS  depth-2 u19: the unreadable vendor keeps its own date instead of borrowing today's
  PASS  depth-2 u19: Samsara's two-layer gate is recorded, size asked before price given
  PASS  depth-2 u20: the $20 is identified as the annual rate, with the monthly derived openly
  PASS  depth-2 u20: the per-page ladder is computed, including where it turns back up
  PASS  depth-2 u20: the three-year table says which billing basis each row is
  PASS  depth-2 u20: the withdrawn desktop price keeps its date and the tiers are named
  PASS  depth-2 u21: the onboarding fee is on the tier we had exempted, and it outruns year one
  PASS  depth-2 u21: the currency "selector" is corrected to regional editions
  PASS  depth-2 u21: the same-digits pattern is found in the vendor we called the counter-example
  PASS  depth-2 u21: the gap the guide left open is closed in the open
  PASS  depth-2 u21: Timetastic caught holding both prices and showing one
  PASS  depth-2 u22: the vendor defines its own meter, and the guide quotes the definition
  PASS  depth-2 u22: the fourth tier and the trial the August read had missed
  PASS  depth-2 u22: the other meters are priced, so "several meters" has a number
  PASS  depth-2 u22: the published figures behind the guide's own three-year sums still hold
  PASS  depth-2 u23: the same five-client cap, priced $276 apart, is put side by side
  PASS  depth-2 u23: the three free tiers the article about free tiers had missed
  PASS  depth-2 u23: the CAKE bundle is not counted as a Clockify seat tier here either
  PASS  depth-2 u23: Invoice Ninja's annual saving is its own printed arithmetic
  PASS  depth-2 u24: the two conflicting read dates are reconciled into one history
  PASS  depth-2 u24: the ladder is completed in both billing directions
  PASS  depth-2 u24: the annual commitment is priced as the option it is
  PASS  depth-2 u24: the vendor's own definition of a billable user is still quoted exactly
  PASS  depth-2 u25: the two minimums are settled as two billing states, not one error
  PASS  depth-2 u25: the yearly figure is published even though it halves our own comparison
  PASS  depth-2 u25: the "save 10%" label is set beside the halving it describes
  PASS  depth-2 u25: Timetastic re-read, and the currency it chooses for the reader recorded
  PASS  depth-2 u25: the record now carries the settled reading, dated today
  PASS  depth-2 u26: the median the page prints is the median the ledger holds
  PASS  depth-2 u26: the three proportions are recomputed, not re-quoted
  PASS  depth-2 u26: the headline now agrees with the index it cites, and says it moved
  PASS  depth-2 u27: the dead comparison is stated as dead, not priced
  PASS  depth-2 u27: the intro rate that costs more than the plan it undercuts
  PASS  depth-2 u27: Fiix's free tier is quoted even though it argues against the row it sits in
  PASS  depth-2 u28: an unreadable pricing page does not buy a fresh date
  PASS  depth-2 u28: the unconfirmed figure is flagged, not repeated as fact
  PASS  depth-2 u28: the free tier is described by its limits rather than as "small"
  PASS  depth-2 u28: the 403 is disclosed where the claim it supports is made
  PASS  depth-2 u28: the three-year arithmetic the guide prints still holds
  PASS  depth-2 u29: the unit cap is priced, not just noted
  PASS  depth-2 u29: both TenantCloud billing states, and both annual totals
  PASS  depth-2 u29: AppFolio quoted verbatim and Buildium's far end recorded
  PASS  depth-2 u29: the five-unit figure the guide argues from still holds
  PASS  depth-2 u30: the free alternative is only free if you run it, and the guide says so
  PASS  depth-2 u30: Calendly is capped by event type, not seats, and has a 50-seat floor above
  PASS  depth-2 u30: the conflated Acuity ladder is separated and the correction disclosed
  PASS  depth-2 u30: the free PHP option is quoted in its own words, paid extras noted
  PASS  depth-2 u30: the three-year arithmetic the guide argues from still holds
  PASS  depth-2 u31: the derived monthly figure is replaced by the published one
  PASS  depth-2 u31: what Qminder actually meters is recorded
  PASS  depth-2 u31: the per-location claim is corrected to what the page meters
  PASS  depth-2 u31: the headline no longer leads with a figure the vendor does not publish
  PASS  depth-2 u32: the "scales by units" claim is corrected in the vendor's favour
  PASS  depth-2 u32: where portfolio size DOES re-enter is stated precisely
  PASS  depth-2 u32: unit 9's DoorLoop finding is carried here too
  PASS  depth-2 u32: the three-year range and break-even the guide argues from still hold
  PASS  depth-2 u33: the three-person crew is priced for three people
  PASS  depth-2 u33: the correction is disclosed as one that helps our own case
  PASS  depth-2 u33: the expiring promotion expired, and the guide records the test
  PASS  depth-2 u33: the surcharge that falls with the tier is set against the one that climbs
  PASS  depth-2 u34: the meter is quoted from the page, and the unsourced catch withdrawn
  PASS  depth-2 u34: the ladder ceiling is the published one, not the old understatement
  PASS  depth-2 u34: the free tier and entry price still read as published
  PASS  depth-2 u35: all three unknowns stacked on the one published figure
  PASS  depth-2 u35: prices are not taken off a test host
  PASS  depth-2 u35: the rental-business option meters people and premises, and the guide says so
  PASS  depth-2 u35: the free option is quoted in its own words
  PASS  depth-2 u35: the three-admin arithmetic is per-admin, so multiplying is correct
  PASS  depth-2 u36: the "free tier" is corrected to the trial it is, contradiction named
  PASS  depth-2 u36: the asset-band ladder is published rather than approximated
  PASS  depth-2 u36: the licence claim is sourced where licences live, not where marketing is
  PASS  depth-2 u36: the quote-gated vendor is recorded by what it offers instead
  PASS  depth-2 u37: the vendor that stopped publishing is recorded as having moved
  PASS  depth-2 u37: an entry figure that would not render keeps its own date
  PASS  depth-2 u37: what each vendor meters is stated, and it is members every time
  PASS  depth-2 u37: the proof-of-work gate is disclosed as the reason for the older date
  PASS  depth-2 u37: the three-year range the guide argues from still computes
  PASS  depth-2 u38: the flat rate is shown as the new-customer rate it is
  PASS  depth-2 u38: the free tier that undercuts our own recommendation is stated plainly
  PASS  depth-2 u38: the figure no longer rests on embedded page data alone
  PASS  depth-2 u38: the blocked project is disclosed where its description is made
  PASS  depth-2 u38: the per-person table still computes, and the unit is genuinely per person
  PASS  depth-2 u39: the worked example is disclosed as free at two competitors
  PASS  depth-2 u39: Connecteam is priced per hub, in blocks of thirty seats
  PASS  depth-2 u39: Homebase's free tier has both its limits, and its meter is premises
  PASS  depth-2 u39: the vendor with no free tier is not credited with one
  PASS  depth-2 u40: the bundle is counted, not described as everything
  PASS  depth-2 u40: the sum-of-parts multiple is the real one
  PASS  depth-2 u40: Odoo's rate is identified as the first-year rate it is
  PASS  depth-2 u40: the competitor free tier is described by its real shape
  PASS  depth-2 u41: the garbled sentence is repaired and the withdrawal re-verified
  PASS  depth-2 u41: the quote-gated vendor still has a nameable meter, and it is stock
  PASS  depth-2 u41: an upfront-pricing promise is not treated as a published price
  PASS  depth-2 u41: the dated Cogsy figure and its three-year sum are kept as a record
  PASS  depth-2 u42: the free recommendation distinguishes the source from the service
  PASS  depth-2 u42: the hosted names now say what they count
  PASS  depth-2 u42: the vendor that would not render is named without a borrowed figure
  PASS  depth-2 u42: the free PHP option is quoted in its own words
  PASS  depth-2 u43: the two meters are shown to be coupled, not separable
  PASS  depth-2 u43: the crossing point is computed from the two published rates
  PASS  depth-2 u43: the third Square tier and the 18 subscriptions it replaced are recorded
  PASS  depth-2 u43: Lightspeed is recorded as the opposite arrangement, with its own gate
  PASS  depth-2 u43: the per-location three-year table still computes
  PASS  depth-2 u44: the booking allowance is named, since that is the meter here
  PASS  depth-2 u44: the localising vendor is disclosed and not converted
  PASS  depth-2 u44: "flat per account" is corrected to what the ladder actually counts
  PASS  depth-2 u44: the free heavyweight is distinguished from its paid service
  PASS  depth-2 u44: Calendly's free cap is by event type, not seats
  PASS  depth-2 u45: the promotional rate is identified as promotional, with its footnote
  PASS  depth-2 u45: the three-year arithmetic runs one discounted year and two standing ones
  PASS  depth-2 u45: the same correction is carried into the other guide citing that page
  PASS  depth-2 u45: the figure we could not attribute is not characterised
  PASS  depth-2 u46: the derived monthly figure is replaced by the published one, here too
  PASS  depth-2 u46: Qminder's user meter is carried into this guide as well
  PASS  depth-2 u46: the per-location claim is corrected to visits, consistent with unit 31
  PASS  depth-2 u46: both queue guides now state the same meter for both vendors
  PASS  depth-2 u47: the vendor states the audience this guide had been inferring
  PASS  depth-2 u47: not sold to you is distinguished from not available to you
  PASS  depth-2 u47: the caveats that keep the suggestion narrow are stated
  PASS  depth-2 u48: the middle case is recorded as gone, and the title re-justified
  PASS  depth-2 u48: the withdrawn vendor is described by what it shows now
  PASS  depth-2 u48: the one published ladder says what it buys
  PASS  depth-2 u48: the intro no longer claims a single July reading for all three
  PASS  depth-2 u49: the free tier that competes with our own product is stated plainly
  PASS  depth-2 u49: the entry price names its billing state
  PASS  depth-2 u49: the quote-gated vendor is recorded by what it lists instead
  PASS  depth-2 u49: the statutory claims are untouched, neither re-dated nor restated
  PASS  depth-2 u50: the retry is recorded honestly, timeouts and success both
  PASS  depth-2 u50: the quote-gated assertion is now cited rather than asserted
  PASS  depth-2 u50: the gated vendor still names its meter, and the guide says what it is
  PASS  depth-2 u50: the second unreachable vendor is named on its earlier reading
  PASS  depth-2 u51: the ladder above the entry tier is carried, with its bundled seats
  PASS  depth-2 u51: ten reps is costed off the bundled-seat basis, not the headline
  PASS  depth-2 u51: the transparent vendor is shown gating its own top plan
  PASS  depth-2 u52: the entry price is read as the floor it says it is
  PASS  depth-2 u52: accounts payable is a second purchase, not part of the first
  PASS  depth-2 u52: the gated vendor names the inputs to its quote
  PASS  depth-2 u53: the plan list is re-dated but the price basis is not
  PASS  depth-2 u53: the machine-read range is unchanged and still attributed to the price API
  PASS  depth-2 u54: no guide links the lapsed domain any more
  PASS  depth-2 u54: the archived project is described accurately in both guides
  PASS  depth-2 u54: the correction says why a dead link is worse than a stale price
  PASS  depth-2 u54: the surviving free option has its licence verified at the repository
  PASS  depth-2 u54: the annual-only vendor is described as annual-only
  PASS  depth-2 u54: the blocked vendor keeps its earlier date, disclosed
  PASS  depth-2 u55: the audience figure is sourced, dated and labelled as the vendor's own
  PASS  depth-2 u55: the uncited predecessor is named rather than silently replaced
  PASS  depth-2 u55: the first-party claim declares that it is first-party
  PASS  depth-2 u56: the deadline carries a COMPLETED dated read at the primary source
  PASS  depth-2 u56: the reader is sent to the primary source, with the CELEX link
  PASS  depth-2 u56: every clock is the one the Regulation sets, and the 72-hour rung is corrected
  PASS  depth-2 u57: the post-cutoff amending regulation is verified and quoted by its title
  PASS  depth-2 u57: both deferral dates are attributed to the recital that carries them
  PASS  depth-2 u57: what was verified today is separated from what was not
  PASS  depth-2 u58: the national transposition is verified at a per-section source and linked
  PASS  depth-2 u58: the Directive quotation declares which reading it carries
  PASS  depth-2 u58: the Article 9(1) text that caught unit 16 is still intact, seven DAYS
  PASS  depth-2 u59: the threshold is sourced at a state department, not a vendor summary
  PASS  depth-2 u59: the dropped transaction-count limb is stated, with the irony named
  PASS  depth-2 u60: both ends of our own hosted range are stated, not just the cheap one
  PASS  depth-2 u60: the exits are quoted in the page's own words
  PASS  depth-2 u61: the pivoted project is gone from the chooser as well as the entry
  PASS  depth-2 u61: the pivoted project is not linked, and is described accurately
  PASS  depth-2 u61: the free invoicing tool is described by its limits, not just its price
  PASS  depth-2 u61: the hosted competitor's free tier and annual price are carried
  PASS  depth-2 u62: the ladder has one axis, and the guide names it
  PASS  depth-2 u62: the hundredfold jump at the first paid step is stated
  PASS  depth-2 u62: the gated vendor that names nothing is contrasted with those that do
  PASS  depth-2 u63: the same order allowance at two very different prices is put side by side
  PASS  depth-2 u63: the caveat keeps the comparison honest
  PASS  depth-2 u63: every rung now carries its allowance, and the gated rungs are named
  PASS  depth-2 u64: the comparison-page source is gone from this guide too
  PASS  depth-2 u64: the free tier is quoted in the page's own words
  PASS  depth-2 u64: the withdrawn vendor's free plan carries its numbers
  PASS  depth-2 u66: the free tier is stated where it undercuts our own licence
  PASS  depth-2 u66: the quoted band is identified as the one without the duty
  PASS  depth-2 u66: the gated vendors are recorded by what they offer instead of a price
  PASS  depth-2 u66: the pinned citations still read as the records state them
  PASS  depth-2 u67: the guide no longer recommends the archived project
  PASS  depth-2 u67: the "both are usable" claim is resolved to the one that is
  PASS  depth-2 u67: the surviving option carries its verified licence and hosted figures
  PASS  depth-2 u68: the export claim matches what the products document
  PASS  depth-2 u68: the argument that does not depend on the format is kept
  PASS  GD2 u70: the install guide's stated PHP floor matches the product notes (4 app notes ask for 8.1 or newer)
  PASS  GD2 u70: the guide no longer calls both engines first-class in every product
  PASS  GD2 u70: the container and demo-data facts are stated as counts, not hedged as "most"
  PASS  GD2 u70: the cloud-host price keeps its own read date and records the 5 September re-read
  PASS  GD2 u71: the Claimlane billing-frequency claim is withdrawn in the text, not silently deleted
  PASS  GD2 u71: the guide carries both published WarrantyHub tiers and marks Enterprise as quoted
  PASS  GD2 u71: the unpriced extras a buyer meets on top of the headline are stated
  PASS  GD2 u71: both vendor figures carry the original read date and the re-read date
  PASS  GD2 u72: the internal-desk lines are priced beside the customer-service ones
  PASS  GD2 u72: the three-agent arithmetic matches the plans it names ($87 and $57 a month)
  PASS  GD2 u72: the annual-billing state is stated rather than left implied
  PASS  GD2 u72: both read dates survive the rewrite
  PASS  GD2 u73: the suites guide links every active bundle, including the whole-catalogue ones
  PASS  GD2 u73: every bundle really is priced below the sum of its parts, as the guide claims
  PASS  GD2 u74: the full Whistlelink employee-band table is printed, not just its cheapest row
  PASS  GD2 u74: the guide names the band an obliged organisation actually falls in
  PASS  GD2 u74: the vendor free trial is disclosed rather than omitted
  PASS  GD2 u74: every vendor named as quote-gated carries a source URL
  PASS  GD2 u74: all three read dates survive, none of them overwritten
  PASS  GD2 u75: no guide body renders a literal backslash-apostrophe (nowdoc escaping) (132 scanned)
  PASS  GD2 u75: the field guide sources NavEx and prints the whole Whistlelink ladder
  PASS  GD2 u75: the two whistleblowing guides agree on which band carries the duty
  PASS  GD2 u76: the EPR duty is quoted from the state programme, with its statutory citation
  PASS  GD2 u76: the exemption is stated before the product is sold
  PASS  GD2 u76: the guide no longer ranks states it never read
  PASS  GD2 u76: Packgine is cited at its new pricing page, still without a figure
  PASS  GD2 u77: both quoted Waiverly answers match the live product page word for word
  PASS  GD2 u77: the invented "no built-in email sending" exclusion is gone
  PASS  GD2 u77: the tamper-evidence description matches what Waiver.php actually fingerprints
  PASS  GD2 u78: no guide quotes a product page in words the product page does not use
  PASS  GD2 u78b: the free alternatives are named with their own words and a source
  PASS  GD2 u78b: GnuCash is no longer filed under personal finance as a different user
  PASS  GD2 u79: the "markets the absence of self-hosting" claim is cited at the vendor
  PASS  GD2 u79: the field-service comparison carries published figures and their source
  PASS  GD2 u79: the unverifiable paper-tracking statistic is still refused, with its reason
  PASS  GD2 u80: the whole BambooHR ladder is published, not just its cheapest rung
  PASS  GD2 u80: the small-team arithmetic is done rather than left to the reader
  PASS  GD2 u80: both vendors carry the original read date and the re-read
  PASS  GD2 u81: a price carrying a lone footnote marker has an explanation within reach of it
  PASS  GD2 u81: the Open Badges sentence is quoted to its end, not stopped early
  PASS  GD2 u81: the spec is no longer quoted in words it does not use
  PASS  GD2 u81: the specification carries both its read dates
  PASS  GD2 u82: guide quotations of a named vendor match the verified capture in comparisons
  PASS  GD2 u82b: the caveat attached to the "same features" claim is quoted with it
  PASS  GD2 u82b: both vendors show their whole ladder, not just the entry rung
  PASS  GD2 u82b: the discounts a club actually qualifies for are named
  PASS  GD2 u82b: both read dates survive
  PASS  GD2 u83: every guide body closes the emphasis it opens
  PASS  GD2 u83b: the self-quote is attributed to the pages that carry it verbatim
  PASS  GD2 u83b: that quotation still matches Tokora word for word
  PASS  GD2 u83b: the unsourceable control-panel claim is a reader check, not an assertion
  PASS  GD2 u84: sqlite.org fragment stands as verified — "SQLite works great as the database engine fo…"
  PASS  GD2 u84: sqlite.org fragment stands as verified — "any site that gets fewer than 100K hits/day …"
  PASS  GD2 u84: sqlite.org fragment stands as verified — "SQLite supports an unlimited number of simul…"
  PASS  GD2 u84: sqlite.org fragment stands as verified — "if the website is write-intensive or is so b…"
  PASS  GD2 u84: sqlite.org fragment stands as verified — "Nevertheless, client/server database systems…"
  PASS  GD2 u84: the concurrency line is quoted as the whole sentence it is
  PASS  GD2 u85: the PHP advice names the actual end-of-support dates and their source
  PASS  GD2 u85: the reader is sent to the source, since the urgent row changes with the calendar
  PASS  GD2 u86: the rule is testable from outside, not only asserted
  PASS  GD2 u86: the checks name the second-door failure the guide argues for
  PASS  GD2 u87: the race can be run by the reader, on both engines
  PASS  GD2 u87: the guide hands the reader a question to put to any other vendor
  PASS  GD2 u88: the install guide no longer sends readers to an end-of-life PHP branch
  PASS  GD2 u88: it separates what the app requires from what the reader should run
  PASS  GD2 u88: no guide tells a reader to switch to any 8.x, EOL branches included
  PASS  GD2 u89: the Calendly seven-day claim is withdrawn on the page, not silently dropped
  PASS  GD2 u89: the headline count reflects the re-read rather than the first reading
  PASS  GD2 u89: the Setmore sentence is quoted as the page words it
  PASS  GD2 u90: the reader is given the free version of the fix before the paid one
  PASS  GD2 u90: it says where the free version stops working, rather than only praising it
  PASS  GD2 u91: the config array is attributed to the client that reads it, not to editors
  PASS  GD2 u91: VS Code is cited for its real format, with the failure spelled out
  PASS  GD2 u92: the read-only gate is verifiable by the reader, not merely asserted
  PASS  GD2 u92: the reader is told to point the same check at any other product
  PASS  GD2 u92: no angle-bracket placeholder that strip_tags would swallow
  PASS  GD2 guide claim: every catalogue product documents its limitations in plain text (49 of 49; bare rows promo-test, uikit-pro are run.php fixtures)
  PASS  retrofit w3-5: Deputy's three plans are still the published ones
  PASS  retrofit w3-6: the Timetastic table carries the third tier found on 3 September
  PASS  retrofit w3-6: the two figures the guide already had are unchanged, and the Vacation Tracker quote is untouched
  PASS  retrofit w3-7: Concord's six figures survive the 3 September re-read
  PASS  retrofit w3-7: the guide now carries Concord's annual-commitment and included-users conditions
  PASS  retrofit w3-7: ContractWorks' withdrawn pricing page is recorded as a dated 404
  PASS  retrofit w3-7: the guide still refuses third-party price figures
  PASS  retrofit w3-8: every floor is dated to the last read that actually happened
  PASS  depth-2: the minimum-spend guide names the page that disagrees with itself, and the tier below the floor
  PASS  retrofit w3-8: Veryfi's dearer document rates are on the page
  PASS  retrofit w3-8: Cheqroom's upper tiers carry the same undisclosed floor
  PASS  retrofit w3-8: the vendors' own sentences are still quoted verbatim
  PASS  retrofit w3-8: the currency caveat now records the reading from outside the EU
  PASS  retrofit w3-9: Cheqroom re-read, and the guide now says what the per-admin meter does not count
  PASS  retrofit w3-9: Booqable's Start tier held and the tiers above it are recorded
  PASS  retrofit w3-9: the three-admin arithmetic still reads from the published per-admin price
  PASS  retrofit w3-10: the SafetyCulture redirect and the Mitti name are on the record
  PASS  retrofit w3-10: both vendors' quoted figures are unchanged after the re-read
  PASS  retrofit w3-11: the iAuditor guide tells its reader the product is now called Mitti
  PASS  retrofit w3-11: both published figures held at the 3 September re-read
  PASS  retrofit w3-11: the free plan's ten-person ceiling sits beside the twelve-person example
  PASS  retrofit w3-11: the seat arithmetic is unchanged and still multiplication on the published price
  PASS  retrofit w3-12: the description's yearly total equals the table it describes
  PASS  retrofit w3-12: the five line items still sum to the printed monthly total
  PASS  retrofit w3-12: the cafe guide carries the Mitti rebrand and the free-tier ceiling
  PASS  depth-2: the cafe guide credits Zoho's free plan and does not borrow a date for the Square rates
  PASS  retrofit w3-12: both food-safety figures held at the re-read
  PASS  3c: no published guide still promises AssetTiger a permanent free tier
  PASS  3c: the depreciation guide keeps the reason AssetTiger is worth naming
  PASS  3c: the AssetTiger record no longer states a free tier anywhere
  PASS  3c: fifteen comparison rows carry the 3 September re-read
  PASS  3c: every comparison row still carries a source URL
  PASS  set 10 is registered in ownware-seed.php
  PASS  3b: set 10 holds two guides, the lawful daily pace for new ones
  PASS  3b: what-a-buying-agent-reads-on-your-store is seeded, published and dated to the day it was written
  PASS  3b: what-a-buying-agent-reads-on-your-store cites the blueprint at its own source with a read date
  PASS  3b: what-a-buying-agent-reads-on-your-store never claims this store implements the blueprint
  PASS  3b: staged-writes-an-ai-in-the-back-office-without-the-keys is seeded, published and dated to the day it was written
  PASS  3b: staged-writes-an-ai-in-the-back-office-without-the-keys cites the blueprint at its own source with a read date
  PASS  3b: staged-writes-an-ai-in-the-back-office-without-the-keys never claims this store implements the blueprint
  PASS  3b: the staged-writes guide states the limit outright rather than implying capability
  PASS  3b: the blueprint quotes are verbatim from the sources read on 3 September
  PASS  3b: the buying-agent guide keeps its honest limit about recommendation
  PASS  3a-13: the property guide dates its 3 September re-read of all five vendors
  PASS  3a-13: Hemlane is costed from the platform fee plus the per-unit rate, not a round $50
  PASS  3a-13: the Hemlane row is the arithmetic it claims (28 + 10*2 = 48, x12/36/60)
  PASS  3a-13: the four unchanged vendor figures are still the published ones
  PASS  3a-14: the hotel guide records the 3 September re-read and the Mitti rebrand
  PASS  3a-14: the free-plan ceiling is stated beside the per-seat argument
  PASS  3a-14: the seat arithmetic is unchanged and still multiplication on the published price
  PASS  3a-14: Safora is priced at the overlay price the store actually charges
  PASS  3a-15: the two dollar-priced vendors carry the 3 September re-read
  PASS  3a-15: the SimplyBook euro figure is untouched and its regional pricing is disclosed
  PASS  3a-15: the seat arithmetic is the sum it claims (3 x $10 x 36 = $1,080; $16 x 36 = $576)
  PASS  3a-16: the suite guide carries the 3 September re-read and the Mitti rebrand
  PASS  3a-16: the three members are priced as the store prices them, and sum to the stated $267
  PASS  3a-16: the bundle price and its membership match the DB
  PASS  3a-17: all five Workforce members are priced as the store prices them
  PASS  3a-17: the five sum to the $385 the guide prints, and the bundle is the $249 it prints
  PASS  3a-17: the guide names exactly the five products the bundle contains
  PASS  3a-17: the price paragraph is dated to the day the figures were re-verified
  PASS  3a-18: all five Field-Service members are priced as the store prices them
  PASS  3a-18: the five sum to the $465 printed, against the $369 bundle the DB holds
  PASS  3a-18: the price paragraph is dated to the day the figures were re-verified
  PASS  3a-19: the three comparators carry the 3 September re-read
  PASS  3a-19: Rentara is the $119 the guide prints, and the Property Suite the $149
  PASS  3a-19: the three-year comparisons are the multiplication they claim (62/69/15 x 36)
  PASS  3a-20: the two comparators carry the 3 September re-read
  PASS  3a-20: Hemlane is described as the vendor prices it — per unit ON TOP OF the platform fee
  PASS  3a-20: the guide still refuses to print a hosting price it cannot verify
  PASS  3a-20: the licence figures match the store
  PASS  3a-21: Calendly carries the 3 September re-read and Slotly is the store price
  PASS  3a-21: the three-seat comparison is the multiplication it claims (3 x $10 x 36)
  PASS  3a-21: the guide still sends the reader to the free options first
  PASS  3a-21: the card-processing limit is still stated as a reason to buy elsewhere
  PASS  3a-22: every route the story says was added still exists
  PASS  3a-22: the bare-slug redirect is still registered LAST, as the story claims
  PASS  3a-22: the story still names no buyer and annualises nothing
  PASS  3a-22: the advice the story ends on is still there
  PASS  3c: Clockify carries the read date its page was actually re-read on
  PASS  3c: Veryfi (OCR API) carries the read date its page was actually re-read on
  PASS  3c: FreshBooks carries the read date its page was actually re-read on
  PASS  3c: Timetastic carries the read date its page was actually re-read on
  PASS  3c: Buildium carries the read date its page was actually re-read on
  PASS  3c: Hemlane carries the read date its page was actually re-read on
  PASS  3c: DoorLoop carries the read date its page was actually re-read on
  PASS  3c: AppFolio carries the read date its page was actually re-read on
  PASS  3c: Calendly carries the read date its page was actually re-read on
  PASS  3c: Setmore carries the read date its page was actually re-read on
  PASS  3c: Acuity Scheduling carries the read date its page was actually re-read on
  PASS  3c: TenantCloud carries the date of the attempt that finally succeeded
  PASS  3c: the menura Veryfi row is dated from the menu-OCR page it actually cites
  PASS  3c: the Clockify row anchors on the cheapest paid seat, 3 x $3.99
  PASS  3c: the 10-seat Clockify table is the arithmetic it prints (10 x 3.99 = 39.90; x 36 = 1,436.40)
  PASS  3c: the ladder never appears in a guide without the cheapest paid seat in front of it
  PASS  3c: the per-seat ledger table still ranks by monthly cost, so Clockify at $11.97 sits below Setmore at $15.00
  PASS  3c: the Setmore row records BOTH billing states (3 seats: $15/mo annual, $36/mo monthly)
  PASS  3c: the Calendly row records the Teams seat that round-robin actually needs, in both billing states
  PASS  3c: the Timetastic row names the plan the page names (Business) and carries the third tier
  PASS  3c: no guide still calls that plan Timetastic Basic
  PASS  3c: the Veryfi row records the free tier the page offers, not only the $500 floor
  PASS  3c: the FreshBooks note states the promo term the page now shows
  PASS  3c: no guide still caps the Setmore free plan at 200 appointments a month
  PASS  3c: the DoorLoop row no longer quotes a sentence that has left the vendor's page
  PASS  3c: the Acuity Scheduling row no longer quotes a sentence that has left the vendor's page
  PASS  3c: the Calendly row no longer quotes a sentence that has left the vendor's page
  PASS  3c: the Timetastic row no longer quotes a sentence that has left the vendor's page
  PASS  3c: Precoro carries the read date its page was actually re-read on
  PASS  3c: Procurify carries the read date its page was actually re-read on
  PASS  3c: FaceUp carries the read date its page was actually re-read on
  PASS  3c: ConsignCloud carries the read date its page was actually re-read on
  PASS  3c: Mindee carries the read date its page was actually re-read on
  PASS  3c: GymMaster carries the read date its page was actually re-read on
  PASS  3c: Zoho Invoice carries the read date its page was actually re-read on
  PASS  3c: Invoice Ninja carries the read date its page was actually re-read on
  PASS  3c: the Precoro row no longer quotes a sentence that has left the vendor's page
  PASS  3c: the Procurify row no longer quotes a sentence that has left the vendor's page
  PASS  3c: the Mindee row no longer quotes a sentence that has left the vendor's page
  PASS  3c: no guide still quotes the Procurify sentence that has left its pricing page
  PASS  3c: Mindee records the Pro tier beside Starter, both billing states
  PASS  3c: GymMaster records the member cap each per-site tier is metered by
  PASS  3c: the GymMaster three-year figure in the guide is the arithmetic it claims (89 x 36 = 3,204)
  PASS  3c: the Precoro three-year figure in the guide is the arithmetic it claims (499 x 36 = 17,964)
  PASS  3c: Invoice Ninja records the annual state, and two months free is what the annual price means (14 x 10 = 140)
  PASS  3c: the quote-gated rows still say so, with no invented figure
  PASS  depth-2 u12: Parseur carries its own 5 September re-read date
  PASS  depth-2 u20: DocuClipper carries its own 5 September re-read date
  PASS  depth-2 u27: Cogsy carries its own 5 September re-verification date
  PASS  3c: Expensify carries the read date its page was actually re-read on
  PASS  3c: TaxJar carries the read date its page was actually re-read on
  PASS  3c: Enzuzo carries the read date its page was actually re-read on
  PASS  3c: Osano carries the read date its page was actually re-read on
  PASS  3c: Onetime Secret carries the read date its page was actually re-read on
  PASS  3c: Bitwarden carries the read date its page was actually re-read on
  PASS  3c: DocuClipper names the billing state each figure belongs to, and the guide agrees
  PASS  3c: the DocuClipper per-page figure is still the arithmetic it claims (20 / 60 = 0.33)
  PASS  3c: the Enzuzo row records the vendor's own DSAR discrepancy rather than choosing a side
  PASS  3c: the Enzuzo row carries the annual billing state beside the monthly one
  PASS  3c: the Expensify row states that its source is a dated blog post, not a live pricing page
  PASS  3c: the guide never dates two vendors from a single reading
  PASS  3c: the Bitwarden row records that the page says nothing about the free tier's Send limits
  PASS  3c: Onetime Secret keeps its euro figures and gains the tier above (EUR 125)
  PASS  3c: the still-quote-gated rows carry no invented figure
  PASS  3c: Veryfi Restaurant Menu OCR API carries the read date its page was actually re-read on
  PASS  3c: Inventory Planner carries the read date its page was actually re-read on
  PASS  3c: Plytix carries the read date its page was actually re-read on
  PASS  3c: Salsify carries the read date its page was actually re-read on
  PASS  3c: Smartwaiver was NOT re-dated - its page could not be read from here on 2026-09-03
  PASS  3c: Lemon Squeezy was NOT re-dated - its page could not be read from here on 2026-09-03
  PASS  3c: SimplyBook.me was NOT re-dated - its page could not be read from here on 2026-09-03
  PASS  3c: the SimplyBook.me row records the currency it was served and why that is not a re-verification
  PASS  depth-2: the Mindbody withdrawal is recorded in the row and in the guide
  PASS  3c: the Veryfi menu row separates the page that has no price from the page that has the floor
  PASS  3c: Inventory Planner is still quote-gated, with no figure invented for it
  PASS  3c: Salsify is still quote-gated, with no figure invented for it
  PASS  3c: Asset Panda carries the read date its page was actually re-read on
  PASS  3c: Harvest carries the read date its page was actually re-read on
  PASS  3c: QuotaPath carries the read date its page was actually re-read on
  PASS  3c: Qminder carries the read date its page was actually re-read on
  PASS  3c: Waitwhile carries the read date its page was actually re-read on
  PASS  3c: Featurebase carries the read date its page was actually re-read on
  PASS  3c: ProvePrivacy carries the read date its page was actually re-read on
  PASS  3c: Packgine carries the read date its page was actually re-read on
  PASS  3c: the Featurebase whitelabel add-on is gone from the row, and the row records why
  PASS  3c: Harvest's free plan is on the row and in the guide that argues about per-seat cost
  PASS  3c: Harvest annual billing is recorded as the same rate, not a discount (108 / 12 = 9)
  PASS  3c: Featurebase records that every tier is priced billed-yearly with no monthly rate shown
  PASS  3c: Waitwhile records what the paid tiers meter, and that the annual figure is not printed
  PASS  3c: the Qminder annual figure is the arithmetic the row prints (9,468 / 12 = 789)
  PASS  3c: QuotaPath still leads with the platform fee, not the per-seat price
  PASS  3c: Wave carries the read date its page was actually re-read on
  PASS  3c: SimpleConsign carries the read date its page was actually re-read on
  PASS  3c: Gumroad carries the read date its page was actually re-read on
  PASS  3c: Glofox carries the read date its page was actually re-read on
  PASS  3c: Rentec Direct carries the read date its page was actually re-read on
  PASS  3c: Nolt was NOT re-dated - its page could not be read from here on 2026-09-03
  PASS  3c: WaiverForever was NOT re-dated - its page could not be read from here on 2026-09-03
  PASS  3c: the Rentec row is anchored on a figure that is actually on the page
  PASS  3c: the guide's Rentec three-year figure is the arithmetic it claims (25 x 36 = 900)
  PASS  3c: that three-year table is still in ascending cost order after the change
  PASS  3c: the Rentec strength quote is a phrase the page actually prints
  PASS  3c: Square Appointments keeps its figures and its old date after an unrendered read
  PASS  3c: the Glofox row carries no mechanism quote, and says why
  PASS  3c: Wave records the annual price and the separately-priced extras
  PASS  3c-60: the guide citing https://www.fooddocs.com/pricing carries the date its row was read on
  PASS  3c-60: the guide citing https://www.freshbooks.com/pricing carries the date its row was read on
  PASS  3c-60: the guide citing https://www.deputy.com/pricing carries the date its row was read on
  PASS  3c-60: the guide citing https://www.getmaintainx.com/pricing carries the date its row was read on
  PASS  3c-60: the guide citing https://limble.com/pricing carries the date its row was read on
  PASS  3c-60: the guide citing https://www.cheqroom.com/pricing/ carries the date its row was read on
  PASS  3c-60: the guide citing https://vacationtracker.io/pricing/ carries the date its row was read on
  PASS  3c-60: the guide citing https://www.assettiger.com/pricing carries the date its row was read on
  PASS  3c-60: Smartwaiver keeps the earlier date and records the discrepancy rather than adopting it
  PASS  3c-60: no published guide still prints "Starting at $45 per month"
  PASS  3c-60: no published guide still prints "Timetastic Basic"
  PASS  3c-60: no published guide still prints "200 appointments per month"
  PASS  3c-60: no published guide still prints "whitelabel"
  PASS  3c: MoneyThumb carries the read date its page was actually re-read on
  PASS  3c: NiceJob carries the read date its page was actually re-read on
  PASS  3c: Podium carries the read date its page was actually re-read on
  PASS  3c: Canny carries the read date its page was actually re-read on
  PASS  3c: Perfex CRM SaaS carries the read date its page was actually re-read on
  PASS  3c: Acculance SaaS carries the read date its page was actually re-read on
  PASS  3c: Lemon Squeezy was NOT re-dated - it answered 403 on every attempt
  PASS  3c: the Cogsy row quotes the withdrawal notice and nothing that has left the page
  PASS  3c: no guide still sells Cogsy in the present tense
  PASS  3c: the withdrawn price survives only as a dated historical figure (199 x 36 = 7,164)
  PASS  3c: the Smartwaiver row still records a citation it cannot evidence rather than adopting its date
  PASS  3c: the CodeCanyon rows carry the extended licence and date their sales counts
  PASS  3c: the MoneyThumb row flags the figure that is not on the page it cites
  PASS  3c: Canny records both billing states across its tracked-user ladder
  PASS  3c: Docsumo carries the read date its page was actually re-read on
  PASS  3c: Bill.com carries the read date its page was actually re-read on
  PASS  3c: Avalara carries the read date its page was actually re-read on
  PASS  3c: Sling carries the read date its page was actually re-read on
  PASS  3c: Square POS carries the read date its page was actually re-read on
  PASS  3c: 7shifts was NOT re-dated - the page returned no pricing content on 2026-09-03
  PASS  3c: the Docsumo row records that the withdrawn $499 price is still absent a month later
  PASS  3c: Square Appointments records the press-page corroboration without adopting its date
  PASS  3c: Sling records both billing states and the free tier, and the 15% is the arithmetic it claims
  PASS  3c: the Bill.com row keeps the $0 Spend & Expense product separate from the AP/AR subscription
  PASS  3c: Fleetio carries the read date its page was actually re-read on
  PASS  3c: Simply Fleet carries the read date its page was actually re-read on
  PASS  3c: Samsara carries the read date its page was actually re-read on
  PASS  3c: Smile.io carries the read date its page was actually re-read on
  PASS  3c: LoyaltyLion carries the read date its page was actually re-read on
  PASS  3c: Loyverse carries the read date its page was actually re-read on
  PASS  3c: Square Loyalty carries the read date its page was actually re-read on
  PASS  3c: Whip Around was NOT re-dated - its pricing URL served the homepage instead
  PASS  3c: the Loyverse row names both currencies it has been served and does not claim the USD figure was re-verified
  PASS  3c: the Square Loyalty quote is contiguous text, not two buttons joined together
  PASS  3c: the Fleetio row records the fleet size its displayed prices assume
  PASS  3c: Simply Fleet carries the annual state as well as the monthly one (5 x $20/yr = $100)
  PASS  3c: LoyaltyLion records that only its entry tier carries a published figure
  PASS  3c: Smile.io records the top tier order allowance and that only monthly rates are printed
  PASS  3c: Tradogram carries the read date its page was actually re-read on
  PASS  3c: Payhip carries the read date its page was actually re-read on
  PASS  3c: SendOwl carries the read date its page was actually re-read on
  PASS  3c: Sellfy carries the read date its page was actually re-read on
  PASS  3c: eMaint carries the read date its page was actually re-read on
  PASS  3c: FMX carries the read date its page was actually re-read on
  PASS  3c: Facilio carries the read date its page was actually re-read on
  PASS  3c: the Tradogram strength quote is contiguous text from the page
  PASS  3c: the SendOwl quotes use the page's wording, not a tidied-up version of it
  PASS  3c: Tradogram records the user bands its quote-only tiers start from
  PASS  3c: the Sellfy ladder is a consistent 25% annual discount at every tier
  PASS  3c: eMaint still publishes no figure, and none is invented for it
  PASS  3c: FMX still publishes no figure, and none is invented for it
  PASS  3c: Facilio still publishes no figure, and none is invented for it
  PASS  3c: Hippo CMMS carries the read date its page was actually re-read on
  PASS  3c: Azuga carries the read date its page was actually re-read on
  PASS  3c: Fleet Complete carries the read date its page was actually re-read on
  PASS  3c: PushPress carries the read date its page was actually re-read on
  PASS  3c: Wodify carries the read date its page was actually re-read on
  PASS  3c: Mariana Tek carries the read date its page was actually re-read on
  PASS  3c: Zen Planner was NOT re-dated - the page came back truncated on 2026-09-03
  PASS  3c: Azuga and Fleet Complete quote sentences rather than lists of features run together
  PASS  3c: the PushPress rate is written the way the page writes it, and the ACH rate is recorded too
  PASS  3c: the Wodify row records that its promo outlived its own stated deadline
  PASS  3c: the Mariana Tek quote is the whole sentence the page prints, vendor spelling included
  PASS  3c: Azuga still anchors on the per-vehicle entry rate it publishes
  PASS  3c: Bonsai carries the read date its page was actually re-read on
  PASS  3c: HoneyBook carries the read date its page was actually re-read on
  PASS  3c: Invoicely carries the read date its page was actually re-read on
  PASS  3c: Sortly carries the read date its page was actually re-read on
  PASS  3c: Zoho Inventory carries the read date its page was actually re-read on
  PASS  3c: Booksy carries the read date its page was actually re-read on
  PASS  3c: no row in this batch still uses the bare word Free as its evidence
  PASS  3c: Bonsai and HoneyBook quote sentences rather than feature bullets run together
  PASS  3c: the rates and per-seat lines are written the way the pages write them
  PASS  3c: the Invoicely row cites the metered dimension and explains why it is a label, not a sentence
  PASS  3c: the Zoho Inventory row records the free plan and the separately-sold caps
  PASS  3c: the Booksy four-person figure is the arithmetic it claims (29.99 + 3 x 20 = 89.99)
  PASS  3c: Fresha carries the read date its page was actually re-read on
  PASS  3c: Vagaro carries the read date its page was actually re-read on
  PASS  3c: Skiplino carries the read date its page was actually re-read on
  PASS  3c: Lightspeed Retail carries the read date its page was actually re-read on
  PASS  3c: Shopify POS carries the read date its page was actually re-read on
  PASS  3c: Erply carries the read date its page was actually re-read on
  PASS  3c: no row in this batch offers a product name or a price as its strength quote
  PASS  3c: Erply and Shopify quote contiguous text rather than joined cells
  PASS  3c: the Lightspeed source quote drops a sentence the page never printed
  PASS  3c: the currency-served rows still carry the currency they were read in
  PASS  3c: Skiplino quotes the page's own hyphenation of its trial
  PASS  3c: Hike POS carries the read date its page was actually re-read on
  PASS  3c: KORONA POS carries the read date its page was actually re-read on
  PASS  3c: Pleo carries the read date its page was actually re-read on
  PASS  3c: Certifier carries the read date its page was actually re-read on
  PASS  3c: PermitFlow carries the read date its page was actually re-read on
  PASS  3c: Whistlelink carries the read date its page was actually re-read on
  PASS  3c: TenantCloud carries the read date its page was actually re-read on
  PASS  3c: the TenantCloud row records that the third attempt succeeded and corroborates the guide
  PASS  3c: the Certifier allowances match the tiers the page puts them on
  PASS  3c: KORONA quotes its no-fees and no-contract claims in the vendor's own sentences
  PASS  3c: the Hike POS strength quote is a phrase the page prints
  PASS  3c: Pleo stores no monthly cents, so no dollar saving is invented from a pound price
  PASS  3c: the Whistlelink row flags that it stores cents for a euro price where Pleo does not
  PASS  retrofit b1 hot-fix: no published guide still carries a statement the live store disproves
  PASS  retrofit b1 hot-fix: the suites overview counts nothing it cannot read live
  PASS  retrofit b1 hot-fix: the Workforce Suite line in the timesheet guide carries the live bundle price
  PASS  retrofit b1 hot-fix: the Compliance Suite has five members and both guides say five (aiactora out 2026-09-06)
  PASS  retrofit b1 hot-fix: the suites overview links every active suite (OS bundles aside) and no unlisted product
  PASS  retrofit b1: the Bing sibling title carries the harvested phrase

== Package 4 phase B, batch 2 (2026-09-02): back-catalogue retrofit ==
  PASS  retrofit b2: contract-renewal-tracker-self-hosted is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b2: contract-renewal-tracker-self-hosted — every internal link resolves (8)
  PASS  retrofit b2: contract-renewal-tracker-self-hosted — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b2: document-extraction-break-even-volume is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b2: document-extraction-break-even-volume — every internal link resolves (6)
  PASS  retrofit b2: document-extraction-break-even-volume — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b2: stop-paying-gumroad-10-percent is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b2: stop-paying-gumroad-10-percent — every internal link resolves (5)
  PASS  retrofit b2: stop-paying-gumroad-10-percent — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b2: salon-clinic-software-stack-what-to-own is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b2: salon-clinic-software-stack-what-to-own — every internal link resolves (11)
  PASS  retrofit b2: salon-clinic-software-stack-what-to-own — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b2: timesheet-software-without-per-seat-pricing is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b2: timesheet-software-without-per-seat-pricing — every internal link resolves (10)
  PASS  retrofit b2: timesheet-software-without-per-seat-pricing — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b2: eu-data-residency-buyers-guide is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b2: eu-data-residency-buyers-guide — every internal link resolves (15)
  PASS  retrofit b2: eu-data-residency-buyers-guide — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b2: quote-gated-pricing-what-it-costs-you is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b2: quote-gated-pricing-what-it-costs-you — every internal link resolves (5)
  PASS  retrofit b2: quote-gated-pricing-what-it-costs-you — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b2: haccp-logbook-per-seat-vs-per-site is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b2: haccp-logbook-per-seat-vs-per-site — every internal link resolves (8)
  PASS  retrofit b2: haccp-logbook-per-seat-vs-per-site — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b2: fleet-software-cost-teardown is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b2: fleet-software-cost-teardown — every internal link resolves (5)
  PASS  retrofit b2: fleet-software-cost-teardown — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b2: bank-statement-converter-who-sees-your-statements is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b2: bank-statement-converter-who-sees-your-statements — every internal link resolves (5)
  PASS  retrofit b2: bank-statement-converter-who-sees-your-statements — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b2: contract-renewal-tracker-self-hosted types supplia at the live single price
  PASS  retrofit b2: document-extraction-break-even-volume types extracta at the live single price
  PASS  retrofit b2: stop-paying-gumroad-10-percent types deliora at the live single price
  PASS  retrofit b2: salon-clinic-software-stack-what-to-own types slotly at the live single price
  PASS  retrofit b2: salon-clinic-software-stack-what-to-own types rostera at the live single price
  PASS  retrofit b2: salon-clinic-software-stack-what-to-own types waiverly at the live single price
  PASS  retrofit b2: timesheet-software-without-per-seat-pricing types clockora at the live single price
  PASS  retrofit b2: timesheet-software-without-per-seat-pricing types invora at the live single price
  PASS  retrofit b2: eu-data-residency-buyers-guide types privara at the live single price
  PASS  retrofit b2: eu-data-residency-buyers-guide types confida at the live single price
  PASS  retrofit b2: eu-data-residency-buyers-guide types complia at the live single price
  PASS  retrofit b2: eu-data-residency-buyers-guide types secreta at the live single price
  PASS  retrofit b2: quote-gated-pricing-what-it-costs-you types confida at the live single price
  PASS  retrofit b2: haccp-logbook-per-seat-vs-per-site types safora at the live single price
  PASS  retrofit b2: fleet-software-cost-teardown types fleetora at the live single price
  PASS  retrofit b2: bank-statement-converter-who-sees-your-statements types ledgira at the live single price
  PASS  retrofit b2: contract-renewal-tracker-self-hosted cites Concord as the record states ($499) with the vendor URL in the body
  PASS  retrofit b2: contract-renewal-tracker-self-hosted cites ContractWorks as the record states (withdrew its pricing page) with the vendor URL in the body
  PASS  retrofit b2: document-extraction-break-even-volume cites Parseur as the record states ($39/month) with the vendor URL in the body
  PASS  retrofit b2: document-extraction-break-even-volume cites Mindee as the record states ($44/month) with the vendor URL in the body
  PASS  retrofit b2: document-extraction-break-even-volume cites Docsumo as the record states (Talk to us) with the vendor URL in the body
  PASS  retrofit b2: document-extraction-break-even-volume cites Veryfi (OCR as the record states ($500+/mo) with the vendor URL in the body
  PASS  retrofit b2: stop-paying-gumroad-10-percent cites Gumroad as the record states (10% + $0.50) with the vendor URL in the body
  PASS  retrofit b2: stop-paying-gumroad-10-percent cites Lemon Squeezy as the record states (5% + 50c) with the vendor URL in the body
  PASS  retrofit b2: salon-clinic-software-stack-what-to-own cites Setmore as the record states (Pro $5/user/month) with the vendor URL in the body
  PASS  retrofit b2: salon-clinic-software-stack-what-to-own cites SimplyBook as the record states (EUR 11.9) with the vendor URL in the body
  PASS  retrofit b2: salon-clinic-software-stack-what-to-own cites Acuity as the record states ($16/mo) with the vendor URL in the body
  PASS  retrofit b2: salon-clinic-software-stack-what-to-own cites Calendly as the record states ($10/seat/mo) with the vendor URL in the body
  PASS  retrofit b2: salon-clinic-software-stack-what-to-own cites Square Appointments as the record states (Plus $49/mo) with the vendor URL in the body
  PASS  retrofit b2: salon-clinic-software-stack-what-to-own cites Smartwaiver as the record states (Basic $19/mo) with the vendor URL in the body
  PASS  retrofit b2: salon-clinic-software-stack-what-to-own cites WaiverForever as the record states (Essential $19/mo) with the vendor URL in the body
  PASS  retrofit b2: salon-clinic-software-stack-what-to-own cites Deputy as the record states (Lite $5) with the vendor URL in the body
  PASS  retrofit b2: salon-clinic-software-stack-what-to-own cites Expensify as the record states ($5/member/month) with the vendor URL in the body
  PASS  retrofit b2: salon-clinic-software-stack-what-to-own cites Zoho Expense as the record states ($4/user/month) with the vendor URL in the body
  PASS  retrofit b2: timesheet-software-without-per-seat-pricing cites Clockify as the record states ($5.49) with the vendor URL in the body
  PASS  retrofit b2: timesheet-software-without-per-seat-pricing cites Harvest as the record states ($9/seat/month) with the vendor URL in the body
  PASS  retrofit b2: eu-data-residency-buyers-guide cites Enzuzo as the record states ($9 / month) with the vendor URL in the body
  PASS  retrofit b2: eu-data-residency-buyers-guide cites Osano as the record states (No public price) with the vendor URL in the body
  PASS  retrofit b2: eu-data-residency-buyers-guide cites Whistlelink as the record states (EUR 79/month) with the vendor URL in the body
  PASS  retrofit b2: eu-data-residency-buyers-guide cites FaceUp as the record states (No public price) with the vendor URL in the body
  PASS  retrofit b2: eu-data-residency-buyers-guide cites ProvePrivacy as the record states (No public price) with the vendor URL in the body
  PASS  retrofit b2: eu-data-residency-buyers-guide cites Onetime Secret as the record states (EUR 35/month) with the vendor URL in the body
  PASS  retrofit b2: quote-gated-pricing-what-it-costs-you cites Bill.com as the record states ($49/user/month) with the vendor URL in the body
  PASS  retrofit b2: quote-gated-pricing-what-it-costs-you cites Avalara as the record states ($699 per state) with the vendor URL in the body
  PASS  retrofit b2: quote-gated-pricing-what-it-costs-you cites Cheqroom as the record states (184 per admin) with the vendor URL in the body
  PASS  retrofit b2: quote-gated-pricing-what-it-costs-you cites Podium as the record states (No public price) with the vendor URL in the body
  PASS  retrofit b2: quote-gated-pricing-what-it-costs-you cites Salsify as the record states (No public price) with the vendor URL in the body
  PASS  retrofit b2: quote-gated-pricing-what-it-costs-you cites ConsignCloud as the record states ($139/month) with the vendor URL in the body
  PASS  retrofit b2: haccp-logbook-per-seat-vs-per-site cites SafetyCulture as the record states ($24/seat/month) with the vendor URL in the body
  PASS  retrofit b2: haccp-logbook-per-seat-vs-per-site cites FoodDocs as the record states ($79 per site/month) with the vendor URL in the body
  PASS  retrofit b2: fleet-software-cost-teardown cites Simply Fleet as the record states ($2 per vehicle) with the vendor URL in the body
  PASS  retrofit b2: fleet-software-cost-teardown cites Fleetio as the record states ($4 per vehicle) with the vendor URL in the body
  PASS  retrofit b2: fleet-software-cost-teardown cites Whip Around as the record states ($5 USD/asset/mo) with the vendor URL in the body
  PASS  retrofit b2: fleet-software-cost-teardown cites Samsara as the record states (No public price) with the vendor URL in the body
  PASS  retrofit b2: bank-statement-converter-who-sees-your-statements cites DocuClipper as the record states ($20/month) with the vendor URL in the body
  PASS  retrofit b2: bank-statement-converter-who-sees-your-statements cites MoneyThumb as the record states ($24.95/month) with the vendor URL in the body
  PASS  retrofit b2: the salon guide quotes Slotly's current FAQ on deposits, not the retired "gateways are roadmap" line

== Package 4 phase B, batch 3 (2026-09-02): back-catalogue retrofit ==
  PASS  retrofit b3: what-currency-are-you-actually-billed-in is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b3: what-currency-are-you-actually-billed-in — every internal link resolves (4)
  PASS  retrofit b3: what-currency-are-you-actually-billed-in — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b3: visitor-management-cost-what-a-reception-book-rents-for is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b3: visitor-management-cost-what-a-reception-book-rents-for — every internal link resolves (8)
  PASS  retrofit b3: visitor-management-cost-what-a-reception-book-rents-for — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b3: agency-stack-when-free-is-the-right-answer is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b3: agency-stack-when-free-is-the-right-answer — every internal link resolves (10)
  PASS  retrofit b3: agency-stack-when-free-is-the-right-answer — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b3: inspection-software-cost-teardown-per-user-forever is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b3: inspection-software-cost-teardown-per-user-forever — every internal link resolves (8)
  PASS  retrofit b3: inspection-software-cost-teardown-per-user-forever — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b3: timetastic-alternative-self-hosted-leave is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b3: timetastic-alternative-self-hosted-leave — every internal link resolves (10)
  PASS  retrofit b3: timetastic-alternative-self-hosted-leave — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b3: the-five-year-math-honestly is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b3: the-five-year-math-honestly — every internal link resolves (6)
  PASS  retrofit b3: the-five-year-math-honestly — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b3: rent-vs-own-three-year-math is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b3: rent-vs-own-three-year-math — every internal link resolves (11)
  PASS  retrofit b3: rent-vs-own-three-year-math — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b3: expense-report-software-buy-once is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b3: expense-report-software-buy-once — every internal link resolves (8)
  PASS  retrofit b3: expense-report-software-buy-once — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b3: self-hosted-rental-property-management is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b3: self-hosted-rental-property-management — every internal link resolves (12)
  PASS  retrofit b3: self-hosted-rental-property-management — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b3: self-hosted-calendly-alternative is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b3: self-hosted-calendly-alternative — every internal link resolves (8)
  PASS  retrofit b3: self-hosted-calendly-alternative — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b3: visitor-management-cost-what-a-reception-book-rents-for types visitora at the live single price
  PASS  retrofit b3: agency-stack-when-free-is-the-right-answer types clockora at the live single price
  PASS  retrofit b3: agency-stack-when-free-is-the-right-answer types invora at the live single price
  PASS  retrofit b3: inspection-software-cost-teardown-per-user-forever types inspectora at the live single price
  PASS  retrofit b3: timetastic-alternative-self-hosted-leave types leavora at the live single price
  PASS  retrofit b3: the-five-year-math-honestly types invora at the live single price
  PASS  retrofit b3: the-five-year-math-honestly types rostera at the live single price
  PASS  retrofit b3: rent-vs-own-three-year-math types rentara at the live single price
  PASS  retrofit b3: rent-vs-own-three-year-math types fixora at the live single price
  PASS  retrofit b3: rent-vs-own-three-year-math types safora at the live single price
  PASS  retrofit b3: rent-vs-own-three-year-math types consigna at the live single price
  PASS  retrofit b3: rent-vs-own-three-year-math types restock at the live single price
  PASS  retrofit b3: expense-report-software-buy-once types expensa at the live single price
  PASS  retrofit b3: self-hosted-calendly-alternative types slotly at the live single price
  PASS  retrofit b3: what-currency-are-you-actually-billed-in cites Deputy as the record states (USD $30/month minimum) with the vendor URL in the body
  PASS  retrofit b3: what-currency-are-you-actually-billed-in cites Timetastic as the record states ($1.50/user/month) with the vendor URL in the body
  PASS  retrofit b3: what-currency-are-you-actually-billed-in cites FoodDocs as the record states (ex. VAT) with the vendor URL in the body
  PASS  retrofit b3: what-currency-are-you-actually-billed-in cites Zoho Expense as the record states ($3/user/month annually) with the vendor URL in the body
  PASS  retrofit b3: visitor-management-cost-what-a-reception-book-rents-for cites Sign In App as the record states (£415 per site) with the vendor URL in the body
  PASS  retrofit b3: visitor-management-cost-what-a-reception-book-rents-for cites Envoy as the record states ($362 per location) with the vendor URL in the body
  PASS  retrofit b3: agency-stack-when-free-is-the-right-answer cites Clockify as the record states ($5.49) with the vendor URL in the body
  PASS  retrofit b3: agency-stack-when-free-is-the-right-answer cites Harvest as the record states ($9/seat/month) with the vendor URL in the body
  PASS  retrofit b3: agency-stack-when-free-is-the-right-answer cites FreshBooks as the record states ($23.00/mo) with the vendor URL in the body
  PASS  retrofit b3: agency-stack-when-free-is-the-right-answer cites Invoice Ninja as the record states ($14/mo) with the vendor URL in the body
  PASS  retrofit b3: agency-stack-when-free-is-the-right-answer cites Wave as the record states (Pro $19/mo) with the vendor URL in the body
  PASS  retrofit b3: inspection-software-cost-teardown-per-user-forever cites MaintainX as the record states ($20 per user/month) with the vendor URL in the body
  PASS  retrofit b3: inspection-software-cost-teardown-per-user-forever cites Limble as the record states (No public price) with the vendor URL in the body
  PASS  retrofit b3: timetastic-alternative-self-hosted-leave cites Timetastic as the record states ($1.50/user/month) with the vendor URL in the body
  PASS  retrofit b3: timetastic-alternative-self-hosted-leave cites Vacation Tracker as the record states (EUR 50/month minimum) with the vendor URL in the body
  PASS  retrofit b3: the-five-year-math-honestly cites FreshBooks as the record states ($23.00/mo) with the vendor URL in the body
  PASS  retrofit b3: rent-vs-own-three-year-math cites Buildium as the record states ($62/month) with the vendor URL in the body
  PASS  retrofit b3: rent-vs-own-three-year-math cites Fiix as the record states ($45 per user) with the vendor URL in the body
  PASS  retrofit b3: rent-vs-own-three-year-math cites FoodDocs as the record states ($79 per site/month) with the vendor URL in the body
  PASS  retrofit b3: rent-vs-own-three-year-math cites SimpleConsign as the record states ($159/mo) with the vendor URL in the body
  PASS  retrofit b3: rent-vs-own-three-year-math cites Cogsy as the record states (Discontinued) with the vendor URL in the body
  PASS  retrofit b3: expense-report-software-buy-once cites Zoho Expense as the record states ($4/user/month) with the vendor URL in the body
  PASS  retrofit b3: self-hosted-rental-property-management cites Buildium as the record states ($62/month) with the vendor URL in the body
  PASS  retrofit b3: self-hosted-rental-property-management cites DoorLoop as the record states ($69.00/mo) with the vendor URL in the body
  PASS  retrofit b3: self-hosted-rental-property-management cites TenantCloud as the record states ($15.00/mo) with the vendor URL in the body
  PASS  retrofit b3: self-hosted-rental-property-management cites AppFolio as the record states (50-unit minimum) with the vendor URL in the body
  PASS  retrofit b3: self-hosted-calendly-alternative cites Calendly as the record states ($10/seat/mo) with the vendor URL in the body
  PASS  retrofit b3: self-hosted-calendly-alternative cites Acuity as the record states ($16/mo billed annually) with the vendor URL in the body
  PASS  retrofit b3: the agency guide quotes Invora's current FAQ (recurring schedules, Pay button), not the retired 1.0 lines, and prices it at $99
  PASS  retrofit b3: the five-year math carries the recomputed own-once figure and gap ($583 / $10,605.20)
  PASS  retrofit b3: the rental guide no longer claims Rentara sends no tenant email

== Package 4 phase B, batch 4 (2026-09-02): back-catalogue retrofit ==
  PASS  retrofit b4: self-hosted-queue-system-qminder-alternative is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b4: self-hosted-queue-system-qminder-alternative — every internal link resolves (7)
  PASS  retrofit b4: self-hosted-queue-system-qminder-alternative — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b4: property-management-software-one-time-price is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b4: property-management-software-one-time-price — every internal link resolves (10)
  PASS  retrofit b4: property-management-software-one-time-price — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b4: field-service-software-what-renting-costs is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b4: field-service-software-what-renting-costs — every internal link resolves (5)
  PASS  retrofit b4: field-service-software-what-renting-costs — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b4: self-hosted-canny-alternative is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b4: self-hosted-canny-alternative — every internal link resolves (7)
  PASS  retrofit b4: self-hosted-canny-alternative — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b4: equipment-checkout-self-hosted-honest-comparison is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b4: equipment-checkout-self-hosted-honest-comparison — every internal link resolves (6)
  PASS  retrofit b4: equipment-checkout-self-hosted-honest-comparison — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b4: fixed-asset-depreciation-register-self-hosted is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b4: fixed-asset-depreciation-register-self-hosted — every internal link resolves (5)
  PASS  retrofit b4: fixed-asset-depreciation-register-self-hosted — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b4: gym-management-without-subscription is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b4: gym-management-without-subscription — every internal link resolves (8)
  PASS  retrofit b4: gym-management-without-subscription — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b4: self-hosted-expense-claims-not-expense-tracking is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b4: self-hosted-expense-claims-not-expense-tracking — every internal link resolves (6)
  PASS  retrofit b4: self-hosted-expense-claims-not-expense-tracking — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b4: shift-scheduling-software-buy-once is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b4: shift-scheduling-software-buy-once — every internal link resolves (9)
  PASS  retrofit b4: shift-scheduling-software-buy-once — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b4: ownware-os-the-anti-erp is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b4: ownware-os-the-anti-erp — every internal link resolves (12)
  PASS  retrofit b4: ownware-os-the-anti-erp — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b4: self-hosted-queue-system-qminder-alternative types tokora at the live single price
  PASS  retrofit b4: property-management-software-one-time-price types rentara at the live single price
  PASS  retrofit b4: field-service-software-what-renting-costs types jobora at the live single price
  PASS  retrofit b4: self-hosted-canny-alternative types votera at the live single price
  PASS  retrofit b4: equipment-checkout-self-hosted-honest-comparison types lendra at the live single price
  PASS  retrofit b4: fixed-asset-depreciation-register-self-hosted types assetora at the live single price
  PASS  retrofit b4: gym-management-without-subscription types gymora at the live single price
  PASS  retrofit b4: self-hosted-expense-claims-not-expense-tracking types expensa at the live single price
  PASS  retrofit b4: shift-scheduling-software-buy-once types rostera at the live single price
  PASS  retrofit b4: self-hosted-queue-system-qminder-alternative cites Qminder as the record states ($9,468/year) with the vendor URL in the body
  PASS  retrofit b4: self-hosted-queue-system-qminder-alternative cites Waitwhile as the record states ($31/month) with the vendor URL in the body
  PASS  retrofit b4: property-management-software-one-time-price cites Buildium as the record states ($62/month) with the vendor URL in the body
  PASS  retrofit b4: property-management-software-one-time-price cites DoorLoop as the record states ($69.00/mo billed yearly) with the vendor URL in the body
  PASS  retrofit b4: property-management-software-one-time-price cites TenantCloud as the record states ($15.00/mo) with the vendor URL in the body
  PASS  retrofit b4: field-service-software-what-renting-costs cites Jobber as the record states (Core $49/mo) with the vendor URL in the body
  PASS  retrofit b4: field-service-software-what-renting-costs cites Housecall Pro as the record states (Basic $59/mo) with the vendor URL in the body
  PASS  retrofit b4: field-service-software-what-renting-costs cites Tradify as the record states ($47 USD per user) with the vendor URL in the body
  PASS  retrofit b4: self-hosted-canny-alternative cites Canny as the record states (Pro $99/mo) with the vendor URL in the body
  PASS  retrofit b4: equipment-checkout-self-hosted-honest-comparison cites Cheqroom as the record states (184 per admin) with the vendor URL in the body
  PASS  retrofit b4: equipment-checkout-self-hosted-honest-comparison cites Booqable as the record states (Start $29/mo) with the vendor URL in the body
  PASS  retrofit b4: fixed-asset-depreciation-register-self-hosted cites AssetTiger as the record states (30-day free trial up to 250 assets) with the vendor URL in the body
  PASS  retrofit b4: fixed-asset-depreciation-register-self-hosted cites Asset Panda as the record states (No public price) with the vendor URL in the body
  PASS  retrofit b4: gym-management-without-subscription cites GymMaster as the record states ($89/month) with the vendor URL in the body
  PASS  retrofit b4: gym-management-without-subscription cites Mindbody as the record states (EUR 99/month) with the vendor URL in the body
  PASS  retrofit b4: gym-management-without-subscription cites Glofox as the record states (No public price) with the vendor URL in the body
  PASS  retrofit b4: self-hosted-expense-claims-not-expense-tracking cites Expensify as the record states ($5/member/month) with the vendor URL in the body
  PASS  retrofit b4: self-hosted-expense-claims-not-expense-tracking cites Zoho Expense as the record states ($4/user/month) with the vendor URL in the body
  PASS  retrofit b4: shift-scheduling-software-buy-once cites When I Work as the record states ($2.50/user/mo) with the vendor URL in the body
  PASS  retrofit b4: shift-scheduling-software-buy-once cites Deputy as the record states (Lite $5) with the vendor URL in the body
  PASS  retrofit b4: the Ownware OS guide counts the bundle as the DB does (apps + the SaaS Kit) and prices it at the live bundle price
  PASS  retrofit b4: the equipment guide title carries the live Lendra price
  PASS  retrofit b4: the expense-claims guide no longer says $49 once
  PASS  retrofit b4: the Canny guide states Votera's opt-in ship notification, not the retired "does not email voters" line

== Package 4 phase B, batch 5 (2026-09-02): back-catalogue retrofit ==
  PASS  retrofit b5: inventory-forecasting-show-me-the-formula is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b5: inventory-forecasting-show-me-the-formula — every internal link resolves (5)
  PASS  retrofit b5: inventory-forecasting-show-me-the-formula — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b5: best-self-hosted-booking-systems is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b5: best-self-hosted-booking-systems — every internal link resolves (7)
  PASS  retrofit b5: best-self-hosted-booking-systems — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b5: pos-subscription-plus-processing-fee-stack is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b5: pos-subscription-plus-processing-fee-stack — every internal link resolves (6)
  PASS  retrofit b5: pos-subscription-plus-processing-fee-stack — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b5: self-hosted-appointment-booking is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b5: self-hosted-appointment-booking — every internal link resolves (9)
  PASS  retrofit b5: self-hosted-appointment-booking — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b5: odoo-alternative-without-the-erp is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b5: odoo-alternative-without-the-erp — every internal link resolves (4)
  PASS  retrofit b5: odoo-alternative-without-the-erp — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b5: best-self-hosted-queue-systems is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b5: best-self-hosted-queue-systems — every internal link resolves (6)
  PASS  retrofit b5: best-self-hosted-queue-systems — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b5: menu-digitisation-the-job-nobody-prices is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b5: menu-digitisation-the-job-nobody-prices — every internal link resolves (5)
  PASS  retrofit b5: menu-digitisation-the-job-nobody-prices — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b5: gym-software-two-of-three-hide-the-price is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b5: gym-software-two-of-three-hide-the-price — every internal link resolves (6)
  PASS  retrofit b5: gym-software-two-of-three-hide-the-price — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b5: self-hosted-dsar-portal-gdpr-requests is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b5: self-hosted-dsar-portal-gdpr-requests — every internal link resolves (10)
  PASS  retrofit b5: self-hosted-dsar-portal-gdpr-requests — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b5: best-self-hosted-commission-tracking is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b5: best-self-hosted-commission-tracking — every internal link resolves (7)
  PASS  retrofit b5: best-self-hosted-commission-tracking — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b5: inventory-forecasting-show-me-the-formula types restock at the live single price
  PASS  retrofit b5: pos-subscription-plus-processing-fee-stack types vendra at the live single price
  PASS  retrofit b5: best-self-hosted-queue-systems types tokora at the live single price
  PASS  retrofit b5: menu-digitisation-the-job-nobody-prices types menura at the live single price
  PASS  retrofit b5: gym-software-two-of-three-hide-the-price types gymora at the live single price
  PASS  retrofit b5: self-hosted-dsar-portal-gdpr-requests types privara at the live single price
  PASS  retrofit b5: best-self-hosted-commission-tracking types commissa at the live single price
  PASS  retrofit b5: inventory-forecasting-show-me-the-formula cites Cogsy as the record states ($199/month) with the vendor URL in the body
  PASS  retrofit b5: inventory-forecasting-show-me-the-formula cites Inventory Planner as the record states (No public price) with the vendor URL in the body
  PASS  retrofit b5: pos-subscription-plus-processing-fee-stack cites Square POS as the record states ($49/mo) with the vendor URL in the body
  PASS  retrofit b5: pos-subscription-plus-processing-fee-stack cites Lightspeed as the record states ($89 USD/mo) with the vendor URL in the body
  PASS  retrofit b5: self-hosted-appointment-booking cites Calendly as the record states ($10/seat/mo) with the vendor URL in the body
  PASS  retrofit b5: self-hosted-appointment-booking cites Acuity as the record states ($16/mo billed annually) with the vendor URL in the body
  PASS  retrofit b5: self-hosted-appointment-booking cites SimplyBook as the record states (EUR 11.9) with the vendor URL in the body
  PASS  retrofit b5: best-self-hosted-queue-systems cites Qminder as the record states ($9,468/year) with the vendor URL in the body
  PASS  retrofit b5: best-self-hosted-queue-systems cites Waitwhile as the record states ($31/month) with the vendor URL in the body
  PASS  retrofit b5: menu-digitisation-the-job-nobody-prices cites Veryfi Restaurant as the record states (quote-gated) with the vendor URL in the body
  PASS  retrofit b5: gym-software-two-of-three-hide-the-price cites GymMaster as the record states ($89/month) with the vendor URL in the body
  PASS  retrofit b5: gym-software-two-of-three-hide-the-price cites Mindbody as the record states (EUR 99/month) with the vendor URL in the body
  PASS  retrofit b5: gym-software-two-of-three-hide-the-price cites Glofox as the record states (No public price) with the vendor URL in the body
  PASS  retrofit b5: self-hosted-dsar-portal-gdpr-requests cites Enzuzo as the record states ($9 / month) with the vendor URL in the body
  PASS  retrofit b5: self-hosted-dsar-portal-gdpr-requests cites Osano as the record states (No public price) with the vendor URL in the body
  PASS  retrofit b5: best-self-hosted-commission-tracking cites QuotaPath as the record states ($525/month platform fee) with the vendor URL in the body
  PASS  retrofit b5: the DSAR guide counts the Compliance Suite as the DB does and no longer names the unlisted nexus tracker
  PASS  retrofit b5: the Odoo guide states the live single-price range of the business apps
  PASS  retrofit b5: the appointment guide no longer says gateways are on the roadmap

== Package 4 phase B, batch 6 (2026-09-02): back-catalogue retrofit ==
  PASS  retrofit b6: self-hosted-sales-commission-software is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b6: self-hosted-sales-commission-software — every internal link resolves (5)
  PASS  retrofit b6: self-hosted-sales-commission-software — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b6: purchase-approval-the-shelf-between-499-and-an-erp is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b6: purchase-approval-the-shelf-between-499-and-an-erp — every internal link resolves (7)
  PASS  retrofit b6: purchase-approval-the-shelf-between-499-and-an-erp — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b6: self-host-on-shared-hosting is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b6: self-host-on-shared-hosting — every internal link resolves (4)
  PASS  retrofit b6: self-host-on-shared-hosting — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b6: run-your-own-product-roadmap is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b6: run-your-own-product-roadmap — every internal link resolves (7)
  PASS  retrofit b6: run-your-own-product-roadmap — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b6: run-lifetime-deals-from-your-own-server is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b6: run-lifetime-deals-from-your-own-server — every internal link resolves (4)
  PASS  retrofit b6: run-lifetime-deals-from-your-own-server — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b6: rent-the-hosting-own-the-software is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b6: rent-the-hosting-own-the-software — every internal link resolves (8)
  PASS  retrofit b6: rent-the-hosting-own-the-software — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b6: invoice-software-buy-once is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b6: invoice-software-buy-once — every internal link resolves (10)
  PASS  retrofit b6: invoice-software-buy-once — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b6: spec-sheets-to-product-data-without-a-pim-subscription is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b6: spec-sheets-to-product-data-without-a-pim-subscription — every internal link resolves (12)
  PASS  retrofit b6: spec-sheets-to-product-data-without-a-pim-subscription — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b6: loyalty-program-cost-teardown is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b6: loyalty-program-cost-teardown — every internal link resolves (5)
  PASS  retrofit b6: loyalty-program-cost-teardown — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b6: short-shipment-reconciliation-po-vs-packing-slip is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b6: short-shipment-reconciliation-po-vs-packing-slip — every internal link resolves (6)
  PASS  retrofit b6: short-shipment-reconciliation-po-vs-packing-slip — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b6: self-hosted-sales-commission-software types commissa at the live single price
  PASS  retrofit b6: purchase-approval-the-shelf-between-499-and-an-erp types approva at the live single price
  PASS  retrofit b6: run-your-own-product-roadmap types votera at the live single price
  PASS  retrofit b6: run-lifetime-deals-from-your-own-server types deliora at the live single price
  PASS  retrofit b6: invoice-software-buy-once types invora at the live single price
  PASS  retrofit b6: spec-sheets-to-product-data-without-a-pim-subscription types specta at the live single price
  PASS  retrofit b6: loyalty-program-cost-teardown types loyalora at the live single price
  PASS  retrofit b6: short-shipment-reconciliation-po-vs-packing-slip types cargora at the live single price
  PASS  retrofit b6: self-hosted-sales-commission-software cites QuotaPath as the record states ($525/month platform fee) with the vendor URL in the body
  PASS  retrofit b6: purchase-approval-the-shelf-between-499-and-an-erp cites Precoro as the record states ($499/mo) with the vendor URL in the body
  PASS  retrofit b6: purchase-approval-the-shelf-between-499-and-an-erp cites Procurify as the record states (No public price) with the vendor URL in the body
  PASS  retrofit b6: run-your-own-product-roadmap cites Canny as the record states (Pro $99/mo) with the vendor URL in the body
  PASS  retrofit b6: run-your-own-product-roadmap cites Featurebase as the record states ($29/seat/mo) with the vendor URL in the body
  PASS  retrofit b6: run-your-own-product-roadmap cites Nolt as the record states (Essential $29/mo) with the vendor URL in the body
  PASS  retrofit b6: invoice-software-buy-once cites Invoice Ninja as the record states ($14/mo) with the vendor URL in the body
  PASS  retrofit b6: invoice-software-buy-once cites Zoho Invoice as the record states (Free) with the vendor URL in the body
  PASS  retrofit b6: invoice-software-buy-once cites FreshBooks as the record states ($23.00/mo) with the vendor URL in the body
  PASS  retrofit b6: spec-sheets-to-product-data-without-a-pim-subscription cites Plytix as the record states ($499/mo) with the vendor URL in the body
  PASS  retrofit b6: spec-sheets-to-product-data-without-a-pim-subscription cites Salsify as the record states (No public price) with the vendor URL in the body
  PASS  retrofit b6: loyalty-program-cost-teardown cites Smile as the record states ($15 per month) with the vendor URL in the body
  PASS  retrofit b6: loyalty-program-cost-teardown cites LoyaltyLion as the record states ($199/month) with the vendor URL in the body
  PASS  retrofit b6: loyalty-program-cost-teardown cites Loyverse as the record states (Free) with the vendor URL in the body
  PASS  retrofit b6: loyalty-program-cost-teardown cites Square Loyalty as the record states (No public price) with the vendor URL in the body
  PASS  retrofit b6: short-shipment-reconciliation-po-vs-packing-slip cites Parseur as the record states ($39/month) with the vendor URL in the body
  PASS  retrofit b6: short-shipment-reconciliation-po-vs-packing-slip cites Docsumo as the record states (Talk to us) with the vendor URL in the body
  PASS  retrofit b6: the roadmap guide states Votera's current opt-in notice and team roles, not the retired 1.0 lines
  PASS  retrofit b6: the invoice guide states Invora's current recurring/Send/payment-link behaviour and the FreshBooks regular price
  PASS  retrofit b6: the purchase-approval guide prices Approva in words at the live price

== Package 4 phase B, batch 7 (2026-09-02): back-catalogue retrofit ==
  PASS  retrofit b7: spreadsheet-to-system is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b7: spreadsheet-to-system — every internal link resolves (12)
  PASS  retrofit b7: spreadsheet-to-system — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b7: compliance-software-what-it-cannot-do is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b7: compliance-software-what-it-cannot-do — every internal link resolves (7)
  PASS  retrofit b7: compliance-software-what-it-cannot-do — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b7: best-self-hosted-feedback-boards is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b7: best-self-hosted-feedback-boards — every internal link resolves (7)
  PASS  retrofit b7: best-self-hosted-feedback-boards — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b7: your-data-your-server is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b7: your-data-your-server — every internal link resolves (6)
  PASS  retrofit b7: your-data-your-server — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b7: buying-self-hosted-scripts-safely is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b7: buying-self-hosted-scripts-safely — every internal link resolves (4)
  PASS  retrofit b7: buying-self-hosted-scripts-safely — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b7: self-host-in-10-minutes is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b7: self-host-in-10-minutes — every internal link resolves (9)
  PASS  retrofit b7: self-host-in-10-minutes — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b7: warranty-expiry-is-computed-not-stored is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b7: warranty-expiry-is-computed-not-stored — every internal link resolves (3)
  PASS  retrofit b7: warranty-expiry-is-computed-not-stored — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b7: first-response-time-the-only-number-a-shared-inbox-cannot-produce is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b7: first-response-time-the-only-number-a-shared-inbox-cannot-produce — every internal link resolves (4)
  PASS  retrofit b7: first-response-time-the-only-number-a-shared-inbox-cannot-produce — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b7: own-the-stack-suite-bundles is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b7: own-the-stack-suite-bundles — every internal link resolves (19)
  PASS  retrofit b7: own-the-stack-suite-bundles — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b7: self-hosted-whistleblowing-software is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b7: self-hosted-whistleblowing-software — every internal link resolves (6)
  PASS  retrofit b7: self-hosted-whistleblowing-software — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b7: compliance-software-what-it-cannot-do types privara at the live single price
  PASS  retrofit b7: compliance-software-what-it-cannot-do types complia at the live single price
  PASS  retrofit b7: compliance-software-what-it-cannot-do types confida at the live single price
  PASS  retrofit b7: best-self-hosted-feedback-boards types votera at the live single price
  PASS  retrofit b7: warranty-expiry-is-computed-not-stored types warrantora at the live single price
  PASS  retrofit b7: first-response-time-the-only-number-a-shared-inbox-cannot-produce types helpora at the live single price
  PASS  retrofit b7: self-hosted-whistleblowing-software types confida at the live single price
  PASS  retrofit b7: compliance-software-what-it-cannot-do cites Enzuzo as the record states ($9 / month) with the vendor URL in the body
  PASS  retrofit b7: compliance-software-what-it-cannot-do cites Whistlelink as the record states (EUR 79/month) with the vendor URL in the body
  PASS  retrofit b7: compliance-software-what-it-cannot-do cites Osano as the record states (No public price) with the vendor URL in the body
  PASS  retrofit b7: compliance-software-what-it-cannot-do cites FaceUp as the record states (No public price) with the vendor URL in the body
  PASS  retrofit b7: warranty-expiry-is-computed-not-stored cites WarrantyHub as the record states ($549/mo) with the vendor URL in the body
  PASS  retrofit b7: warranty-expiry-is-computed-not-stored cites Claimlane as the record states ($800/month) with the vendor URL in the body
  PASS  retrofit b7: first-response-time-the-only-number-a-shared-inbox-cannot-produce cites Zendesk as the record states ($55 per agent/month) with the vendor URL in the body
  PASS  retrofit b7: first-response-time-the-only-number-a-shared-inbox-cannot-produce cites Freshdesk as the record states ($19/agent/month) with the vendor URL in the body
  PASS  retrofit b7: self-hosted-whistleblowing-software cites Whistlelink as the record states (EUR 79/month) with the vendor URL in the body
  PASS  retrofit b7: self-hosted-whistleblowing-software cites FaceUp as the record states (No public price) with the vendor URL in the body
  PASS  retrofit b7: the spreadsheet guide states the live single-price range of the business apps
  PASS  retrofit b7: the compliance guide no longer carries the unsourced GlobaLeaks reviewer quote

== Package 4 phase B, batches 8+9 (2026-09-02): back-catalogue retrofit, final ==
  PASS  retrofit b8-9: best-self-hosted-whistleblowing-tools is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b8-9: best-self-hosted-whistleblowing-tools — every internal link resolves (6)
  PASS  retrofit b8-9: best-self-hosted-whistleblowing-tools — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b8-9: self-hosted-packaging-epr-reporting is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b8-9: self-hosted-packaging-epr-reporting — every internal link resolves (5)
  PASS  retrofit b8-9: self-hosted-packaging-epr-reporting — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b8-9: self-hosted-waiver-software-honest is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b8-9: self-hosted-waiver-software-honest — every internal link resolves (6)
  PASS  retrofit b8-9: self-hosted-waiver-software-honest — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b8-9: petty-cash-ledger-spreadsheet-replacement is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b8-9: petty-cash-ledger-spreadsheet-replacement — every internal link resolves (5)
  PASS  retrofit b8-9: petty-cash-ledger-spreadsheet-replacement — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b8-9: permit-inspection-tracking-for-contractors is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b8-9: permit-inspection-tracking-for-contractors — every internal link resolves (5)
  PASS  retrofit b8-9: permit-inspection-tracking-for-contractors — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b8-9: onboarding-checklists-derive-the-dates-dont-store-them is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b8-9: onboarding-checklists-derive-the-dates-dont-store-them — every internal link resolves (5)
  PASS  retrofit b8-9: onboarding-checklists-derive-the-dates-dont-store-them — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b8-9: training-certificate-generator-self-hosted is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b8-9: training-certificate-generator-self-hosted — every internal link resolves (6)
  PASS  retrofit b8-9: training-certificate-generator-self-hosted — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b8-9: quorum-is-not-attendance-club-membership-records is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b8-9: quorum-is-not-attendance-club-membership-records — every internal link resolves (4)
  PASS  retrofit b8-9: quorum-is-not-attendance-club-membership-records — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b8-9: your-backup-is-not-a-backup-until-restored is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b8-9: your-backup-is-not-a-backup-until-restored — every internal link resolves (7)
  PASS  retrofit b8-9: your-backup-is-not-a-backup-until-restored — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b8-9: sqlite-or-mysql-for-a-small-business-app is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b8-9: sqlite-or-mysql-for-a-small-business-app — every internal link resolves (4)
  PASS  retrofit b8-9: sqlite-or-mysql-for-a-small-business-app — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b8-9: is-a-shared-email-inbox-enough-for-the-eu-whistleblowing-directive is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b8-9: is-a-shared-email-inbox-enough-for-the-eu-whistleblowing-directive — every internal link resolves (6)
  PASS  retrofit b8-9: is-a-shared-email-inbox-enough-for-the-eu-whistleblowing-directive — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b8-9: securing-a-self-hosted-business-app is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b8-9: securing-a-self-hosted-business-app — every internal link resolves (5)
  PASS  retrofit b8-9: securing-a-self-hosted-business-app — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b8-9: service-due-by-date-or-distance is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b8-9: service-due-by-date-or-distance — every internal link resolves (4)
  PASS  retrofit b8-9: service-due-by-date-or-distance — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b8-9: loyalty-points-ledger-not-a-balance is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b8-9: loyalty-points-ledger-not-a-balance — every internal link resolves (5)
  PASS  retrofit b8-9: loyalty-points-ledger-not-a-balance — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b8-9: install-php-app-cpanel-step-by-step is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b8-9: install-php-app-cpanel-step-by-step — every internal link resolves (5)
  PASS  retrofit b8-9: install-php-app-cpanel-step-by-step — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b8-9: what-happens-to-your-data-when-you-cancel is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b8-9: what-happens-to-your-data-when-you-cancel — every internal link resolves (4)
  PASS  retrofit b8-9: what-happens-to-your-data-when-you-cancel — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b8-9: training-records-never-recorded-is-not-expired is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b8-9: training-records-never-recorded-is-not-expired — every internal link resolves (5)
  PASS  retrofit b8-9: training-records-never-recorded-is-not-expired — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b8-9: connect-claude-to-your-invoicing-mcp is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b8-9: connect-claude-to-your-invoicing-mcp — every internal link resolves (3)
  PASS  retrofit b8-9: connect-claude-to-your-invoicing-mcp — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b8-9: cra-reporting-11-september-2026-the-24-72-hour-clock is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b8-9: cra-reporting-11-september-2026-the-24-72-hour-clock — every internal link resolves (4)
  PASS  retrofit b8-9: cra-reporting-11-september-2026-the-24-72-hour-clock — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b8-9: let-an-agent-run-your-rota is published, created_at untouched, updated_at stamped on or after 2026-09-02
  PASS  retrofit b8-9: let-an-agent-run-your-rota — every internal link resolves (4)
  PASS  retrofit b8-9: let-an-agent-run-your-rota — no absolute ownware.io link, no AmE 'license' in prose, no stale observatory count
  PASS  retrofit b8-9: best-self-hosted-whistleblowing-tools types confida at the live single price
  PASS  retrofit b8-9: self-hosted-packaging-epr-reporting types packora at the live single price
  PASS  retrofit b8-9: self-hosted-waiver-software-honest types waiverly at the live single price
  PASS  retrofit b8-9: petty-cash-ledger-spreadsheet-replacement types cashora at the live single price
  PASS  retrofit b8-9: permit-inspection-tracking-for-contractors types permora at the live single price
  PASS  retrofit b8-9: onboarding-checklists-derive-the-dates-dont-store-them types onboardora at the live single price
  PASS  retrofit b8-9: training-certificate-generator-self-hosted types certora at the live single price
  PASS  retrofit b8-9: quorum-is-not-attendance-club-membership-records types membora at the live single price
  PASS  retrofit b8-9: is-a-shared-email-inbox-enough-for-the-eu-whistleblowing-directive types confida at the live single price
  PASS  retrofit b8-9: service-due-by-date-or-distance types fleetora at the live single price
  PASS  retrofit b8-9: loyalty-points-ledger-not-a-balance types loyalora at the live single price
  PASS  retrofit b8-9: training-records-never-recorded-is-not-expired types trainora at the live single price
  PASS  retrofit b8-9: cra-reporting-11-september-2026-the-24-72-hour-clock types cyresora at the live single price
  PASS  retrofit b8-9: best-self-hosted-whistleblowing-tools cites Whistlelink as the record states (EUR 79/month) with the vendor URL in the body
  PASS  retrofit b8-9: best-self-hosted-whistleblowing-tools cites FaceUp as the record states (No public price) with the vendor URL in the body
  PASS  retrofit b8-9: self-hosted-packaging-epr-reporting cites Packgine as the record states (No public price) with the vendor URL in the body
  PASS  retrofit b8-9: self-hosted-waiver-software-honest cites Smartwaiver as the record states (Basic $19/mo) with the vendor URL in the body
  PASS  retrofit b8-9: self-hosted-waiver-software-honest cites WaiverForever as the record states (Essential $19/mo) with the vendor URL in the body
  PASS  retrofit b8-9: onboarding-checklists-derive-the-dates-dont-store-them cites BambooHR as the record states ($10 USD per employee) with the vendor URL in the body
  PASS  retrofit b8-9: onboarding-checklists-derive-the-dates-dont-store-them cites Enboarder as the record states (No public price) with the vendor URL in the body
  PASS  retrofit b8-9: quorum-is-not-attendance-club-membership-records cites WildApricot as the record states ($66.00/mo) with the vendor URL in the body
  PASS  retrofit b8-9: quorum-is-not-attendance-club-membership-records cites Join It as the record states (Starter $29/mo) with the vendor URL in the body
  PASS  retrofit b8-9: the waiver and petty-cash guides no longer carry the stale $39
  PASS  retrofit b8-9: no published guide still quotes an unattributed search result or reviewer
  PASS  retrofit whole: no published guide links a demo host or the store by absolute URL (Ownware Cloud aside)
  PASS  retrofit whole: no published guide carries a stale observatory count phrase

== Package 5 (2026-09-02): the OYA flagship page ==
  PASS  oya flagship: the product row exists and is active
  PASS  oya flagship: /p/oya renders the flagship view, not the generic template
  PASS  oya flagship: the body carries the flagship class so header and footer join the dark object
  PASS  oya flagship: the pre-flagship hero partial is retired
  PASS  oya flagship: three licence tiers in the database
  PASS  oya flagship: tier 'Personal licence' shows the database price $249.00
  PASS  oya flagship: tier 'Personal licence' shows 'Available soon' when not buyable
  PASS  oya flagship: licence grant present — Install it on the machines you personall
  PASS  oya flagship: licence grant present — Full source — read it, change it, keep i
  PASS  oya flagship: licence grant present — Use it for your own paid work
  PASS  oya flagship: tier 'Business licence' shows the database price $749.00
  PASS  oya flagship: tier 'Business licence' shows 'Available soon' when not buyable
  PASS  oya flagship: licence grant present — Roll it out to everyone in your organisa
  PASS  oya flagship: licence grant present — Everything the Personal licence grants
  PASS  oya flagship: tier 'Agency licence' shows the database price $1,499.00
  PASS  oya flagship: tier 'Agency licence' shows 'Available soon' when not buyable
  PASS  oya flagship: licence grant present — Everything the Business licence grants
  PASS  oya flagship: licence grant present — Use it inside client engagements, on the
  PASS  oya flagship: no price on the page is typed — every $ figure matches an edition, the bundle or a comparison row
  PASS  oya flagship: the tool count is readable from the features JSON
  PASS  oya flagship: the stat band shows the database tool count
  PASS  oya flagship: no other "N tools in the core" figure appears anywhere on the page
  PASS  oya flagship: the retired typed test count (863) is gone
  PASS  oya flagship: feature card — Runs on a model you own
  PASS  oya flagship: feature card — The ledger: every outside connection, co
  PASS  oya flagship: feature card — Tool use, with the trace on the table
  PASS  oya flagship: feature card — 58 tools in the core, and pieces you cho
  PASS  oya flagship: feature card — You connect it to every Ownware tool
  PASS  oya flagship: feature card — Web app and terminal, one engine
  PASS  oya flagship: feature card — Frozen core, no update race
  PASS  oya flagship: feature card — Source included, yours to keep
  PASS  oya flagship: feature card — Own It 3.1 — it writes to the people you
  PASS  oya flagship: FAQ — What do I need to run it?
  PASS  oya flagship: FAQ — Does it phone home?
  PASS  oya flagship: FAQ — Is a model included?
  PASS  oya flagship: FAQ — How is this different from a chat UI lik
  PASS  oya flagship: FAQ — Does it work with my Ownware apps?
  PASS  oya flagship: FAQ — Will it get updates?
  PASS  oya flagship: FAQ — If I use OYA to generate content for my 
  PASS  oya flagship: FAQ — Can I use it for clients or in my compan
  PASS  oya flagship: honesty line — Not a model: you bring the model server 
  PASS  oya flagship: honesty line — Linux and macOS are the execution hosts;
  PASS  oya flagship: honesty line — No desktop app, editor plugin, image gen
  PASS  oya flagship: honesty line — The public showcase at oya.ownware.io re
  PASS  oya flagship: honesty line — Mail is IMAP/SMTP over TLS with app pass
  PASS  oya flagship: the version in the eyebrow is the edition version
  PASS  oya flagship: at least one priced comparison row feeds the rent section
  PASS  oya flagship: rent card — Claude Pro (Anthropic) (13 months, source + read date)
  PASS  oya flagship: rent card — Claude Max (Anthropic) (3 months, source + read date)
  PASS  oya flagship: rent card — Microsoft 365 Copilot (bundled plans) (11 months, source + read date)
  PASS  oya flagship: the receipt card names its date and links the verifiable sample report
  PASS  oya flagship: no invented run id or signature from the design mock-up
  PASS  oya flagship: the silk shader is inline and self-hosted (no external script)
  PASS  oya flagship: WebGL failure hides the canvas and leaves the CSS wash (fallback path present)
  PASS  oya flagship: reduced motion draws one frame and never starts the loop
  PASS  oya flagship: the loop pauses when the hero leaves the viewport and when the tab hides
  PASS  oya flagship: the stylesheet carries the flagship block, the dark-token body class and the reduced-motion rule
  PASS  oya flagship: the retired .oyahero rules are gone from the stylesheet
  PASS  oya flagship: BrE — no "license" outside code and quoted vendor text
  PASS  oya flagship: never mentions the network project
  PASS  oya flagship: never claims PHP source for a Node.js product
  PASS  oya flagship: /demo/oya still forwards to the showcase (demo_url is the product row's)
  PASS  oya flagship: checkout flow untouched — no edition id on the page is missing from the /buy links when live
  PASS  oya flagship (demos on): the demo CTA is the generic template's own target (/demo/oya) and opens in a new tab
  PASS  oya flagship (sales on): tier 'Personal licence' buys through /buy/82 — the Lemon Squeezy hand-off is unchanged
  PASS  oya flagship (sales on): tier 'Business licence' buys through /buy/83 — the Lemon Squeezy hand-off is unchanged
  PASS  oya flagship (sales on): tier 'Agency licence' buys through /buy/84 — the Lemon Squeezy hand-off is unchanged
  PASS  oya flagship (sales on): the hero CTA is "Own it once — <cheapest price>" pointing at that edition's /buy link
  PASS  oya flagship (sales on): the closing panel offers "See pricing" and no notify form renders
  PASS  oya flagship (sales on): no "Available soon" chip remains for a wired tier
  PASS  oya flagship: /p/invora still renders the generic template without the flagship block

== The customer story (operator GO 2026-09-02): published under the reshaped slug ==
  PASS  story: exactly one row under the new slug after the release seed
  PASS  story: the OLD draft row was updated in place (same id), not replaced
  PASS  story: the old slug no longer exists in the guides table
  PASS  story: published = 1 under the new slug
  PASS  story: created_at is the real publish moment (2026-09-02, not the 08-30 draft stamp)
  PASS  story: pattern-led title, they/them
  PASS  story: the body never genders the buyer
  PASS  story: the body carries no buyer email or name-shaped PII
  PASS  story: the release migration is idempotent (second seed keeps one row, same id, still published)
  PASS  story: listed on the guides index under the new slug
  PASS  story: the old slug never appears on the guides index
  PASS  story: listed on the sitemap under the new slug
  PASS  story: the old slug never appears on the sitemap
  PASS  story: listed on the RSS feed under the new slug
  PASS  story: the old slug never appears on the RSS feed
  PASS  story: listed on the JSON feed under the new slug
  PASS  story: the old slug never appears on the JSON feed
  PASS  story: /press carries the proof block linking the story, and speaks of the buyer as they
  PASS  story: the proof block never annualises and names no buyer
  PASS  story: the guide page renders the pattern-led title
  PASS  story: unpublishing the guide removes the press proof block (no dangling link)

== Doorman close-out (2026-09-03): the agent pack ==
  PASS  agent card is valid JSON and its purpose carries the DB product count
  PASS  agent card addresses: openapi under /api/, the /mcp door named, a mail contact present
  PASS  agents.md names the addresses an agent needs (llms, pricing, data, legal) and the human boundary
  PASS  /data-for-agents lists the observatory dataset with its licence and the OpenAPI address
  PASS  home JSON-LD names what is for sale (OfferCatalog with priced Offers)
  PASS  sitemap lists /data-for-agents
  PASS  routes registered: the card, agents.md, the data page, the well-known openapi alias
  PASS  the surface table advertises the card, agents.md and the data page

== WS-4 per-product packs — 51 product(s): aiactora, approva, assetora, cargora, cashora, certora, clockora, commissa, complia, confida, consigna, cyresora, deliora, expensa, extracta, fixora, fleetora, gymora, helpora, inspectora, invora, jobora, leavora, ledgira, lendra, loyalora, membora, menura, nexura, onboardora, oya, packora, permora, privara, rentara, restock, revup, rostera, saas-kit, safora, secreta, slotly, specta, supplia, tokora, trainora, vendra, visitora, votera, waiverly, warrantora ==
  PASS  WS-4/6 wired fixture: every edition wired here carries BOTH a download_file and a checkout_url (103 wired here, 103 of all wired carry both)
  PASS  WS-4/6 seed state recorded: 1 edition(s) already carried a download_file before wiring — uikit-pro/single
  PASS  [aiactora] 1a. product row exists and is UNLISTED (operator ruling)
  PASS  [approva] 1a. product row is active in the catalogue
  PASS  [approva] 1. /p/ renders through the layout, carries its canonical, raises no PHP notice
  PASS  [approva] 2. JSON-LD Product parses and every Offer price equals the DB edition price
  PASS  [approva] 3. every money figure in the copy comes from the record (edition, bundle, cited comparison, linked guide, cloud offer or stored copy) — none invented by the view
  PASS  [approva] 4. demo_url follows the https://<slug>.ownware.io scheme
  PASS  [approva] 5. every gallery image the page references exists on disk (5 files)
  PASS  [approva] 6. every edition naming a download_file has that file on disk (2 wired in this fixture)
  PASS  [approva] 7. every tier sold renders its price and its licence terms (single+extended; 2/2 priced, 25 licence mentions)
  PASS  [approva] 8. /vs/ renders and all 3 comparison rows are source-cited
  PASS  [approva] 9. agent-first: the first 2KB of visible text answers what, price, stack, demo, tests
  PASS  [assetora] 1a. product row is active in the catalogue
  PASS  [assetora] 1. /p/ renders through the layout, carries its canonical, raises no PHP notice
  PASS  [assetora] 2. JSON-LD Product parses and every Offer price equals the DB edition price
  PASS  [assetora] 3. every money figure in the copy comes from the record (edition, bundle, cited comparison, linked guide, cloud offer or stored copy) — none invented by the view
  PASS  [assetora] 4. demo_url follows the https://<slug>.ownware.io scheme
  PASS  [assetora] 5. every gallery image the page references exists on disk (5 files)
  PASS  [assetora] 6. every edition naming a download_file has that file on disk (2 wired in this fixture)
  PASS  [assetora] 7. every tier sold renders its price and its licence terms (single+extended; 2/2 priced, 23 licence mentions)
  PASS  [assetora] 8. /vs/ renders and all 3 comparison rows are source-cited
  PASS  [assetora] 9. agent-first: the first 2KB of visible text answers what, price, stack, demo, tests
  PASS  [cargora] 1a. product row is active in the catalogue
  PASS  [cargora] 1. /p/ renders through the layout, carries its canonical, raises no PHP notice
  PASS  [cargora] 2. JSON-LD Product parses and every Offer price equals the DB edition price
  PASS  [cargora] 3. every money figure in the copy comes from the record (edition, bundle, cited comparison, linked guide, cloud offer or stored copy) — none invented by the view
  PASS  [cargora] 4. demo_url follows the https://<slug>.ownware.io scheme
  PASS  [cargora] 5. every gallery image the page references exists on disk (5 files)
  PASS  [cargora] 6. every edition naming a download_file has that file on disk (2 wired in this fixture)
  PASS  [cargora] 7. every tier sold renders its price and its licence terms (single+extended; 2/2 priced, 23 licence mentions)
  PASS  [cargora] 8. /vs/ renders and all 2 comparison rows are source-cited
  PASS  [cargora] 9. agent-first: the first 2KB of visible text answers what, price, stack, demo, tests
  PASS  [cashora] 1a. product row is active in the catalogue
  PASS  [cashora] 1. /p/ renders through the layout, carries its canonical, raises no PHP notice
  PASS  [cashora] 2. JSON-LD Product parses and every Offer price equals the DB edition price
  PASS  [cashora] 3. every money figure in the copy comes from the record (edition, bundle, cited comparison, linked guide, cloud offer or stored copy) — none invented by the view
  PASS  [cashora] 4. demo_url follows the https://<slug>.ownware.io scheme
  PASS  [cashora] 5. every gallery image the page references exists on disk (5 files)
  PASS  [cashora] 6. every edition naming a download_file has that file on disk (2 wired in this fixture)
  PASS  [cashora] 7. every tier sold renders its price and its licence terms (single+extended; 2/2 priced, 23 licence mentions)
  PASS  [cashora] 8. /vs/ renders and all 3 comparison rows are source-cited
  PASS  [cashora] 9. agent-first: the first 2KB of visible text answers what, price, stack, demo, tests
  PASS  [certora] 1a. product row is active in the catalogue
  PASS  [certora] 1. /p/ renders through the layout, carries its canonical, raises no PHP notice
  PASS  [certora] 2. JSON-LD Product parses and every Offer price equals the DB edition price
  PASS  [certora] 3. every money figure in the copy comes from the record (edition, bundle, cited comparison, linked guide, cloud offer or stored copy) — none invented by the view
  PASS  [certora] 4. demo_url follows the https://<slug>.ownware.io scheme
  PASS  [certora] 5. every gallery image the page references exists on disk (5 files)
  PASS  [certora] 6. every edition naming a download_file has that file on disk (2 wired in this fixture)
  PASS  [certora] 7. every tier sold renders its price and its licence terms (single+extended; 2/2 priced, 23 licence mentions)
  PASS  [certora] 8. /vs/ renders and all 3 comparison rows are source-cited
  PASS  [certora] 9. agent-first: the first 2KB of visible text answers what, price, stack, demo, tests
  PASS  [clockora] 1a. product row is active in the catalogue
  PASS  [clockora] 1. /p/ renders through the layout, carries its canonical, raises no PHP notice
  PASS  [clockora] 2. JSON-LD Product parses and every Offer price equals the DB edition price
  PASS  [clockora] 3. every money figure in the copy comes from the record (edition, bundle, cited comparison, linked guide, cloud offer or stored copy) — none invented by the view
  PASS  [clockora] 4. demo_url follows the https://<slug>.ownware.io scheme
  PASS  [clockora] 5. every gallery image the page references exists on disk (5 files)
  PASS  [clockora] 6. every edition naming a download_file has that file on disk (2 wired in this fixture)
  PASS  [clockora] 7. every tier sold renders its price and its licence terms (single+extended; 2/2 priced, 24 licence mentions)
  PASS  [clockora] 8. /vs/ renders and all 5 comparison rows are source-cited
  PASS  [clockora] 9. agent-first: the first 2KB of visible text answers what, price, stack, demo, tests
  PASS  [commissa] 1a. product row is active in the catalogue
  PASS  [commissa] 1. /p/ renders through the layout, carries its canonical, raises no PHP notice
  PASS  [commissa] 2. JSON-LD Product parses and every Offer price equals the DB edition price
  PASS  [commissa] 3. every money figure in the copy comes from the record (edition, bundle, cited comparison, linked guide, cloud offer or stored copy) — none invented by the view
  PASS  [commissa] 4. demo_url follows the https://<slug>.ownware.io scheme
  PASS  [commissa] 5. every gallery image the page references exists on disk (5 files)
  PASS  [commissa] 6. every edition naming a download_file has that file on disk (2 wired in this fixture)
  PASS  [commissa] 7. every tier sold renders its price and its licence terms (single+extended; 2/2 priced, 23 licence mentions)
  PASS  [commissa] 8. /vs/ renders and all 3 comparison rows are source-cited
  PASS  [commissa] 9. agent-first: the first 2KB of visible text answers what, price, stack, demo, tests
  PASS  [complia] 1a. product row is active in the catalogue
  PASS  [complia] 1. /p/ renders through the layout, carries its canonical, raises no PHP notice
  PASS  [complia] 2. JSON-LD Product parses and every Offer price equals the DB edition price
  PASS  [complia] 3. every money figure in the copy comes from the record (edition, bundle, cited comparison, linked guide, cloud offer or stored copy) — none invented by the view
  PASS  [complia] 4. demo_url follows the https://<slug>.ownware.io scheme
  PASS  [complia] 5. every gallery image the page references exists on disk (5 files)
  PASS  [complia] 6. every edition naming a download_file has that file on disk (2 wired in this fixture)
  PASS  [complia] 7. every tier sold renders its price and its licence terms (single+extended; 2/2 priced, 23 licence mentions)
  PASS  [complia] 8. /vs/ renders and all 2 comparison rows are source-cited
  PASS  [complia] 9. agent-first: the first 2KB of visible text answers what, price, stack, demo, tests
  PASS  [confida] 1a. product row is active in the catalogue
  PASS  [confida] 1. /p/ renders through the layout, carries its canonical, raises no PHP notice
  PASS  [confida] 2. JSON-LD Product parses and every Offer price equals the DB edition price
  PASS  [confida] 3. every money figure in the copy comes from the record (edition, bundle, cited comparison, linked guide, cloud offer or stored copy) — none invented by the view
  PASS  [confida] 4. demo_url follows the https://<slug>.ownware.io scheme
  PASS  [confida] 5. every gallery image the page references exists on disk (5 files)
  PASS  [confida] 6. every edition naming a download_file has that file on disk (2 wired in this fixture)
  PASS  [confida] 7. every tier sold renders its price and its licence terms (single+extended; 2/2 priced, 23 licence mentions)
  PASS  [confida] 8. /vs/ renders and all 3 comparison rows are source-cited
  PASS  [confida] 9. agent-first: the first 2KB of visible text answers what, price, stack, demo, tests
  PASS  [consigna] 1a. product row is active in the catalogue
  PASS  [consigna] 1. /p/ renders through the layout, carries its canonical, raises no PHP notice
  PASS  [consigna] 2. JSON-LD Product parses and every Offer price equals the DB edition price
  PASS  [consigna] 3. every money figure in the copy comes from the record (edition, bundle, cited comparison, linked guide, cloud offer or stored copy) — none invented by the view
  PASS  [consigna] 4. demo_url follows the https://<slug>.ownware.io scheme
  PASS  [consigna] 5. every gallery image the page references exists on disk (5 files)
  PASS  [consigna] 6. every edition naming a download_file has that file on disk (2 wired in this fixture)
  PASS  [consigna] 7. every tier sold renders its price and its licence terms (single+extended; 2/2 priced, 26 licence mentions)
  PASS  [consigna] 8. /vs/ renders and all 2 comparison rows are source-cited
  PASS  [consigna] 9. agent-first: the first 2KB of visible text answers what, price, stack, demo, tests
  PASS  [cyresora] 1a. product row is active in the catalogue
  PASS  [cyresora] 1. /p/ renders through the layout, carries its canonical, raises no PHP notice
  PASS  [cyresora] 2. JSON-LD Product parses and every Offer price equals the DB edition price
  PASS  [cyresora] 3. every money figure in the copy comes from the record (edition, bundle, cited comparison, linked guide, cloud offer or stored copy) — none invented by the view
  PASS  [cyresora] 4. demo_url follows the https://<slug>.ownware.io scheme
  PASS  [cyresora] 5. every gallery image the page references exists on disk (5 files)
  PASS  [cyresora] 6. every edition naming a download_file has that file on disk (2 wired in this fixture)
  PASS  [cyresora] 7. every tier sold renders its price and its licence terms (single+extended; 2/2 priced, 23 licence mentions)
  PASS  [cyresora] 8. /vs/ renders and all 3 comparison rows are source-cited
  PASS  [cyresora] 9. agent-first: the first 2KB of visible text answers what, price, stack, demo, tests
  PASS  [deliora] 1a. product row is active in the catalogue
  PASS  [deliora] 1. /p/ renders through the layout, carries its canonical, raises no PHP notice
  PASS  [deliora] 2. JSON-LD Product parses and every Offer price equals the DB edition price
  PASS  [deliora] 3. every money figure in the copy comes from the record (edition, bundle, cited comparison, linked guide, cloud offer or stored copy) — none invented by the view
  PASS  [deliora] 4. demo_url follows the https://<slug>.ownware.io scheme
  PASS  [deliora] 5. every gallery image the page references exists on disk (5 files)
  PASS  [deliora] 6. every edition naming a download_file has that file on disk (2 wired in this fixture)
  PASS  [deliora] 7. every tier sold renders its price and its licence terms (single+extended; 2/2 priced, 40 licence mentions)
  PASS  [deliora] 8. /vs/ renders and all 6 comparison rows are source-cited
  PASS  [deliora] 9. agent-first: the first 2KB of visible text answers what, price, stack, demo, tests
  PASS  [expensa] 1a. product row is active in the catalogue
  PASS  [expensa] 1. /p/ renders through the layout, carries its canonical, raises no PHP notice
  PASS  [expensa] 2. JSON-LD Product parses and every Offer price equals the DB edition price
  PASS  [expensa] 3. every money figure in the copy comes from the record (edition, bundle, cited comparison, linked guide, cloud offer or stored copy) — none invented by the view
  PASS  [expensa] 4. demo_url follows the https://<slug>.ownware.io scheme
  PASS  [expensa] 5. every gallery image the page references exists on disk (5 files)
  PASS  [expensa] 6. every edition naming a download_file has that file on disk (2 wired in this fixture)
  PASS  [expensa] 7. every tier sold renders its price and its licence terms (single+extended; 2/2 priced, 23 licence mentions)
  PASS  [expensa] 8. /vs/ renders and all 4 comparison rows are source-cited
  PASS  [expensa] 9. agent-first: the first 2KB of visible text answers what, price, stack, demo, tests
  PASS  [extracta] 1a. product row is active in the catalogue
  PASS  [extracta] 1. /p/ renders through the layout, carries its canonical, raises no PHP notice
  PASS  [extracta] 2. JSON-LD Product parses and every Offer price equals the DB edition price
  PASS  [extracta] 3. every money figure in the copy comes from the record (edition, bundle, cited comparison, linked guide, cloud offer or stored copy) — none invented by the view
  PASS  [extracta] 4. demo_url follows the https://<slug>.ownware.io scheme
  PASS  [extracta] 5. every gallery image the page references exists on disk (5 files)
  PASS  [extracta] 6. every edition naming a download_file has that file on disk (2 wired in this fixture)
  PASS  [extracta] 7. every tier sold renders its price and its licence terms (single+extended; 2/2 priced, 24 licence mentions)
  PASS  [extracta] 8. /vs/ renders and all 3 comparison rows are source-cited
  PASS  [extracta] 9. agent-first: the first 2KB of visible text answers what, price, stack, demo, tests
  PASS  [fixora] 1a. product row is active in the catalogue
  PASS  [fixora] 1. /p/ renders through the layout, carries its canonical, raises no PHP notice
  PASS  [fixora] 2. JSON-LD Product parses and every Offer price equals the DB edition price
  PASS  [fixora] 3. every money figure in the copy comes from the record (edition, bundle, cited comparison, linked guide, cloud offer or stored copy) — none invented by the view
  PASS  [fixora] 4. demo_url follows the https://<slug>.ownware.io scheme
  PASS  [fixora] 5. every gallery image the page references exists on disk (5 files)
  PASS  [fixora] 6. every edition naming a download_file has that file on disk (2 wired in this fixture)
  PASS  [fixora] 7. every tier sold renders its price and its licence terms (single+extended; 2/2 priced, 24 licence mentions)
  PASS  [fixora] 8. /vs/ renders and all 8 comparison rows are source-cited
  PASS  [fixora] 9. agent-first: the first 2KB of visible text answers what, price, stack, demo, tests
  PASS  [fleetora] 1a. product row is active in the catalogue
  PASS  [fleetora] 1. /p/ renders through the layout, carries its canonical, raises no PHP notice
  PASS  [fleetora] 2. JSON-LD Product parses and every Offer price equals the DB edition price
  PASS  [fleetora] 3. every money figure in the copy comes from the record (edition, bundle, cited comparison, linked guide, cloud offer or stored copy) — none invented by the view
  PASS  [fleetora] 4. demo_url follows the https://<slug>.ownware.io scheme
  PASS  [fleetora] 5. every gallery image the page references exists on disk (5 files)
  PASS  [fleetora] 6. every edition naming a download_file has that file on disk (2 wired in this fixture)
  PASS  [fleetora] 7. every tier sold renders its price and its licence terms (single+extended; 2/2 priced, 24 licence mentions)
  PASS  [fleetora] 8. /vs/ renders and all 6 comparison rows are source-cited
  PASS  [fleetora] 9. agent-first: the first 2KB of visible text answers what, price, stack, demo, tests
  PASS  [gymora] 1a. product row is active in the catalogue
  PASS  [gymora] 1. /p/ renders through the layout, carries its canonical, raises no PHP notice
  PASS  [gymora] 2. JSON-LD Product parses and every Offer price equals the DB edition price
  PASS  [gymora] 3. every money figure in the copy comes from the record (edition, bundle, cited comparison, linked guide, cloud offer or stored copy) — none invented by the view
  PASS  [gymora] 4. demo_url follows the https://<slug>.ownware.io scheme
  PASS  [gymora] 5. every gallery image the page references exists on disk (5 files)
  PASS  [gymora] 6. every edition naming a download_file has that file on disk (2 wired in this fixture)
  PASS  [gymora] 7. every tier sold renders its price and its licence terms (single+extended; 2/2 priced, 24 licence mentions)
  PASS  [gymora] 8. /vs/ renders and all 7 comparison rows are source-cited
  PASS  [gymora] 9. agent-first: the first 2KB of visible text answers what, price, stack, demo, tests
  PASS  [helpora] 1a. product row is active in the catalogue
  PASS  [helpora] 1. /p/ renders through the layout, carries its canonical, raises no PHP notice
  PASS  [helpora] 2. JSON-LD Product parses and every Offer price equals the DB edition price
  PASS  [helpora] 3. every money figure in the copy comes from the record (edition, bundle, cited comparison, linked guide, cloud offer or stored copy) — none invented by the view
  PASS  [helpora] 4. demo_url follows the https://<slug>.ownware.io scheme
  PASS  [helpora] 5. every gallery image the page references exists on disk (5 files)
  PASS  [helpora] 6. every edition naming a download_file has that file on disk (2 wired in this fixture)
  PASS  [helpora] 7. every tier sold renders its price and its licence terms (single+extended; 2/2 priced, 23 licence mentions)
  PASS  [helpora] 8. /vs/ renders and all 3 comparison rows are source-cited
  PASS  [helpora] 9. agent-first: the first 2KB of visible text answers what, price, stack, demo, tests
  PASS  [inspectora] 1a. product row is active in the catalogue
  PASS  [inspectora] 1. /p/ renders through the layout, carries its canonical, raises no PHP notice
  PASS  [inspectora] 2. JSON-LD Product parses and every Offer price equals the DB edition price
  PASS  [inspectora] 3. every money figure in the copy comes from the record (edition, bundle, cited comparison, linked guide, cloud offer or stored copy) — none invented by the view
  PASS  [inspectora] 4. demo_url follows the https://<slug>.ownware.io scheme
  PASS  [inspectora] 5. every gallery image the page references exists on disk (5 files)
  PASS  [inspectora] 6. every edition naming a download_file has that file on disk (2 wired in this fixture)
  PASS  [inspectora] 7. every tier sold renders its price and its licence terms (single+extended; 2/2 priced, 25 licence mentions)
  PASS  [inspectora] 8. /vs/ renders and all 4 comparison rows are source-cited
  PASS  [inspectora] 9. agent-first: the first 2KB of visible text answers what, price, stack, demo, tests
  PASS  [invora] 1a. product row is active in the catalogue
  PASS  [invora] 1. /p/ renders through the layout, carries its canonical, raises no PHP notice
  PASS  [invora] 2. JSON-LD Product parses and every Offer price equals the DB edition price
  PASS  [invora] 3. every money figure in the copy comes from the record (edition, bundle, cited comparison, linked guide, cloud offer or stored copy) — none invented by the view
  PASS  [invora] 4. demo_url follows the https://<slug>.ownware.io scheme
  PASS  [invora] 5. every gallery image the page references exists on disk (5 files)
  PASS  [invora] 6. every edition naming a download_file has that file on disk (2 wired in this fixture)
  PASS  [invora] 7. every tier sold renders its price and its licence terms (single+extended; 2/2 priced, 23 licence mentions)
  PASS  [invora] 8. /vs/ renders and all 8 comparison rows are source-cited
  PASS  [invora] 9. agent-first: the first 2KB of visible text answers what, price, stack, demo, tests
  PASS  [jobora] 1a. product row is active in the catalogue
  PASS  [jobora] 1. /p/ renders through the layout, carries its canonical, raises no PHP notice
  PASS  [jobora] 2. JSON-LD Product parses and every Offer price equals the DB edition price
  PASS  [jobora] 3. every money figure in the copy comes from the record (edition, bundle, cited comparison, linked guide, cloud offer or stored copy) — none invented by the view
  PASS  [jobora] 4. demo_url follows the https://<slug>.ownware.io scheme
  PASS  [jobora] 5. every gallery image the page references exists on disk (5 files)
  PASS  [jobora] 6. every edition naming a download_file has that file on disk (2 wired in this fixture)
  PASS  [jobora] 7. every tier sold renders its price and its licence terms (single+extended; 2/2 priced, 24 licence mentions)
  PASS  [jobora] 8. /vs/ renders and all 9 comparison rows are source-cited
  PASS  [jobora] 9. agent-first: the first 2KB of visible text answers what, price, stack, demo, tests
  PASS  [leavora] 1a. product row is active in the catalogue
  PASS  [leavora] 1. /p/ renders through the layout, carries its canonical, raises no PHP notice
  PASS  [leavora] 2. JSON-LD Product parses and every Offer price equals the DB edition price
  PASS  [leavora] 3. every money figure in the copy comes from the record (edition, bundle, cited comparison, linked guide, cloud offer or stored copy) — none invented by the view
  PASS  [leavora] 4. demo_url follows the https://<slug>.ownware.io scheme
  PASS  [leavora] 5. every gallery image the page references exists on disk (5 files)
  PASS  [leavora] 6. every edition naming a download_file has that file on disk (2 wired in this fixture)
  PASS  [leavora] 7. every tier sold renders its price and its licence terms (single+extended; 2/2 priced, 23 licence mentions)
  PASS  [leavora] 8. /vs/ renders and all 4 comparison rows are source-cited
  PASS  [leavora] 9. agent-first: the first 2KB of visible text answers what, price, stack, demo, tests
  PASS  [ledgira] 1a. product row is active in the catalogue
  PASS  [ledgira] 1. /p/ renders through the layout, carries its canonical, raises no PHP notice
  PASS  [ledgira] 2. JSON-LD Product parses and every Offer price equals the DB edition price
  PASS  [ledgira] 3. every money figure in the copy comes from the record (edition, bundle, cited comparison, linked guide, cloud offer or stored copy) — none invented by the view
  PASS  [ledgira] 4. demo_url follows the https://<slug>.ownware.io scheme
  PASS  [ledgira] 5. every gallery image the page references exists on disk (5 files)
  PASS  [ledgira] 6. every edition naming a download_file has that file on disk (2 wired in this fixture)
  PASS  [ledgira] 7. every tier sold renders its price and its licence terms (single+extended; 2/2 priced, 23 licence mentions)
  PASS  [ledgira] 8. /vs/ renders and all 3 comparison rows are source-cited
  PASS  [ledgira] 9. agent-first: the first 2KB of visible text answers what, price, stack, demo, tests
  PASS  [lendra] 1a. product row is active in the catalogue
  PASS  [lendra] 1. /p/ renders through the layout, carries its canonical, raises no PHP notice
  PASS  [lendra] 2. JSON-LD Product parses and every Offer price equals the DB edition price
  PASS  [lendra] 3. every money figure in the copy comes from the record (edition, bundle, cited comparison, linked guide, cloud offer or stored copy) — none invented by the view
  PASS  [lendra] 4. demo_url follows the https://<slug>.ownware.io scheme
  PASS  [lendra] 5. every gallery image the page references exists on disk (5 files)
  PASS  [lendra] 6. every edition naming a download_file has that file on disk (2 wired in this fixture)
  PASS  [lendra] 7. every tier sold renders its price and its licence terms (single+extended; 2/2 priced, 23 licence mentions)
  PASS  [lendra] 8. /vs/ renders and all 3 comparison rows are source-cited
  PASS  [lendra] 9. agent-first: the first 2KB of visible text answers what, price, stack, demo, tests
  PASS  [loyalora] 1a. product row is active in the catalogue
  PASS  [loyalora] 1. /p/ renders through the layout, carries its canonical, raises no PHP notice
  PASS  [loyalora] 2. JSON-LD Product parses and every Offer price equals the DB edition price
  PASS  [loyalora] 3. every money figure in the copy comes from the record (edition, bundle, cited comparison, linked guide, cloud offer or stored copy) — none invented by the view
  PASS  [loyalora] 4. demo_url follows the https://<slug>.ownware.io scheme
  PASS  [loyalora] 5. every gallery image the page references exists on disk (5 files)
  PASS  [loyalora] 6. every edition naming a download_file has that file on disk (2 wired in this fixture)
  PASS  [loyalora] 7. every tier sold renders its price and its licence terms (single+extended; 2/2 priced, 24 licence mentions)
  PASS  [loyalora] 8. /vs/ renders and all 4 comparison rows are source-cited
  PASS  [loyalora] 9. agent-first: the first 2KB of visible text answers what, price, stack, demo, tests
  PASS  [membora] 1a. product row is active in the catalogue
  PASS  [membora] 1. /p/ renders through the layout, carries its canonical, raises no PHP notice
  PASS  [membora] 2. JSON-LD Product parses and every Offer price equals the DB edition price
  PASS  [membora] 3. every money figure in the copy comes from the record (edition, bundle, cited comparison, linked guide, cloud offer or stored copy) — none invented by the view
  PASS  [membora] 4. demo_url follows the https://<slug>.ownware.io scheme
  PASS  [membora] 5. every gallery image the page references exists on disk (5 files)
  PASS  [membora] 6. every edition naming a download_file has that file on disk (2 wired in this fixture)
  PASS  [membora] 7. every tier sold renders its price and its licence terms (single+extended; 2/2 priced, 23 licence mentions)
  PASS  [membora] 8. /vs/ renders and all 3 comparison rows are source-cited
  PASS  [membora] 9. agent-first: the first 2KB of visible text answers what, price, stack, demo, tests
  PASS  [menura] 1a. product row is active in the catalogue
  PASS  [menura] 1. /p/ renders through the layout, carries its canonical, raises no PHP notice
  PASS  [menura] 2. JSON-LD Product parses and every Offer price equals the DB edition price
  PASS  [menura] 3. every money figure in the copy comes from the record (edition, bundle, cited comparison, linked guide, cloud offer or stored copy) — none invented by the view
  PASS  [menura] 4. demo_url follows the https://<slug>.ownware.io scheme
  PASS  [menura] 5. every gallery image the page references exists on disk (5 files)
  PASS  [menura] 6. every edition naming a download_file has that file on disk (2 wired in this fixture)
  PASS  [menura] 7. every tier sold renders its price and its licence terms (single+extended; 2/2 priced, 23 licence mentions)
  PASS  [menura] 8. /vs/ renders and all 1 comparison rows are source-cited
  PASS  [menura] 9. agent-first: the first 2KB of visible text answers what, price, stack, demo, tests
  PASS  [nexura] 1a. product row exists and is UNLISTED (operator ruling)
  PASS  [onboardora] 1a. product row is active in the catalogue
  PASS  [onboardora] 1. /p/ renders through the layout, carries its canonical, raises no PHP notice
  PASS  [onboardora] 2. JSON-LD Product parses and every Offer price equals the DB edition price
  PASS  [onboardora] 3. every money figure in the copy comes from the record (edition, bundle, cited comparison, linked guide, cloud offer or stored copy) — none invented by the view
  PASS  [onboardora] 4. demo_url follows the https://<slug>.ownware.io scheme
  PASS  [onboardora] 5. every gallery image the page references exists on disk (5 files)
  PASS  [onboardora] 6. every edition naming a download_file has that file on disk (2 wired in this fixture)
  PASS  [onboardora] 7. every tier sold renders its price and its licence terms (single+extended; 2/2 priced, 23 licence mentions)
  PASS  [onboardora] 8. /vs/ renders and all 3 comparison rows are source-cited
  PASS  [onboardora] 9. agent-first: the first 2KB of visible text answers what, price, stack, demo, tests
  PASS  [oya] 1a. product row is active in the catalogue
  PASS  [oya] 1. /p/ renders through the layout, carries its canonical, raises no PHP notice
  PASS  [oya] 2. JSON-LD Product parses and every Offer price equals the DB edition price
  PASS  [oya] 3. every money figure in the copy comes from the record (edition, bundle, cited comparison, linked guide, cloud offer or stored copy) — none invented by the view
  PASS  [oya] 4. demo_url follows the https://<slug>.ownware.io scheme
  PASS  [oya] 5. every gallery image the page references exists on disk (6 files)
  PASS  [oya] 6. every edition naming a download_file has that file on disk (3 wired in this fixture)
  PASS  [oya] 7. every tier sold renders its price and its licence terms (single+extended+saas; 3/3 priced, 18 licence mentions)
  PASS  [oya] 8. /vs/ renders and all 3 comparison rows are source-cited
  PASS  [oya] 9. agent-first: the first 2KB of visible text answers what, price, stack, demo, tests
  PASS  [packora] 1a. product row is active in the catalogue
  PASS  [packora] 1. /p/ renders through the layout, carries its canonical, raises no PHP notice
  PASS  [packora] 2. JSON-LD Product parses and every Offer price equals the DB edition price
  PASS  [packora] 3. every money figure in the copy comes from the record (edition, bundle, cited comparison, linked guide, cloud offer or stored copy) — none invented by the view
  PASS  [packora] 4. demo_url follows the https://<slug>.ownware.io scheme
  PASS  [packora] 5. every gallery image the page references exists on disk (5 files)
  PASS  [packora] 6. every edition naming a download_file has that file on disk (2 wired in this fixture)
  PASS  [packora] 7. every tier sold renders its price and its licence terms (single+extended; 2/2 priced, 23 licence mentions)
  PASS  [packora] 8. /vs/ renders and all 1 comparison rows are source-cited
  PASS  [packora] 9. agent-first: the first 2KB of visible text answers what, price, stack, demo, tests
  PASS  [permora] 1a. product row is active in the catalogue
  PASS  [permora] 1. /p/ renders through the layout, carries its canonical, raises no PHP notice
  PASS  [permora] 2. JSON-LD Product parses and every Offer price equals the DB edition price
  PASS  [permora] 3. every money figure in the copy comes from the record (edition, bundle, cited comparison, linked guide, cloud offer or stored copy) — none invented by the view
  PASS  [permora] 4. demo_url follows the https://<slug>.ownware.io scheme
  PASS  [permora] 5. every gallery image the page references exists on disk (5 files)
  PASS  [permora] 6. every edition naming a download_file has that file on disk (2 wired in this fixture)
  PASS  [permora] 7. every tier sold renders its price and its licence terms (single+extended; 2/2 priced, 23 licence mentions)
  PASS  [permora] 8. /vs/ renders and all 1 comparison rows are source-cited
  PASS  [permora] 9. agent-first: the first 2KB of visible text answers what, price, stack, demo, tests
  PASS  [privara] 1a. product row is active in the catalogue
  PASS  [privara] 1. /p/ renders through the layout, carries its canonical, raises no PHP notice
  PASS  [privara] 2. JSON-LD Product parses and every Offer price equals the DB edition price
  PASS  [privara] 3. every money figure in the copy comes from the record (edition, bundle, cited comparison, linked guide, cloud offer or stored copy) — none invented by the view
  PASS  [privara] 4. demo_url follows the https://<slug>.ownware.io scheme
  PASS  [privara] 5. every gallery image the page references exists on disk (5 files)
  PASS  [privara] 6. every edition naming a download_file has that file on disk (2 wired in this fixture)
  PASS  [privara] 7. every tier sold renders its price and its licence terms (single+extended; 2/2 priced, 27 licence mentions)
  PASS  [privara] 8. /vs/ renders and all 3 comparison rows are source-cited
  PASS  [privara] 9. agent-first: the first 2KB of visible text answers what, price, stack, demo, tests
  PASS  [rentara] 1a. product row is active in the catalogue
  PASS  [rentara] 1. /p/ renders through the layout, carries its canonical, raises no PHP notice
  PASS  [rentara] 2. JSON-LD Product parses and every Offer price equals the DB edition price
  PASS  [rentara] 3. every money figure in the copy comes from the record (edition, bundle, cited comparison, linked guide, cloud offer or stored copy) — none invented by the view
  PASS  [rentara] 4. demo_url follows the https://<slug>.ownware.io scheme
  PASS  [rentara] 5. every gallery image the page references exists on disk (5 files)
  PASS  [rentara] 6. every edition naming a download_file has that file on disk (2 wired in this fixture)
  PASS  [rentara] 7. every tier sold renders its price and its licence terms (single+extended; 2/2 priced, 27 licence mentions)
  PASS  [rentara] 8. /vs/ renders and all 6 comparison rows are source-cited
  PASS  [rentara] 9. agent-first: the first 2KB of visible text answers what, price, stack, demo, tests
  PASS  [restock] 1a. product row is active in the catalogue
  PASS  [restock] 1. /p/ renders through the layout, carries its canonical, raises no PHP notice
  PASS  [restock] 2. JSON-LD Product parses and every Offer price equals the DB edition price
  PASS  [restock] 3. every money figure in the copy comes from the record (edition, bundle, cited comparison, linked guide, cloud offer or stored copy) — none invented by the view
  PASS  [restock] 4. demo_url follows the https://<slug>.ownware.io scheme
  PASS  [restock] 5. every gallery image the page references exists on disk (5 files)
  PASS  [restock] 6. every edition naming a download_file has that file on disk (2 wired in this fixture)
  PASS  [restock] 7. every tier sold renders its price and its licence terms (single+extended; 2/2 priced, 23 licence mentions)
  PASS  [restock] 8. /vs/ renders and all 5 comparison rows are source-cited
  PASS  [restock] 9. agent-first: the first 2KB of visible text answers what, price, stack, demo, tests
  PASS  [revup] 1a. product row is active in the catalogue
  PASS  [revup] 1. /p/ renders through the layout, carries its canonical, raises no PHP notice
  PASS  [revup] 2. JSON-LD Product parses and every Offer price equals the DB edition price
  PASS  [revup] 3. every money figure in the copy comes from the record (edition, bundle, cited comparison, linked guide, cloud offer or stored copy) — none invented by the view
  PASS  [revup] 4. demo_url follows the https://<slug>.ownware.io scheme
  PASS  [revup] 5. every gallery image the page references exists on disk (5 files)
  PASS  [revup] 6. every edition naming a download_file has that file on disk (2 wired in this fixture)
  PASS  [revup] 7. every tier sold renders its price and its licence terms (single+extended; 2/2 priced, 23 licence mentions)
  PASS  [revup] 8. /vs/ renders and all 3 comparison rows are source-cited
  PASS  [revup] 9. agent-first: the first 2KB of visible text answers what, price, stack, demo, tests
  PASS  [rostera] 1a. product row is active in the catalogue
  PASS  [rostera] 1. /p/ renders through the layout, carries its canonical, raises no PHP notice
  PASS  [rostera] 2. JSON-LD Product parses and every Offer price equals the DB edition price
  PASS  [rostera] 3. every money figure in the copy comes from the record (edition, bundle, cited comparison, linked guide, cloud offer or stored copy) — none invented by the view
  PASS  [rostera] 4. demo_url follows the https://<slug>.ownware.io scheme
  PASS  [rostera] 5. every gallery image the page references exists on disk (5 files)
  PASS  [rostera] 6. every edition naming a download_file has that file on disk (2 wired in this fixture)
  PASS  [rostera] 7. every tier sold renders its price and its licence terms (single+extended; 2/2 priced, 23 licence mentions)
  PASS  [rostera] 8. /vs/ renders and all 5 comparison rows are source-cited
  PASS  [rostera] 9. agent-first: the first 2KB of visible text answers what, price, stack, demo, tests
  PASS  [saas-kit] 1a. product row is active in the catalogue
  PASS  [saas-kit] 1. /p/ renders through the layout, carries its canonical, raises no PHP notice
  PASS  [saas-kit] 2. JSON-LD Product parses and every Offer price equals the DB edition price
  PASS  [saas-kit] 3. every money figure in the copy comes from the record (edition, bundle, cited comparison, linked guide, cloud offer or stored copy) — none invented by the view
  PASS  [saas-kit] 4. demo_url follows the https://<slug>.ownware.io scheme
  PASS  [saas-kit] 5. every gallery image the page references exists on disk (5 files)
  PASS  [saas-kit] 6. every edition naming a download_file has that file on disk (2 wired in this fixture)
  PASS  [saas-kit] 7. every tier sold renders its price and its licence terms (single+extended; 2/2 priced, 24 licence mentions)
  PASS  [saas-kit] 8. /vs/ renders and all 2 comparison rows are source-cited
  PASS  [saas-kit] 9. agent-first: the first 2KB of visible text answers what, price, stack, demo, tests
  PASS  [safora] 1a. product row is active in the catalogue
  PASS  [safora] 1. /p/ renders through the layout, carries its canonical, raises no PHP notice
  PASS  [safora] 2. JSON-LD Product parses and every Offer price equals the DB edition price
  PASS  [safora] 3. every money figure in the copy comes from the record (edition, bundle, cited comparison, linked guide, cloud offer or stored copy) — none invented by the view
  PASS  [safora] 4. demo_url follows the https://<slug>.ownware.io scheme
  PASS  [safora] 5. every gallery image the page references exists on disk (5 files)
  PASS  [safora] 6. every edition naming a download_file has that file on disk (2 wired in this fixture)
  PASS  [safora] 7. every tier sold renders its price and its licence terms (single+extended; 2/2 priced, 23 licence mentions)
  PASS  [safora] 8. /vs/ renders and all 3 comparison rows are source-cited
  PASS  [safora] 9. agent-first: the first 2KB of visible text answers what, price, stack, demo, tests
  PASS  [secreta] 1a. product row is active in the catalogue
  PASS  [secreta] 1. /p/ renders through the layout, carries its canonical, raises no PHP notice
  PASS  [secreta] 2. JSON-LD Product parses and every Offer price equals the DB edition price
  PASS  [secreta] 3. every money figure in the copy comes from the record (edition, bundle, cited comparison, linked guide, cloud offer or stored copy) — none invented by the view
  PASS  [secreta] 4. demo_url follows the https://<slug>.ownware.io scheme
  PASS  [secreta] 5. every gallery image the page references exists on disk (5 files)
  PASS  [secreta] 6. every edition naming a download_file has that file on disk (2 wired in this fixture)
  PASS  [secreta] 7. every tier sold renders its price and its licence terms (single+extended; 2/2 priced, 23 licence mentions)
  PASS  [secreta] 8. /vs/ renders and all 3 comparison rows are source-cited
  PASS  [secreta] 9. agent-first: the first 2KB of visible text answers what, price, stack, demo, tests
  PASS  [slotly] 1a. product row is active in the catalogue
  PASS  [slotly] 1. /p/ renders through the layout, carries its canonical, raises no PHP notice
  PASS  [slotly] 2. JSON-LD Product parses and every Offer price equals the DB edition price
  PASS  [slotly] 3. every money figure in the copy comes from the record (edition, bundle, cited comparison, linked guide, cloud offer or stored copy) — none invented by the view
  PASS  [slotly] 4. demo_url follows the https://<slug>.ownware.io scheme
  PASS  [slotly] 5. every gallery image the page references exists on disk (5 files)
  PASS  [slotly] 6. every edition naming a download_file has that file on disk (2 wired in this fixture)
  PASS  [slotly] 7. every tier sold renders its price and its licence terms (single+extended; 2/2 priced, 24 licence mentions)
  PASS  [slotly] 8. /vs/ renders and all 9 comparison rows are source-cited
  PASS  [slotly] 9. agent-first: the first 2KB of visible text answers what, price, stack, demo, tests
  PASS  [specta] 1a. product row is active in the catalogue
  PASS  [specta] 1. /p/ renders through the layout, carries its canonical, raises no PHP notice
  PASS  [specta] 2. JSON-LD Product parses and every Offer price equals the DB edition price
  PASS  [specta] 3. every money figure in the copy comes from the record (edition, bundle, cited comparison, linked guide, cloud offer or stored copy) — none invented by the view
  PASS  [specta] 4. demo_url follows the https://<slug>.ownware.io scheme
  PASS  [specta] 5. every gallery image the page references exists on disk (5 files)
  PASS  [specta] 6. every edition naming a download_file has that file on disk (2 wired in this fixture)
  PASS  [specta] 7. every tier sold renders its price and its licence terms (single+extended; 2/2 priced, 23 licence mentions)
  PASS  [specta] 8. /vs/ renders and all 3 comparison rows are source-cited
  PASS  [specta] 9. agent-first: the first 2KB of visible text answers what, price, stack, demo, tests
  PASS  [supplia] 1a. product row is active in the catalogue
  PASS  [supplia] 1. /p/ renders through the layout, carries its canonical, raises no PHP notice
  PASS  [supplia] 2. JSON-LD Product parses and every Offer price equals the DB edition price
  PASS  [supplia] 3. every money figure in the copy comes from the record (edition, bundle, cited comparison, linked guide, cloud offer or stored copy) — none invented by the view
  PASS  [supplia] 4. demo_url follows the https://<slug>.ownware.io scheme
  PASS  [supplia] 5. every gallery image the page references exists on disk (5 files)
  PASS  [supplia] 6. every edition naming a download_file has that file on disk (2 wired in this fixture)
  PASS  [supplia] 7. every tier sold renders its price and its licence terms (single+extended; 2/2 priced, 23 licence mentions)
  PASS  [supplia] 8. /vs/ renders and all 4 comparison rows are source-cited
  PASS  [supplia] 9. agent-first: the first 2KB of visible text answers what, price, stack, demo, tests
  PASS  [tokora] 1a. product row is active in the catalogue
  PASS  [tokora] 1. /p/ renders through the layout, carries its canonical, raises no PHP notice
  PASS  [tokora] 2. JSON-LD Product parses and every Offer price equals the DB edition price
  PASS  [tokora] 3. every money figure in the copy comes from the record (edition, bundle, cited comparison, linked guide, cloud offer or stored copy) — none invented by the view
  PASS  [tokora] 4. demo_url follows the https://<slug>.ownware.io scheme
  PASS  [tokora] 5. every gallery image the page references exists on disk (5 files)
  PASS  [tokora] 6. every edition naming a download_file has that file on disk (2 wired in this fixture)
  PASS  [tokora] 7. every tier sold renders its price and its licence terms (single+extended; 2/2 priced, 24 licence mentions)
  PASS  [tokora] 8. /vs/ renders and all 4 comparison rows are source-cited
  PASS  [tokora] 9. agent-first: the first 2KB of visible text answers what, price, stack, demo, tests
  PASS  [trainora] 1a. product row is active in the catalogue
  PASS  [trainora] 1. /p/ renders through the layout, carries its canonical, raises no PHP notice
  PASS  [trainora] 2. JSON-LD Product parses and every Offer price equals the DB edition price
  PASS  [trainora] 3. every money figure in the copy comes from the record (edition, bundle, cited comparison, linked guide, cloud offer or stored copy) — none invented by the view
  PASS  [trainora] 4. demo_url follows the https://<slug>.ownware.io scheme
  PASS  [trainora] 5. every gallery image the page references exists on disk (5 files)
  PASS  [trainora] 6. every edition naming a download_file has that file on disk (2 wired in this fixture)
  PASS  [trainora] 7. every tier sold renders its price and its licence terms (single+extended; 2/2 priced, 23 licence mentions)
  PASS  [trainora] 8. /vs/ renders and all 3 comparison rows are source-cited
  PASS  [trainora] 9. agent-first: the first 2KB of visible text answers what, price, stack, demo, tests
  PASS  [vendra] 1a. product row is active in the catalogue
  PASS  [vendra] 1. /p/ renders through the layout, carries its canonical, raises no PHP notice
  PASS  [vendra] 2. JSON-LD Product parses and every Offer price equals the DB edition price
  PASS  [vendra] 3. every money figure in the copy comes from the record (edition, bundle, cited comparison, linked guide, cloud offer or stored copy) — none invented by the view
  PASS  [vendra] 4. demo_url follows the https://<slug>.ownware.io scheme
  PASS  [vendra] 5. every gallery image the page references exists on disk (5 files)
  PASS  [vendra] 6. every edition naming a download_file has that file on disk (2 wired in this fixture)
  PASS  [vendra] 7. every tier sold renders its price and its licence terms (single+extended; 2/2 priced, 23 licence mentions)
  PASS  [vendra] 8. /vs/ renders and all 6 comparison rows are source-cited
  PASS  [vendra] 9. agent-first: the first 2KB of visible text answers what, price, stack, demo, tests
  PASS  [visitora] 1a. product row is active in the catalogue
  PASS  [visitora] 1. /p/ renders through the layout, carries its canonical, raises no PHP notice
  PASS  [visitora] 2. JSON-LD Product parses and every Offer price equals the DB edition price
  PASS  [visitora] 3. every money figure in the copy comes from the record (edition, bundle, cited comparison, linked guide, cloud offer or stored copy) — none invented by the view
  PASS  [visitora] 4. demo_url follows the https://<slug>.ownware.io scheme
  PASS  [visitora] 5. every gallery image the page references exists on disk (5 files)
  PASS  [visitora] 6. every edition naming a download_file has that file on disk (2 wired in this fixture)
  PASS  [visitora] 7. every tier sold renders its price and its licence terms (single+extended; 2/2 priced, 23 licence mentions)
  PASS  [visitora] 8. /vs/ renders and all 4 comparison rows are source-cited
  PASS  [visitora] 9. agent-first: the first 2KB of visible text answers what, price, stack, demo, tests
  PASS  [votera] 1a. product row is active in the catalogue
  PASS  [votera] 1. /p/ renders through the layout, carries its canonical, raises no PHP notice
  PASS  [votera] 2. JSON-LD Product parses and every Offer price equals the DB edition price
  PASS  [votera] 3. every money figure in the copy comes from the record (edition, bundle, cited comparison, linked guide, cloud offer or stored copy) — none invented by the view
  PASS  [votera] 4. demo_url follows the https://<slug>.ownware.io scheme
  PASS  [votera] 5. every gallery image the page references exists on disk (5 files)
  PASS  [votera] 6. every edition naming a download_file has that file on disk (2 wired in this fixture)
  PASS  [votera] 7. every tier sold renders its price and its licence terms (single+extended; 2/2 priced, 25 licence mentions)
  PASS  [votera] 8. /vs/ renders and all 4 comparison rows are source-cited
  PASS  [votera] 9. agent-first: the first 2KB of visible text answers what, price, stack, demo, tests
  PASS  [waiverly] 1a. product row is active in the catalogue
  PASS  [waiverly] 1. /p/ renders through the layout, carries its canonical, raises no PHP notice
  PASS  [waiverly] 2. JSON-LD Product parses and every Offer price equals the DB edition price
  PASS  [waiverly] 3. every money figure in the copy comes from the record (edition, bundle, cited comparison, linked guide, cloud offer or stored copy) — none invented by the view
  PASS  [waiverly] 4. demo_url follows the https://<slug>.ownware.io scheme
  PASS  [waiverly] 5. every gallery image the page references exists on disk (5 files)
  PASS  [waiverly] 6. every edition naming a download_file has that file on disk (2 wired in this fixture)
  PASS  [waiverly] 7. every tier sold renders its price and its licence terms (single+extended; 2/2 priced, 23 licence mentions)
  PASS  [waiverly] 8. /vs/ renders and all 2 comparison rows are source-cited
  PASS  [waiverly] 9. agent-first: the first 2KB of visible text answers what, price, stack, demo, tests
  PASS  [warrantora] 1a. product row is active in the catalogue
  PASS  [warrantora] 1. /p/ renders through the layout, carries its canonical, raises no PHP notice
  PASS  [warrantora] 2. JSON-LD Product parses and every Offer price equals the DB edition price
  PASS  [warrantora] 3. every money figure in the copy comes from the record (edition, bundle, cited comparison, linked guide, cloud offer or stored copy) — none invented by the view
  PASS  [warrantora] 4. demo_url follows the https://<slug>.ownware.io scheme
  PASS  [warrantora] 5. every gallery image the page references exists on disk (5 files)
  PASS  [warrantora] 6. every edition naming a download_file has that file on disk (2 wired in this fixture)
  PASS  [warrantora] 7. every tier sold renders its price and its licence terms (single+extended; 2/2 priced, 24 licence mentions)
  PASS  [warrantora] 8. /vs/ renders and all 3 comparison rows are source-cited
  PASS  [warrantora] 9. agent-first: the first 2KB of visible text answers what, price, stack, demo, tests

Warning: Undefined array key "tier" in tests/store_instance.php on line 5087
  PASS  WS-4/6 planted fault: an edition naming a file that is not on disk IS detected
  PASS  WS-4/6 planted fault removed: the same check reports clean again
  PASS  WS-4/6 fixture restored: the DB is back to its pre-wiring state (1 wired, as before)

== WS-14 guards: citation reach, currency honesty, clip boundaries, page integrity ==
  PASS  WS-14: every cited comparison row reaches its /vs page with source URL + read date (got array (
), want array (
))
  PASS  WS-14: the citation guard actually covered rows (188 across 49 products)
  PASS  WS-14: /calculator renders no rival whose published price is not in dollars (got array (
), want array (
))
  PASS  WS-14: no stored price text or assumption note sits at the seed clip boundary (got array (
), want array (
))
  PASS  WS-14: every /self-hosted page lists only products that exist and are active (got array (
), want array (
))
  PASS  WS-14: llms-full.txt states requirements wherever the record has them (got 49, want 49)
  PASS  WS-14: llms-full.txt carries the stored FAQ wherever there is one (got 49, want 49)
  PASS  WS-14: llms-full.txt lists the cited rivals for every product that has them (got 49, want 49)
  PASS  WS-14: llms-full.txt states the licences for every product with an edition (got 51, want 51)
  PASS  WS-14: llms-full.txt gives comparison addresses to every product with a cited rival (got 49, want 49)
  PASS  WS-14: every source URL printed in llms-full carries a read date beside it

== TAIL GUIDES: every money figure in the rent-vs-own guides, asserted against the database ==
  PASS  TAIL: the tail-guide set is loaded and complete (got 20, want 20)
  PASS  TAIL: staged release — no more than three published in the seeded batch
  PASS  TAIL: every money figure in every guide derives from this database (58 checked)
  PASS  TAIL: every guide is about an active, sellable product
  PASS  TAIL: twenty guides cover twenty distinct products (got 20, want 20)
  PASS  TAIL: staged guides carry no publish date until they are released
  PASS  licence: every font ships the SIL OFL text for its own family beside it
  PASS  licence: LICENSE.txt is present and carries the IF WE STOP (CONTINUITY) clause
  PASS  reach: the home catalogue is an OfferCatalog (an ItemList) of the priced products
  PASS  reach: every home Product CARRIES its Offer with price + currency + availability (the GSC critical)
  PASS  reach: the home Offer carries the merchant fields (shipping + return policy) like the product page
  PASS  reach: a free product is a SoftwareApplication with a $0 offer, never a Product without one
  PASS  reach: no aggregateRating and no review is ever invented (2 buyers, no ratings to mark up)
  PASS  reach: no Product node anywhere in the home graph lacks offers
  PASS  reach: suite Offer carries sku, name, seller, priceValidUntil (C5 §2: 13 suites, one code path)
  PASS  reach: /faq FAQPage from the help_qa sections, incomplete pairs skipped
  PASS  reach: /guides ItemList lists the published guides by url + name, in order
  PASS  reach: /suites ItemList carries each suite as the Product+Offer its page carries
  PASS  reach: /pricing ItemList carries both licence Offers per wired product and the suites, and skips "Available soon"
  PASS  reach: a page that brings no richer markup still gets a WebPage node from its own head
  PASS  reach: no WebPage node without a canonical
  PASS  reach: a product Offer carries validFrom from the edition date (GSC warning ×25)
  PASS  reach: no validFrom is asserted when no date is on the row
  PASS  reach: validFromDate accepts a datetime and refuses garbage
  PASS  reach: the product hero image carries fetchpriority="high" and banner dimensions
  PASS  reach: the layout preloads the two above-the-fold fonts and falls back to a WebPage graph
  PASS  reach: the router sends a slashed GET to the slashless address with a 301 and keeps the query string

== email list: exit token, welcome once, audience, buyer invite, broadcasts ==
  PASS  list: migration added the row columns
  PASS  list: migration added broadcasts + broadcast_sends + the buyer_invite_live flag (default 0)
  PASS  list: signup records its source and mints a 48-hex exit token distinct from the confirm token
  PASS  list: an unconfirmed row is not in any audience
  PASS  list: the welcome mail goes ONCE across two confirm clicks (welcomed_at)
  PASS  list: the welcome mail carries THIS row's one-click unsubscribe URL and no unfilled placeholder
  PASS  list: a confirmed row is in the audience; store audience sees it, guides audience does not
  PASS  list: one address on two tags is ONE recipient
  PASS  list: garbage exit tokens are refused
  PASS  list: one click leaves EVERY list of that address
  PASS  list: signing up again after leaving re-opens the row as UNconfirmed (the new click is the consent)
  PASS  list: List-Unsubscribe headers are emitted and a CRLF in a value cannot inject a header
  PASS  list: the buyer opt-in token is stateless and tamper-evident
  PASS  list: the click creates ONE confirmed buyer row and the buyers audience sees it
  PASS  list: the delivery mail carries the invite ONLY when buyer_invite_live = 1 (default 0 = no invite)
  PASS  list: the form partial states the purpose, the ceiling, the confirm step and the exit; posts source + honeypot
  PASS  list: the home page footer carries the form with source=footer
  PASS  list: mail template confirm fills every placeholder and names no other brand
  PASS  list: mail template welcome fills every placeholder and names no other brand
  PASS  list: mail template footer fills every placeholder and names no other brand
  PASS  list: mail template buyer_invite fills every placeholder and names no other brand
  PASS  list: broadcast.php refuses without the operator's approval line and needs BOTH --send and --go; caps a run at the provider's daily free limit
  PASS  list: routes for the exit and the buyer yes exist

== SC. Store conversion (F51) ==
  PASS  SC1: Storefront::proof() reads assets/store/{slug}/proof.json from an overridable dir
  PASS  SC1: no proof.json -> null (a missing proof is never a number)
  PASS  SC1: proof.json read: 140 passed (got 140, want 140)
  PASS  SC1: a proof with failures is refused (null) — the strip never shows a red suite as proof
  PASS  SC1: a corrupt proof.json is refused (null), never a warning on the page
  PASS  SC1: the product hero carries the proof strip
  PASS  SC1: strip: "140 tests" links to the real run log /p/{slug}/tests
  PASS  SC1: strip: the manual links to the manual rendered on the store
  PASS  SC1: strip: "API + MCP" links to the rendered API.md
  PASS  SC1: strip: the version is the edition's (v1.0.0) and links to the quickstart
  PASS  SC1: strip: "Source included" links to the licence answer on the page
  PASS  SC1: strip: the demo item links the demo and says it resets itself
  PASS  SC1: proof-first: the strip sits ABOVE the price box
  PASS  SC1: without proof.json the strip is absent — no typed fallback number
  PASS  SC1: a product with no shipped document at all (no tree) says so in its strip — the pre-release line, never a number
  PASS  SC1: the route /p/{slug}/{doc} exists and the controller product_doc() is defined
  PASS  SC1: /p/{slug}/manual renders the manual through the escape-first md renderer
  PASS  SC1: the manual page names the product and links back to it
  PASS  SC1: /p/{slug}/tests renders the run log verbatim-escaped with its run date
  PASS  SC1: an unknown doc name is the 404 page
  PASS  SC1: a product without a shipped manual is the 404 page, never an empty page
  PASS  SC1: bin/ownware-proof-collect.php exists, runs each product suite itself and refuses to write a proof for a failing or unparseable run
  PASS  SC1: collector parses "ALL 140 TESTS PASSED (0 failed)" (got array (
  'passed' => 140,
  'failed' => 0,
), want array (
  'passed' => 140,
  'failed' => 0,
))
  PASS  SC1: collector parses "124 passed, 0 failed" (got array (
  'passed' => 124,
  'failed' => 0,
), want array (
  'passed' => 124,
  'failed' => 0,
))
  PASS  SC1: collector parses "257/257 PASS, 0 FAIL" (got array (
  'passed' => 257,
  'failed' => 0,
), want array (
  'passed' => 257,
  'failed' => 0,
))
  PASS  SC1: collector falls back to counting PASS/FAIL markers when a suite prints no summary (got array (
  'passed' => 2,
  'failed' => 1,
), want array (
  'passed' => 2,
  'failed' => 1,
))
  PASS  SC1: collector returns null for output with neither summary nor markers (got NULL, want NULL)
  PASS  SC3: fixture: sc-invoicer sits in an active suite
  PASS  SC3: fixture: the paid order exists
  PASS  SC3: mail: subject says start here
  PASS  SC3: mail: the download link is first
  PASS  SC3: mail: the QUICKSTART travels inline
  PASS  SC3: mail: the manual and Connect-your-AI links
  PASS  SC3: a suite-upgrade code is minted at fulfilment (one per order)
  PASS  SC3: the code is worth exactly the paid amount (suite arithmetic, no typed money) (got 4900, want 4900)
  PASS  SC3: the code targets the best suite for the product (got 17, want 17)
  PASS  SC3: the code lives 30 days
  PASS  SC3: mail: the suite bridge names the suite, the code, the computed difference and the expiry
  PASS  SC3: mail: the difference is suite price minus what was paid
  PASS  SC3: mail: portal link + the licence-key ruling line survive
  PASS  SC3: minting twice returns the same code (idempotent)
  PASS  SC3: a product in no suite mints no code and its mail carries no bridge
  PASS  SC3: a suite order mints no upgrade code
  PASS  SC2: /thanks: the quickstart renders inline under the download
  PASS  SC2: /thanks: manual + Connect-your-AI links
  PASS  SC2: /thanks: the suite bridge with the computed difference and the code
  PASS  SC2: /thanks: "the other N" is counted from the catalogue
  PASS  SC2: /thanks/{unknown numeric ref} is the recording state, not a 404 (the webhook can arrive after the redirect)
  PASS  SC2: the recording state refreshes itself and offers /claim as the fallback
  PASS  SC2: the recording state is noindex
  PASS  SC2: a non-numeric unknown ref is still the 404 page
  PASS  SC3: routes /upgrade GET+POST exist
  PASS  SC3: /upgrade renders a code form
  PASS  SC3: lookup: a live code reports its suite, amount and the difference
  PASS  SC3: lookup: an unknown code is null
  PASS  SC3: request: marks the code requested and mails the owner the exact figure
  PASS  SC3: request: a second request on the same code is refused
  PASS  SC3: request: the wrong email is refused
  PASS  SC3: an expired code reads expired and is refused
  PASS  SC4: a guide that mentions a product links its demo, tagged guide/cta/{guide-slug}
  PASS  SC4: the demo link promises sample data and no sign-up
  PASS  SC4: the guide ENDS with the demo: the closer band carries the demo of the product it teaches
  PASS  SC4: gated — with demos_live = 0 a guide links no /demo/
  PASS  SC5: Deliora::numbersPayload() parses the form field: calc:<slugs> keeps only real calculator rows
  PASS  SC5: numbersPayload(): vs:<slug> for a product with priced rows; garbage -> []
  PASS  SC5: the numbers block is computed from the cited rows: rent/month, 3 years, own once, break-even
  PASS  SC5: the vs block lists every priced competitor of the product with its source
  PASS  SC5: notifySignup() stores the payload on the row
  PASS  SC5: the confirmation mail carries the numbers when a payload is stored — and only then
  PASS  SC5: the calculator carries the "email me these numbers" form with source=calculator and a numbers field
  PASS  SC5: calculator.js fills the numbers field from the ticked rows
  PASS  SC5: the rent-vs-own table carries the form with numbers=vs:{slug}
  PASS  SC5: the controller accepts the two new sources
  PASS  SC6: the price block carries the rent-vs-own anchor from the top cited row
  PASS  SC6: the anchor sits inside the price box
  PASS  SC6: the buy button answers the licence question: Single licence · one site
  PASS  SC6: overlay flag ships OFF
  PASS  SC6: with the flag off there is no lemon.js and no overlay class
  PASS  SC6: flag on + LS: the buy button is an overlay button on the LS URL and loads lemon.js
  PASS  SC6: flag on: the click still counts (beacon to /buy/{id}?ov=1) and Checkout.Success lands on /thanks/{order id}
  PASS  SC6: buy_target(): the beacon answers 204 and never redirects; a plain click is the 302 to the provider
  PASS  SC6: flag back off: no overlay markup
  PASS  SC6: the admin settings form saves the flag

————————————————————————————————————————————————————
ALL 3112 TESTS PASSED (0 failed)

← Back to Deliora · Manual · Quickstart · API

Affiliate program
Recommend tools people own — earn 35% on every sale. 90-day tracking, instant delivery, payouts by Lemon Squeezy.
Become an affiliate →