Releases, dated. Methodology never changes silently.
"Release-gated" is a core LEXUN claim; this page is its receipt. Every entry names the model versions it shipped and what changed. The full methodology lives on the Accuracy Centre.
| Date | Versions | Change |
|---|---|---|
| 2026-07 | runway@1.0.0 · core@1.0.0 | Initial release: seeded Monte-Carlo cash-runway model, evidence gates that refuse to run on unknowns, frozen resolution criteria, banded probabilities, reproducibility receipts. |
| 2026-07 | career@1.0.0 · learning@1.0.0 · intelligence@1.0.0 · governor@1.0.0 | Career financial-resilience model (buffer survival only — career "success" has no defensible base rate and is refused); outcome-gated learning layer; governor health checks. |
| 2026-07 | career@1.1.0 · opportunity@1.0.0 · challenge@1.1.0 | Independent deterministic cross-check on every simulation with material-disagreement display; major-purchase affordability model with break-even commitment. Test suite: 120 checks. |
| 2026-07 | reality@1.0.0 | Decision Reality layer: monitored assumptions with approximate validity thresholds, materiality engine, forecast versioning (v1 never rewritten), decision radar, trust receipts (SHA-256), .lexun package export, evaluation separated from outcome. Test suite: 233 checks. |
| 2026-07 | core@1.1.0 · vault@1.0.0 | The LEXUN Key: the dashboard's saved record is now encrypted at rest with AES-256-GCM under a key derived from your passcode by PBKDF2-HMAC-SHA256 at 600,000 iterations, using the browser's own WebCrypto. The passcode is never stored or transmitted, so an unlock is a real decryption rather than a removable check — and a forgotten passcode is unrecoverable, which the sign-up says in those words before it takes one. Core gains a persistence seam (setStore) and no change to any model maths. This release also required a Key before the dashboard would run a decision — a reversal of what this site previously promised, recorded in privacy and terms rather than quietly deleted, and itself half-withdrawn on 5 August 2026 (see below); reproducing a published result and inspecting accuracy, verify and trust stay open to everyone with no Key, because a claim you cannot check is not a claim. Also in this release: the homepage deck now verifies a receipt live in the visitor's own browser by running the engine twice and comparing the ids, and reports a failure if they differ; and audit/identity.py ships so the company number, registered office, VAT and ICO registration can only ever be published to all thirty-three legal-line pages at once. Test suite: 292 checks. |
| 2026-07 | site | Trust release: fabricated Labs metrics deleted; claims registry; robots allow-by-default; canonical extensionless URLs; shared chrome; self-hosted type; WCAG AA contrast pass; public Reproduce & verify page. |
| 2026-07 | site · cmd@1.0.0 | Navigation release: the command palette gains a visible control in the header on every page that ships one, so the feature exists for visitors who do not know the keyboard shortcut and for phones, which have no Ctrl key; the primary navigation drops from six links to five, with the API kept in the footer where it was already listed; the phone header is re-laid from four rows to two; and every page below the homepage gains a hand-written three-item "where to go next" rail above the footer, checked so that no page offers itself and no step points at a page that has since been renamed. The homepage globe now draws the same woven signal field as LEXUN Earth, from the same seeded algorithm rather than a lookalike. |
| 2026-08 | site · billing@1.0.0 | Payments release: a metered free allowance and a Stripe checkout, with every price and every sentence about cost read from one file so no page can disagree with the till. Checkout now carries the buyer’s reference, which Stripe will not accept after a payment has been taken, so payments can be matched to people later. The page shown after a card is charged was rewritten: it previously claimed features an upgrade does not unlock, and now shows the receipt reference, states that an upgrade removes the run limit and nothing else, and grants nothing at all when opened without a payment. Someone who paid on one device can restore their plan on another without paying twice, recorded as a declaration rather than as a Stripe payment so the two are never confused. The run limit is a request and not a lock, which Pricing and the Terms say in those words. Test suite: 333 checks. |
| 2026-08 | site | Layout release: the twenty-two different widths this site used to branch on were replaced by one ladder of seven, declared once as named parameters, and page padding, grid gaps and vertical rhythm were moved onto fluid clamp() values that interpolate across the whole range instead of jumping at a rung. Grids holding a variable number of items now fold on their own, because the column count is a consequence of the width they are given rather than of a breakpoint someone remembered to write. Eight checks police it: the build fails if any page or stylesheet branches on a width outside the ladder, if a parameter that should interpolate is replaced by a fixed value, or if an auto-folding grid lets a column outgrow the container it sits in. |
| 2026-08 | extract@1.1.0 · site | Correctness release. Two things the site was saying were not true of the code. First, the hero placeholder — the very first sentence a visitor is shown — could not be parsed by the engine it was demonstrating: "£12k a month in, £18k a month out" returned the cash figure alone and landed the flagship demo on INSUFFICIENT EVIDENCE. The extractor now reads direction (in/out, coming in/going out, inbound/outbound, burn, spend, MRR, turnover, take-home), the per-month idioms people actually type (pm, /mo, pcm, p.c.m.), dollars and euros as well as pounds, and horizons written as "over 18 months", "for 6 months", "in 9 months" or "by March" — the last resolved against the day you typed it and labelled an assumption rather than a fact, because a calendar horizon is relative. The regression test is not a hand-copied list: it scrapes every placeholder and every quick-start chip out of the shipped pages, routes each one through the real router, and fails the build if any example the site puts in front of a person cannot be read. A chip added tomorrow is tested tomorrow. Second, the home page promised "free, in your browser" and the button under it landed on a screen headed "Your decision record is locked". The door was the thing that was wrong: a simulation writes nothing, so nothing about running one needs a key. Framing and running a decision is now open, and the Key is asked for at the one moment it is load-bearing — pressing save, which is the first action that puts a record into storage and the point at which an unencrypted save would otherwise happen. The locked screen names the decision it is holding, and creating the Key completes the save rather than sending you back to press the button again. No model version, seed derivation or hash function changed, so every reproducibility id issued before this release still resolves to the same result. Test suite: 390 checks. |
| 2026-08 | path-trace@1.0.0 · site | Instrument release. The fan of paths behind the homepage result is now the model’s own output. It used to be re-simulated on the main thread from a second, hand-copied recurrence that had drifted — it ignored cost growth and committed inflows entirely — under a caption reading “real simulated paths”. A new module, path-trace@1.0.0, walks the trajectories with the same generator from the same seed as the result on screen, and the build fails if its survival verdicts ever differ, path for path, from the model’s. The five thousand paths stream from a Web Worker in slices of two hundred and fifty and are painted as they arrive, one slice per frame; the canvas’s spoken description is written after the drawing, from what was actually drawn. This release also repaired something this page had never noticed: the engine worker had never once run. Every engine module registered itself on window, which does not exist in a worker, so the worker died on load and every caller quietly waited out a four-second timeout before re-computing on the main thread. The numbers were always right — they were computed in the wrong place, at the cost of a frozen page. The modules now register on the worker’s own global, the results are proven byte-identical between the two scopes, and a test executes the real files in a real window-less scope so the mistake cannot come back silently. No model version, seed derivation or hash function changed; all 96 frozen reproducibility results resolve unchanged. |
| 2026-08 | site · earth-data@1.0.0 | Deep Earth release. The globe’s zoom range grows from 3.5× to 30× — space to city scale. Past country level a self-hosted layer takes over: 2,765 coastline rings from Natural Earth’s public-domain 10m dataset and 9,508 towns (the sixty most populous per country, GeoNames-derived), fetched from this origin only when someone first zooms past 2.2×, never on load and never from a third party. A “Fly anywhere” search — the rail’s first control — flies the planet to any of those towns with the same easing as a drag; the search runs entirely on the visitor’s device and matches carry their country so the eight Londons stay distinct. Past 6× the old 110m land pass is retired from the frame — it had become both a watercolour and a tax — and the 10m layer carries geography with its own land fill. |
| 2026-08 | site | Experience release. The homepage entrance is a photograph of Earth that is now alive: it breathes on a 34-second cycle, its real city lights — extracted from the photograph’s own pixels — shimmer and switch off and on, the sunrise glare pulses, and on scroll the planet pins in place while the words land on top of it. Page scrolling was handed back to the browser: the wheel-intercepting glide engine is gone, so ten flicks travel like ten flicks. Scenario switches roll their numbers to the new value instead of cutting; the receipt’s hash glyphs settle into place when a result is minted. Every result links its model’s stated weaknesses; the command palette gains a topics tier (glossary terms, template sections, models, all anchor-checked by the build); both billing cycles and the three-run free allowance are stated in plain text; and the changelog and forecast register gain RSS feeds. All reduced-motion paths preserve the information without the movement. Test suite: 390 checks. |
| 2026-08 | site | Instrument-panel release. Every place a person types a decision — the homepage Analyse box, the workspace question and framing statement, the assistant, the Earth’s fly-anywhere search — now shares one command-surface treatment: glass depth, an accent caret, and a focus ring that arrives on a 180ms ease. The three example chips compute their own probability bands in the visitor’s browser over the engine worker and wear them; a build check proves each badge equals the engine’s own output to the character. The top drivers on every result grew sliders: dragging one re-runs the frozen model with that single input shifted by up to ±20%, the resulting band lands beside it labelled modelled, the scrubbed value is classified as an assumption, and the receipt — which describes only the run that was frozen — never moves. The workspace result on /platform carries the same scrub, wired to the same worker. Also in this round: /world now 301s to /earth, the sitemap and feeds carry explicit content-types, the contact page gained a two-field door for individuals, /accuracy gained a watch-the-record signup that admits its zero, both billing cycles and founding-member pricing are stated in plain text, guides carry visible last-updated dates and Article markup, and the one intermittent page error the site ever threw — a race between the lights engine’s observer and its lazy boot — was found by the verification sweep and fixed. Test suite: 390 checks. |
| 2026-08 | site | Fewer words, same meaning. The homepage lost 13% of its copy and the pricing page 11%, without losing a single claim: sentences that explained twice now explain once, and the decision record’s twelve-row inventory dropped the three rows a reader can already see in the exported JSON. Pricing’s internal architecture commentary — the paragraph explaining why a static site cannot enforce a paywall, and the one about seat provisioning — is now a sentence each with a link to the trust centre, which is where an architecture explanation belongs. The disclosure itself stays word for word, because a test guards it: delete the sentence saying the gate is not a lock and the build fails. Two tests caught real drift during the edit — the FAQ structured data still carried the old question text, and its answer differed from the visible one by an em dash. Schema that disagrees with the page is the kind of thing search engines notice and readers never do. |
| 2026-08 | site | The planet at native resolution. Filling the width exposed a compression decision made when the film was letterboxed: it had been encoded at 1080×1080 to keep the page light, which was fine inside a 900px box and soft the moment it spanned 1920. The film is now encoded at its native 1440×1440 at a much higher quality setting — upscaling on a 1920px screen falls from 1.78× to 1.34× — and wide screens receive it while phones keep the lighter file, because a 1440-line planet on mobile data buys nothing a 390px screen can show. Both codecs match: 8.7 MB H.264 and 4.6 MB VP9, so a browser without licensed H.264 gets the same detail rather than the fallback it used to get. Day-long cache headers on all four files. |
| 2026-08 | site | Full-width planet, and type that answers the width. The hero band was already the full width of the page, but the film inside it was letterboxed to the shorter side — so on a 1920px screen the black field ran 1920 wide while the planet painted 898 in the middle of it. On a landscape viewport the film now covers: it spans the page edge to edge and crops top and bottom, which is what makes it read as an environment rather than a globe centred in a wide dark field. Portrait keeps the contained fit, because cropping a tall phone would cut the planet’s edges off and seeing it is the entire point. A responsive type scale went in behind it on 34 pages: every size clamps between a mobile floor and a desktop ceiling, so one rule serves 320 and 2560 without a breakpoint each, and body stops growing around 20px — a paragraph does not become more readable at 30px. Headings, leads, tables, buttons, inputs, footer and navigation all move together, and inputs never fall below 16px, which is what stops mobile browsers zooming on focus. Verified: zero horizontal overflow at all seventeen widths, and zero WCAG violations across 37 pages. |
| 2026-08 | site | Legacy /app closed, and one absolute claim withdrawn. The retired /app tree was still publicly reachable on the deployed site, serving a product this one contradicts — billions of simulations, millions of active users, 195 nations, 71% accuracy, thousands of verified sources. It never appeared in any scan because it exists only on the deploy, not in the source. /app, /app.html and every path beneath /app now force-redirect to /platform, and /labs with them. The homepage described the Decision Reality Loop as “the part nobody else ships”. That is a claim about every competitor and cannot be substantiated, so it now reads “the loop LEXUN is built around” — which is true and needs no one else’s permission. The contradiction engine gained a rule for absolute competitor claims, proven by restoring the old wording; it also had to learn that “nobody else has any right to enforce them” in the terms is the Contracts (Rights of Third Parties) Act talking, not a boast. |
| 2026-08 | site | The Prediction Ledger. The register is still empty, and the honest thing is to say so — but the infrastructure a first forecast needs now exists, so that entry can be frozen properly rather than added to a file invented afterwards. A forecast carries a band and never a point estimate, a resolution criterion and named source written before the answer is known, a data cutoff, and a receipt hashed over its frozen fields. The gate refuses seven things outright: a forecast issued after its own due date, a point estimate wearing a band, a missing criterion or source, an immutable field edited after freezing, a resolution with no evidence, a withdrawal with no reason, and a ledger that has shrunk — entries are never deleted, and a correction supersedes rather than replaces. Each rule was proven by violating it and confirming the build fails. No accuracy figure may be computed below ten resolved outcomes per domain, which the gate also enforces rather than merely promising. |
| 2026-08 | site | Width release, and an iPad bug that was live. The site now resolves to one grid: --page-max 1600px for the product field, --content-max 1440px for demonstrations, --reading-max 800px for prose — because a 1600px paragraph is unreadable at any budget — and a gutter that scales with the viewport instead of stepping at breakpoints, which is what stopped 1280 looking like a squeezed 1440. Header, sections and footer share it, so the logo and the footer align. Building it found a defect that was already live: at 1024×1366, iPad portrait, the homepage scrolled sideways by 116px. The desktop navigation engages at 64rem but its intrinsic width was 1099px, so for anyone on an iPad the page simply did not fit. The nav’s rhythm now scales with the viewport and the brand descriptor stands down between 64 and 90rem, where the row has no room for it. Verified across all seventeen supported widths from 320 to 3440 on five pages: zero horizontal overflow anywhere, prose holding its measure, and the header field using 83% of a 1920px screen. |
| 2026-08 | site | Production Maturity instrument. LEXUN now measures itself against eleven pillars — correctness, reliability, reproducibility, evidence, model, decision, privacy, security, experience, reality and learning integrity — and every figure is read out of a gate that actually ran. A pillar with no evidence gets no number: privacy integrity reads asserted, not proven because the automated network-assertion gate is not built; reality and learning integrity read zero, honestly, because calibration needs ten resolved outcomes per domain and none exist. Four of eleven are measured and passing; the rest are named rather than scored. The instrument earned its place on first run by catching a browser harness that reported 15 of 17 under load and 17 of 17 alone — a flaky test, which is a defect and not a mood. Its fixed waits were replaced with waits on the fact being tested, since a fixed two seconds is a guess about how fast a software decoder is today. It is an engineering instrument and is never published as a marketing figure. |
| 2026-08 | site | Zero-Fault Release Gate. Every check LEXUN owns now runs from one command and answers one question: GREEN, or BLOCKED. Twenty gates — the 390 engine checks, the 96 frozen results, the contradiction engine, a new legacy/placeholder/hype scanner, four content audits, WCAG across 37 pages, 26 user journeys, the paid door, and the result, entrance, mobile and control harnesses — run in order, and a critical failure blocks the release rather than printing a warning someone can scroll past. A gate that cannot run says so; an unrunnable critical gate blocks. This exists because the list got long, and a release that depends on remembering a long list eventually ships the thing nobody meant to ship. The new scanner refuses three kinds of text that outlive the truth: a retired identity’s claims, placeholders that reached production, and language a forecasting product cannot support at any sample size. Like the contradiction engine before it, it had to learn precision before it was worth running — a reserved example address inside a form placeholder, a URL shape in a code comment, and the claims registry’s own record of what was deleted are all correct uses, and a scanner that fails on those gets switched off. It was then proven by injecting a legacy claim and confirming the gate caught it. |
| 2026-08 | site | Truth Lock release. LEXUN now has one canonical source for every public product fact — truth-registry.json — and a contradiction engine that reads all 37 pages against it at build time and fails the release rather than warning. It was written because the site had genuinely contradicted itself: /security said a LEXUN Key gated who may run the engine, while /plans and the workspace said running needs no Key at all. Both sentences were written carefully; neither had been checked against the other. The registry now states it once — no Key to run, a Key to save — and the gate enforces it. Fixed in the same pass: the pricing page called the models “validated” while the Accuracy Centre correctly reports zero resolved outcomes, so they are now described as released and test-gated, with the difference spelled out; /status claimed there is no backend to be down, which is true of the simulation engine and false of the assistant, the forms and payments, so the page now carries a per-component table naming each one and how it fails; and the company record is published in full — CA Capital Limited, registered in England and Wales, company number 10848369, registered office 320 Firecrest Court, Centre Park, Warrington, United Kingdom, WA1 1RG — replacing the placeholder that stood on 36 pages. ICO registration ZC183768. The gate was then proven by reintroducing each contradiction in turn and confirming it fails the build; it also had to learn the difference between a claim and a quotation, and between a present-tense claim and a dated history row, because a checker that cries wolf gets switched off. |
| 2026-08 | site | Survival & coverage release. Two things every serious reader of a probability asks next are now answered on the result itself. When does it stop holding? Runway results draw a survival curve read out of the same five thousand seeded paths the probability came from — the share still solvent at each month — plus the end-cash tail at the 5th, 25th, 50th, 75th and 95th percentiles. Nothing is modelled or smoothed: every figure is a count over those paths, and the final month equals the published probability by construction, arrived at from the opposite direction. Building it found a real off-by-one — the walk stops at the month cash first reaches zero, so that month is the failure, not survival — which had put the curve three points above the number it is supposed to equal; the harness that caught it now enforces the identity on every run. Models whose recurrence this is not show no curve rather than borrowing one. What does the number actually cover? Every result now states, in its own model’s terms, what the probability is about and lists concrete things it does not contain — customer demand, execution, emergency funding, regulation, litigation, illness. A model that listed nothing there would be claiming to model everything. |
| 2026-08 | site | What-would-change-my-mind release. Every workspace result now answers the question a probability provokes: what would have to become true for this answer to be different? For each of the top drivers the engine walks that one input outward and re-runs itself over the worker, reporting the smallest single move that changes the published band — separated into what would improve the answer and what would break it, the second being the list worth monitoring. Every line is the engine’s own output on the same seed derivation, verified by a harness that independently re-runs the model at each stated value and demands exactly the band the line promises; a driver that never crosses a band inside a 50% move says so rather than rounding into a claim, and a threshold that prints the same as today’s value is dropped rather than sold as a target. The engine worker gained an optional passthrough token so a batch caller can tell answers apart — callers that send none receive the same bare result as before, and the frozen 96 remain unchanged. Accessibility: an axe-core sweep of all 37 pages against WCAG 2.1 AA now reports zero violations. Fixed in this round — ten named regions whose labels screen readers silently discarded, three charts that now speak their actual numbers rather than their titles, an Earth detail panel that was hidden from screen readers while still reachable by Tab, an ARIA attribute illegal on its role, and prose links across the site distinguished only by colour on a monochrome palette. |
| 2026-08 | site | Living planet release. The homepage Earth is now a film, permanently: a seamless 13.8-second loop of the planet at night — the close pass over the lit cities, the pull-back through the sunrise, the full globe, dissolving back into the flight — playing muted, forever. No frozen frame and no still photograph ever shows while video can play; the page opens on black space and the film lights it. A still cut from the film and a city-light shimmer measured from that same frame exist only as fallbacks, for reduced motion, Save-Data, slow connections and playback failure. The previous photograph, its blurred loading placeholder and the old social-share card are all retired — og.png is recut from the film’s own frame. The film ships as 1.9 MB H.264 with a 1.7 MB VP9 companion for browsers without licensed codecs, and the service worker steps aside for media entirely: it used to intercept the film’s ranged requests and could answer a failed one with the homepage HTML, proven fixed by a harness replaying the film across three worker-controlled visits. The shot is as wide as the screen: the film sits in the largest centred square that fits, its outer 4% fades through a mask, and a tiled CSS starfield continues its stars across the full hero on every aspect ratio — desktop, laptop and phone verified with zero horizontal overflow. Where autoplay is refused — iPhone Low Power Mode does this even for muted video — the page shows the living still and starts the film on the first touch instead of giving up. The film also learned to husband power: it pauses the moment it is scrolled out of sight or the tab is hidden and resumes exactly where it left off, and the city-shimmer engine draws nothing while the film is on duty. And every interactive surface on the site was walked end-to-end as a user in an automated journey audit: the search palette on multiple pages (including its honest empty state), the homepage chips and inline console, all three engines run twice to prove identical reproducible answers, template deep-links, the jobsafe quiz’s qualitative bands, the verifier passing a live sample and loudly failing a tampered one, and the assistant’s refusal to invent a reply when its backend is absent. Also fixed: the mobile menu’s close control was buried beneath its own overlay — the menu now carries a visible Close button inside the dialog, 44px tall, focus-reachable. |
| 2026-08 | site | Hardening release. The assistant endpoint’s gate gained a speed bump: at most ten requests a minute per visitor, answered with 429 and Retry-After and a sentence that says why — best-effort per warm instance, and described as exactly that in the source rather than dressed up as a distributed limiter. The pricing page now opens its three doors by name — individuals, organisations, education — each routed to its own page, and the OpenAPI contract’s security scheme now states in the contract itself that keys ship with paid plans only. The service-worker cache stepped to v78 so returning visitors pick up this release cleanly. |
| 2026-08 | site | Audiences & the gate release. LEXUN now speaks to three audiences by name: /individuals — the full engine, free and private in the browser, with what stays free and what costs money stated plainly — and /education — the engine as a teaching instrument for probability, calibration and evidence discipline, with three classroom exercises that work today and the limits (no LMS, no gradebook) stated in the same breath — joining /enterprise. Every footer on the site now routes all three, and the homepage engine rail closes with the trio. On the money: the site’s one paid server endpoint, the assistant function, now refuses requests that do not come from this site’s own pages — each call costs the operator a real API fee, so the gate is an Origin/Referer allowlist answering 403 with an honest explanation. /api now states outright that there is no free public endpoint and never will be: hosted keys ship with paid plans only, and the request-access door leads to the contact page. |
| 2026-08 | site | Workspace engine release. The framing view at /platform#new now answers while you tune it: any edit to a field re-runs the engine over a persistent worker and lands a preview band beside the Run button — labelled unfrozen, never billed, with the evidence gate speaking through it so a form of pure assumptions previews as the refusal it would earn. Every runway result draws its five thousand futures live — the same streamed fan the homepage carries, from the same seed as the result above it, survivors in white and failures ending at the dashed £0 line, with the spoken description written from what was actually drawn; other models hide the card rather than borrow a walker that is not theirs. Ctrl+Enter runs the simulation from anywhere in the form. Test suite: 390 checks. |
| 2026-08 | site | Accuracy scorecard, and one alignment defect closed site-wide. Every result in the workspace now carries a scorecard that states, in six separate rows, what can and cannot be said about its reliability: how many of the inputs are stated facts rather than assumptions, how far the biggest driver can move the answer against the width of the published band, how far the simulated paths spread around their own median, which model version produced it, the seed and input hash that reproduce it, and — last, and deliberately not averaged in with the rest — whether any of it has been checked against reality. That final row reads NOT YET VALIDATED because no forecast has yet met its resolution date. It is not written into the page: it is read from the local ledger every time a result is drawn, and the same code prints a measured Brier score the moment ten outcomes are resolved. The six rows are not collapsed into a single score, because a single score is exactly how weak evidence gets laundered into apparent confidence. Where a run’s median outlasts its own horizon the spread row says so rather than quoting a number the simulation did not measure. Thirty-four checks police it, including that the figures it prints are the same ones the verdict card prints. Separately, the header and the footer disagreed about where the page begins: the header held its gutter inside the 1600px field and the footer held it outside, so the footer sat up to 162px to the right of the logo at 1920px, on every page. Both now resolve to one rule, checked at seven widths on every page. The lead paragraph under each page title was also running to 79 characters at wide sizes, because a measure set in ch grows with a font that scales with the viewport; it is now capped by both. No model version, seed derivation or hash function changed; all 96 frozen reproducibility results resolve unchanged. Test suite: 390 checks. |
| 2026-08 | site · truth-registry@2 | Truth Lock II — the gate failed, and this is the repair. A reader audited the live site and found five contradictions on pages the contradiction engine had just declared clean: About, Privacy and Terms all said the company number and registered office were “not yet published” while the footer of those same pages printed both; /enterprise said “nothing reaches LEXUN’s servers — there are none to reach” while /security documents four network components; /platform said every forecast is scored in public when personal forecasts are private and local; /individuals sold the career model as “the honest odds of landing where you aim” when that model reports buffer survival and the Accuracy Centre says so; and /templates advertised routing a question to the “closest model”, which is the exact behaviour the engine’s refusal logic exists to prevent. Every one was inside the scanner’s stated remit. It caught none of them, because the company rule matched one exact placeholder sentence and the other four rules did not exist. All five sentences are now corrected on the page, nine new rules are in the engine, and the registry gained model scope, routing policy, form processor, analytics and legal-version facts to check them against. The important change is audit/mutate.py: it re-injects twenty-one defects — one per rule — into a scratch copy of the site on every release and fails if the gate does not catch each one and name the right rule. It immediately found a hole nobody had noticed: the model-count rule’s word list stopped at “five”, so a page claiming “seven decision models” passed. Also in this release: the dormant third-party analytics loader was deleted from the bundle rather than left switched off; the storage banner no longer says “essential storage only” when the inventory below it lists functional and preference keys; /contact names the form processor instead of saying nothing is shared; /verify claims what a content hash can actually prove — that the contents match the sealed hash, not that they are unchanged since writing, which needs a signature and a timestamp that do not exist; the classroom exercise on /education uses the worked example rather than a public register that is still empty; the major-purchase model explains that opportunity@1.0.0 is its internal id and will not be renamed because receipts resolve against it; and Privacy, Terms and Cookies are re-dated with a change summary, with the 29 July text kept unchanged at /legal/. No model version, seed derivation or hash function changed; all 96 frozen reproducibility results resolve unchanged. Test suite: 390 checks. |
| 2026-08 | site · earth-loop@2.0.0 | One full turn. The homepage planet was a fifteen-second clip that rotates about seventy degrees and stops — measured, not guessed: tracking the surface across its own frames gives roughly 0.19° per frame over 361 frames. Looping it meant snapping the planet back four-fifths of a turn every thirteen seconds, which is the “turn and come back” that had been reported four times. A crossfade only smears that snap; it cannot invent the missing 290 degrees. So the turn was rendered instead. Frame k is the planet rotated by exactly 2πk/720, which makes frame 720 the same picture as frame 0 — there is no seam to hide because there is no seam, and the measured difference across the join is smaller than the difference between any two ordinary frames. It is built from NASA Visible Earth imagery in the public domain — Blue Marble surface, city lights, cloud layer, topography and a water mask — shaded with a physical model rather than a filter: Lambert diffuse from a sun fixed in space so the terminator sweeps the surface and returns exactly where it began, a soft terminator, city lights only where the sun has actually set, sun glint restricted to water, relief from the topography, and an atmosphere whose inner haze and outer halo both follow the view and sun angles. Nothing about it is AI-generated and nothing about it is stock. The film is 1600×1600 for desktop and 1080×1080 elsewhere, up from 1440, and because it is rendered rather than re-compressed there is no generation loss in it. The whole planet now fits the page at every screen shape: a rule forcing object-fit:cover on landscape was there because the old film was a cropped close-up that had to fill its box, and applying it to a film of the whole globe simply cut the poles off. Eight checks police all of this from pixels, in the browser, on every release — that the join costs less than one frame, that the middle of the film is a different face of the world, and that the quarter and three-quarter points differ, which is what separates a turn from a pendulum. All three were proven by building the broken films and confirming the gate rejects them: a ping-pong cut fails the pendulum check, a film trimmed short of a full turn fails the join check. The poster stills, the social card and the inline placeholder are all regenerated from the new film, so no surface still shows the old one. No model version, seed derivation or hash function changed. |
| 2026-08 | site | The entrance film is reverted to the one that stood before earth-loop@2.0.0. The rendered 360-degree globe solved the problem it was built for — it is a genuine full turn and its loop has no join — and it was rejected on look, which is the owner’s call to make and not something a measurement settles. The previous film is restored byte-for-byte, along with the poster stills, the social card, the inline placeholder and the landscape fit rule that suits a close framing rather than a whole disc. The trade-off comes back with it and is recorded rather than glossed: this film contains roughly seventy degrees of rotation, so it cannot loop without returning, and the return is covered by a crossfade. truth-registry.json now states that plainly — completes_full_rotation: false, loops_seamlessly: false — so no page can describe the entrance as a seamless turn. The check that proved a full rotation was removed with it: a gate that cannot pass against what actually ships would block every future release, and a gate kept green by not running it is worse than no gate at all. Everything else from the two releases either side of it stays: the accuracy scorecard, the contradiction rules, the mutation tests, the header and footer alignment, and the corrected storage and company wording. The earlier entry for earth-loop@2.0.0 is left standing above, because the changelog records what was released, not what was kept. |
| 2026-08 | site | The ICO registration is now a single switchable fact rather than a paragraph someone has to remember to rewrite. truth-registry.json holds the reference, the status and the fee tier; audit/ico.py records an issued reference and rewrites the Privacy Policy paragraph in one command, with a link to the entry on the ICO’s own register so a reader can check it rather than trust this site. Five rules police it in both directions, because a status that can change is a status that can drift: while no reference is held, no page may print anything shaped like one — a plausible Z-number is exactly the detail that gets typed in early to look finished — and the policy is required to keep saying registration is not yet in place; once a reference is held the pending wording becomes the falsehood, and the policy is required to carry the real number. No page may claim a fee exemption while the registry claims none. The registry must also agree with itself: registered with no reference, a reference held while the status still says pending, and a reference that is not an ICO reference are all build failures. That last set exists because the mutation tests found the first version of the rule read “no number held” and silently skipped, so an inconsistent registry disabled the very check that depended on it. The switch was rehearsed on a copy of the live site — on, off and back — with the gate green in both states and the original paragraph restored byte-for-byte. Mutation coverage is 27 injected defects, 27 caught, and the ICO mutations follow the registry’s actual state so they keep testing the right half on the day the fee is paid. Nothing here claims a registration that does not exist: the status is still pending, and the site says so. |
| 2026-08 | reality@1.1.0 · site | The Decision Reality Loop section on the homepage is live rather than a diagram of one, and getting it there meant building three things rather than relabelling them. The record already stored what was forecast and what happened; it rated how WELL an action was carried out without ever recording WHAT the action was, so the evaluation gains a free-text account of what you actually did and a separate free-text account of why reality differed — separate from the error taxonomy, because the taxonomy is for counting across decisions and the sentence is for understanding one of them. Lessons stopped being a list filed behind the loop: lessonsForDomain puts your own words from resolved decisions in the same domain on the framing screen, above the inputs, before the run — the only moment a lesson is any use. Those three rows were badged PLANNED, and two of them had been wrong for weeks. The four figures under “the public record, today” were typed into the HTML; a typed zero is exactly right for as long as the register is empty and becomes false the hour the first forecast is frozen, on the page nobody would think to go and correct. They are read from forecast-ledger.json at load, with the Brier score computed from the resolved entries and the minimum sample taken from the ledger’s own rule; if the file cannot be read the shipped markup stands, because a network hiccup must never invent a number here. Beneath it the visitor now sees their OWN record — frozen, resolved, and how many have reached the date they froze — read from their browser, never transmitted, and hidden entirely until they have one, because a row of zeros aimed at a first-time visitor is a scolding. A new rule ties every badge in that list to the code that writes the field: a LIVE badge for a field nothing writes fails the build, and so does a PLANNED badge for a field the engine already writes — understating is a contradiction too, and it is the one that hid three finished features. Thirteen browser checks police the section from pixels and state, including that a populated ledger moves the homepage with nobody editing it, that the Brier shown is the Brier of the data, and that a visitor’s private record never leaks into the public figures. Mutation coverage is 29. No model version, seed derivation or hash function changed; all 96 frozen results resolve unchanged. |
| 2026-08 | site | The entrance fills the screen. It had not been: the header took 64px of flow before it, the picture was given a box 100svh tall starting underneath that, and a scroll hint was given a row of its own — 118px of a 1080px screen spent on a 47px label. Add the mask that faded the top and bottom four per cent to transparent and the film reached neither the top of the screen nor the bottom of it, with black bands at both. The film now starts at the true top with the header floating over it, the hint shares the picture’s cell and sits low in the frame with its own shadow — a shadow rather than a plate, because a box would be a bar across the shot — and the vertical fade is gone. The shared box the film, the still and the shimmer live in was the largest centred square, which on a portrait phone left 170px of black under the planet; it fills the field now, and the film covers at every shape rather than only in landscape, which crops ocean and sky rather than any pole because this film is a close framing of the planet and not the whole disc. Measured after the change: the picture reaches every edge at 1920×1080, 1440×900 and 390×844 with nothing above it and nothing below. Two checks had to change with it, and both were rewritten to the new intent rather than relaxed: one asserted the hint sat under the planet, which is the layout that was just removed, and now asserts it sits low in the frame AND carries the contrast it needs to be read over a film that ranges from black ocean to a lit sunrise limb; the other sampled the letterbox margin beside the planet for stars, and those margins no longer exist, so it now asserts the shimmer is alive and drawing across the whole field — which is what it falls back to if the film ever fails. |
| 2026-08 | site · forecast-ledger | The public forecast register is open. Six forecasts were frozen on 14 August 2026, ending the state this project had been in since the register was built: the machinery finished, the page written, and nothing in it. They are questions settled by named official sources on dates already in those bodies’ published calendars — the Bank of England’s September and November rate announcements, the ONS’s July CPI and its labour market release, and the Insolvency Service’s monthly company insolvency statistics. For every one, the criterion and the resolution source were written before the probability, which is the order that stops a question being quietly shaped to fit the answer. The bands are deliberately spread: one sits at 42–58% because a register made only of near-certainties cannot demonstrate calibration in the middle of the range, and the honest thing to do with a question nobody knows the answer to is to say so and be scored on it. Two carry explicit withdrawal clauses — if the ONS stops publishing a headline unemployment rate, or an announcement is postponed, the entry is recorded as unresolvable rather than scored as a hit or a miss. audit/forecast.py is the issuing tool: it refuses a point probability, a band narrower than two points or wider than thirty-five, a due date already past, a data cutoff after the moment of issue, a missing criterion or source, a reused id, and a probability with no stated reasoning. It does not choose questions and it does not choose numbers — a person does both, and reads the draft before it freezes. The register page renders from forecast-ledger.json rather than from a second copy in the HTML, and so does the homepage counter, so there is one place these numbers live. A new rule polices the register’s own state in both directions: while entries exist no page may say it is empty — five pages said so and became wrong in the same minute — and while it is empty the register page is required to say so plainly. These are judgement forecasts about public statistics and they are scored on their own scoreboard: being right about the Bank of England would say nothing about whether the cash-runway model works. No accuracy figure will appear until a domain reaches ten resolved outcomes; today the count is still zero, and the first answer arrives on 18 August. Mutation coverage is 31. |
| 2026-08 | forecast-ledger | Provenance made mandatory on every public forecast, hours after the first cohort was issued and before anything resolved. The entries already carried model: judgement, which is provenance if you know to look for it; the failure it does not prevent is six months out, when a table reading “0.11 Brier over 18 outcomes” would be literally true and would read to every visitor as evidence that the ENGINE is calibrated — when an operator produced every one of those numbers by judgement about public statistics, and none of the three decision models forecasts CPI, Bank Rate, unemployment or insolvency counts. Every record now names its forecaster and its scoreboard, states what it is not evidence for, and the register page prints all three on the card rather than leaving them in the JSON. Scores are never pooled across boards. The issuing tool refuses an entry without provenance, the ledger gate refuses a file containing one, and assigning a judgement forecast to a model board is a build failure — each proven by stripping the field and watching the gate fail. The receipts are unchanged: they seal the claim — question, band, criterion, dates — and this is a label on the claim, not part of it. Credit where it is due: this hole was found by a second review of the brief, not by the gate, which had no rule for it because there had never been a forecast to mis-attribute. |
| 2026-08 | forecast-ledger | Two published forecasts withdrawn the day they were issued, and why. An external review of the first cohort checked the reasoning on the two Bank Rate entries against the July 2026 MPC minutes. Those minutes record a 6–3 vote to hold with three members — Greene, Mann and Pill — voting to increase Bank Rate to 4%, and the Committee judging inflation risks tilted to the upside. Both entries had reasoned the opposite: that falling CPI and a softer labour market made a cut the live alternative to a hold. One of them, at 88–96% that Bank Rate would not rise by 5 November, was not a width error but a directional one, and the corrected figure is roughly 47% — a forty-five point revision. Both were withdrawn with the reason recorded, both stay in the ledger permanently, and both are superseded by entries that name the hike as the tail and cite the vote. The minutes were verified directly rather than taken on trust. Then a second, worse error: the withdrawal notes originally read “withdrawn before publication”, and that was false — the cohort had already been deployed and both entries were live on the site when they were withdrawn. A withdrawal note that understates how far a wrong forecast travelled is the same class of defect as the forecast. The notes now say so, the entries carry was_published: true with the evidence, and the ledger gained a _corrections log recording the change rather than absorbing it. Two code defects fell out of the same exercise: the homepage counter filtered on superseded_by, which is written on the replacement rather than the entry it replaces, so a withdrawn forecast would have gone on being counted as open — found only by withdrawing one; and the check that guards that counter had the same blind spot and agreed with it. Both fixed. The register now shows withdrawn entries in place, marked, with the reason readable on the card. Separately, a critique that this cohort’s insolvency band spans nearer 98% than the 80–90% stated is recorded against that entry and the band is being left as issued: a band widened by caution and then narrowed once someone notices is a band chosen to look good, and if it resolves comfortably inside, that is evidence of under-confidence which belongs in the calibration record. |
| 2026-08 | forecast-ledger | A third forecast withdrawn, for a defect nothing in the tooling could see: lxf_external_005 was issued and published with a due date of 08:00Z, and the Insolvency Service publishes at 08:30Z. The forecast was unresolvable at its own deadline, thirty minutes before the only source that can settle it. The only clock check the issuing tool had was “is the due date in the future”, which it was. Verified from the GOV.UK content API, which gives first_published_at 2026-07-17T09:30:04+01:00 for the June release. Due dates are immutable, so this is corrected by supersession and not by edit: lxf_external_009 carries the same question, the same band and the same criterion with a reachable deadline. Entries now declare source_publishes_at, and both the issuing tool and the ledger gate refuse a due date that arrives before it or within thirty minutes of it — proven by moving the corrected entry back to 08:00Z and watching the gate fail. Separately, the Bank of England’s July 2026 Market Participants Survey turned up after issue, giving a median expected Bank Rate of 3.75% at the September, November and December meetings. That points the opposite way from the 38–56% on lxf_external_008 and suggests yesterday’s correction may have overshot. It is recorded against the entry and the band is not changed: the survey was fielded before the 30 July minutes it would be used to argue with, and re-issuing a forecast every time a datapoint arrives is how a register stops meaning anything. If it resolves TRUE the record will show a band moved too far on one document, and that is a lesson worth keeping. Three of the first cohort of six have now been withdrawn within a day of issue — a bad look and an accurate one, and the register shows all three in place with their reasons readable. |
| 2026-08 | forecast-ledger | A fourth withdrawal, and the more useful finding is about the gate rather than the forecast. lxf_external_008 had a due date of 2026-11-05T12:00:00Z. The Bank of England publishes at 12 noon UK and British Summer Time ends on 25 October, so on 5 November noon UK is 12:00 UTC: the deadline was the publication instant itself, zero margin, against a rule written hours earlier requiring thirty minutes. Same root cause as the withdrawal before it — a deadline set off a UK wall-clock time without carrying the offset through — and one hour short of biting instead of thirty minutes past it. Superseded by lxf_external_010: same question, same band, same criterion, an hour of margin. The gate built that morning for exactly this defect could not see it, because source_publishes_at was optional and only the entry written after the rule declared it. An optional gate is a decoration: it fires when someone remembers, which is the case where it was never needed. The field is mandatory now — in the issuing tool and in the ledger gate, which refuses any open entry that cannot state when its own source publishes — and the verified instants are recorded on all six open entries: 06:00Z for the two ONS releases, 08:30Z for the Insolvency Service, 11:00Z for the September MPC and 12:00Z for November. Three clock defects were injected and all three caught: zero margin, a missing instant, and a deadline before publication. Four of the first cohort have now been withdrawn within a day, none of them for the number being wrong and three of them for the clock. |
| 2026-08 | audit/resolve.py | Resolution built four days before the first outcome needs it. Issuing had a tool and withdrawal had a tool; resolution — the verb the entire register exists for — would have been a hand-edit of the ledger at 07:05 on results morning, under time pressure, against the one file whose whole value is that nobody ever hand-edits it. audit/resolve.py resolves an entry true, false or disputed. It refuses to score a withdrawn forecast, refuses a second outcome forever, refuses a resolution recorded before the source publishes, refuses evidence from any host other than the frozen resolution source or its stated fallback — if the named source is gone, that is a withdrawal, not a substitution — requires the figure as first published and the sentence it came from, and re-verifies the receipt before appending, so a tampered entry cannot be resolved at all. Ambiguity records as disputed and is never scored. All nine refusal-and-success paths were rehearsed on a scratch copy and every one behaved. The rehearsal then paid for itself twice over: the homepage counter read the outcome as a bare number when the real record is an object, so the Brier sum would have been NaN the morning the first outcome landed, and a disputed entry would have been counted — and rendered on the register page — as “criterion met”, because the string “disputed” is truthy. An ambiguous outcome displayed as a hit is the exact dishonesty the disputed state exists to prevent. Both fixed, and the browser checks now serve the real record shape, disputed entry included. The scoreboard prints per board, never pools, and attaches “descriptive only, no accuracy claim” to any board below the ten-outcome minimum. |
| 2026-08 | site · docs | Roadmap and tasksheets reconciled to the code, and the reconciliation gated. The public roadmap carried three claims that had quietly gone stale: the forecast register listed as BUILDING when it opened on 14 August with ten entries and full issue/withdraw/resolve tooling; the entrance described as a “seamless film loop” when the truth registry records it as a partial rotation with a crossfaded join; and “twenty gates behind one command” when the file runs twenty-five. All three corrected, and the third class is now self-checking: the contradiction engine counts the gates in release-gate.mjs itself and fails the build if any page publishes a different number — the same self-counting trick the engine suite uses for its own check count, added with its mutation and proven firing. Building-next now names the true next steps: the first resolved outcomes on 18–19 August, the Calibration League, and ICO registration marked BLOCKED — EXTERNAL ACTION, because code cannot pay a fee. The three internal sheets that ship in the deploy folder — PLATFORM-ROADMAP.md, AUDIT.md, LAUNCH.md — were reconciled from their 31 July state (333 checks, hand-run audits) to today: 390 checks, 25 gates, the register open, four withdrawals kept visible, and a known-debts list that names what is still wrong rather than trailing off. The 31 July narratives are kept as written where they are history; only counts and supersessions were annotated. |
| 2026-08 | site | The Evidence Hunter: “what to verify before you decide”, measured. Every result has carried the same typed sentence claiming to name the single most valuable evidence to add — one sentence, all results, never computed, the exact naked-prose pattern this site criticises elsewhere. It ships inside the engine’s frozen output, so editing it would move 96 frozen reproducibility results; the page now out-argues it with measurement instead. Only inputs the person classified as ASSUMPTIONS are candidates — a fact does not need verifying, and listing one would teach people to distrust their own records. For each assumption the real model re-runs at the edges of a plausible error range, same seed: ±25% for money, the sensitivity sweep’s own additive steps for rates. The spread of the band midpoints across those runs is the measured price of not knowing that input. The list ranks by it and names the document that settles each — a bank statement, a signed offer, a written quote — rather than an instruction to feel more certain. A run where every input is a fact gets the honest empty state: nothing left to verify, the strongest position a forecast can be in. Eight browser checks police it, including that a fact is never listed, that the ranking is descending, and that reclassifying every input as fact flips the panel to the empty state. The release gate is now twenty-six gates, and the self-counting rule added in the last release meant the roadmap’s published count had to be corrected in the same commit — which is precisely the behaviour it was built for. |
| 2026-08 | site | Four live defects named by an external audit, each verified against the code before acting, two rejected as already-fixed and four repaired. Wrong-model routing: measured in a real browser, two FRAME templates whose cards promise the major-purchase model landed on the runway model — “debt repayment” keyword-matched “cash” and routed there. The card’s promise is the contract, so every FRAME link now pins its model explicitly with ?model=, an unknown pin or example id is refused out loud rather than silently landing on the default — the silent fallback IS the “closest model” routing this product refuses — and a new release gate reads the real hrefs out of the templates page and drives all seventeen modelled links in a browser, asserting each opens exactly the model its card names. “Nothing here is estimated”: the what-would-change-my-mind panel said it of threshold searches, meaning “computed, not typed” and reading as “not an estimate” — the exact category blur this product exists to prevent. It now says what is true: every threshold is a model-derived figure under the other inputs held constant. Thirteen months over a twelve-month horizon: the engine clamps to “12+” but two hand-written passages did not, printing a month the simulation never ran; both corrected. All three defect classes gained contradiction rules with mutations proven firing — a page printing horizon+1 months as a runway figure, or describing model output as not estimated, is now a build failure. The gate is twenty-seven gates and the roadmap’s self-checked count moved with it. Not acted on from the same audit: the homepage six-versus-zero contradiction (the counter reads the live ledger and showed six; the reviewer read a stale deploy), and the sample-classification gap (the worked examples classify every field they fill). No model version, seed derivation or hash function changed. |
| 2026-08 | router@2.0.0 · site | The capability firewall. The homepage accepted “Will Bitcoin rise tomorrow?” and answered with a business cash-runway form labelled “best guess” — the silent default at the heart of router 1.0, which sent every unmatched sentence to the runway model. Router 2.0.0 has three outcomes and only three: supported (one released model clearly fits, named with its matched evidence, confirmed before anything runs), clarify (a weak or contested signal gets one question and three doors, never a default), unsupported (markets, medical, legal, gambling, relationship outcomes, elections, weather and unresolvable “success” questions are refused with reasons, and offered a supported reframing — “model the financial consequence of losing a stated amount” — where one honestly exists). Worked-example chips and template cards pin their model explicitly; free text alone never starts a calculation. From the same audit: the JobSafe headline could print LOWER TASK EXPOSURE beside “None stood out from your answers yet” — a verdict its own components refuted; headlines are now earned by named components, middle answers get “not enough detail” instead of an invented reading, results are session-only unless remembered, and a per-answer “why this result” ships with every profile. Find-my-money summed an average pension pot, annual benefit flows and conditional childcare support into one “Potentially waiting for you” range — unaddable kinds of number; the bar now counts official checks, every card carries an amount-type label, an eligibility caveat, its geography and what remains unknown, and “exactly what you’re due” became “can estimate whether you may qualify”. The verify page gained a permanent fourth dimension — external provenance: not established — because a self-contained hash proves a body matches the hash it carries, not when the record existed or who made it; “the number is real” became “the recorded calculation reproduces exactly”. The glass-box page’s deliberately dead “contact sales” button is a non-interactive label now — a dead button is still a dead button. Three release gates were added (firewall refusals, JobSafe headline discipline, find-my-money totals — thirty gates), four contradiction rules with mutations proven firing (thirty-eight injected, thirty-eight caught). Routing decides which door opens and never touches model output: no model version, seed derivation or hash function changed, and all 96 frozen results resolve unchanged. Test suite: 397 checks. |
| 2026-08 | cmd@2.0.0 · site | Search, status and shared-receipt truth. Search: the command palette scored loose character similarity, so “bitcoin” returned a page list, “cancer” returned unrelated models, and glossary entries rendered under a “Your decisions” header they had no business under. The palette now loads the same capability firewall the homepage uses — one source of truth for what LEXUN refuses: a market or medical query gets the boundary and the supported alternative, and nothing else beneath it; “hire”, “compare” and “house” pin their exact task matches first; subsequence padding is gone; the zero state names safe destinations instead of weak matches; and every result group is labelled by what it actually is. Shared receipts: a malformed #r= fragment used to be swallowed by a silent catch, leaving the ordinary page — it now says out loud that the shared receipt is invalid, and a receipt naming no model is refused rather than assumed to be runway. Status: the register row said “no forecasts published yet” while the ledger held six open — the row now reads the ledger itself; “it cannot be taken down by an outage of ours” became the qualified truth (first loads, asset delivery and browser storage can still fail); forms admit no independent delivery monitoring exists. Coverage and claims: Earth’s “Global Decision Intelligence” title became “Evidence Explorer (UK signals today)” and its closing invitation stopped implying geography changes the calculation; the scenario tables on three surfaces clamped the engine’s frozen never-ran-out sentinel so a 12-month simulation prints “12+ mo”, never 13; Join’s “the longer it runs, the sharper it gets” became the honest calibration sentence; Security’s “only feature that transmits what you type” was corrected against its own table; Enterprise stopped saying a Key is needed to run and its hiring card now names what the framing does not model; Education’s LIVE badges became “available lesson activity”; Pricing’s two reminder rows now name their different mechanisms; the roadmap’s gate entry states its own coverage limits. Four new contradiction rules with mutations proven firing (forty-two injected, forty-two caught), three new release gates (thirty-three total). No model version, seed derivation or hash function changed; all 96 frozen results resolve unchanged. Test suite: 397 checks. |
| 2026-08 | site · audit tools | One source of truth, enforced both ways. A full repository audit confirmed what the architecture is — a static local-first site, one assistant function with its key server-side, a checkout scaffold that is off until configured, and a paid door that has always said out loud that it asks rather than enforces — and the release now proves the facts stay connected. Ledger ↔ registry: the truth registry’s forecast counts are a cache of forecast-ledger.json, and a cache nobody checks is a second copy of the truth waiting to diverge; the contradiction engine now compares them on every run, and the mutation suite gained compound mutations that move a fact in the ledger and the stale sentence on a page together — the only honest way to test a rule that compares two sources. Resolution-proof wording: five pages said “nothing has resolved yet” in the present tense, which the first resolved outcome — due within days — would have silently falsified; every one now reads from the ledger or speaks historically, and a new rule fires on the phrase the moment the ledger holds a resolved outcome. Locked workspace tabs keep their identity: Overview, Library, Outcomes and Settings used to collapse into one identical Key wall; locked is a state, not a place, so each now names what is waiting behind the lock. Type floor: substantive prose sat at 12–13px on nine pages — pricing FAQ answers and consent lines included; everything substantive now sits at 14px or above, verified by a browser sweep across twenty pages that is itself a release gate. Thirty-five gates, forty-four mutations injected and caught. No model version, seed derivation or hash function changed; all 96 frozen results resolve unchanged. Test suite: 397 checks. |
| 2026-08 | router@2.1.0 · forecast-ledger · site | The first outcome. On 18 August 2026 the ONS published the April–June unemployment rate at 4.9%, inside the frozen 4.6–5.2% band of lxf_external_004 — the register’s first resolution, scored TRUE at Brier 0.0100 on the editorial board, written once and unremovable. The moment it landed, the resolution-proof rules built for exactly this day fired on cue: four pages still said “nothing has resolved yet” in the present tense, the registry cache had drifted from the ledger, and the “validated models” rule — keyed on total resolutions — would have quietly disabled itself on the strength of one editorial macro call; all corrected, with the model/editorial split now explicit in the registry. The July insolvency release could not yet be verified against its frozen source, so lxf_external_009 stays open — a register never resolves on an unverifiable figure. Ledger truth on every surface: the homepage counters no longer initialise at zero (unknown is an em-dash and “reading the ledger”), every reader carries an eight-second timeout into a stated failure state, the service worker no longer answers a failed data fetch with homepage HTML, and with a warm cache it serves the last-known snapshot — all six states tested in a browser. The intent contract: the templates page advertised questions the classifier refused — “Should I increase my prices by 10%?”, “Should I open a second café?” (the accent was being stripped to “caf”), “hire another employee” ambiguous — and two template prefills failed the platform’s own frame check; the router widened, the prefills rephrased to resolvable questions, and a suite test now scrapes every advertised question from the shipped HTML and fails the build if any is refused. Honest state elsewhere: the worked-example receipt and sensitivity panels beside the homepage console are labelled as the canonical demonstration; example chips say “e.g.”; Find-my-money gained a start-again control and announces answers restored from a previous visit; JobSafe gained start-again; the async threshold-search and survival-curve modules carry watchdogs so a progress line can never outlive its worker; Earth’s search says “9,508 included places” and explains what is not in the list; the career example now classifies all six values it fills; archive links in the legal pages gained underlines (a real WCAG 1.4.1 failure found by the rebuilt axe sweep). Thirty-six gates, forty-four mutations, all caught. No model version, seed derivation or hash function changed; 96 frozen results unchanged. Test suite: 399 checks. |
| 2026-08 | site · workspace | The Decision OS layer. The workspace stops being a place you bring questions and starts being a place that brings you yours. Decision Inbox: the Overview now answers “what deserves attention today?” with cards computed from the real graph — material changes and due outcomes from the Reality layer’s validity engine, deadlines inside a week with their frozen criteria, the most sensitive input still resting on an assumption, and unfinished official money checks — each deep-linking to its own action. Pre-mortem: every result now carries “if this goes wrong”, derived entirely from the engine’s own output (the stress scenario, the largest assumption-classified sensitivities, the challenge model’s opposing case) with numeric early-warning levels at the ±15% recheck rule — frozen onto the decision as monitorable conditions. Timeline: each saved decision shows every event from its hash-chained audit ledger, in sealed order. Outcome Day: the moment reality answers, the loop closes visibly — the frozen band against the verdict, the Brier score, whether the forecast leaned the right way (misses stay up, priced honestly), and the pointer to the evaluation that carries the lesson into the next decision in the domain. Evidence Wallet: inputs classified as facts are written, at freeze, into a wallet inside the same encrypted store as the graph; later forms offer the value with its age and its use-count — never applied silently, always “Use it” or “Update first”, and invisible while the vault is locked because the wallet is encrypted with everything else. Find My Money gained per-check progress tracking (worth checking / applied / found / not eligible), device-only, surfaced on the Overview; its storage key is published on /cookies, which the storage-inventory gate enforced before this sentence was written. One end-to-end gate now drives the entire loop in a browser — freeze with pre-mortem, inbox, deadline, outcome day, timeline, wallet reuse — sixteen steps, thirty-seven gates total. No model version, seed derivation or hash function changed; all 96 frozen results resolve unchanged. Test suite: 399 checks. |
| 2026-08 | forecast-ledger · site | Two more outcomes, one honest miss. On 19 August 2026 the ONS published July CPI at 2.9%. lxf_external_002 (band 2.2–3.0% inclusive) resolved TRUE at Brier 0.0121; lxf_external_003 (strictly below June’s 2.6%) resolved FALSE at Brier 0.2500 — the register’s deliberately-uncertain middle-of-the-range call, priced near even and scored exactly as written, because a track record made only of near-certainties cannot demonstrate calibration. Both outcomes are write-once, scored against the band midpoint, with the ONS bulletin sentence and URL frozen into the ledger. The editorial board stands at three resolved of ten issued — below the ten-outcome minimum, so no accuracy percentage is published. lxf_external_009 stays open: the trade press reports a July company-insolvency count inside the band, but the frozen gov.uk source could not yet be verified from the build environment, and a register never resolves on a secondary source. Type floor raised: after a reader reported the smallest text hard to read, every font size below thirteen pixels increased by one pixel across every page, stylesheet and script — the letter-spaced kicker labels were the worst offenders at 9.5px. The content-hashed stylesheets were renamed to their new hashes, and the frozen legal snapshots keep their original stylesheet bytes under /css-archive so an archived page still renders exactly as archived. No model version, seed derivation or hash function changed; all 96 frozen results resolve unchanged. Test suite: 399 checks. |
| 2026-08 | site · homepage · templates | The floor, never sold as the whole decision. Ten broad decision templates — hiring, price rises, marketing, expansion, debt strategy, leaving a job, starting a business, retraining, equipment, moving home — now say on the card what the model calculates and what it cannot determine, and the workspace shows the same scope panel the moment such a question arrives: what is modelled, what is not, and that the result is the financial floor under the decision. A new release gate drives four of these questions through a browser and fails the build if the scope panel is missing or a question already at model scope gets a needless caveat — thirty-eight gates. The hero speaks human: “Make a difficult decision with the numbers in front of you” over the outcome-led description, the submit button says what it does, and the trust line states the checkable facts — free to use, no account or card, figures stay on the device. The duplicate scroll cue went. Plain-English results: “Strongest move” became “Most useful change to test”, “Break-even growth” became “Growth needed for a 50/50 chance”, “Cost of waiting” became “What waiting could change”, the receipt is labelled a verification receipt, and p10/p50/p90 reads downside/expected/upside. Two truths said out loud on the homepage: editorial forecasts demonstrate discipline but do not prove the decision models accurate — each model earns its own calibration; and the automated checks show the engine behaves as specified, not that a forecast will come true. The moat line softened to the defensible version: a public scoring history becomes harder to replicate as verified outcomes accumulate. No model version, seed derivation or hash function changed; all 96 frozen results resolve unchanged. Test suite: 399 checks. |
| 2026-08 | site · navigation · evidence panel | Five doors, one honest scoreboard. The header simplified to four destinations — Decisions, Evidence, Organisations, Pricing — and the vague “Start here” button now says what it does: “Analyse a decision”. The footer’s thirty-four-link sitemap became five named groups of four — Product, Evidence, Solutions, Company, Legal — with every remaining page still reachable under “Everything else”, so nothing was orphaned to look tidy. The public-evidence panel is stage-aware: the open-forecast card names the next date reality answers, read from the ledger’s own due dates — and a forecast past its date is called what it is, “past due, awaiting a verifiable source figure”, never silently folded into “next”. Below the minimum sample the calibration card states the stage (“3 of 10 — descriptive only”) instead of a hopeful blank, and a new line renders per-model calibration separately — runway, career and purchase each at zero resolved, said plainly — beside the editorial board’s count, because three editorial macro calls say nothing about the decision models. All of it computed from forecast-ledger.json at read time; none of it hand-typed. No model version, seed derivation or hash function changed; all 96 frozen results resolve unchanged. Test suite: 399 checks. |
| 2026-08 | site · workspace · audit tools | Ready before you run; test the driver after. The evidence bar grew into a Decision Readiness Check that states, before the run, exactly what the engine’s gate will do: an empty input is named, a field marked unknown is refused in advance with the way forward (“the engine refuses to invent a value”), an all-assumption run is called out as one the gate will refuse, and a ready form says why — facts tighten the band, assumptions widen it honestly. Every result now carries the Assumption Lab: the biggest driver offered for a baseline-versus-adjusted comparison — two real 5,000-path runs on the same model version, each with its own reproducible seed, an out-of-validity value refused rather than extrapolated, and the comparison stating its own limit: modelled financial resilience, not every reason one choice may be better. A ninth browser gate drives both — thirty-nine gates. Privacy wording made exact: the assistant warning now names the path (your message → a LEXUN server function → Anthropic) and what never to type into it; “nothing leaves your device” claims were requalified to the precise true statement on five pages. The roadmap caught up with reality: its register entry still said “none yet resolved” three resolutions after the fact — a phrasing the resolved-state rule did not cover; the wording is fixed and the rule now catches that variant too, still proven by its mutation. No model version, seed derivation or hash function changed; all 96 frozen results resolve unchanged. Test suite: 399 checks. |
| 2026-08 | site · workspace | Verify it, then take it with you. Every result now ends with an Evidence Checklist: the specific document that would turn each remaining assumption into a fact — bank statements for banked revenue, a signed offer for expected income, written quotes for a commitment — personalised from that run’s own classifications, ordered so the biggest driver is verified first, capped at five, with fact-classified inputs acknowledged rather than re-verified. Nothing uploads or inspects a document; the list names what to check and where. And every result can now leave as a Decision Brief — a self-contained printable HTML page or JSON file carrying the question, every input with its classification, the band, the stress case, the biggest driver, the pre-mortem routes, the model’s stated limits, and the seed and hash that reproduce it — generated on the device from the result object alone, stating in print that probability and input confidence are different measures and that the brief is the financial floor under the decision, not the whole decision. A tenth browser gate downloads both files in a real browser and fails the build if the export drifts from the result — forty gates. No model version, seed derivation or hash function changed; all 96 frozen results resolve unchanged. Test suite: 399 checks. |
| 2026-08 | site · workspace · audit tools | Two options, one honest table. Every result now carries Compare two options: Option B described as a whole alternative — every figure editable, prefilled from Option A — run through the same model version on the same horizon, inheriting Option A’s classifications. The table compares band, survival, stress case and median months across two real 5,000-path runs, names exactly what differs with its from→to values, and carries Option B’s own seed and hash so both sides reproduce. Identical options are refused with an instruction rather than compared; an Option B outside the model’s stated validity is refused rather than extrapolated; and the table states its own limit in every render: modelled financial resilience, not every reason one option may be better. An eleventh browser gate proves all of it, including that raising costs can never print a better survival number — forty-one gates. The gate-count rule’s number-word map, which stopped at “forty” and would have gone silently blind at forty-one, was extended to fifty and re-proven by its mutation. No model version, seed derivation or hash function changed; all 96 frozen results resolve unchanged. Test suite: 399 checks. |
| 2026-08 | site · typography | The 16-pixel floor. The base reading size on twenty-two pages sat at 15px; every one now opens at 16px, so default body prose — the paragraphs people actually read — meets the floor everywhere, with the guide, legal and accuracy pages already above it at 16.5–17px and untouched. Interface furniture keeps its own scale (labels, tables, receipts, footer — all already raised one pixel in an earlier release), because the floor is for reading prose, not for turning every caption into a headline. The type gate grew a second assertion — the computed body size must be 16px or above on every audited page — and the full sweep re-verified layout at all seventeen breakpoints with zero overflow. No model version, seed derivation or hash function changed; all 96 frozen results resolve unchanged. Test suite: 399 checks. |
| 2026-08 | site · workspace · accuracy | The outside view, promoted. Every result now opens its historical frame as a first-class card: the real base rate (38.4% five-year survival for UK businesses born 2019, ONS) with its full provenance — publisher, publication date, retrieval date, licence, reliability class — marked bundled snapshot, not live, with survivorship and selection bias stated and the known data gap shown rather than estimated. Beneath it, current conditions read only from the register’s own resolved sources — the CPI and unemployment figures this register froze, scored and published, each with its publication date — labelled context that never enters the simulation. The Accuracy Centre gained “The three clocks”: how the ledger keeps happened, published and learned apart — resolution before the source publishes refused as “a guess wearing a timestamp”, outcomes scored against figures as first published so revisions can never rewrite a score, with the July CPI resolution as the worked example. A twelfth browser gate proves the card’s provenance, the bias statement, the never-live rule and that the conditions strip contains only resolved-register figures — forty-two gates. No model version, seed derivation or hash function changed; all 96 frozen results resolve unchanged. Test suite: 399 checks. |
| 2026-08 | forecast-ledger · site | The fourth outcome, and a steadier planet. The July company-insolvency release finally became verifiable against its frozen gov.uk source — five days after the trade press carried the number, because a register never resolves on a secondary source — and lxf_external_009 resolved TRUE: 1,931 registered company insolvencies in England and Wales, inside the frozen 1,550–2,150 band, Brier 0.0225 against the band midpoint, with the exact first-published sentence and URL frozen into the ledger. The editorial board stands at four resolved of ten issued — still below the ten-outcome minimum, so still no accuracy percentage. Two forecasts remain open: the September Bank Rate hold and the November path. The entrance stopped glitching under scroll: the three Earth layers — photograph, city lights, arrival film — are now pinned to the compositor with will-change so the browser can never promote and demote them mid-scroll (the visible flicker), and the per-frame scroll-grade variables moved off <html> onto the entrance section itself, so a scroll frame no longer invalidates style for the whole document. Two regression checks now guard both fixes in the opening-invariants gate. No model version, seed derivation or hash function changed; all 96 frozen results resolve unchanged. Test suite: 399 checks. |
| 2026-08 | source registry · audit tools | One registry, machine-readable, zero fake connectors. The source registry the engines load — seven bundled reference sources, every one carrying publisher, publication and retrieval dates and licence — now also carries an authority tier (1 official statistics · 2 recognised research · 3 reputable industry · 4 secondary reporting, needs corroboration) and ships machine-readable at /source-registry.json, generated from the same code rather than typed twice, together with the register’s four resolved-outcome sources read straight from the ledger. The file states the architecture plainly: a static, local-first site with zero live data connectors — a source described as live here would be fabricated, so none is. A new gate regenerates the derivation and blocks the release on any drift between the shipped file and the code, on any source missing tier, licence or dates, on any connected:true, and on any workspace reference to a source id the registry does not hold — forty-three gates. No model version, seed derivation or hash function changed; all 96 frozen results resolve unchanged. Test suite: 399 checks. |
| 2026-08 | source registry · audit tools | The data-gap census. The machine-readable registry at /source-registry.json now carries a coverage matrix — every figure LEXUN actually holds, with its authority tier, geography, cohort, publication and retrieval dates, refresh reality (“bundled snapshot — refreshed only by a release”) and the surface that uses it — and a blind-spot register: six gaps the platform does not fill, each classified against a fixed taxonomy (discoverable-and-open, restricted, not-worth-acquiring-as-framed, unavailable-in-this-architecture), with why it is missing and the honest acquisition path. The census can never include data the platform does not really have, because it is derived from the same code the engines load; the sources gate validates every coverage row and every blind-spot classification and blocks the release on drift. Knowing what you lack, in machine-readable form, is the beginning of acquiring it honestly. No model version, seed derivation or hash function changed; all 96 frozen results resolve unchanged. Test suite: 399 checks. |
| 2026-08 | site · audit tools | An outside audit, answered the only honest way. A reader’s fresh pass over the live product reported four wording contradictions. Two had already been fixed in earlier releases and one was a misreading — the Trust page’s “390 checks” sits in a version-history row recording the suite as it stood at that release, and the table now carries a note saying exactly that. The fourth was real: the join page claimed the system teaches itself and that every prediction adjusts the model — an overclaim on both halves, since only saved-and-resolved forecasts are scored and the frozen models change only by versioned release — and its neighbour spoke of opt-in sync as if the option existed. Both sentences now say the true thing. And per the house rule that every found defect becomes a gate: the learning-claim rule now fires on teach-itself phrasings and model-adjusting claims, a new sync-claim rule fires on present-tense sync while the registry says cloud_sync_live is false — each proven by its own injected mutation, forty-six mutations, all caught. The first draft of the sync rule was itself too broad, flagging correctly-labelled “coming soon” wording on two pages; it was narrowed to present-tense operational claims before shipping, which is the difference between a gate and a nuisance. No model version, seed derivation or hash function changed; all 96 frozen results resolve unchanged. Test suite: 399 checks. |
| 2026-08 | workspace | The decision journal, sealed at the freeze. Beside the acceptance buttons the workspace now asks, in a structured way, for the things hindsight always rewrites: why this option, the alternative you nearly chose, and felt confidence — recorded as a word (low · moderate · high) on purpose, because a percentage there would masquerade as output of the model when it is a reading of you. The entry freezes with the forecast, write-once like everything else in the record: the library card shows the journal exactly as written, and Outcome Day replays it beside what actually happened — what you said, next to what reality said, which is where calibration of the person (not just the model) begins. Leaving it blank is allowed and stored as nothing; the journal never invents an answer for you. Four new checks in the Decision OS gate drive the full loop — write, freeze, clear, replay on the library card and on Outcome Day — twenty checks in that gate. No model version, seed derivation or hash function changed; all 96 frozen results resolve unchanged. Test suite: 399 checks. |
| 2026-08 | workspace | The halfway checkpoint, and a health label every card earns. When a decision freezes with resolution at least two weeks away, the workspace now sets a review checkpoint at the midpoint — a dated commitment, sealed on the timeline, to re-check the inputs against reality before the answer arrives. When the date passes the inbox raises REVIEW DUE; running it is one honest act — re-check the inputs on the control panel, mark it reviewed, and the completion seals write-once beside the setting. The frozen forecast itself never changes at a checkpoint; a material change becomes a new, versioned forecast, exactly as before. Every library card also gained a decision-health label — on track · review due · resolves in N days · outcome overdue · scored with its Brier — computed purely from dates and outcomes the record already holds: a position on a timeline, never a judgement of quality. Five new checks drive checkpoint set, surface, run, seal and label through the full loop — twenty-five in the Decision OS gate. No model version, seed derivation or hash function changed; all 96 frozen results resolve unchanged. Test suite: 399 checks. |
| 2026-08 | workspace | The weekly review — a ritual, not a report. The command centre gained a weekly review: one summary in five sections — what’s open with each decision’s health label, everything landing in the next fourteen days (deadlines, checkpoints, anything overdue), unclaimed lessons (outcomes reported but never evaluated — because the outcome is not the lesson), the most valuable evidence still missing (the sensitive inputs still resting on assumptions), and calibration under the same honesty rules as everywhere else. Every line is computed from the record this device already holds; nothing is estimated, padded or uploaded, and an empty section says so plainly instead of inventing content. Running it stamps a local date so the inbox can nudge when a week passes — the stamp is device-local convenience, never data. Five new checks drive nudge, computation, unclaimed-lesson surfacing, calibration and stand-down — thirty in the Decision OS gate. No model version, seed derivation or hash function changed; all 96 frozen results resolve unchanged. Test suite: 399 checks. |
| 2026-08 | workspace | Scenario branches — decide the response before the moment. The engine already prices four ways every decision could go — expected, upside, downside, stress, each with its own survival probability. The workspace now lets you attach a response to any of them, written while you are calm and the stakes are still theoretical: if this happens, I will… The branches are strictly the model’s own scenarios — nothing invited you to imagine new futures — and only the responses are yours; empty branches are simply not recorded. Each pre-committed response freezes write-once with the forecast, carrying the scenario it answers and that scenario’s priced probability. The library card lists them under the sealed journal, and Outcome Day replays them beside what reality actually did — the difference between a plan made before the moment and one improvised inside it. Four new checks drive the branch through freeze, empty-branch omission, library and Outcome Day — thirty-four in the Decision OS gate. No model version, seed derivation or hash function changed; all 96 frozen results resolve unchanged. Test suite: 399 checks. |
| 2026-08 | model registry · audit tools · accuracy | The model registry — released by proof, never by interface. LEXUN now ships a machine-readable model coverage and release registry at /model-registry.json: for each of the three released models — versions and required inputs read from the model code itself, never typed twice — the exact target, supported and unsupported decisions, output distribution, reference class, assumptions and known weaknesses stated as a required field, including that no released model uses location, that scenario shifts are predefined stress tests rather than historical percentiles, and that the business reference class pools all UK businesses. Nine candidate models are listed as concepts, each naming the path it has not walked — historical validation, then a shadow record, then the gate — and the registry’s own invariants refuse to let a concept call itself released by editing a file. Resolved outcomes now carry verification grades computed from the ledger’s own evidence (grade A is impossible here because no connectors exist; all four current outcomes earn grade B), and the same tool enforces ledger resolution hygiene on every run: open forecasts must carry criterion, due date and frozen source; outcomes can never precede their source’s publication; withdrawn forecasts can never be scored. A forty-fourth release gate blocks any drift, proven against three injected tamperings — a concept promoted, a version forged, a withdrawn forecast scored — each caught. No model version, seed derivation or hash function changed; all 96 frozen results resolve unchanged. Test suite: 399 checks. |
| 2026-08 | workspace | Evidence import — a CSV in, nothing entering silently. The evidence step can now read a bank or accounting CSV export — parsed entirely in this browser, never uploaded, with the harness watching the network to prove it. The importer handles UK export reality (dd/mm/yyyy dates, £ signs, thousands separators, quoted cells, bracketed negatives), summarises what the file actually contains — rows, columns, detected date range — and computes candidate figures that each name their derivation: sum of a column, mean per row, latest value, monthly average over the detected span. Then the honesty rules hold the door: nothing fills a field until you choose the field and press Use; pressing Use without choosing is refused (“LEXUN will not guess”); and a used value is deliberately left unclassified — an imported number is evidence you hold, not a fact the system gets to assume, so you classify it yourself as everywhere else. Files it cannot read honestly are refused outright with the rule stated: over 2 MB, over five thousand rows, or no column that is at least 80% numeric — refusal beats silent truncation. A forty-fifth release gate drives all of it, including the no-network proof. No model version, seed derivation or hash function changed; all 96 frozen results resolve unchanged. Test suite: 399 checks. |
| 2026-08 | data · accuracy · source registry | Historical Intelligence, dataset one: the full Bank Rate record. LEXUN’s first bundled historical series is the Bank of England’s official Bank Rate change history — all 258 changes from January 1975 to December 2025, shipped machine-readable at /data/boe-bank-rate.json with publisher, source URL, licence, retrieval date and method stated inside the file, and six anchor values (the 17% peak of 1979, the 0.10% floor of 2020, the 5.25% plateau of 2023 among them) cross-checked against independently known history before bundling. The Accuracy Centre’s new Rate regimes section reads that file and answers one honest question — is today’s rate environment ordinary or unusual by the record’s own standard? — with time-in-band shares since 1975 and the full episode table, under thresholds stated as a naming convention rather than analysis. The discipline is written into the data file itself: this series records where the rate has been, never where it will go, and similarity is not repetition. No released model takes the rate as an input, so the record sits beside results, never inside them; the source registry grew to eight sources, still with zero live connectors. A forty-sixth gate proves the arithmetic on the page against the bundled file, the anchor values, the provenance and the framing. No model version, seed derivation or hash function changed; all 96 frozen results resolve unchanged. Test suite: 399 checks. |
| 2026-08 | data · accuracy · source registry | Dataset two, and the first honest analogue. The second Historical Intelligence series is the ONS CPI annual rate (D7G7): 37 yearly averages, 1989–2025, from the 19 August 2026 release, shipped at /data/ons-cpi-annual.json with six anchors cross-checked before bundling — and with the vintage limitation written into the file in capitals: current vintage only, revisions included, original first-published values not preserved, which is exactly the distinction the register itself lives by from the other side. With two real series the Accuracy Centre can now ask a deliberately narrow question: which past years most resembled today on these two variables alone? Today’s pair is real on both sides — the register’s own first-published-resolved July 2026 CPI beside the bundled Bank Rate — and the closest years are ranked by a standardised distance the page describes as resemblance on two numbers, never a probability of anything. The panel states its own limits in its own text: two variables are not a regime, the 12-month-rate-versus-year-average mismatch is said rather than hidden, and the blind-spot register already names the series a real regime comparison would need. Nine sources, zero live connectors; the forty-sixth gate grew to eighteen checks covering both files, both anchor sets, the vintage disclosure and the framing. No model version, seed derivation or hash function changed; all 96 frozen results resolve unchanged. Test suite: 399 checks. |
| 2026-08 | audit tools | The adversarial sweep — the corners, not the happy path. Everything shipped since the decision journal was driven back through its edges, deliberately hostile: script-injection text written into the journal, the alternative field and a scenario branch (escaped everywhere — nothing executed, nothing rendered, and the record stores the raw text faithfully); a journal saved with only felt confidence (nulls for the unwritten fields, toggle-off honoured); branches left untouched on a second model (absent, never empty entries); the weekly review run on an empty record (no nudge — nothing to review is not a task — and every section states its emptiness rather than inventing content); a semicolon-delimited, headerless, ISO-dated CSV carrying spreadsheet formulas and HTML in its cells (parsed correctly, every cell inert text); a second Use overwriting a first (latest explicit choice wins); the regime tables at 360px (scrolling inside their wrappers, zero page overflow); and the two-variable analogue re-derived independently from the raw files, arriving at the same closest year the page shows. Thirteen checks, and they are now permanent: a forty-seventh release gate runs the sweep on every release, so the corners stay tested after everyone has forgotten they exist. No model version, seed derivation or hash function changed; all 96 frozen results resolve unchanged. Test suite: 399 checks. |
| 2026-08 | workspace · registries | Geography becomes an honest variable. Every decision now records where it lives — country and currency, chosen on the framing screen with the United Kingdom preselected and visible, never silently assumed — and that choice is stored write-once on the record and shown on the library card. What the choice does today is stated in plain text on the framing screen itself: the released models’ arithmetic does not yet vary by location, and instead of pretending otherwise, geography now gates the evidence. A decision recorded for Dubai, Istanbul or New York no longer receives the UK base rate with a different currency symbol: the outside view is withheld, honestly — “no verified evidence for this country; a UK figure here would be fabricated relevance, so none is shown” — and the conditions strip names its figures as United Kingdom figures when the decision lives elsewhere. Amount fields relabel to the chosen currency (AED, ₺, ₹, €…), result texts follow, and nothing is ever converted: two currencies are never treated as the same number. The machine registries carry the same truth — the source registry now declares evidence coverage (United Kingdom only) separately from place-name search, because names are not evidence, and every released model’s registry entry states geography as recorded-not-modelled. A forty-eighth gate drives the whole path: preselection, relabelling, the withheld card, the stored record, the library display and both registries. No model version, seed derivation or hash function changed; all 96 frozen results resolve unchanged. Test suite: 399 checks. |
| 2026-08 | audit tools · trust | The system manifest — every public number derived, never typed twice. A stale counter typed in two places is how trust dies quietly, so LEXUN now ships /system-manifest.json: every public platform statistic derived from the repository itself — the engine suite reports its own check count by running, the frozen-results snapshot reports its own, the release gate counts its own rows, the mutation suite counts its own probes, and sources, models, register counts, outcome grades, bundled datasets, evidence countries and pages are read from the registries that already drift-block themselves. The manifest cross-checks the truth registry against the ledger and refuses to describe a broken build at all. A forty-ninth release gate re-derives the whole file on every release and blocks on any drift — and because the manifest includes the gate count, adding that gate changed the manifest, which the gate then re-verified: the instrument measures itself. The Trust page now links the file beside its historical-counts note. No model version, seed derivation or hash function changed; all 96 frozen results resolve unchanged. Test suite: 399 checks. |
| 2026-08 | llms.txt · about · audit tools | Answer-engine honesty — and the sweep that caught our own stale claim. Extending the contradiction scanner beyond HTML found a real defect in /llms.txt — the curated file answer engines quote — still telling assistants the accuracy record was “an honest zero” days after the fourth outcome resolved. Per the house rule, the defect became a rule: the scanner now reads llms.txt as a page, a zero-outcome-claim rule fires on empty-record phrasings whenever the register holds resolved outcomes, and a forty-seventh mutation proves it fires. The file itself was rewritten to the current truth — ten issued, four resolved grade B, two open, four withdrawn — and gained a machine-readable ground truth section pointing assistants at the derived registries (system manifest, model registry, source registry, both historical datasets, the ledger) in preference to prose. The About page gained the five questions people actually ask, answered honestly on the page and in FAQ structured data that the schema gate verifies word-for-word against the visible text — including “Can LEXUN predict the future? No, and it never claims to.” No model version, seed derivation or hash function changed; all 96 frozen results resolve unchanged. Test suite: 399 checks. |
| 2026-08 | workspace | The answer-mode contract — every part of a result says what kind of answer it is. A result is not one claim; it is three different kinds of claim, and they now declare themselves on every result. Forecast: the probability band, from the released model, with the supported decisions listed. Scenario: the four stress shifts and any pre-committed branch — structured futures with no probabilities attached, testing your inputs without claiming to know which path arrives. Not modelled: the refusals, named — refused rather than improvised. The lists are read live from the drift-gated /model-registry.json rather than typed into the page, so the contract can never claim more than the registry does — and the model-coverage gate, extended with three contract checks that compare the rendered lists verbatim against the registry, was promoted from advisory to release-blocking. No model version, seed derivation or hash function changed; all 96 frozen results resolve unchanged. Test suite: 399 checks. |
| 2026-08 | learn pages · accuracy | Answer-engine reach, wave two — honest answers where people actually search. The three decision guides gained the questions people actually type — “How do I calculate my business runway?”, “How much money should I save before quitting my job?”, “Can I afford this big purchase?”, and yes, “Will AI take my job?” — each answered on the page in LEXUN’s own voice, refusals included (“Nobody can give you a single honest percentage for that, and LEXUN refuses to invent one”), and mirrored word-for-word into FAQ structured data the schema gate verifies against the visible text. The two bundled historical series now carry Dataset structured data on the Accuracy Centre — publisher, licence, temporal coverage, the original source they are based on, and their limitations restated — so answer engines can cite the data itself rather than paraphrase the prose. Nine honest questions, two citable datasets, zero new claims. No model version, seed derivation or hash function changed; all 96 frozen results resolve unchanged. Test suite: 399 checks. |
| 2026-08 | jobsafe · findmoney · compare | Answer-engine reach, wave three — the hard questions, answered the LEXUN way. Nine more search-intent questions now live where people land asking them, visible on-page and mirrored word-for-word into gate-verified FAQ structured data. JobSafe answers “Is my job safe from AI?” with the refusal that is the product’s actual position — no honest single percentage exists, so the checker reasons through your tasks instead of ranking doomed professions. Find My Money answers “Is there really unclaimed money waiting for me?” with sometimes — and nobody can tell you a number without checking. And the comparison page answers the question every vendor dodges — “Where is LEXUN weaker than the alternatives?” — in plain text: three models not three hundred, UK-only verified evidence, bundled snapshots not live feeds, and a resolved sample still below the accuracy-percentage minimum. Stating weaknesses in structured data an answer engine can quote is the wager the whole product makes: checkable beats impressive. No model version, seed derivation or hash function changed; all 96 frozen results resolve unchanged. Test suite: 399 checks. |
| 2026-08 | site-wide · llms-full · metadata | Answer-engine reach, wave four — the entity, the application, the queries. The Organization entity now carries a sameAs link to its Companies House record on all thirty-six pages, and the homepage and workspace declare WebApplication structured data with the truthful feature list — 5,000 seeded paths, bands never points, frozen forecasts, Brier scoring, price £0, figures never leaving the browser. Six pages had their titles and descriptions rewritten around the queries people actually type — cash runway calculator, career change calculator — can I afford to quit?, find unclaimed money UK, AI job risk checker — synced across title, social tags and structured data by the metadata gates. The three guides gained a checkable-facts box near the top, because answer engines cite concrete numbers, and every number in it is gate-verified elsewhere. And /llms-full.txt now ships the complete text of ten core pages, regenerated on every release by the same tool that maintains the sitemap — so the answer-engine copy can never go stale relative to the pages, by construction. No model version, seed derivation or hash function changed; all 96 frozen results resolve unchanged. Test suite: 399 checks. |
| 2026-08 | extract 1.2.0 · verify | “My business makes 8k a month” now means what it says. An outside audit reproduced a real extractor gap on the live site: makes, brings in, generates, grosses and takes in were not revenue cues, so a perfectly ordinary sentence — “I have 40k cash, my business makes 8k a month and costs 11k” — arrived with its revenue silently dropped. The extractor (now v1.2.0, versioned like everything else) recognises the spoken-English forms, including “8 grand” as eight thousand with the word consumed so nothing downstream misreads it; ten audit phrasings now extract every field, verified against the full 399-check suite with all 96 frozen results unchanged — extraction feeds the form, never the frozen maths. The audit’s other reproductions — a stuck Earth table, an empty forecast register, visible honeypots, placeholder company numbers — were checked one by one and are defects of the currently deployed version only: all were fixed in intervening releases awaiting deployment, which is its own lesson about shipping. One cosmetic catch was real and is fixed: “.lexun” could wrap into “. lexun” on the verify page. Test suite: 399 checks. |
| 2026-08 | index · forecast · stamp | The first frame earns its screen, and the ledger reaches readers who don’t run JavaScript. The entrance no longer spends a full viewport on the photograph alone: the sentence, the sub-line and the question box now land on the first frame at any laptop size, over a scrim that keeps the type legible on the night side of the planet, and the dead black scroll region between film and content is gone — the section is exactly one viewport. Submitting a question lands with the console in view, and its headline finally tells the truth about its state: Confirm and run when every figure was read from your sentence, Nearly there — Got: costs £11,000, cash £40,000, just need revenue when one is missing, never a blanket “insufficient evidence” over a fully-read sentence. Separately, an honest gap for machine readers closed: the register page and the homepage counters rendered only after JavaScript, so crawlers saw “Loading…” where four resolved outcomes actually stood — and one such reader concluded the register was empty. The release stamp now writes the ledger’s truth into the static HTML itself — the full register table, the resolved and open counts, the next resolution date — regenerated from the same file every release, with the live view re-reading that same ledger in the browser. Status and Trust gained release-stamped last-updated lines; the glossary and pricing pages state what they are in their own headlines; the planet photograph finally describes itself. Test suite: 399 checks; all 96 frozen results resolve unchanged. |
| 2026-08 | key-panel · extract 1.2.0 · mcp · fpages | Sign-in becomes the Key, the register becomes citable, and agents get the engine with receipts. The homepage and every marketing page gain a Sign in control that opens the LEXUN Key panel — not an account: the passphrase derives the encryption key on the device (PBKDF2 → AES-GCM, the same vault the workspace has always used) and the email address is the only thing a server receives; the workspace’s “No key yet” pill, previously decorative, now opens the same screen, and freezing still routes through the Key and returns to the filled-in numbers. The extractor closes the audited phrasing gaps (“£14k going out each month”, “out monthly”, “two years”, “60k saved”, bare “9000 in and 14000 out”), guarded by a permanent twenty-phrasing language gate; a blank screen can no longer appear between the hero and its answer — a “choosing the right model…” state holds the frame. Every public forecast now has a permanent server-rendered page at /f/<number> (full content with JavaScript disabled, Schema.org Claim + Dataset, OpenGraph), the register ships an Atom feed, and /cite maps every machine-readable endpoint with citation rules; llms.txt points at all of it. A working MCP server ships in the bundle (mcp/server.mjs): the three released models, receipt verification and the sourced reference classes as tools for AI agents, stateless, refusing exactly as the browser does — exercised by its own release gate. Results gain an odds toggle and a ten-cases frequency sentence; freezing gains a three-question resolution-criteria checklist (who decides, from what source, what if partially true); /education gains a ninety-second Brier-scored calibration test, teacher notes and a printable one-pager; /enterprise gains the Advisers & Consumer Duty section with a sign-off line on the exported Decision Record (“supports your evidence obligations”, never “makes you compliant”); /glass-box names the biases the engine is built against, with sources; the homepage states the trust gap with chatbots and the three falsification conditions. No model version, seed derivation or hash function changed; all 96 frozen reproducibility results resolve unchanged. Fifty-two release gates; 399 checks. |
| 2026-08 | site · tests 400 | Refusal becomes a feature you can press. The homepage example chips gain “Watch it refuse” — an unsupported question wired straight to the router’s honest no, with its own test class: refusal chips must be refused, exactly as example chips must parse. /trust shows what hostile input meets (free text never reaches a model as an instruction; there is no language model in the answering path to talk out of its discipline), and /compare answers the question people actually ask an AI product: what you type is never used to train anything, and there is no analytics script to smuggle it out. Suite grows to 400 checks; all counts on every page updated by the drift gate that makes stale counts a build failure. |
| 2026-08 | world-state · coverage · library | The recorded world, and what changed since you decided. Two new derived registries, both drift-gated: world-state.json holds current UK conditions built only from the bundled datasets and the register’s resolved outcomes — four indicators, every value resolving to a named source, content-versioned, refreshed only by a release — and coverage-registry.json computes which countries LEXUN supports on a six-level ladder, so “global coverage” can only ever be printed from the file (today: the UK at Level 3, everywhere else an honest Level 0 — /coverage explains the ladder and what Level 0 means in the product). Every decision frozen from now on snapshots the world-state version and values, and the decision control panel gains The world since you decided: when a later release ships a moved indicator, the panel names it, shows both values with the publication date, and points at which of your inputs it is worth re-checking — feeding the existing same-seed materiality checker, so a material change becomes a new version and the original forecast is never rewritten. Results gain Why did LEXUN say this? — the one-glance census of declared facts, assumptions, model, seed, context, and what the answer is deliberately not based on. Fifty-five gates. |
| 2026-08 | register +2 · regimes · horizons | Two new public forecasts, and history counted without being dressed up. Forecasts 011 and 012 join the register, issued 30 August against release dates verified on the ONS calendar: August CPI between 2.5% and 3.3% as first published on 16 September (band 84–92%, method identical to the resolved July call, set slightly lower because July’s +0.3pp move and un-analysed base effects are the honest price of admission), and the May–July unemployment rate between 4.7% and 5.1% on 15 September (band 86–94%, capped below 90s because the Labour Force Survey’s transformation-era volatility is methodological risk the band must carry). Both frozen with sealed receipts, permanent /f/ pages, criteria naming their sources in advance, and withdrawal rules if the bulletins slip. The Accuracy Centre’s rate-regime exhibit gains Where each band went next: band-to-band transition counts and long-hold direction stats computed in the browser from the bundled 1975–2025 record, with samples attached and an explicit refusal to present them as a transition matrix — five decades of monetary regimes are not stable draws. The model registry now declares each model’s enforced 3–36-month horizon bound as its defensible limit: beyond it the model refuses rather than extrapolating. Open forecasts: 4 · issued: 12 · next resolution 15 September. |
| 2026-08 | world-gb · earth | The country page LEXUN can write honestly — and Earth stops pretending. /world-gb is the first country intelligence page, for the one country with verified evidence: the recorded conditions (static copy written by the release process for non-JS readers, live view re-reading the same world-state file), the 1975–2025 historical record, the four register-resolved figures with their Brier scores, the three supported models with their horizon bounds — and a “what is still missing” section that names the absent city state, the unbuilt research pipeline and the below-minimum calibration sample instead of hiding them. A second country page appears the day a second country earns Level 2 on the coverage ladder, and not before. LEXUN Earth gains a Coverage panel reading coverage-registry.json live: the UK’s basis counted, every other country stated at Level 0, live connectors 0 — the globe no longer risks reading as equally intelligent everywhere. |
| 2026-08 | world-state · accuracy | Cheap information, dated in advance — and the baseline every model must beat. The world state gains a known information arrivals calendar derived entirely from the register’s own open forecasts — each entry is the official publication a forecast named before its outcome was known (15 Sep labour market, 16 Sep CPI, 17 Sep and 5 Nov MPC), and the list empties as forecasts resolve. Results for UK decisions now show it beside the outside view: if waiting is an option, these dates are the cheapest information available — a claim about information arrival, never a prediction of what arrives. The Accuracy Centre gains the baseline every model must beat: the do-nothing CPI forecast walked forward through all 36 years of the bundled ONS series with no hindsight, computed in the visitor’s browser — mean absolute error 1.16pp, within ±1pp in 21 of 36 years, and a misses table led by 2022 (predicted 2.6%, actual 9.1%): in quiet years the naive line is very hard to beat and in regime breaks it fails catastrophically, which is the honest shape of the forecasting problem and the standing bar for any model promotion. |
| 2026-08 | router 2.2.0 · compare | The refusal firewall learns war, markets and the idioms that fool routers. The capability router gains a conflict category: a war or geopolitics question now meets a tailored refusal — no released model estimates conflict risk, low-base-rate events are where an invented probability does the most harm, a resolvable contract is described and still refused for lack of validated evidence, and anyone near an affected area is pointed at official safety guidance rather than a simulation. Idiom guards keep commerce out of the war category: “price war”, “war chest” and “war room” stay business questions, verified in the browser gate. Conditional-market phrasings (“what happens to gold if the Fed cuts”, “will oil hit $150”) now land in the markets refusal with the loss-consequence reframe instead of a generic no. /compare answers the question people actually bring an AI product — can it pick stocks or crypto? No, with the reasoning and the honest reframe, in the page and its structured data. Firewall gate grows to 17 checks. |
| 2026-08 | router 2.3.0 | Documented ownership over undocumented control. The router gains a power-claims category: “who controls the banks / the world / the money” questions meet a refusal that neither repeats nor scores the claim — the more powerful the claim, the stronger the evidence it requires, and popularity is not evidence. The refusal points at what actually answers ownership questions (Companies House PSC filings, SEC ownership filings, GLEIF entity data, BIS banking statistics) and states the distinction a lot of these claims blur: an asset manager administering client funds does not thereby own them. A money-figure override keeps real decisions safe — a runway question that happens to mention an entity routes to its model, not to the refusal; both directions are pinned in the firewall gate, now 19 checks. |
| 2026-08 | results · experiments | The cheapest real-world test. When a result’s dominant driver — the input the forecast moves most with — is still classified as an assumption, the result now names the one cheap measurement that would turn it into a fact: a month of itemised outgoings from the bank feed, a written quote instead of an estimate, two people who made the same move asked how long it actually took. The line states the ordering that matters: a measurement like that improves the forecast more than any amount of extra simulation — spend £50 of effort measuring before committing £50,000 on an assumption. When the dominant driver is already a declared fact the line stays silent; there is nothing cheaper than a figure already measured. Display layer only — engine mathematics untouched, 96 frozen results unchanged; both branches pinned in a new release gate (56 gates). |
| 2026-08 | world · three states | Recorded fact, unvalidated estimate and simulated possibility — never blurred into one voice. The UK country page now states LEXUN’s three world states explicitly: the official past (every figure as first published, provenanced, revisions never overwriting the record), the estimated present (deliberately absent — zero live connectors, gated in the coverage registry; a nowcast layer earns publication only by being scored in public against the official releases it tried to anticipate, and none has), and the probabilistic future (the register’s open forecasts frozen with sealed receipts, and the platform’s many-path simulations). The separation is asserted in the world gate, which also pins the zero-connector claim to the registry that derives it. The full backend architecture this framing belongs to is written up as an engineering blueprint in the project tasksheet — a design document, not a shipped system, and the site says nothing about it. |
| 2026-08 | world · knowledge boundary | The gaps become data. A fourth world state joins the record: the knowledge boundary — what LEXUN cannot currently observe, verify or estimate. A machine-readable gap registry now lists every known gap — no estimate of the present, no country beyond the UK, no city evidence, no research parameters, no calibration record, whole question classes refused, century-scale history not yet licensed — each with why it exists, what it does to an answer, what evidence closes it, and what the build verifies it against. A gap that silently closes, or a capability that silently appears, breaks the build; the registry structurally cannot claim completeness. Missing information is modelled as missing: it widens uncertainty or refuses the question, never filled with confidence. New release gate (57 gates); the world gate grows to 13 checks. |
| 2026-08 | accuracy · three histories | Reality, knowledge, expectation — the three histories, kept apart. The Accuracy Centre now states the discipline most forecasting records quietly skip: reality history (outcomes as first published, never rewritten by revision), knowledge history (what could genuinely be known at each entry’s cutoff, sealed by the receipts), and expectation history — what LEXUN believed would happen next, which is the history systems lose because keeping it means leaving your worst calls on display. A new belief-history exhibit, regenerated from the ledger at every release, shows every correction on the register with the earlier band still published and the reason in the record’s own words — the withdrawn 62–78% MPC call beside the 70–84% entry that superseded it. Entries ever issued, withdrawn, deleted and edited are counted from the ledger: deleted and edited are zero by construction. The missing external expectation archive (IMF and central-bank projection vintages) is recorded as a gap in the gap registry, not papered over. World gate grows to 15 checks. |
| 2026-08 | homepage · mobile | The blank-viewport bug, fixed at the root. The entrance choreography pre-hid every section’s content with opacity:0 until an IntersectionObserver revealed it — so phones met black and white empty screens mid-scroll, and a blocked script erased the whole page below the hero. The choreography is gone: content is simply there, with or without JavaScript. The three “Swipe for more” rails now stack vertically on phones — nothing essential hides off-axis; the swipe hints went with them. The hero says what the product does — See what could happen before you decide — and a discreet Analyse action follows on phones once the hero scrolls away. The live tile’s bare “—” placeholders became a labelled simulating state that resolves into computed values; with JavaScript off it says plainly that the demonstration cannot run and points at the precomputed worked example instead of faking one. A new release gate scrolls the homepage at five widths, JavaScript on and off, and fails the build on any blank viewport band or horizontal overflow (58 gates). |
| 2026-08 | homepage · decision record | The record becomes the product. The hero now asks the product’s real question — Will this still be true when the date arrives? — and says what you leave with: a probability band, a receipt you can replay, and a date when reality is allowed to answer. A trust rail states the checkable facts (on-device, the company number, no accuracy % claimed on any decision model, and the next public score date, stamped from the ledger at every release). The live worked example is framed as what it is — a Decision Record — with a visible freeze line: a dated, checkable test, without which a forecast is only a sketch. The public record strip now leads with the miss: f/003, Brier 0.25, band 42–58% on July CPI, and reality answered up — the entry stays at the same size as the hits. The five-surfaces rail and audience triptych left the homepage for their own pages, replaced by the three released models and an honest till: free is the full engine, the maths never gets better when you pay, and unbuilt tier features are labelled, not sold. |
| 2026-08 | homepage · key | The Earth is back on the phone, and the Key stops pretending to be a login. On phones the entrance now keeps a real horizon: the orbital footage holds the top quarter of the first screen before the question begins, instead of surviving as a sliver behind the header — same footage, honest composition, verified by screenshot at 390×844. And the header control that opened the LEXUN Key was labelled “Sign in” — the language of a server account, which the Key is not. It now says Your Key on all 35 pages and in the panel itself: a key that is created and kept on your device, not a session granted by us. The vault’s own copy was corrected to match (“unlock it”, not “sign in with it”). New-component prose that sat below 14px was raised to the floor. |
| 2026-08 | platform · breakpoint | The number that changes the answer, drawn. Every result now carries a breakpoint block: the engine already computed the 50/50 threshold for each model — the revenue growth, confirmed income or largest commitment at which the median path flips — and it now stands beside the figure you actually entered, with the decision margin between them in real units (£/month or points of growth, never a score). A fragile–buffer line marks where you are; the marker’s position is illustrative and says so, the numbers are exact and come from re-running the same seeded simulation. Verified on all three released models. |
| 2026-08 | homepage · breakpoint | The breakpoint reaches the front door, and the chips stop disagreeing with the card. The live Decision Record tile now carries its own breakpoint line: the growth rate at which the worked example’s survival flips to 50/50, computed by the same run that fills the card, beside the assumed 2%/month and the margin between them in points of growth — with the fragile–buffer marker from the platform’s breakpoint block. And the cash-runway example chip previously answered a different question than the paper card beside it (an 18-month horizon with no growth, band 25–35%, against the card’s 12-month 60–70%) — honest but confusing side by side. The chip now poses the card’s exact question, growth assumption included, and its engine-computed badge lands on the same 60–70% band. Nothing typed ahead of time: both figures are computed in the visitor’s browser. |
| 2026-09 | one truth everywhere · five contradictions closed | An outside A–Z audit found five places where this site contradicted itself, and the point it made about all of them is the right one: they were data being maintained as prose. Each is fixed, and each now has a check that reads the source rather than the sentence. The Trust page was wrong about the worked example. On the page whose subject is that this site cannot contradict itself, the canonical runway run was described as having a top driver of “monthly revenue” and a stress case “near 30%”. The engine says monthly costs (62 points against revenue’s 46) and a stress scenario of 21.7% — beside a reproducibility id that resolves to the run that disagreed. The homepage’s copy of this example had been checked against the engine for months; nothing checked anyone else’s. Every page that quotes the seed now is. The privacy notice could not count its own list. It opened “there are exactly seven ways personal data can reach us” and then listed eight, a) to h). A route had been added and the number had not. The count is now checked against the number of routes actually enumerated. The Key’s email is optional and the legal copy said it was not. The field’s placeholder is “Leave blank to skip”; Terms said “we receive the email address you type at sign-up … and nothing else” and Privacy said “we receive two things”, both describing a transmission that does not happen on the path the interface actively invites. A policy that overstates what is collected is still wrong about what is collected. /join was three releases out of date. It told visitors the free tier includes three decision runs while /plans said runs are unlimited; it named the retired Plus plan inside a consent statement; and under the heading “Unlike every prediction company: our accuracy is public” it described a live track record, when the three decision models have no resolved outcomes at all. audit/pricing.py had reported CLEAN throughout, because it checks prices and an allowance is not a price. Three new checks cover the class: what the free plan includes, against billing.js; retired plan names, in pages and in the scripts that write UI copy; and any claim of a track record while none exists. A status table that was wrong about status. /packages marked the AI Copilot LIVE while /agent told the same visitor, at runtime, that the assistant is not connected on this deployment. Both were honest alone. The Copilot function returns 503 until an assistant key is set, which is a deployment fact no static check can know — so the page asks, once, the way the pricing pages already ask about checkout, and says plainly that the key is missing. It corrects itself the moment the key is set, with nobody editing prose. And one this release’s predecessor caused. The Key control’s short label was two spans with one hidden by display:none — which removes an element from the accessibility tree but not from textContent, so every text extractor read “Get your KeyKey”. The short form is generated content now: one label in the DOM, at every width. Separately, a layout fault nobody could measure. The entrance stage is a grid, and the trust strip inside it broke out of the text column with width 1120px, left 50% and a negative transform. In a grid that does not overflow the column — it widens it — so every other child was centred inside a column wider than the box holding it, and the headline, subheading, command box and three decision cards all sat 184px right of the page centre at 1440px. The strip’s compensating shift never ran either, because the stage kills reveal transforms on its children with transform:none!important, so it ran 584 pixels past the right edge, clipped rather than scrolling, with its last guarantee cut in half. Every sweep passed: nothing overflowed the document, and no gate measured where anything was. It does now. And the workspace got its doors back. A release removed “Sign in / Get started” from the top bar for a reason that still holds — there is no account — but it removed the doors with the words, leaving openKeyPanel() and the #authpair logic with no markup to act on and a returning person’s only route to their own encrypted record being a pill reading “Not saved yet”. The two doors are back under the only names that are true here: Unlock my record and Create your Key. Neither says account, because there is not one. No model version, seed derivation or hash function changed; all 96 frozen results resolve unchanged. And three more from a second, deeper audit. The defensibility page claimed a flywheel this architecture forbids. It said “each resolved outcome sharpens the reference classes and priors for its domain — accuracy improves as a function of usage”. Decisions and outcomes are encrypted on the visitor’s own device and never transmitted, so a private outcome cannot sharpen anything for anybody else, and there is no corpus of customer outcomes here. The page now says what actually compounds — the public register, and each person’s own calibration on their own machine — and says plainly that consented anonymised aggregation, if it is ever built, will be announced as a change to what leaves your device rather than shipped as a side effect. That was the one claim on this site that the privacy notice forbade. The same page was wrong about its own register: it said the register opened with six frozen forecasts; the ledger records ten on 14 August 2026, and two more on the 30th. And the security page contradicted itself about the assistant. Its server-side data-flow table — the one headed “that is the complete list” — promised “never any decision, figure, assumption or result”, four paragraphs after the same page correctly described Explain, Challenge and Board Summary sending a result summary containing the band, the probability range, the scenario percentages and the names of the inputs with which are assumptions. Both sentences described the same request; the wrong one was the sentence a procurement reviewer reads. The row now states what the code sends and what it never sends — the figures — and a check reads the shaped context and fails if that row overclaims again. Test suite: 576 checks. |
| 2026-09 | a to z · aria · the label that only shortened where a script ran | A whole-site sweep for defects, and three real ones. Forty-five pages driven in a real browser at four widths: zero page errors, zero sideways scroll, zero broken media, and no dangling reference anywhere. The three that were found were all invisible to the gates that already run. A control that announced a menu which did not exist. The Menu button ships in the markup of forty pages carrying aria-controls="lxnav-sheet", and the sheet was built on first click — so from page load until somebody pressed it, that attribute pointed at nothing, and a screen-reader user was told there was a menu to go to when there was not. axe grades a dangling aria-controls below the threshold the release gate blocks on, which is why five releases of a clean sweep never mentioned it. The sheet is built when the button is wired now, and the sweep gained a check of its own: every id named by aria-controls, aria-labelledby, aria-describedby or a label’s for must resolve on the page as it actually runs. A rule that was only a rule where a script happened to run. The Key control shortens to “Key” below 35 rem so it fits a 320-pixel header, and the previous release chose that wording inside key-panel.js from matchMedia. /agent ships the same header and does not load the key panel, so its label never shortened and it was the last page in the bundle still scrolling sideways. The switch is CSS now and the script writes the markup CSS needs; the accessible name carries the whole sentence at every width. And markup that could never have rendered. The first attempt at that swap left two spans in forty-one pages that the next textContent assignment deleted before they could paint, plus a stylesheet rule for them that could never apply. Both removed. Also checked and clean, none of it previously covered: WCAG 1.4.4 reflow at 200% zoom on ten pages; the light chapter’s inverted chrome in Chromium, Firefox and WebKit; the site with JavaScript off, under forced colours, and under reduced motion; twenty-six tabs of keyboard-only navigation with a visible ring on every stop; 280 px, 2560 px and a 400 px-tall viewport; three independent loads producing byte-identical figures; the workspace walked end to end to a band and a receipt; and 803 fuzzed runs across all three models — no NaN, no Infinity, no probability outside 0–1, no out-of-order quantile, no throw. No model version, seed derivation or hash function changed; all 96 frozen results resolve unchanged. Test suite: 566 checks. |
| 2026-09 | presentation · page length · one label · one price | The second half of an outside design review, executed against its own acceptance criteria — and two defects it did not find. The review was re-checked page by page first, because it was written against the live site before the previous two releases and several of its findings had already been fixed. What survived was actioned. Page length. The homepage laid the whole worked example out end to end — six figures, the breakpoint, a change-one-number control, four scenario chips, the path canvas, four archetype charts and the freeze panel — to a visitor who had not run one. Four instruments moved behind one door labelled with what is behind it; the same markup, the same ids, the same live engine writing into them. The nine-field record schema moved to the Accuracy Centre, where the documentation lives, and the public record took the width the schema had been sharing. Measured at 1440×900: 5,871 → 4,749 px; on a Pixel 5 at 393 px through real device emulation, 7,569 → 6,371 px. /organisations lost a five-card intro that previewed sections four seconds below it, nine of fourteen record fields to a disclosure, six of ten capability rows to another, a duplicate Pro card that belongs on /plans, and an editorial note about a previous version of the page that had leaked into live copy: 6,894 → 6,313 px and 1,884 → 1,578 words. Nothing was deleted from the site; every cut piece is either consolidated, moved to its natural home, or one click down. One price. /plans opened on the annual toggle and led with £6.58 while every other surface led with £9. Both are true and both pages state both, but a person skimming three pages saw two prices for one plan. The page opens on monthly now; no figure changed, and a test asserts all four surfaces lead with the same one. A fifth label the review did not catch. It listed four names for one act and they had already been unified. Checking the whole site rather than the homepage found a fifth: “Analyse a decision” pointed at /platform from the Free plan’s button, the phone’s sticky pill, the glass-box page and the command palette. One label now, and the invariant is asserted across every page that ships rather than on the homepage alone. A defect nobody had ever been able to see. Six rules in css/premium raise their own specificity with :not(#_) and then exclude themselves from the homepage’s light chapter — by naming .lxlight, which is a class on the section. The class on <html> is .lxpaper. The exclusion never fired, so for six releases the navigation painted near-black text on a near-black bar for the height of that whole chapter. No sweep caught it because the contrast gates photograph pages from the top, where that state does not exist. The axe sweep now scrolls into it and audits it, which found twenty-two further contrast failures in a footer that was 70% black over whatever the body happened to be — stated rather than mixed now. And one this release caused. Relabelling the Key control from “Your Key” to “Get your Key” — so a first-time visitor is told what pressing it does — added fifty pixels to a header row with none to spare, and at 320 px eight pages scrolled sideways. The jargon did not come back: below 35 rem the control says “Key” and carries the whole sentence in its accessible name. Also: the design system is now a document, DESIGN-SYSTEM.md, and a test reads all 38 tokens it quotes back out of the shipped stylesheet, so it cannot rot into a description of a site that no longer exists. Track B of the review — Open Banking, accounting integrations, seasonality, correlated shocks, new domains — is untouched, as its own terms require: every item changes either what this site can truthfully say about computing in your browser, or what a published forecast means. No model version, seed derivation or hash function changed; all 96 frozen results resolve unchanged. Test suite: 565 checks. |
| 2026-09 | core@1.2.0 · runway · career · opportunity · path-trace | The shock stops being able to delete a business, and the same five thousand paths are measured a third more precisely. Two changes to the arithmetic every model runs on, both in lexun-core so all three models and the homepage path tracer share one implementation. First, a defect. Every model advanced a quantity by multiplying it by (1 + growth + normal × volatility) and clamping the result at zero. That bracket goes negative, and the solver on this site lets revenue volatility run to 80% a month — a figure a seasonal or project-based business really does report. Measured on the worked example: at 50% volatility 17% of the five thousand paths had their revenue set to zero by a single month’s draw and, because zero multiplied by anything is zero, never recovered; at 80% volatility it was 64%. Those paths were counted as business failures and reported inside a survival probability. The multiplier is now log-normal — exp(ln(1+g) − v²/2 + v·z), the standard discrete geometric Brownian step — which is strictly positive, so nothing is ever clamped, and whose −v²/2 term keeps the expected multiplier exactly 1+g at every volatility, so turning volatility up widens the spread instead of smuggling in growth. Volatility of zero still returns the closed form to the last bit. Second, the same paths, measured better. Paths now run in antithetic pairs: each block of monthly shocks is used once as drawn and once negated, so a pair that is unluckily optimistic in one half is pessimistic in the other and the two sampling errors cancel rather than accumulate. Measured over 300 independent seeds at 5,000 paths each, the standard deviation of the survival probability falls from 0.69 to 0.45 points — 34% less Monte-Carlo error for identical work, with the mean unmoved (0.6548 against 0.6551), which is what an unbiased variance reduction looks like. A block per path also ends a quiet dependency: a path that ran out of cash in month three used to consume three draws and leave the next path starting from wherever it stopped. What moved. The canonical worked example goes from 66.5% to 65.1% — inside the published 60–70% band, which does not move, and inside the Monte-Carlo error of the old estimator. All 96 frozen regression results were re-run and re-frozen; the diff is the review, and the reproducibility id rw_52f9a7c3_234 is a hash of the inputs, so it still names the same run. The five demonstration decisions were regenerated from the shipped model, and every page that describes the arithmetic in prose — the Accuracy Centre, the three model guides, the homepage receipt and the board report — was rewritten to match it, with a build check now tying those pages to the code so the description cannot drift from the implementation again. Figures quoted in changelog rows below this one were computed by the previous estimator and are left as written, because a changelog is a record of what was released and not a description of what runs today. Test suite: 562 checks. |
| 2026-09 | homepage · change one number | Change one number, watch the decision move. The worked example’s monthly revenue is now testable in place — £9,000, £12,000 or £15,000 — and each pick reruns the full 5,000-path simulation in the visitor’s browser. Every figure above recomputes through the same render path: the band rolls to its new value, the breakpoint line and growth margin move, the seed and receipt rewrite themselves from the new run (the seed is input-derived, and the page now proves it). A delta line states exactly what changed — “Revenue £12,000 → £9,000 moved the band 60–70% → 25–40% and the growth margin +2.1 → −2.2 pts” — and tested values are labelled as tests, not the example’s measured facts. Engine failure leaves the previous result standing and says so. |
| 2026-09 | homepage · scenario diff | Scenarios stop asking you to remember. Switching the worked example to Downside, Upside or Stress now states the difference instead of leaving it to memory: “vs expected: −19 pts of survival — revenue −10%, growth −1pt” — the exact shifts each scenario applies, printed from the scenario definition itself, with the reminder that it is the same engine and the same seed rule, only the stated shifts differing. Expected clears the line. Announced politely to screen readers as a status. |
| 2026-09 | site · count rule · handoff | The gate that missed its own About page. A sweep found /about still saying “ten forecasts issued” — in the visible FAQ and in its FAQPage structured data — two days after the register reached twelve, llms.txt saying the same with “two remain open” (four do), and the About beliefs list calling the resolved-outcome count zero eighteen days after it reached four. The empty-register rule only knew the word “empty”, so a stale non-zero count sailed through. All corrected; per the house rule the defects became rules: the contradiction engine now reads every present-tense forecast count — issued, resolved, open, withdrawn — against the register, thresholds and dated milestones excluded, and knows two more zero-outcome phrasings; two new mutations re-introduce the exact wording and prove the gate names the right rule. Separately, the /* 404 splat in _redirects sat above the archived legal routes and all twenty-four forecast routes, which resolved only because a static file beats an unforced rule. It is now the last line, the page generator inserts above it, and a new check fails the release if anything is ever written below it again. The workspace gained the manifest link every other app page had. A handoff document now ships in the bundle so the project can be resumed from the zip alone. No model version, seed derivation or hash function changed. Run for this release from the shipped bundle: 401 checks; 48 mutation probes caught; 96 frozen unchanged; 15 registry and page audits clean; the browser gates were not run. |
| 2026-09 | organisations · release 1 | Decisions for Organisations — the sellable pilot. A new front door at /organisations (“Your biggest decisions deserve a record”), a packages page with every entitlement labelled live, pilot or planned, the founding pilot (£1,500 for 30 days; £2,500–£5,000 with workshops), the Decision Audit service in three packages, a trust and procurement pack that claims no certification, and a request form on each that books nothing until a person confirms it. A read-only demonstration workspace — Northstar Kitchens Ltd, a company that does not exist — runs five decisions through the whole loop across fourteen destinations with a nine-step tour; every band, sensitivity and receipt is a live runway@1.0.0 output at a stated seed, and the page re-runs all five in the visitor’s browser and reports how many receipts reproduce. A sample board report ships as a page and a PDF. One price configuration now lives in the truth registry and is read by billing.js, the JSON-LD offers, the terms of service and sixteen sales documents; the Teams & Advisers tier (£32 / £24 per seat) is retired; three new contradiction rules — retired price, unregistered price, planned capability sold as live — and a pricing gate police it, with three new mutations proving they fire. Two gates join the release gate (sixty), and the accessibility sweep is rebuilt into the bundle. /enterprise redirects to /organisations; the privacy notice and terms are updated for the new form and prices. No model version, seed derivation or hash function changed; all 96 frozen results resolve unchanged. Run for this release from the shipped bundle: 415 checks; 51 mutation probes caught; 96 frozen unchanged; 17 registry and page audits clean; WCAG 2.1 A/AA sweep clean on 46 pages; the remaining browser gates were not run. |
| 2026-09 | site · glow · performance | The signature glow, a header that paints once, and the fastest first screens the site has had. Every interactive element in the top navigation, the menus, the command palette, the LEXUN Key panel and the workspace now lights up the instant a pointer touches it: the control brightens, a soft halo in the brand accent surrounds it and its surface lifts, in 150 ms, out in 250 ms; keyboard focus mirrors hover exactly, a press lights it on touch, a menu button stays lit while its menu is open and each row lights on its own, and under prefers-reduced-motion the highlight is applied without animation rather than removed. It is one system in one small sheet (css/system.*.css) driven by six custom properties, verified by a new browser gate in Chromium, Firefox and WebKit (46 checks each) that hovers, tabs, presses and opens the menus and reads the computed style back. The Search and Menu buttons now ship in the header markup and cmd.js binds to them instead of building them: the phone header no longer paints at 106 px and collapses to 67 px when the script runs, which was the 0.32-0.36 layout shift on every marketing page that Lighthouse had blamed on the web font. Below 52 rem the header links move into the Menu; the Key link sorts after the brand on phones and sits with the other controls on desktop; a legacy nav rule that boxed the header links in grey on nineteen pages is gone; and the white header CTA keeps black ink on hover instead of turning accent-blue at 2.5:1. The homepage entrance paints the photograph first and attaches the film only after it, WebM first at half the bytes, never under reduced motion or save-data; the film's properties are scoped to the entrance rather than the root. The hero now says what LEXUN is in plain words, the phone header carries the Key and the menu only, and the floating pill yields to the storage notice. The workspace loads its engine one frame after the first paint, opens on New decision where a bare visit lands (Key holders get the overview before first paint), and pre-renders the stage bar and domain help so nothing moves. Lighthouse mobile, medians of three: platform 70 to 91 (first paint 4.5 s to 2.0 s), organisations 82 to 95, plans 81 to 93 and homepage 49 to 63, with every marketing-page layout shift at zero; the homepage's remaining cost is its inline deck script. Tooling: audit/hashcss.py content-hashes a sheet and repoints every page; the contradiction engine's gate-count rule now reads number words beyond fifty (it had silently skipped “sixty”), with a mutation proving it; three glow gates join the release gate (sixty-three). No model version, seed derivation or hash function changed; all 96 frozen results resolve unchanged. Run for this release from the shipped bundle: 459 checks; 52 mutation probes caught; 96 frozen unchanged; 17 registry and page audits clean; WCAG 2.1 A/AA sweep clean on 46 pages; glow gate clean in Chromium, Firefox and WebKit; width sweep clean on 46 pages at 360, 768 and 1440; the remaining browser gates were not run. |
| 2026-09 | revenue · billing · release 2 | The site can now take money, honestly. Three tiers replace the Plus, Professional, Team and Business packages, none of which was ever charged: Free (unlimited runs, three saved decisions, three Copilot messages a day, no card), Pro at £9 a month or £79 a year (every decision kept, exports and the printed Decision Record, the calibration view; a 14-day trial with no card) and Organisation seats at £49 a seat a month or £490 a year (everything in Pro for every seat, the audit-trail export, VAT invoices, priority support; the shared workspace, roles, approvals and SSO stay labelled planned). Enterprise at £25,000 to £100,000 a year after a pilot, the founding pilot and the Decision Audit are unchanged. Six dependency-free Netlify functions (billing-config, checkout, entitlement, portal, stripe-webhook, restore) talk to Stripe over plain HTTPS: Checkout with cards, Apple Pay and Google Pay, annual shown first, promotion codes, VAT numbers for organisations and Stripe Tax when enabled; a trial that needs no card and ends by itself rather than charging; a signed 30-day plan token that the workspace presents on every visit, so Stripe and never the browser decides who holds a plan (seven days of grace when Stripe cannot be reached, a dead token signs the device out to Free, and nothing saved is ever deleted); the Stripe billing portal from Settings, Manage plan; signed webhooks recorded as audit notes on the customer; and a 30-minute sign-in link by email for a plan bought on another device. Checkout is switched on by environment variables alone (STRIPE-SETUP.md); with none set every page says so and nothing is limited. The run meter and the local plan flag are gone: runs are unlimited on every plan, and the upgrade sheet (one screen, one button, a plain way out, never shown twice for the same moment) appears only where the record is wanted: the fourth save on Free, the sealed export and the printed record, the day an outcome is reported, the third run, and the Copilot's daily allowance; every gate stays open while checkout is off. Terms, privacy and cookies are rewritten for the model, with the 1 September and 13 August versions archived under /legal/. Verification: a Stripe stand-in (gates/stripe-mock.mjs) lets the functions be walked with no key, from subscribe through verify, portal, upgrade, cancel, failed payment, recovery, lapse and restore to the webhook signature rules (36 checks), and gates/stripe-live-check.mjs walks the same journey against Stripe test mode with real objects, including a test clock for the failed renewal, whenever a test key is present. A browser journey walked the whole path at 1366 and 360 px: land, three runs, the third-run moment, three saves under a Key, the fourth save opening the sheet, the trial started through the stand-in, /upgrade-success confirming it against Stripe, the 14-day countdown in the workspace, the fourth save and the .lexun export on the trial, Manage plan opening the portal, cancellation on Stripe's side, and re-verification to Free with all four decisions still readable and the export asking again (28 checks each). Also in this release: the sixteen strategy documents with STRATEGY-CORE.md, the 95-organisation target list and REVENUE-AUDIT-2026-09.md ship in the bundle, web-blocked; the contradiction engine now reads the mutation-probe count from the manifest; the roadmap's gate count is sixty-four. No model version, seed derivation or hash function changed; all 96 frozen results resolve unchanged. Run for this release from the shipped bundle: 487 checks; 52 mutation probes caught; 96 frozen unchanged; 17 registry and page audits clean; billing gate 36 checks against the stand-in; browser journey 28 checks at 1366 and at 360 px; WCAG 2.1 A/AA sweep clean on 46 pages and on the upgrade sheet; glow gate clean in Chromium, Firefox and WebKit; width sweep clean on 46 pages at 360, 768 and 1440; Lighthouse mobile on the static server: plans 94, packages 99, platform 91 to 94, homepage 56; the Stripe test-mode gate was not run because no test key exists yet. |
| 2026-09 | copilot · workspace · release 3 | The Copilot: an assistant that can never put a number on the screen. Four ways to use it in the workspace, each a single request to one server function (netlify/functions/ask.mjs, sharing netlify/lib/copilot.mjs): describe a decision in your own words on New decision and the form is filled only with figures that appear in your words, each marked fact or assumption as you implied, with anything the model inferred dropped and listed as still needed; under a result, Explain this result and Challenge my assumptions; for Organisation seats, a Board summary that travels into the exported decision brief as labelled commentary. Four rules are enforced on the server and tested: no number from the model — every numeral the model was not given is removed and the reply says how many were removed; extraction is quotation — an intake value is accepted only if the person wrote it; the allowance is the server’s — three messages a day on Free, sixty on Pro, two hundred a seat on Organisation, carried in a signed token and backed by a per-address daily ceiling, with the plan read from the Stripe entitlement token and never from the request; cost has a ceiling — identical requests come from a cache, a daily call budget pauses politely, the cheaper model carries intake, explain and challenge when one is named, and the hard spend limit sits in the Anthropic console. The three result buttons send the engine’s result summary — band, probability range, scenario percentages, the names of the inputs and which are assumptions, the sensitivity ranking — and never an input figure; the request is built from a whitelist. Every reply is labelled AI-written or AI-extracted; offline, unconfigured or exhausted, the engine’s own plain explanation is shown instead and the engine itself is never gated. The board summary sells a seat, not Pro: its sheet links to Organisation seats; while checkout is off nothing is limited, as with every workspace gate. Privacy, terms and cookies are rewritten for the Copilot (section 3(g), section 4B, the allowance token lexun.copilot.v1) and dated 3 September 2026, with the 2 September versions archived under /legal/; the security, procurement, packages and plans pages and the sales documents say the same. No model version, seed derivation or hash function changed; all 96 frozen results resolve unchanged. Run for this release from the shipped bundle: 511 checks; 52 mutation probes caught; 96 frozen unchanged; 17 registry and page audits clean; Copilot gate 24 checks against an Anthropic stand-in that deliberately invents figures; billing gate 36 checks against the Stripe stand-in; browser journey for the Copilot 19 checks at 1366 and at 360 px (intake, explain, challenge, the cache, the fourth message opening the sheet, the engine running with the allowance spent, an Organisation seat bought through the stand-in, the board summary and its place in the exported brief); WCAG 2.1 A/AA sweep clean on 46 pages; glow gate clean in Chromium, Firefox and WebKit; width sweep clean on 46 pages at 360, 768 and 1440; Lighthouse mobile on the static server: platform 91 to 92, plans 96; the Stripe test-mode gate and the live Anthropic key were not run because neither key exists on this deployment yet. |
| 2026-09 | homepage · about | Who we are, where it belongs. The company line (CA Capital Limited and the company number) leaves the homepage hero’s trust rail, which now carries three statements about the product, and a Who we are block joins the closing section: the operating company, its registration and registered office, that LEXUN is founder-built and independent, that the site is a public record, and that LEXUN is a trading name of CA Capital Limited not connected to any cryptocurrency exchange or other company using a similar name; the About page carries the same disambiguation sentence. The About page’s privacy answer no longer says the only thing that ever leaves the device is an email address — since v168 and v169 that is also a payment made on Stripe’s own page and the words typed to the optional Copilot — and the FAQ structured data says the same. Nothing else changed: no model version, seed derivation or hash function; all 96 frozen results resolve unchanged. Run for this release from the shipped bundle: 511 checks; 52 mutation probes caught; 96 frozen unchanged; 17 registry and page audits clean; WCAG 2.1 A/AA sweep clean on the two changed pages; the homepage rendered at 1366 and 360 px with the new block and no page errors. |
| 2026-09 | homepage · ledger · audit tools | The planet is the picture, and the ledger says which board it counts. Homepage: the two veils that blacked out most of the entrance film — a gradient to solid black by mid-screen and a radial shade behind the words — are cut to what legibility needs, so the film fills the first screen on desktop and on phones alike; the form floats as glass over it; on wide screens the film gets a small lift in brightness; the words start a little lower so the opening is planet first. Phones: a 3G connection class no longer removes the film (Android reports 3G on good connections, and phones were seeing the still where desktops saw the planet turn) — it gets a 720-pixel film at a third of the bytes (earth-loop-sm, 0.7 MB WebM / 0.9 MB MP4), armed only once the page has loaded and gone idle; Save-Data, reduced motion and the two slowest classes still remove it; a refused autoplay now starts on any first gesture; the still is chosen by screen height on phones so it is sharp when it has to stand alone. External audit of the live site (3 September 2026), five findings fixed: the homepage counter is labelled Editorial forecasts resolved and says in the same breath that the decision models have 0 resolved outcomes; the Accuracy Centre and the trust page say Model-domain outcomes resolved: 0 and point at the editorial register separately, and the Accuracy Centre states once that Major purchase is opportunity@1.0.0; the name Big purchase and the label purchase 1.0 are gone from every public string; the worked example is inlined for the no-script render (survival 60–70%, runway 9 / 12+ / 12+ months, confidence moderate, driver monthly costs), marked precomputed at seed 564 and replaced by the live run when scripts are allowed, so no crawler or no-script visitor ever reads simulating…; the corrections log gains a clock-stamped entry acknowledging that two earlier entries carried a midnight timestamp that predated the withdrawals they describe (lxf_external_005 at 18:58:41Z and lxf_external_008 at 19:38:41Z on 14 August), which are not edited; audit/forecast.py --correct is now the only way a correction is added and audit/ledger.py refuses any correction dated before the events it refers to unless a later entry acknowledges it. The contradiction engine gains scoreboard-label and scoreboard-count rules read from forecast-ledger.json, and three mutation probes prove them. No model version, seed derivation or hash function changed; all 96 frozen results resolve unchanged. Run for this release from the shipped bundle: 520 checks; 55 mutation probes caught; 96 frozen unchanged; 17 registry and page audits clean; the ledger gate shown failing on the two midnight stamps with the acknowledgement removed and passing with it; WCAG 2.1 A/AA sweep clean on 46 pages; glow gate clean in Chromium; width sweep clean on 46 pages at 360, 768 and 1440; the entrance rendered at 1366, 1920 and 390 px and on a simulated 3G phone with the small film playing; Lighthouse mobile on the static server: homepage 57 to 62 against 55 to 57 for the previous bundle. |
| 2026-09 | workspace · the live readout | The simulator answers while you type. The decision screen no longer ends in a Run button: a readout sits above the form and holds a real released-model run on whatever figures are in the fields, recomputed every time one of them changes — the same analyse() call, the same seed rule, the same reproducibility ID that /reproduce replays, computed in the engine worker so typing never blocks. Move monthly costs from £18,000 to £11,000 and the band goes 60–70% to 95–100% with a new receipt, in place. It fills no gap: while a required figure is missing the number is an em dash and the missing fields are named, an unknown is refused by name, and when the evidence gate holds — LEXUN will not put a probability on six guesses — the readout says a stated fact is what it wants and points at the control that gives it, without ever making that choice for you. A live run steers; Freeze is still the run that writes the record, with its receipt, journal and due date. The explanation under each question is folded away by default behind one switch that remembers itself (lexunp.guidance.v1, published on the cookies page); every word is still in the page and still read aloud when opened. Horizon, reversibility, risk appetite, country and currency fold into one line, the reference class folds into another, and the classification strip is compact rather than four full-size buttons a field. On a phone the readout stays pinned instead of scrolling away. The readiness line no longer calls an optional field a gap, which was the one place the screen contradicted itself. Homepage: the hero sentence is shorter, the three objections and the nine record fields fold. Defects found and fixed in /agent, which shipped without the reset every other page has: no box-sizing and the browser’s default body margin (a pixel of sideways scroll at 320 px), a header copied from the homepage whose stylesheet the page never loaded (raw default-blue links stacked vertically), no base link colour, no visually-hidden rule — screen-reader labels painting black on black — and no styles at all for its own next-steps rail. It now ships the same header, footer and reset as every other page. The visual sweep gained the one thing it lacked: when a page scrolls sideways it now names the element that does it. No model version, seed derivation or hash function changed; all 96 frozen results resolve unchanged. Run for this release from the shipped bundle: 520 checks; 54 mutation probes caught; 96 frozen unchanged; 20 registry and page audits clean; 28 release gates green with one advisory; the decision screen driven in a browser at 1440, 390, 360 and 320 px in both themes. |
| 2026-09 | workspace · correction | The live readout was a second and a half behind. Shipped in v175 and caught on the live site, not in the build: the readout built a fresh Worker for every recompute and terminated it after, so each change paid a cold thread start plus a re-fetch and re-parse of the engine. Measured on lexun.co.uk that was 1,651 ms per change, and because the reply landed after the next keystroke had already been typed the panel showed the previous answer while it waited — a readout that lags is not a live readout. One worker is now created and kept, replies are matched to the run that asked for them by the token protocol engine-worker.js already spoke, and a run that does not come back within 1,200 ms drops the worker and finishes on the main thread instead of waiting four seconds. Measured after the fix: 291–309 ms from keystroke to new band and new receipt, of which 220 ms is the deliberate debounce. No model version, seed derivation or hash function changed; all 96 frozen results resolve unchanged, and the receipts are the same ones v175 produced — only the wait is gone. Run for this release from the shipped bundle: 520 checks; 54 mutation probes caught; 96 frozen unchanged; 20 registry and page audits clean; 28 release gates green with one advisory; the change-to-answer latency measured five times in a browser. |
| 2026-09 | solver · retired product · two new gates | The questions a probability cannot answer on its own. A new solver (platform/solve.js) answers three of them by running the released model again and reading what it returns — it contains no mathematics of its own, no fitted curve and no interpolated midpoint, and a release gate now asserts that. What must be true reports the value each input would have to take, alone, to reach a target the person picks — located by scanning the range and refining the bracket, never by bisection, because bisection silently assumes a monotonic curve and survival is not dependably monotonic in volatility. Worth measuring and not worth researching fall out of the same sweep, and the distinction between them is only possible because LEXUN already makes people label each figure a fact or an assumption: that label now sets how far the solver will move the number, so a bank balance is swept ±10% and a guessed growth rate ±5 points. A fact that moves the answer is not something to go and research — you already know it. How close to the edge reports the nearest value at which the verdict band itself changes, or says plainly that nothing in range changes it. Every probe runs on the seed of the result above it, at the 1,500-path budget the model’s own sensitivity already uses, and the swept window is shown with every answer because a threshold without its range means nothing. It sits behind a press, one level below the answer, and takes about a fifth of a second. Find My Money is gone from every surface a visitor can reach. Deleting the page in v174 was the easy half: the workspace still built a Decision Radar card linking to /findmoney — a dead button in production pointing at a 301 — the cookies page still documented three storage keys nothing wrote, and the registry still carried four evidence sources whose only consumer was the removed tool. All gone; a device that used it has its leftover data deleted once, on that device. The career model’s honest limitation is reworded generically (“any other income or support during the transition”) — the limitation itself is unchanged. Two gates join the release chain (thirty): one fails the build if the retired product reappears in any shipped surface, sitemap, palette or registry, and one fails it if any displayed figure could originate in a sentence rather than the engine. Both were written, found to pass a deliberate break, and rewritten until every break fired — the first missed “benefits you are not claiming” because it required the verb before the noun, and the second missed a deleted numeral count because it read three files as one string. No model version, seed derivation or hash function changed; all 96 frozen results resolve unchanged and the canonical runway receipt is still rw_52f9a7c3_234 at 60–70%. Run for this release from the shipped bundle: 520 checks; 54 mutation probes caught; 96 frozen unchanged; 22 registry and page audits clean; 30 release gates green with one advisory. |
| 2026-09 | entrance · hero · sign in | One entrance, not two. The homepage painted a photograph of Earth, then a moment later dissolved a video film in over it and hid the photograph. That swap lands about when a visitor is leaving the first screen, which is why it reads as the globe changing into a different animation on scroll. An entrance that becomes a second entrance is not an entrance, so the film is gone: no <video>, no earth-film.js, no six earth-loop files, no _headers rules for them, and no MEDIA bundle at all — the release is one zip now instead of two, and the site went from 29 MB to 11. What remains is the photograph and the city lights extracted from that same photograph, twinkling on it: one image, one motion, derived from itself, and still stopped entirely under reduced motion. Verified by driving the whole entrance scroll in a browser: zero video or WebM requests at any point. Sign in is back on a phone. A rule added in v174 to stop the top bar overflowing at 320 px hid #btnSignIn below 35 rem, so a returning person on a phone was offered only “Get started” — the door for someone who has never been here — with no way back into their own record. Search steps aside instead: it is a convenience, it is still on Ctrl+K and still in the menu, and a way back into your record is not a convenience. Both doors now show at 320, 360, 390, 430 and 1440 px with no sideways scroll at any of them. The hero names the act. “An honest probability for a cash, career or purchase decision” described what you leave with, which only lands if you already know what LEXUN is for. It now reads Simulate the decision before you live it, the subheading is 23 words instead of 39, and the button says Simulate futures. The dated-record question survives the rewrite — it is what separates a forecast from an opinion — but it moved out of the subheading, where it read as a caveat, into the trust strip, where it reads as a promise. Six tests went with the film and the published check count follows the suite: 520 → 517, corrected in the truth registry first and then in all sixteen places that publish it, which is the gate that caught the drift in the first place. No model version, seed derivation or hash function changed; all 96 frozen results resolve unchanged and the canonical runway receipt is still rw_52f9a7c3_234 at 60–70%. Run for this release from the shipped bundle: 517 checks; 54 mutation probes caught; 96 frozen unchanged; 22 registry and page audits clean; 30 release gates green with one advisory. |
| 2026-09 | navigation · four destinations | The site stops advertising itself and points at the simulator. Every page carried five primary destinations — Ask LEXUN, Decisions, Evidence, Organisations, Pricing — and a nineteen-link footer in five groups, which is a documentation site’s navigation on a product that does one thing. The header is now four: Simulate, My decisions, Evidence, Teams, with one call to action, Run a simulation, on all forty-two pages that ship a header. The footer is fifteen links in four groups. Nothing was orphaned to achieve it. Templates became Quick Starts inside the simulator; Pricing moved to the footer and Teams; and the evidence pages — the forecast register, verify, the trust centre, the glass box, reproduce, coverage and Earth — left the global footer because /accuracy already links to every one of them, so they did not lose a home, they gained a parent. That is the whole point of an Evidence hub: one system, not six trust products. /agent comes out of the primary navigation for a reason beyond tidiness — on a deployment without an API key it advertises an assistant that cannot answer — and is now linked from the simulator’s own intake, beside the form it is an alternative to. /join is linked from the plans page. The internal-link sweep is down to a single pre-existing advisory. The command palette still reaches every indexable page, so nothing became unfindable, only un-advertised. No model version, seed derivation or hash function changed; 96 frozen results unchanged. Run for this release from the shipped bundle: 517 checks; 54 mutation probes caught; 96 frozen unchanged; 22 registry and page audits clean; 30 release gates green with one advisory. Two gates had to be repaired to get there, and both repairs are the point: the glow gate probed a header link that the new navigation no longer carries, and the contradiction engine’s solicitor-review rule silenced itself because an unrelated neighbouring sentence — the new “Not ready to run one yet?” line on the plans page — fell inside its 120-character negation window. A window measures proximity; what matters is whether the negation attaches to the claim, so the rule now reads the sentence. The mutation that had started surviving is caught again: 54 of 54. |
| 2026-09 | entity · structured data | The strongest identity signal on the site pointed at a domain that does not exist. Forty-five pages published sameAs as find-and-check.company-information.service.gov.uk. Companies House is find-and-update. The visible footer link had it right the whole time, so nothing a human clicked ever revealed it — only the machine-readable claim was broken, which is exactly the claim search and answer engines read. A sameAs that does not resolve is worse than none: an engine following it finds nothing and has been given a reason to doubt the rest. Corrected in 51 places, verified against the live register (CA CAPITAL LIMITED, 10848369, 320 Firecrest Court, Warrington WA1 1RG, Active), and now gated: the schema audit checks every sameAs host against the register of hosts LEXUN is actually on and the company number in the URL against the truth registry. Three deliberate breaks — the dead domain returning, a link to an unrelated host, a wrong company number — all fire. The forecast register now says it is a dataset. Twelve dated forecasts, frozen before the answer was known, licensed, downloadable as JSON and scored once reality answers: that is what Dataset structured data is for, and here it is true rather than aspirational, which is the only reason to claim it. Every value — the counts, the temporal coverage, the download URL — is read from forecast-ledger.json at build time, and two tests assert the description cannot drift from the file it describes. /agent gained the Twitter card it was missing, mirroring its own Open Graph tags so the two cannot disagree. The published check count follows the suite again: 517 → 519, in the truth registry first. No model version, seed derivation or hash function changed; 96 frozen results unchanged. Run for this release from the shipped bundle: 519 checks; 54 mutation probes caught; 96 frozen unchanged; 22 registry and page audits clean; 30 release gates green with one advisory. |
| 2026-09 | search · the queries LEXUN can actually win | The simulator’s own page targeted nothing. /platform is the most important page on the site and its title was “LEXUN Platform — decide, then measure”: a brand nobody is searching for yet, followed by an internal slogan. It now says what the page does. The homepage spent the highest-weight position in its tag the same way and now leads with the job. The runway page stopped fighting a race it loses. Searching “cash runway calculator” returns deterministic calculators from accounting and fintech brands with far more authority — cash divided by burn, one number. Searching the probability framing returns something different: every result is an article explaining Monte Carlo, and not one of them is a tool that runs one. That lane is open and LEXUN genuinely occupies it, so the page claims the differentiated query (“Cash runway probability — will it survive?”) and keeps the head term in the description rather than losing to it in the title. The on-page audit then caught four things the rewrite broke or exposed, each of which is the same class of defect: a title over 60 characters, a description over 160, a page missing its brand token, and five structured-data nodes whose name and description no longer matched the tags a reader sees. A page that tells a person one thing and an engine another is the problem this site exists to avoid, so all five were realigned to the page’s own title and meta. No copy claims a ranking, because nobody can honestly promise one. No model version, seed derivation or hash function changed; 96 frozen results unchanged. Run for this release from the shipped bundle: 519 checks; 54 mutation probes caught; 96 frozen unchanged; 22 registry and page audits clean; 30 release gates green with one advisory — after fixing a gate that had been failing for a reason nobody had looked at. The glow check starts its own server on a fixed port and the release gate runs it three times, so the second and third died with EADDRINUSE. Playwright reported that as “Target page, context or browser has been closed”, which reads exactly like a browser crash, and WebKit had been blocking releases while passing three times out of three on its own. It was two servers asking for port 8901. The gate now binds an OS-assigned port. With that gone a genuine, rarer crash remains — WebKit dying under the memory of three browsers and the visual sweep at once — so a browser gate that CRASHES is retried once, and only a crash: a gate that fails an assertion still blocks on the first attempt, and a retry that succeeds prints that it happened rather than hiding it. |
| 2026-09 | the future field · the globe, retired · two new gates | The entrance stops being a picture of a planet and becomes the simulation itself. The homepage entrance is now the FUTURE FIELD: the density of 5,000 simulated cash paths spreading out from now, computed in the visitor’s own browser by path-trace.js — the same generator that runway-model.js uses, held identical to it path for path by test. Brightness is the share of futures in that cash band at that month; the median and the tenth and ninetieth are drawn from the same array the density came from; the canvas’s accessible name is written by the renderer from the quantiles it drew, so the picture and its description cannot disagree. Two of the author’s own defects were caught before release and are recorded here because they are the interesting part: a path that goes insolvent STOPS, so its cash array is shorter than the horizon — reading past the end gave a month-12 ninetieth percentile of NaN and a median £46,000 above the model’s own, fixed by holding a failed path at its terminal cash exactly as the model scores it; and a frame scheduled by the last batch of paths could land after the finished field was drawn and repaint it without the quantile lines, erasing from the picture the very lines the text underneath said were there. The globe is gone from the bundle, not just from the page — earth.html, five scripts and four images, about 240KB, plus every link to them from the simulator footer, the dashboard, the roadmap, the sitemap and the command palette; /earth now redirects permanently to the simulator. The simulator has no sign-in button. There was never an account behind it — the Key is a local passcode — so a top bar that opened with “Sign in” and “Get started” was the loudest contradiction on a product whose claim is that you can just run the thing; the header now offers one action, and it is a simulation. The hero is one line over one input, and the five sentences of claims under it are four words, with the two statements it would be dishonest to drop kept as one fine line. New gate: NO-GLOBE (audit/noglobe.py) — the planet stays deleted and what replaced it stays real: no globe file, link, sitemap entry or markup survives, and the field’s renderer may hold no random number generator, no network call and no hand-written path data. It was proven against eight deliberate breaks, one of which it initially missed: pointing the field at a fake tracer passed because the page loaded the real one elsewhere, so every assertion is now scoped to the field’s own boot block. Three gates were themselves repaired. The visual sweep could not resolve Playwright under ESM and reported “failed” without running a single check — a gate that cannot start has not failed, and saying so matters; it now skips like its siblings, and passes 20/20 for the first time. It also failed on 404s from serverless endpoints that a static file server cannot serve, so those are now counted and printed as a note instead — and because that exemption would have hidden a mistyped function path, the technical gate now requires every /api/ path any shipped file calls to have a redirect rule AND a function file that exists. The mono-discipline rule learned that U+2212 MINUS SIGN is a figure character. Jobsafe leaves every navigation surface and stays findable in search. One more thing the new gate then found: the globe’s DATA had outlived its code — earth-data/, 3.5MB of coastlines and place names, 85% of the release zip, sitting in the bundle because no page loaded it and so no gate had a reason to look. The release is 7.1MB instead of 11MB. 526 checks, 31 gates, all green. |
| 2026-09 | homepage · the story · the copy | The homepage becomes one sequence instead of four panels. Every stage of a run is now labelled where it happens — 04 the spread, 05 alternate futures, 06 breakpoint, 07 the answer, 08 change the future — so a reader knows they are still inside one story rather than looking at unrelated widgets. The breakpoint is a headline figure. It was a row in a table set at the same size as its own labels; it is the single number at which the answer changes character, and it now reads as one, with what lies either side of it said in words. “Change one number” becomes CHANGE THE FUTURE and answers in points: moving revenue from £12,000 to £15,000 prints +18.8 pts above the two bands it moved between. That figure is the difference of two probabilities the engine returned on the same seed with one input changed — never a subtraction of the two displayed bands, which would put a number on screen that no run ever computed. The closing essays become fact lines. Who we are and what leaves the browser were two paragraphs that said true and necessary things in a form nobody finishes reading; they are now eight scannable statements, with the company number, the registered office, the one stated exception to local-only processing and the GDPR basis all still on the screen and the full text still on /about and /privacy. Visible prose on the homepage is down by a third, to 388 words — the rest of what is on screen is labels and live figures, which is the point. The visual sweep caught the author twice more and was right both times: the stage marks were set in the monospace face, which on this site means “the engine produced this” and should not be spent on a section label; and the entrance stagger had a flat 60ms step that pushed the last element past the 600ms ceiling the moment the stage grew a seventh child — it now compresses to fit. 526 checks, 31 gates, all green. |
| 2026-09 | the globe returns · terminator · city lights | The Earth comes back — at the close, turning, with a real day and a real night. It is not the entrance: that stays the Future Field, and the retired /earth product stays retired. It is the last thing on the home page, at its own size in the open, and every element of it is real. Coastlines are Natural Earth 110m (public domain). The 1,100 lights on the night side are GeoNames city coordinates under CC BY 4.0, names and country codes stripped because the globe draws points of light and never a label — both are credited on /cite, and the gate now fails the build if that credit is removed, because on a CC BY dataset the credit is the whole of what is asked in return. The terminator is computed from the sun’s actual subsolar point for the date and time: the tilt is 23.44°, so the north polar cap is lit in June and dark in December because the planet is tilted rather than because someone drew it that way. The first terminator was wrong, and the way it was wrong is the point. It traced the day/night boundary as latitude against longitude and closed it around whichever pole was dark. That works for most of the year and collapses near an equinox — which is when it shipped: at a solar declination of six degrees the boundary runs nearly along a meridian, most longitudes have no crossing at all, and the few that do closed into a polygon covering the wrong half of the world. The screen showed Europe in daylight at 17:45 UTC with its own city lights on. Real coastlines, real cities, a real sun, and a false picture — which is the exact failure this codebase is built against, arriving through the one door nobody was watching. The shadow is now the sun’s height at each cell of the disc, inverse-projected back to a latitude and longitude: the definition of night rather than a construction that approximates it, incapable of degenerating at any date, and it brings a real twilight band with it. The globe is declared decoration in the markup and holds no figure, no caption, no legend and no marker; the gate proves that against eight deliberate breaks, and would fail the build if it ever moved above the fold. 61fps, 4,684 coastline points and 1,100 lights a frame, stopped when off screen, when the tab is hidden, and for anyone who asked motion to stop. 535 checks, 31 gates, all green. |
| 2026-09 | the globe, photographed · three gates that were not running | The Earth at the close is now the picture it was asked to be — and finding out why it was slow uncovered a release gate that had been green without running. The globe was a bright blue schematic with a survey graticule across it, which reads as an atlas. It is now the photograph: a nearly black planet, 3,200 real GeoNames cities glowing warm amber on the night side, and the sun coming round the limb as a hard gold flare that travels with the real subsolar point. A thin dawn band runs along the terminator itself, drawn exactly where the shadow calculation says the sun is rising. Then it ran at 19fps. Profiling said land 0.34ms, shadow 0.19ms, lights 11.92ms — and the profile was misleading, because hiding the globe restored 61fps while every other section was already at 61. The cost was area: the same globe at 420 pixels ran at 61, and area is the square of the radius. Three fixes, in order of what they were worth: the drawing surface is capped at 720 pixels and CSS stretches it (every layer here is a soft one, so nothing upscaling would betray); the ocean and the halo are baked once at layout instead of being re-filled sixty times a second to produce identical pixels; the terminator is recomputed when it has moved half a degree rather than every frame. 61fps, at any size on the page. Three gates were not doing their job, and two were hiding each other. gates/axe-sweep.mjs exits 0 with a SKIP notice when axe-core is absent — correct behaviour — and the release gate read the zero exit as a pass. Every run this session printed “Accessibility — WCAG 2.1 AA, every page ✓” for a sweep that had never executed a single check. It also bound port 8899, the very port the release gate requires a server on, so it would have crashed even with axe-core present. Both fixed: an OS-assigned port, and axe-core installed — the sweep now genuinely runs and passes 45 pages. The rule that let it through is fixed too, and took two attempts to get right. Matching the word SKIP over-caught: glow-check legitimately skips two of its forty-four checks on Firefox, which is the gate working, and that was reported as the gate not running. The test is not whether output mentions a skip but whether the gate produced a RESULT — and the gates announce results in several dialects, including a lowercase “all 44 passed” that an uppercase test missed. A critical gate that produced nothing now blocks, for the same reason a missing script does. The Stripe test-mode gate correctly reports as skipped rather than passing. The globe carries no figure, caption, legend or marker, is declared decoration, and the GeoNames CC BY credit on /cite is a build condition. 535 checks, 31 gates, all green — and now all of them actually ran. |
| 2026-09 | globe · measured once, which is measured at the wrong moment | The closing globe drew itself 1×1 and stayed that way forever if its container had no size at boot. Found by checking the deployed site through a browser pane that had collapsed to a zero viewport: the canvas came back as one pixel square. The site was fine — every element on the page measured zero, because the pane did — but the renderer was not, and the way it was wrong outlives the pane. It read its container’s size once, at boot, and never again. A window resize listener does not fire for an element that gets its size on its own, so a globe that booted inside anything not yet laid out — a background tab, a container waiting on a stylesheet, a phone rotated before first paint, a pane with no viewport — was one pixel across for the life of the page with no way back. Now layout() reports whether it found a real size, nothing is drawn until it has one, and a ResizeObserver on the host re-runs it the moment the element is actually measured. Proven by collapsing the container to zero before boot and then giving it a size: the canvas stays at its untouched default while collapsed and paints correctly the instant it has room. Two stale numbers in the file’s own header were corrected while it was open — it still described 1,100 city lights after the dataset went to 3,200, and its cost note predated the terminator raster and the light buffer. A test now checks the header against the shipped data, because a comment that has drifted is a small untruth in the one place a reader is most likely to believe it. 537 checks, 31 gates, all green. |
| 2026-09 | future archetypes · archetypes@1.0.0 | Five thousand futures become four shapes you can read. A probability tells you how likely survival is; it cannot tell you what the futures look like. “Sixty-seven per cent” does not distinguish a business that mostly drifts gently down from one that mostly holds steady with a minority collapsing hard, and those are entirely different situations. The canonical example now reads: 39% runs out of cash · 31% steep decline · 23% holds steady · 7.3% steady growth. This is the easiest place on the site to lie, so none of it is written. Every share is a count of simulated paths over the number simulated — nothing rounded into a tidier set, nothing floored at a minimum. Every trajectory drawn is the cluster’s MEDOID: the real simulated path nearest its centre, never the centroid, which is an average of paths and therefore a future the engine never produced. Every name is a function of two measurements of that medoid — where it ends against where it started, and whether it dips materially and comes back. A cluster is called “Runs out of cash” when its medoid ends at or below zero and for no other reason. It is reproducible, which k-means is not by default. A random initialisation would give different archetypes on every page load, on a site whose central claim is that the same figures give the same answer. The seeding is k-means++ driven by mulberry32 from the run’s own seed, the loop is a fixed twenty passes with an exact label-equality exit, and ties break to the lower index. Same inputs, same seed, same four shapes, forever. The check that matters is that the clusters and the tracer agree on survival exactly: both count the same five thousand paths from opposite ends, and a disagreement of one would mean the labels had stopped describing the simulation. They agree to the path across every test case. The naming ladder was set from measured output, not chosen for the sound of it — the first version had five rungs and collapsed: a healthy business produced four clusters ending at 1.64, 2.57, 3.63 and 5.13 times opening cash, all four landed on “Steady growth”, and the interface showed one row reading 100%. True and useless. The rungs now sit in the gaps of the distribution actually observed across six test businesses spanning −0.48 to 24.5 times opening cash. Separation is measured and published with the result: where four labels are cutting one continuous spread rather than describing four groups, the block says so instead of presenting four confident categories. Ten new tests hold all of it. 547 checks, 31 gates, all green. |
| 2026-09 | entrance speed · the instrument surface · four fixes | The entrance draws on the first frame instead of the fifth second. The field waited for the hero’s engine result before it started, because the seed arrived in that result — but the seed is a pure function of the inputs, so it derives its own and starts the moment its scripts parse. Core.seedFor is now the one place that derivation lives (it was written out separately in all three models) and the worked example is declared once at the top of the homepage instead of four times. The tracer gains a resumable form, LexunPathTrace.tracer, so the entrance walks its own five thousand paths a chunk at a time and hands the frame back between chunks — which removed a worker spawn and the fifty-four kilobytes of modules that worker re-fetched after the page had already parsed them. traceBatched is rewritten in terms of the stepper, so there is still exactly one loop in the file that walks a path. The engine worker no longer imports career-model.js and opportunity-model.js until a caller names that domain; the closing globe’s ninety-eight kilobytes of coastlines and city lights wait until it is within a screen and a half; the hero boots immediately rather than at an idle callback that cost a measured 425ms. First pixels on the same machine: 3,041ms to 640ms. The globe is larger and the site is colder. The closing Earth grows by about a third, gains a deterministic starfield, a two-ramp atmospheric limb and two crossing orbital rings; the mask that was fading out the planet’s own limb from 58% of the box is corrected. Site-wide, the hairlines take the accent’s hue at the same lightness, panels get a lit top edge and a vertical fall, the 64px instrument grid the design system described is actually drawn, and every figure the engine produced — and only those — carries a faint glow. Four defects fixed. Re-hashing a stylesheet orphaned the dated legal snapshots, which are meant to render as issued: their frozen sheets now live in /legal/css/ where a live re-hash cannot reach them, and audit/tech.py gains a gate that resolves every asset every shipped page references. The 14-day trial pill on the plans page wrapped onto two lines at ordinary desktop widths. A stale premium.c5ecc787.css was shipped unreferenced. The field’s started flag was never reset between runs, which had disarmed the fallback for every run after the first. The globe gate stops requiring a worker and requires the property the worker was a means to: the stepper, the yield, and a budget it actually compares against — both it and the new asset gate were verified by breaking them deliberately and watching them fail. No model version, seed derivation or hash function changed; all 96 frozen results resolve unchanged. Run for this release from the shipped bundle: 552 checks; 53 mutation probes caught; 96 frozen unchanged; 21 registry and page audits clean; WCAG 2.1 A/AA sweep clean on 45 pages; glow gate clean in Chromium, Firefox and WebKit; 46 pages swept for console errors, failed requests and horizontal overflow with none found; the entrance measured on throttled connections before and after (Fast 4G 1,811ms to 1,565ms; Slow 4G 3,924ms to 3,627ms). |
| 2026-09 | the entrance light · arrival · the type | The light stops being a wash and the words stop disappearing into it. The field’s density was mapped through two colours, so only brightness varied and the picture read flat; it now passes through three — indigo in the tail, the interface’s own blue through the body, a near-white core only where futures genuinely crowd — with a bright-pass bloom that lets the dense corridor glow without the sparse region hazing over. The falloff was a cube root, which lifted every cell holding one path in five thousand to a fifth of full brightness and put ink on 71% of the canvas; at 0.55 the near-empty region is near-empty again and the corridor has an edge to be bright against. A contrast failure no accessibility tool could see. axe reads an element’s computed background colour, and the entrance’s background is a canvas — so every line over the field passed by default. Measured under the actual glyph pixels, the hero sub-headline sat at 1.00:1 at 1280 and 1024, meaning the corridor reached the exact luminance of the text and the sentence vanished into the picture. The field is composited at 60%, the sub-headline is set at a reading weight, and the scrim under the words is deepened; every element over the field now clears AA at five widths, worst 5.6:1. gates/hero-contrast.mjs is new and photographs the running page twice per element — once as it renders, once with the element hidden — to measure the real background behind each glyph. It was verified by restoring the old values and watching it fail at five widths. Sections arrive rather than appear. The homepage shipped a reveal system — CSS for a .reveal class and an observer watching for it — and not one element on the page carried the class; it had been animating nothing for its whole life. /reveal.js replaces it on all 46 pages: content enters from below and out of focus and settles, groups stagger, the first screen is settled before the first frame, and a two-pixel reading line reports scroll position. The hidden state is scoped to html.lxjs, so a page whose scripts fail renders every word rather than a stack of empty boxes; live regions, disclosures and hidden panels are skipped after testing found twelve elements inside a closed <details> that would have been permanently invisible once opened. The type is set rather than styled. Both faces are variable and both were rendering with optical sizing off, no contextual alternates and browser-default underlines. Optical sizing on, per-step tracking applied to the headings the scale was written for, tabular figures wherever a number is a measurement and proportional ones in prose, underlines dropped clear of the descenders and thickening on hover, hanging punctuation, and a selection colour. --ls-caps was the one tracking value still in pixels, directly beneath the comment explaining why pixels are wrong there; it is 0.075em, identical at the size it was tuned against. The world is awake. The closing globe’s three thousand two hundred city lights were a fixed map; each now carries its own phase and its own period, both hashed once from its coordinates, so places brighten and thin independently and the pattern never visibly repeats — the same city breathes the same way on every load and every machine, because it is a hash of where it is and not a random number. Verified by sampling the canvas twice 400ms apart: eighteen regions brightening while fifteen dim in the same frame, which rotation alone cannot produce. It is atmosphere and declared as atmosphere — the block stays aria-hidden with no legend, figure or marker, and a brightening light reports nothing about that place. The daylit hemisphere was written to match a photograph of the night side and was the dullest thing in the frame; it is lit at roughly twice the previous strength through a cooler ramp, so the ocean, the coastlines and the colour of the planet read on the half the sun is on. No model version, seed derivation or hash function changed; all 96 frozen results resolve unchanged. Run for this release from the shipped bundle: 552 checks; 53 mutation probes caught; 96 frozen unchanged; 21 registry and page audits clean; WCAG 2.1 A/AA sweep clean on 45 pages; hero-contrast clean at 1440, 1280, 1024, 768 and 390; glow gate clean in Chromium, Firefox and WebKit; 46 pages swept for console errors, failed requests and horizontal overflow with none found. |
| 2026-09 | the entrance answers the visitor · activation | The first screen stops explaining the machinery and starts answering the five questions people arrive with. An external review found the entrance leading with five thousand futures, a seed and a reproducibility id, and leaving “can this help me?”, “what will I get?”, “what do I need?” and “can I trust it?” to be inferred. Every claim it raised was checked against the live form first — all of them held, verbatim. The headline stays Simulate the future.: a position nobody else in this category owns is the asset, and the clarity problem was never in the headline. Underneath it, the sub-line now says what the engine does with your own figures, and a new line says what it costs you before it asks for anything — five figures you already know, no account, no card, numbers stay in this browser. Five and six are measured, not assumed: runway and career reach a result on five figures plus a horizon, major purchase on six. The three decisions become the choice. They were four uppercase chips at eleven and a half pixels, reading as examples of what somebody else might type; they are cards now, each naming a situation and what it tests, and each still carrying the band the engine returns for it — computed live in the browser, not written into the page. The refusal moves out of the chip row and becomes an invitation: watch it refuse a question it cannot answer. The trust strip answers a question instead of listing parts. Four words about the engine became five guarantees about the run — computed in this browser, no tracking cookies, every result reproducible, no invented figures, not financial advice — each of them enforced somewhere in this build rather than asserted here. It spans the hero rather than the text column, because five guarantees wrapped onto a second line read as a list of caveats. Two defects found while building it. The example buttons’ click handler was bound to the container they happened to sit in, so moving the refusal one element outside it silently disconnected the button while leaving it looking clickable; it is bound to the form now and a test asserts the binding, not just the markup. And the id selector that gave the old chips their pill radius outranked the new card rule, rendering the cards as ovals with clipped text — the rule was repointed rather than out-specified. The new hero contrast gate caught its own new line at 4.35:1 before it shipped. And the new scroll reveals had blinded two gates. Content below the fold sits at opacity 0 until it is scrolled to, and both the premium sweep and the WCAG sweep read rendered pixels — so every page’s lower half was being judged mid-arrival. A table header whose real colour is #f4f4f4 on #111111, measuring 17.17:1, was reported at 1.48:1 and failing. Both sweeps now run under reduced motion, which the site’s own CSS answers by settling every revealed block immediately: the tools see what a person who asked for no animation sees, nothing is excluded from the check, and the contrast sweep is clean at 20 of 20 for the first time since the reveals landed. The reviewer’s worked example used invented probabilities; the page uses the engine’s own, at seed 564, as it always has. No model version, seed derivation or hash function changed; all 96 frozen results resolve unchanged. Run for this release from the shipped bundle: 555 checks; 53 mutation probes caught; 96 frozen unchanged; 21 registry and page audits clean; WCAG 2.1 A/AA sweep clean on 45 pages; hero contrast 39 checks clean at five widths; glow gate clean in Chromium, Firefox and WebKit; 46 pages swept for console errors, failed requests and horizontal overflow with none found. |
| 2026-09 | the scroll · five paint costs · a pause that was not pausing | The homepage scrolled badly, and everything making it do so had been added in the previous two releases. Measured across a full scroll of the page: 38% of frames missed their budget, p90 frame time 50ms, worst frame 83ms. It is 9.5% now, p90 16.8ms, worst 50ms — and the fix was found by isolation rather than guesswork, disabling one thing at a time against a control page that already scrolled at 60fps. Five things were paying for decoration on every scrolled pixel. The instrument grid was a background-image on <body>, repainted for every frame of a page nearly six thousand pixels tall; it is a fixed composited layer now, identical to look at and free to scroll. The figure glow was on .num, which marks every engine-produced figure — over a hundred text-shadows repainting on a page that moves; it is scoped to the large display figures, where it was the only place it ever read. The sticky header carried backdrop-filter: blur(14px), re-blurring the page beneath it every frame: on its own, removing it took p90 from 50ms to 33ms, and on a site this dark a nearly opaque bar is indistinguishable. Its spread glow went with it. The arrival animation used filter: blur(), which cannot be composited and forces a repaint on every frame it runs; it is a fade now, on thirteen section-level blocks rather than forty individual cards — forty things arriving separately is not an effect, it is a page that looks like it is still loading. Off-screen sections are skipped entirely with content-visibility. And the globe was never actually pausing. A scroll handler added last release cancelled the pending frame and set a flag to resume — but frame() re-arms itself at the end of every pass, so a frame already in flight put the loop straight back. It measured at 21.8% of frames over budget against 7.4% with the globe removed entirely: the pause was doing nothing. With a flag the loop actually checks, those two numbers are now 9.7% and 9.4% — the globe costs nothing while the page moves, freezes while you scroll, and picks up where elapsed time says it should, so the planet never jumps. Other pages were measured too: the workspace and the trust pages scroll with zero long frames. The plans page sits at 15%, unchanged with every script blocked, so it is that page’s own layout and predates all of this; it is not claimed as fixed. No model version, seed derivation or hash function changed; all 96 frozen results resolve unchanged. Run for this release from the shipped bundle: 555 checks; 53 mutation probes caught; 96 frozen unchanged; 21 registry and page audits clean; WCAG 2.1 A/AA sweep clean on 45 pages; hero contrast 39 checks clean at five widths; premium visual sweep 20 of 20; glow gate clean in Chromium, Firefox and WebKit; 46 pages swept for console errors, failed requests and horizontal overflow with none found. |
| 2026-09 | an outside review · five findings · one correction | A design review of the live site was checked claim by claim before anything was changed, and five findings held. A mobile layout fault: the list item carrying “One stated exception:” was a flex row, which made the bold label its own shrinkable column — at 480px it broke over two lines and at 360px over three, stacked beside its own sentence. Reproduced at every width, fixed, and re-checked at five. It is a block with inline prose again, which is what it always was. Four labels for one action: the same destination was called “Run a simulation” in the nav, “Run simulation” in the workspace, “Simulate my decision” on the hero and “Start here — free, in your browser” at the close. It is one phrase now; the two facts the long label carried are stated beside it rather than lost. Section numbers leaking: the six stage labels were prefixed 07, 06, 08, 05, 04, 04b — not even in order, which is what an internal component name looks like from outside. The numbers are gone and every label stays. The raw receipt led with itself: model runway@1.0.0 · seed 564 · reproducibility_id rw_52f9a7c3_234 sat at full prominence. It is one disclosure down, unchanged, under “See the technical receipt”; the plain sentence that says the same thing in English stays visible. The company block was said twice: the number and registered office appeared mid-page and again verbatim in the footer. The duplicate is gone — but not the block: the independence statement and the similarly-named-company disclaimer exist nowhere else on the page, so deleting it as the review suggested would have dropped a disclosure. Condensed, not cut, and a test now asserts both survive. A correction to the previous release’s own figures. v191 published the scroll fix as “38% of frames over budget, now 9.5%; p90 50ms to 16.8ms”. Both endpoints were single samples. Measured properly, four runs each against the shipped v190 and v191 bundles: before, 55–59% of frames over budget, p90 50–67ms, worst 100–117ms; after, 11–16%, p90 33ms, worst 67–83ms. The fix is larger than was claimed in one direction and smaller in the other, and the honest number is a range from repeated runs, not the best of them. The review’s pricing finding is real and is not changed here: Pro reads “£9/mo or £79/yr” on the homepage and organisations pages and leads with the £6.58 annual-equivalent on /plans, because that page’s toggle defaults to annual. All three are arithmetically identical and each states both figures, but which one leads is a commercial choice, and the review’s own escalation list puts any pricing change with the owner. Its second track — bank and accounting integrations, new model inputs, new domains — is untouched for the same reason: it is gated by its own terms and would change what this site can truthfully say about computing in your browser. No model version, seed derivation or hash function changed; all 96 frozen results resolve unchanged. Run for this release from the shipped bundle: 559 checks; 53 mutation probes caught; 96 frozen unchanged; 21 registry and page audits clean; WCAG 2.1 A/AA sweep clean on 45 pages; hero contrast 39 checks clean at five widths; premium visual sweep 20 of 20; glow gate clean in Chromium, Firefox and WebKit; 46 pages swept for console errors, failed requests and horizontal overflow with none found. |
| 2026-09 | a question that did nothing · correction · one new invariant | The workspace asked a question, told the person it changed the model, and it did not. “How much risk can you carry?” sat under the line “your answer sets the survival threshold the model scores against”. It did not. riskTolerance appears exactly once in the entire shipped bundle — being written into the decision’s frame. No model takes a threshold argument, and survival is, and was, hard-coded at cash falling to zero: if (cash <= 0) return { survived: false }. The answer was recorded and nothing scored against it. The sentence now says what actually happens: recorded with the decision, does not change the arithmetic, every released model scores survival against cash staying above zero. The question stays, because what it records is worth recording, and the FCA Financial Lives 2024 reference stays with it. No probability, band or frozen result changes — nothing was ever computed from this field, which is the whole point. Nothing on this site was equipped to catch it. The contradiction engine reads pages against truth-registry.json, and this was a claim about code behaviour that no registry describes. So the invariant is asserted directly now: every field the workspace collects into a decision’s frame is either consumed by an engine module, or the page says plainly that it does not affect the arithmetic. A field may be recorded and inert — reversibility always has been, and says so in as many words — but it may not be inert and advertised as computed. The first version of that test passed while the defect was still on the page: it derived the element id from the field name, and the frame collects riskTolerance from #fRisk, so it never found the sentence it was meant to read. It reads the pair out of the frame itself now, and was confirmed by putting the original wording back and watching it name the field. This came out of a fourth outside review, whose other proposals — a user-set safety buffer instead of a hard zero, volatility computed from the visitor’s own monthly figures, a four-step form — are real improvements to what the engine measures rather than how it is presented, and are not shipped here: changing what survival means changes every probability the site has published, and that belongs with whoever owns model validation, versioned and disclosed like everything else. Its worked figures were invented; the site continues to publish only the engine’s own. No model version, seed derivation or hash function changed; all 96 frozen results resolve unchanged. Run for this release from the shipped bundle: 560 checks; 53 mutation probes caught; 96 frozen unchanged; 21 registry and page audits clean; WCAG 2.1 A/AA sweep clean on 45 pages; hero contrast 39 checks clean at five widths; premium visual sweep 20 of 20; glow gate clean in Chromium, Firefox and WebKit. |
| 2026-09 | the entrance light · every question audited | The entrance light becomes volumetric. Four treatments were built and rendered against the same five thousand paths at the same seed, so the choice was between lights and not between simulations, and the owner picked the volumetric one. The falloff eases to 0.50 so a little more of the thin tail survives to feed the glow; the core curve is cubed rather than squared, which makes the brightest cells rarer and is what stops a wide bloom washing the corridor out; and the bright-pass knee drops to 0.34 so the whole bright body of the beam feeds the bloom rather than only its densest few cells. The second bloom pass is deliberately wide — a tight one draws an outline around light, a wide one puts light into the air around it. Ink on the canvas 69.8% to 70.8%, mean luminance 52.3 to 65.1, measured. It is the brightest of the four treatments, so the text over it was measured before it shipped: gates/hero-contrast.mjs passes 39 of 39 at five widths, worst pair still clear of AA. Every question in the workspace was then traced to what the engine does with its answer. The previous release found one that claimed to change the model and did not; this is the same check run across all of them. Thirteen fields: the domain selects which model runs; the horizon and all six figures are consumed by the models between six and twelve times each; the statement is recorded as the decision’s title. Four are recorded and inert — reversibility, risk tolerance, country and currency — and each now says so in its own words on the page: reversibility “changes what the result is for, not the arithmetic”, country “the released models’ arithmetic does not yet vary by location”, currency names the UK reference figures and says the context does not apply elsewhere, and risk tolerance was corrected last release. No question on the workspace now describes an effect the engine does not have. One thing the audit surfaces that it cannot fix: “How much risk can you carry?” is honest now but still inert, and four outside reviews have proposed replacing it with a buffer the person actually chooses — three months of costs, six, or a figure of their own. That would be a genuine improvement and it changes what survival means, which changes every probability this site has published, so it is a versioned model change with disclosure and it sits with the owner. No model version, seed derivation or hash function changed; all 96 frozen results resolve unchanged. Run for this release from the shipped bundle: 560 checks; 53 mutation probes caught; 96 frozen unchanged; 21 registry and page audits clean; WCAG 2.1 A/AA sweep clean on 45 pages; hero contrast 39 checks clean at five widths; premium visual sweep 20 of 20; glow gate clean in Chromium, Firefox and WebKit. |
| 2026-09 | production truth · metadata · the entrance | The first gate that looks at the internet. Every check in this bundle proved something about the bundle. None of them knew anything about production, and the gap had already cost three arguments nobody could settle — outside reviewers reading live copy that had been fixed, and no way to prove it either way. It closes by hash. audit/deploy.py writes a SHA-256 for every file a release puts on the internet, keyed by the URL that serves it, and stamps every page with the release it belongs to (<meta name="lexun-release">), so “which release is this page from?” is answered by looking rather than by reading prose three screens down. gates/production-truth.mjs fetches those URLs and compares: GREEN, or the exact list of files production is serving that this release did not ship, each with both hashes and the release the live page claims for itself. It separates the four cases that matter and returns a different exit code for each — matched, drifted, not yet deployed, unreachable — so a dropped connection is never reported as drift, and a bundle that has simply not been deployed says so instead of raising an alarm. All four were proved against a server that mimics Netlify’s clean URLs, including a deliberate one-file mutation the gate named on sight. It exists because the reading was wrong, not the site. Asked to check the live trust page, a language model reported a check count of 520 and produced a fluent quoted sentence containing it. The page held no such number. That reading came one step from being reported to the owner as a live contradiction in his own site: the deploy folder on his disk said 566, the live page said 566, and the deploy log showed a complete upload. A system whose whole claim is that its numbers are derived rather than asserted cannot verify itself with a method that can invent one, which is why this gate compares bytes and judges nothing. Metadata is copy, and one gate could not see it. The retired-plan check stripped every tag to get at the words, which also strips the words that live inside a tag. /join advertised the waitlist for Plus — a plan retired on 1 September — in its og:description and twitter:description, and /contact offered Teams in all three, for eight releases, while the check read both pages and called them clean. Those are the sentences a search engine prints, a shared link previews with and a language model quotes when asked what LEXUN sells. Both fixed; the check now reads attribute copy and titles, proved by putting the defect back and watching it fire. The check-count drift gate was tested the same way and already saw metadata correctly. One line in the entrance was not centred. The Free · five figures · no account line sat left-aligned inside a centred column, and the moment it wrapped it orphaned “this browser” hard against the left edge beneath four centred elements. Centred now, with the refusal line beside it, matching the statistics, the assurances and the fine print below them, which were always centred. Measured rather than eyeballed: every block in the entrance is 0 px from centre at 810 and 1440 px, where v197 measured 16 px asymmetric at the same widths. No model version, seed derivation or hash function changed; all 96 frozen results resolve unchanged. Run for this release from the shipped bundle: 584 checks; 53 mutation probes caught; 96 frozen unchanged; 33 release gates green. |
| 2026-09 | the gate that cried wolf · the entrance light · the planet | The production gate shipped with a forty-four per cent false-positive rate, and this is the fix. Its first run against a live deployment reported a hundred and fourteen findings, every one of them wrong. A hundred and four were files _redirects forces to 404 on purpose — the audit tools, the gate scripts, the sales folder and two dozen strategy documents, which ship inside the bundle so the suite can be run by whoever unzips it and are deliberately unreachable on the web. The gate did not read _redirects, so it fetched all of them, got exactly the refusal the site is designed to give, and called it drift. The other ten were pages Netlify rewrites in flight: form processing strips data-netlify and injects a hidden form-name input, and pretty-URL post-processing turns href="/x.html" into href="/x" — which is why 404.html arrived exactly ten bytes short, the length of /index.html becoming /. Both are corrected rather than excused. A forced-404 path is no longer skipped: it is recorded as a path that must 404, so the shield is now itself under test — pointed at a server without those rules the gate reports all one hundred and four as served, which is a leak and a failure. The ten rewritten pages are compared after undoing Netlify’s two documented transforms on both sides and nothing else, and the local copy is admissible only while its hash still matches the manifest, so editing a page after writing the manifest makes its drift appear rather than vanish. Proved against a server that reproduces all three behaviours, including a deliberate injection into /join — a page whose bytes are legitimately rewritten — which the gate named while the other nine stayed green. The entrance loses two hairlines and gains a third bloom. The tenth and ninetieth percentile were stroked as two pale one-pixel rules across the opening photograph, where they read as scratches on the print rather than as the spread of five thousand paths; the spread is the shape of the density cloud beneath them, drawn from the same run, and both figures are stated in words on the line below. They are gone. The median stays and is drawn as light instead of as a rule — a wide dim pass, a body, and a soft core — and the beam gains a third bloom pass, far wider and almost not there, which never brightens anything on its own and simply makes the darkness near the light differ from the darkness in the corners. The planet has both halves lit, and its cities look switched on. One dot product used to send every daylight city straight to the next iteration, so the sunlit hemisphere was ocean gradient and nothing else. It now carries the same map as the dark half in the only form daylight allows, a hard cool glint that dies at the terminator so the two halves meet without a seam — and the first falloff written for it read as physics and behaved as a bug, cancelling the glint precisely where the sun stood highest whenever the terminator crossed the middle of the disc. The night lights were re-cut: the sprite held its white for seven per cent of its radius and then ran a long amber tail, which stamped a thousand times and bloomed is a lacquered sheen rather than a city, so the core is held to twelve per cent, the tail is a tenth of what it was, and the bloom drops from 0.44 to 0.30 and tightens, leaving the sharp pass to lead. Four links now open, run and close between distant cities on great circles lifted off the surface, baked once at birth so a frame costs thirty projections and no trigonometry; reduced motion removes them. Measured on the same machine before and after: median frame 20.9 ms to 16.5 ms, ninetieth percentile 35.4 to 31.0. No model version, seed derivation or hash function changed; all 96 frozen results resolve unchanged. Run for this release from the shipped bundle: 590 checks; 53 mutation probes caught; 96 frozen unchanged; 33 release gates green. |
| 2026-09 | structured data · the price an AI is told | The third place a retired price hid, and it was the field written for machines to quote. Inside /plans, the JSON-LD Product carried the sentence “Free decision engine; Pro for individuals; Professional, Team, Business and Enterprise packages for organisations” — three tiers retired on 2 September, in the one field on this site whose whole purpose is to be read and repeated by search engines and language models. The eighteen Offer objects beside it were correct and audit/pricing.py checked every one of them, so the price gate reported CLEAN while the product description sold a catalogue that no longer exists. An outside review found it before any gate here did, and the reason is a pattern now visible three times: this suite reads what a person reads. First the meta description, where /join advertised a retired plan to every link preview; now structured data, which the retired-plan check could not reach twice over — it strips <script> before searching, and its proximity rule wants a price or a tier word within sixty characters, which prose does not supply. Structured data now has its own rule and a bare retired tier name is enough to fail it, because there is no innocent reason for one to appear: the live names are Free, Pro, Organisation and Enterprise. Proved by putting the sentence back and watching it name all three. And the file written for AI systems is no longer unpoliced. The price gate reads billing.js, the registry, the JSON-LD offers, the terms table and sixteen sales documents — and not llms.txt, which is the file that tells an assistant what LEXUN costs. Its figures were right, and nothing would have caught them going wrong. Every £ amount there must now be an amount billing.js holds; a new price is a change to billing.js first and that file second. Proved by planting £59 a seat and watching the gate name it. What the review reported and the site did not do. Three of the four pricing findings were a search cache rather than the live site: /organisations serves £9 and £79 for Pro, £49 a seat a month and £490 a year for Organisation, £25,000–£100,000 for Enterprise, a £1,500 founding pilot and a £2,500–£15,000 Decision Audit — read from the live page, not summarised. There is no £99, no £499 and no Professional, Team or Business anywhere a visitor can reach; “Business from £1,500 a month” is the one-off pilot fee read as a subscription. The single real defect was the structured-data sentence, and it is fixed. No model version, seed derivation or hash function changed; all 96 frozen results resolve unchanged. Run for this release from the shipped bundle: 592 checks; 53 mutation probes caught; 96 frozen unchanged; 33 release gates green. |
| 2026-09 | the register · a forecast nobody settled | Every rule on the ledger guarded against a record being edited. None guarded against one being ignored. That is the easier failure and the more likely one: the outcome arrives, the week is busy, and a claim published as falsifiable quietly becomes a claim nobody ever settled — while the page goes on calling it open. It is worse than a wrong forecast, because a wrong forecast is evidence. Three forecasts on the public register resolve on 15, 16 and 17 September, so the control exists before the first of them rather than after: an open forecast more than seventy-two hours past its own due date now fails the release gate and says which one and what to do. Inside that grace it warns instead — long enough to cover a weekend, short enough that nothing is forgotten, and deliberately generous because resolution here means reading a named publication and quoting it, and a deadline enforced to the minute would push whoever holds it into resolving against a figure they have not read. There is no bypass flag, and there will not be one: a forecast that cannot be resolved has two honest exits, DISPUTED and WITHDRAWN, and both leave a record. Proved at both thresholds by moving a due date nine days into the past (blocked, naming the entry) and thirty hours into the past (warned, not blocked) — and the receipt rule caught the edit while it was at it. The register now announces what is coming. Every run of the ledger gate prints the open forecasts due within ten days, and audit/resolve.py --due prints, for each one, the deadline, the publication time, the band and its midpoint, the primary and fallback source, the frozen criterion and the exact command to run — all read from the sealed entry, so the preflight can never describe a criterion the register does not hold. And the runbook ships in the bundle (RESOLUTION-RUNBOOK.md), written now rather than the night before, so nothing in it can be shaped by an outcome. Each of the three publication dates and times was verified against the publisher’s own page on 10 September: the ONS release calendar gives 15 September at 7:00am for the labour market release and the CPI release page gives 16 September at 7:00am and is marked not yet published; the Bank of England lists Thursday 17 September among its 2026 MPC dates and titles the September summary “to be published at 12pm”, which is the 11:00Z the register already recorded. Two traps are written down because they will not be obvious at 07:05: the ONS titles one release three different ways — the frozen criterion names the Labour market overview bulletin, the calendar entry says UK Labour Market — and all three criteria say as first published, so a later revision does not move a resolution in either direction. What must not change afterwards is stated in advance. Four outcomes are resolved; these three take the editorial board to seven, which is still below the ten-outcome minimum, so no accuracy percentage may appear anywhere — and a test now fails if resolving everything currently open would reach that minimum without the pages being rewritten first. The decision models stay at zero resolved outcomes: all three are operator judgement on the editorial board, each entry says in its own text what it is not evidence for, and a good Brier score on Bank Rate is not evidence that the runway model is calibrated. No model version, seed derivation or hash function changed; all 96 frozen results resolve unchanged. Run for this release from the shipped bundle: 603 checks; 53 mutation probes caught; 96 frozen unchanged; 33 release gates green. Also in this release, from an external review: a tier announced as coming while it was on sale. /join led with “The engine is live and free. The next tier is coming.” as its H1, in a gradient, above body copy that correctly said paid plans are on /plans and that Pro’s exports and reports are live today. Pro went on sale on 1 September; the headline had simply not been rewritten, and the page spent a fortnight telling every visitor that the product they could buy did not exist yet. Two gates read that page and neither could see it: the price gate checks figures and this is not a figure, and the retired-plan rule checks names and “the next tier” names nothing. It is a claim about product status, a class of claim nothing here was reading. There is now a rule for it, and on its first run it found two more instances on the same page that fixing the headline alone would have left — the waitlist email promise and an FAQ heading, both of which now say encrypted sync, which is what the page is actually for. |
| 2026-09 | the date that said every page changed today | A regression this bundle caused itself, three releases ago, invisible to all thirty-three gates. audit/stamp.py exists on one argument: a sitemap that dates every page to the deploy day tells a crawler that forty pages changed when two did, and a crawler that learns the dates are decorative stops reading them. It took each page’s modification time and wrote it into <lastmod>, which was true for as long as a release only touched the pages it changed. Then v199 began stamping every page with its release, every release. Every modification time moved, stamp.py copied them faithfully, and all fifty-one dates collapsed onto the deploy date — the precise failure it was written to prevent, reintroduced by the tool meant to make the deploy honest. Nothing caught it, and the reason is worth recording: audit/tech.py checks that a lastmod agrees with the file it resolves to, and it did agree. The file really had been touched. audit/schema.py checked that every JSON-LD dateModified was a valid ISO date and never that it was true, so fifty-two pages went on telling search engines they last changed on 30 July. Dates no longer come from the filesystem. They come from the page’s content with the one thing that changes every release removed: page-dates.json records each page’s stamp-stripped hash and the day that hash last moved, and both the sitemap and every dateModified are written from that single record. A page that was only restamped keeps its date. Proved three ways: a second write reports no change, a simulated bump of the whole site to v299 moves zero dates, and one real edit to one page moves exactly one. Eight tests hold it, including the invariant recomputed rather than trusted — strip the stamp, hash what is left, and it must equal what the record holds — and reverting stamp.py to modification times fails the gate on sight. The dates before today are not recoverable: the stamp had already reset every modification time and this bundle is not a git repository, so every page was dated to 10 September once, the record says so in its own text, and it is honest from there. Nothing is a guess at history. The rest of an A–Z sweep, reported rather than quietly dropped. Forty-six pages were opened in a real browser in a fresh context each, watching for uncaught errors, failed requests, duplicate DOM ids, references pointing at nothing and sideways scroll: clean on every count, and the nav sheet’s aria-controls now confirmed to resolve from first paint rather than after the first click. Two findings stand open and are not fixed here because half-fixing them would be worse: /demo and /second serve “Loading the demonstration…” and “Loading the question…” as their no-script state, so a crawler and a visitor without JavaScript get a spinner on the two pages that most need to say something, and the homepage pattern of inlining a real pre-rendered answer is what they need. No model version, seed derivation or hash function changed; all 96 frozen results resolve unchanged. Run for this release from the shipped bundle: 611 checks; 53 mutation probes caught; 96 frozen unchanged; 33 release gates green. |
| 2026-09 | the money path, in the state nobody had run | LEXUN cannot take a payment today, and everything else about revenue is downstream of that. /api/billing-config on the live site answers {"live":false,"mode":"off"} with all four price ids false. That is not a defect — the code is written, thirty-six server checks pass against a Stripe stand-in, and every page truthfully says checkout is off — but it means the day the six Stripe variables are set in Netlify, a transition runs that has never been executed once. Four sentences have to disappear, two buttons have to appear, and a press has to reach Stripe with a plan that exists. Nobody had ever seen it. So it was run. A new gate (gates/checkout-live.mjs, the thirty-fourth) drives the pricing page in a browser against a stubbed live billing configuration and asserts what a buyer needs: that a way to pay appears, that it offers both the trial and the seats, that nothing still says checkout is off, that the cost line names £9 a month and £79 a year, that pressing it reaches /api/checkout, and that the payload names a real plan with a seat quantity rather than undefined. It then runs the same page with billing off and asserts the opposite: no buy control, the visitor told plainly, nothing sent. Twelve checks, and the answer is that the path works — pressing the trial button posts {"plan":"pro_monthly","trial":true,"seats":1}. Proved to bite by making live() always return false, which is how this would regress: six of the twelve fail instantly. What still has not run, said plainly rather than implied. The seven in-app upgrade moments — the fourth save, an export, a report, the day reality answers, the third run, the Copilot allowance, the board summary — have never been shown to anyone, because with checkout off the workspace deliberately walls nothing. platform-app.js is an IIFE, so those functions cannot be reached from a test page, and driving them authentically needs a completed decision run and an encrypted vault. Eight tests hold their contract instead: every promised moment exists, each carries a kicker, a promise and a body, a shown moment is recorded so it cannot repeat, the free allowance is read from the price configuration rather than typed, and no moment claims a paid plan buys a better answer. That is weaker than executing the flow and is recorded as weaker. One of those tests was wrong twice before it was right, which is worth keeping. It first read 700 characters after each key and ran past the end of the entry into the next, reporting a phrase belonging to one moment against another. Then it matched “better answer” without reading the word in front of it, and fired on “a plan buys the record, never a better answer” — copy that says precisely the right thing. A gate that fails on correct work is worse than no gate, because it teaches whoever reads it to ignore the output. Entries are now bounded by the next key and negated clauses are stripped before the claim is looked for; planting an affirmative “Pro gives you a more accurate forecast” fails it on sight. Also checked, and clean. A first-time visitor to the workspace sees only the new-decision view, not the command centre, the radar or the calibration record — progressive disclosure already works, contrary to an external report. A capability row on /packages that documents the mechanism (“the buy buttons appear only when the operator has configured Stripe”) reads as a status claim to a naive matcher and is correct in both states; it was left alone. No model version, seed derivation or hash function changed; all 96 frozen results resolve unchanged. Run for this release from the shipped bundle: 619 checks; 53 mutation probes caught; 96 frozen unchanged; 34 release gates green. And the page about why LEXUN is hard to copy was understating LEXUN, in the sentence it offers as proof of its own honesty. /moat led its self-criticism with “LEXUN has resolved zero public forecasts” — true when written, four resolutions out of date, and unqualified. The register holds four resolved and graded editorial forecasts; it is the decision models that have resolved nothing. An external review found it, and the contradiction engine could not: every one of its five resolved-count patterns requires \d+, and this number was spelled as a word — in a file that already reads spelled numbers for the gate count, so the gap was an inconsistency inside one gate rather than an oversight about what a claim looks like. The sentence now says the models have resolved zero outcomes and that four judgement forecasts on the public register have been resolved and are not evidence about the models. Two new rules read a spelled count in both word orders, which matters because the correction itself was written in the order the first rule could not see; both were proved by putting each wrong version back. Also: the new checkout gate blocked its own release, correctly. It listed a fallback path under /home/claude to find playwright — the directory this bundle happened to be built in. audit/portable.py refused the build, which is precisely its job, and the gate now resolves the module the way every other browser gate here does. |
| 2026-09 | the fix that was tested against a guess | v201 taught the production gate to forgive Netlify’s own HTML rewrites. v203 deployed, and the gate reported ten pages drifting with “0 identical once Netlify’s rewrites are undone” — the forgiveness did nothing. The flag was set on all ten, so the code ran and simply failed to reconcile them. The fault is in how the fix was validated, not in the flag: it was proved against a local server written from my own hypothesis about what Netlify does to a page. A simulator built from a guess confirms the guess. It cancelled transforms Netlify may not perform and missed at least one it does, and every test passed while doing it. So the gate now shows its working. When a page still differs after the known rewrites are undone, it prints the byte offset and both sides of the first disagreement, with whitespace escaped — because a transform that moves a newline is invisible otherwise, and invisible is how this survived three releases. Proved by teaching the simulator a transform the rule does not know about: the gate named it on sight at byte 34. The next production run will say what Netlify actually changes rather than leaving anyone to guess a second time. Until it does, the ten pages are reported as drift, which is the correct answer to “is production byte-identical to what shipped” — they are not, and the gate should not pretend otherwise while the reason is unknown. No model version, seed derivation or hash function changed; all 96 frozen results resolve unchanged. Run for this release from the shipped bundle: 619 checks; 53 mutation probes caught; 96 frozen unchanged; 34 release gates green. |
| 2026-09 | a VAT invoice we cannot issue · eight forecasts unaccounted for · the lights | Four surfaces promised a VAT invoice from a company that is not VAT-registered. /organisations stated the fact plainly — LEXUN is not currently VAT-registered, so none is added — and two screens above it listed “VAT invoices” as an Organisation feature. /plans told buyers VAT is added at checkout where it applies; /packages, /upgrade-success and the sales pricing sheet promised one too. A business that is not registered must not charge VAT or issue an invoice showing it, so all four were promising something unlawful to deliver — to the one audience, finance buyers, most certain to check. audit/pricing.py reported CLEAN throughout and was right to: it reconciles £ figures, and VAT status is not a figure. The deeper fault was that the authoritative statement lived only as prose on one page, so no gate had anything to read. It is a registry fact now — pricing.vat_registered — every surface says itemised invoices, and three rules read the flag rather than a sentence. And the public register left eight of twelve forecasts unexplained. The homepage said “4 of 12 issued” and stopped, which invites a reader to assume the other eight are still running. Four are; four were withdrawn. Withdrawal is the number a register is most tempted to omit, on a register that deliberately keeps withdrawn entries at the same size as the hits — so it was the single figure that made the record look tidier than it is. It now reads “of 12 issued (4 open, 4 withdrawn)”, counted from the ledger in both places that write it: audit/stamp.py for the first paint and hero-smart.js at runtime, which must agree character for character. Both findings came from an outside reading of the live site, not from any gate here. The planet got its lights re-cut a second time. Three thousand two hundred cities were drawn at one brightness in one colour, which is most of why a field of dots reads as a map rather than a photograph. The list is the most populous in order, so that ranking is real data rather than an invented weight: the largest now keep full brightness and the tail falls to just over half. Roughly a quarter of cities light cool white-blue instead of amber, chosen by a hash of the index so the mix never changes between frames — older sodium and newer LED do sit street by street in the same city. And the hundred largest get three dimmer satellites at fixed offsets, because a conurbation seen from orbit is a smear, not a point; they are dropped the instant the animation loop stops running at full rate, which it publishes for the purpose rather than the light layer guessing. Measured before and after on the same machine: median frame 14.7 ms to 14.5, ninetieth percentile 35.8 to 35.6, worst frame 58 to 43. No model version, seed derivation or hash function changed; all 96 frozen results resolve unchanged. Run for this release from the shipped bundle: 625 checks; 53 mutation probes caught; 96 frozen unchanged; 34 release gates green. |
| 2026-09 | core@1.2.1 · runway@1.0.1 · career@1.1.1 · opportunity@1.0.1 | The first adversarial pass over the engines themselves: nothing wrong in the Monte-Carlo, three things wrong in what the models said about it. Every sweep to date had attacked the pages; this one attacked the mathematics with a property harness — monotonicity under a shared seed across whole sweeps, the closed form at zero volatility, the mean of the shock multiplier at 15%, 50% and 80% volatility, antithetic pairing, malformed inputs, seeds of every shape. The arithmetic held. The reporting did not. A breakpoint that was the edge of a search. Each model finds its 50/50 figure — the growth a business needs, the income a career change needs, the largest commitment a buyer can carry — by bisection between two bounds, and bisection always returns a number. When the answer lay outside the bounds, the number returned was the bound, and the pages printed it as measured: /platform told a business that no growth inside the model’s range could save “growth needed for a 50/50 median: 50%/month”, wrote into a career record “a confirmed income source at ≥£6,000/month moves the median path to survival” at a point where survival is exactly zero, and told a buyer whose income does not cover essential costs that “keeping the commitment at or below £0/month keeps the median path surviving”. The search now evaluates both ends first (Core.bracketedSearch); when the target is not bracketed the figure is null, a status says which side it fell off, and the page prints the sentence that is true instead. Inside the bracket the midpoints are exactly the ones visited before, so every breakpoint genuinely found is the same figure. A quoted figure that sat on the wrong side of its own claim. The found breakpoint was rounded to nearest, so the homepage’s worked example said the median path survives “at or above 0%/mo” when survival at 0% is 49.7% and at 0.1% is 50.8%; the purchase model quoted £2,201 where the median path survives at £2,200 and not at £2,201. Figures are now rounded onto the surviving side — up for a minimum, down for a maximum — and a gate re-runs the engine at the quoted figure. The homepage worked example reads 0.1%/mo and a margin of +1.9 points; no probability changed. Optional inputs that reached the arithmetic unchecked. Committed one-off amounts and cost growth were never validated. Cost growth typed as “2%” became NaN, and NaN || 0 is 0, so the model ran silently at zero cost growth — 48% reported where the figure the person meant gives 28%. Pasted into /reproduce as the string “2%”, or as a committed amount of “forty thousand”, it made every month’s cash NaN, and NaN is never ≤ 0: the path could not die, survival read 100% and end cash read NaN. Both are refused now, naming the entry, with the message saying how to enter the figure; a committed month of 0, a fractional month, and a month beyond the horizon are refused rather than silently ignored. A thirteenth month. The engine codes a path that survives the whole horizon as horizon + 1. Two views — the results card on /platform and /glass-box — printed that code as a month, so a twelve-month horizon showed “13”; the demo scenario table did the same. All three cap at the horizon as every other view already did. What moved. No probability, band, verdict, receipt id or input hash: the 96 frozen results are byte-identical and the snapshot diff is three version lines. The version bumps are the third digit throughout, which is what this changelog says a third-digit change means. The career model also computed its break-even twice per analysis; once is enough. Forty-three new checks; the break-even and input-validation gates were each proven to fail with the defect reintroduced. And a correction to this page. The tool that keeps the published check count current replaced the old count with the new one in every file it knew about, this one included, so four release rows above — core@1.2.0 through “one truth everywhere” — had come to state a suite count that was never true on their date. Recovered from the shipped bundles and restored: 562, 565, 566 and 576. Every shipped row’s figure is now frozen in audit/changelog-history.json, an append-only record checked by a release gate, so a script can no longer rewrite what a release said about itself. Run for this release from the shipped bundle: 668 checks; 53 mutation probes caught; 96 frozen unchanged; 35 release gates green. |
| 2026-09 | the phone the gates never opened · the hero sells the record · Back that left the workspace | An A-to-Z pass as a first-time visitor, on the phones people actually hold. Every page was driven in a real browser at 320, 360, 375, 390, 430, 768 and 1280 pixels, every form was submitted empty and wrong, every menu and dialog was worked on the keyboard, and the workspace was walked with Back and Forward. The phone the gates never opened. The accessibility sweep runs at 1280, the interaction sweep at 412 and 1440, the visual sweep at 1280 — nothing in the release chain had ever laid a page out at the widths most phones are. The workspace top bar on /platform had shipped for several releases with its primary button clipped to “New / imulatio” and its state pill cut to “NOT” on an iPhone; it never overflowed the document, which is the one thing the earlier sweep checked, it squeezed its own children instead. Below 44rem the bar now drops the search control and the long halves of its labels (the accessible names keep the full wording), and below 35rem the location line and the pill’s words go too, the pill keeping its dot, its colour and its name. The twelve permanent forecast pages under /f scrolled sideways on every phone because a resolution source is a full ONS address and nothing let it wrap; the register page cut the same addresses off. Both wrap now. A new release gate, gates/phone-fit.mjs, loads every page — the permanent pages included — at 320, 360, 375 and 390 and fails on anything clipped, anything past the right edge, any sideways scroll, any broken or unnamed image. It was proven to catch the top bar before it was trusted. Targets under a fingertip. The footer’s site directory was a stack of 21-pixel links, the footer’s API link was 19 pixels wide, the homepage’s “watch it refuse” control was 16 pixels tall, the forecast register’s disclosure rows 21. WCAG 2.2 gives pointer targets 24 pixels unless they sit inline in a sentence; these did not. All are 24 or more now, by padding, so no type moved. Back that left the workspace. Every view change in the workspace rewrote the address with replaceState, so after New decision → Library → Outcomes the first press of Back went to whatever page came before LEXUN. The first view of a visit is still a replace; every change after it is a push, and Back and Forward now move between views. The hero sells the record, not the simulation. “Simulate the future” told a first-time visitor what the machine does and left them to work out why they would want it. The headline is now the proposition — decisions you can defend later; evidence structured, assumptions tested across 5,000 simulated futures, scenarios compared, the decision frozen and later scored — with the organisation door (a Decision Audit, a pilot) on the front page in one line, where until now the only route to the products that are sold was the word “Teams” in the navigation. The title, description and the page’s WebPage structured data say the same thing, and a gate now holds every page’s WebPage node to its own title and description. One directory, every page. Three pages carried older copies of the footer directory, so what a visitor saw depended on where they opened it; the Labs tool at /jobsafe was linked from nowhere and reported as an orphan for several releases. The directory is one list on every page now, the tool is in it under a Labs label and names itself as experimental, and the 404 page offers five signposts instead of two. Not verified here, and said so: Core Web Vitals in the field — the local measurements (largest contentful paint under 400 ms, layout shift under 0.005 on every key page) are on a loopback network and prove only that nothing shifts, not how fast a phone on 4G paints. |
| 2026-09 | two forecasts scored · a register that knew what day it was · ICO ZC183768 · the Copilot said out loud | The public register caught up with reality, and learned to say “due”. Forecast #011 (CPI for the twelve months to August 2026) and #012 (unemployment, May to July 2026) resolved TRUE against the ONS bulletins first published on 16 and 15 September, Brier 0.0144 and 0.0100, from the frozen bands; only status and outcome were appended and every receipt still verifies. A register that knew what day it was. Until now the static register said “OPEN · resolves 2026-09-15” the day after 15 September, and the homepage said “next: 2026-09-15” about a date already gone, while the live JavaScript view said “past due”: two renderings of one file disagreeing. One rule now derives a forecast’s state at the moment of reading — open, due, resolved, withdrawn, disputed — in audit/ledgerlib.py and its browser twin ledger-state.js, and the suite runs both over the same ledger at the same instant and fails if they disagree. A due forecast prints as DUE, awaiting the first-published figure, unscored until sealed; “next” is only ever a future date; the registry’s forecast counts are derived from the ledger rather than typed. ICO ZC183768. The privacy notice said CA Capital Limited’s registration was not yet in place. It has been since 27 June 2026, entry ZC183768, checked against the public register on 16 September; the notice, the legal line on 46 pages, procurement and the sales documents now say so from one canonical record, and the contradiction engine polices the number in both directions. The Copilot said out loud. Every “never leaves your device” claim on a current page now carries the Copilot exception beside it — the optional Copilot sends what a person deliberately types, and the result buttons a filtered summary — and the notice, terms, security page and llms.txt list the two result-summary fields the earlier wording missed: the decision question as typed and the horizon in months. “Never the figures you entered” became “none of the financial figures you entered”, which is the true sentence. The /agent page carries the same notice above its box. The 3 September notice and terms are archived under /legal, and the nine earlier archives no longer print a stray block of stylesheet text above the policy. Also: the homepage hero leads with the sentence a first-time visitor needs (“Stress-test a decision before you make it”), three route cards say what each model answers, does not answer and asks for; the Copilot allowances live in the truth registry and the four copies are gated to it; system-manifest.json explains what each published count counts (engine checks, frozen results, gates, mutation probes) and none is an accuracy figure; /teams and /simulate redirect; the waitlist page is titled for what it is. Not changed, and said so: the /api/ask function’s intake path (a fix is specified, not shipped), the terms’ acceptable-use and termination clauses, and the domain’s missing mail records, which are the owner’s to add. |
| 2026-09 | the Copilot reads what people type · every privacy sentence true · the register explains itself · one VAT sentence | Three audits in one day, and the defects they found, fixed the way the site fixes things: at the source, with a gate behind each. The Copilot. A five-figure career description (“on 55k, going freelance, 20k savings, 2,200 a month, maybe 3k a month for six months”) failed on the live site twice with a 502 and once with a 400. The 400 was the /agent page probing the function with an empty conversation on every load; the 502s were the intake path: a reply that was not pure JSON, or was cut off at the 700-token cap, could not be read. The reply is now prefilled with a brace, the first balanced object is taken whatever surrounds it, a cut-off reply is reported as truncated with the stop reason, the cap is 1000 tokens, the upstream call has a deadline under the platform’s own ten seconds with one retry, GET /api/ask is a health check that sends nothing anywhere, and a failed call is never charged to the per-address ceiling. The intake rules now say plainly that an annual figure never fills a monthly field and that a hire at a salary goes into the question, and the purchase model’s field list — which named an input the model does not have and omitted one it requires — is corrected. Two gates prove it: the stand-in now answers the career phrase three ways (clean, prefaced, truncated), and a new gate runs 96 UK-format phrases (“55k”, “£2.2k”, “2,200 a month”, “per annum”) through the reader with no model involved. Every privacy sentence true. The notice’s own summary still said only the sign-in box sent text to Anthropic; it names every Copilot surface now, /agent included, and /agent no longer claims figures stay in the browser. The processor table carries purpose, location and safeguard; the terms state acceptable use, fair use of the allowances, and when access can be suspended or ended and what is refunded. The gate that guards these sentences no longer accepts the bare word “assistant” as a caveat. The register explains itself. Rule 9: a forecast may be withdrawn only within 24 hours of issue and only for a defect in its own construction; after that it stands and is scored. The gate enforces the window, withdrawn entries are counted as void, the page says why four were withdrawn on 14 August and why that is checkable rather than a do-over, and a hash chain over the ledger (/ledger-anchors.json) gives a stranger something to compare — with the honest note that anchoring outside this site is the owner’s next step, not yet done. One VAT sentence, one free-tier sentence, one descriptor. The Organisation card said Stripe adds VAT at checkout while every other page said none is added; the registry now holds one statement and the contradiction engine polices both tenses. The free tier was described three ways on one page; the sentence that says all three lives in the registry and the pages print it. “Future Intelligence” and shortcuts named “Predict the future” are gone from the web manifest. Also: /trust pointed readers at a test suite the site forced to 404 — it is served read-only now; the two Key doors render at first paint instead of appearing after it; the stuck live panel collapses to one line on a phone so it stops covering the form; the search palette answers “price”, “cancel”, “login”, “delete my data”, “VAT”, “accountant” and “Xero”; forecast-page titles fit a results page; the career example lands mid-band; “Confidence” reads “Evidence quality”; the share image is a fifth of its size and says what the homepage says; the two unsourced sentences about competitors on /verify and /compare are gone. Not changed: the domain’s missing mail records, the no-card trial that depends on them, and the Stripe keys, which are the owner’s to add. |
Entries before public launch are grouped by month. From the first public release onward, every entry will carry a day-precision date and the receipt id of its canonical example run.
How to read a version number
Every LEXUN model carries its own semantic version, and the version travels with the result rather than living only on this page. A change to the third number is a fix that cannot move an output. A change to the second number can move an output, and always ships with a changelog entry naming what moved and why. A change to the first number means the model answers a materially different question, and old results are not comparable to new ones. That is why a saved LEXUN result records the exact version that produced it: a forecast made under runway@1.0.0 is scored against what runway@1.0.0 actually claimed, not against whatever the model believes today.
What counts as a methodology change
A methodology change is any edit that could alter the probability attached to an unchanged set of inputs. Adjusting a distribution, changing an evidence gate, altering how a band is drawn and changing the number of simulation iterations all qualify. Wording, layout, colour and copy do not. Methodology changes are release-gated: they land in a numbered version, appear here on the same day, and never take effect retrospectively on a result you have already saved.
What this page deliberately does not do
It does not backfill. It does not quietly amend a published entry. It does not summarise a change as an improvement without saying what changed. If a model gets worse and has to be rolled back, the rollback appears here as its own dated entry, because a changelog that only records good news is marketing rather than a record.