home.social

Search

243 results for “Ask_aubry”

  1. 🆕 blog! “Gadget Review: LiberNovo Omni - the USB-C powered office chair”
    ★★★★⯪

    Whenever a company asks me to review their gadgets, I always ask if it is USB-C powered. If not, I'm not interested. So, welcome to the future where your chair is USC-C rechargeable!

    WHAT?!

    The LiberNovo Omni looks like a standard office chair - but has two secret…

    👀 Read more: shkspr.mobi/blog/2026/10/gadge
    ⸻
    #chair #furniture #gadget #Review #USB-C

  2. Gadget Review: LiberNovo Omni - the USB-C powered office chair

    shkspr.mobi/blog/2026/10/gadge

    Whenever a company asks me to review their gadgets, I always ask if it is USB-C powered. If not, I'm not interested. So, welcome to the future where your chair is USC-C rechargeable!

    WHAT?!

    The LiberNovo Omni looks like a standard office chair - but has two secret features.

    First, is that it is exceedingly comfortable. Full foam cushions, lovely headrest, and a recline which almost gets you horizontal.

    Second, it is USB-C powered. There's a small battery pack which plugs in to the chair. Why? Read on!

    OK, let's start at the beginning.

    Assembly

    Flat-pack chairs like this are normally notoriously hard to assemble. The LiberNovo bucks that trend - not only does it include a how-to video, it prints the instructions on a MASSIVE piece of cardboard.

    I'm used to peering at tiny black-and-white diagrams in a flimsy paper booklet. IKEA could learn a thing or two from this.

    The screws are all labelled and a hex-driver is included. What's an even nicer touch, however, is some safety gloves:

    That's the sort of thing which doesn't cost much to the manufacturer, but is such a thoughtful gesture. There's nothing too sharp as you assemble, but who wants to cover their new chair in blood, eh?

    The parts come in two large boxes, but there aren't that many separate bits.

    Building it took about half an hour. It's easier with a friend to help - as are most things in life - but doesn't require much skill.

    Go Back To The USB-C Part Again Please?

    The battery pack is a 2200mAh unit with a USB-C port to recharge. It connects in to the chair with this slightly unusual connector:

    The internals of the chair have a USB-C cable to connect everything up.

    LOL!

    YES BUT WHY DOES A CHAIR NEED A BATTERY PACK??!?!

    On the side of the left arm-rest are three buttons.

    Two of them move the lumbar-support up and down. Depending on how your back is feeling and how far you are reclined, you can adjust the the back-support position.

    And the 3rd button?

    That's the build-in back massager, silly!

    Is that useful?

    Yes. Being able to instantly adjust the back support without having to twist around is fantastic, especially for those of us reaching a certain age.

    The "massage" feature essentially just moves the support up and down for five minutes before returning to its previous location. When sat upright, it feels great. But the real benefit is when you're laying down.

    How flat does this thing go?

    160° - not quite flat, but good enough when you're taking a break from Typing Real Hard. You don't want a photo of me sprawled out, so LiberNovo have helpfully provided some stock photos of much better looking folk.

    It is incredibly stable. At no point did it tip over or feel like it was going to deposit me on the floor. What really helps is the included foot stall.

    No Feets On Seats

    Unsurprisingly, this is not USB-C powered. A sturdy plastic footrest with a deeply padded leg rest on top.

    Again, assembly was a cinch - follow the large printed instructions and clip it together. It's rated for 40㎏, so you shouldn't stand on it but it is more than enough to rest your weary legs.

    Price

    I hope you're sitting down for this.

    Direct from LiberNovo, you can expect to pay around £700 - although there are bundles with extra batteries, the footrest, and even an eye mask which will shoot that price up. You can get the full bundle on Amazon for around £1,000.

    There's two ways to look at that price. Firstly, youch. But, alternatively, that's still cheaper than a Herman Miller Aeron. And Herm's doesn't come with a built-in lumbar massage.

    (There is also an upgraded version which has a built in fan under the seat. Personally, I suggest eating a healthier diet.)

    I can't deny that's a chunk of change. If you're anything like me, you probably spend most of your day sat down. You might as well sit on something comfortable.

    Final Thoughts

    Having the back-rest adjustable via arm-rest buttons is a genius touch. I just wish it went further. I'd love a control panel (or, dare I say it, app) which let me adjust the seat height, recline, headrest position etc. Who can be bothered with fiddly manual levers when electricity can do the work for us?

    Building this chair was a breeze - and it was delightful to get a pair of safety gloves with it.

    The chair is extraordinarily comfortable and the back massage, while not on the level of a "shiatsu" style heated massage pillow, is delightfully pleasant. Would I lie all the way back and sleep in it? Yeah! Certainly more comfortable than an economy airline seat.

    If you spend a lot of time sitting at your computer, your arse deserves something supportive. Your back deserves some love too. Yes, the USB-C power-pack is a little bit of a gimmick - but it is a hell of a good one.

    In my opinion, this is worth splashing out on.

    #chair #furniture #gadget #Review #USBC
  3. I used to treat ChatGPT like a vending machine. Need a React hook? Drop a coin. Need a PR summary? Drop another. Every ask started from zero — stack, conventions, what “done” meant — and every reply drifted a little from how we actually ship.

    The waste wasn’t the tokens. It was re-explaining our frontend rules every single time, then cleaning up the same mistakes.

    So I stopped pasting one-offs and started treating prompts like code: named, versioned, and checked into the repo.

    One-off asks don’t compound


    A throwaway chat is fine for a throwaway question. Frontend work rarely is throwaway:

    • “Write a Modal” without our focus-trap / Escape / return-focus rules
    • “Add loading states” without our skeleton vs spinner convention
    • “Review this PR” without what AI should skip vs what a human owns
    • “Refactor this form” without our form library and error-message pattern

    You get something that compiles. You don’t get something that matches the last three PRs. The next person (or the next you) pays the tax again.

    What belongs in a prompt library


    I keep a small folder — prompts/frontend/ — not a novel. Each file is one job, one outcome shape.

    Mine look like this:

    prompts/frontend/
    pr-review-ai.md # what the model checks vs leaves for humans
    new-component.md # scaffold + a11y buckets + token rules
    design-token-change.md # changelog / RFC checklist before merge
    test-plan.md # real coverage vs fake green
    agent-ui-diff.md # component boundaries, no random token edits
    accessible-react.md # roles / keyboard / contrast report required

    If a prompt isn’t reused at least twice a month, it doesn’t earn a file. Sticky notes in chat stay sticky notes.

    The shape every prompt gets


    Same skeleton so humans and agents know where to look:

    # <job name>

    ## When to use
    One sentence. If it doesn’t match, don’t force it.

    ## Context to paste
    - Framework / router / form lib (or “read from repo”)
    - Design tokens source of truth
    - Related golden files (paths)

    ## Hard rules
    Bullet list the model must not violate.
    Prefer native HTML, keep tokens, no drive-by refactors, etc.

    ## Output format
    Numbered sections the reply must include.
    Missing a section = reject the turn.

    ## Done looks like
    Concrete acceptance — not “looks good.”

    The “output format” line is the whole game. Models fill schemas. They invent vibes when you don’t give one.

    From ChatGPT paste to agent / editor default


    Once the files exist, wire them where work actually happens:

    1. Cursor / Copilot / Claude project instructions — point at prompts/frontend/ or inline the two you use daily.
    2. PR bot / agent — load pr-review-ai.md as the system brief; humans still own product judgment.
    3. Slash or snippet — @new-component expands the scaffold prompt so nobody retypes it.
    4. CI-ish habit — if the agent reply skips a required section, treat it like a failed check and re-run with the same file.

    You don’t need a fancy prompt CMS. Markdown in git is enough. Review prompt changes in PRs the same way you’d review eslint config.

    A tiny migration story


    Week 1 I had twelve ChatGPT threads titled “modal again.” Week 3 I had six files and deleted half the threads.

    What changed in practice:

    • New Button / Modal / Combobox asks started from the same a11y report shape
    • Token edits stopped sneaking hex literals into components
    • AI PR comments stopped arguing about naming when the prompt said “leave naming to humans”

    Same models. Less re-prompting. The library held the team memory the chat UI kept forgetting.

    What not to put in the library


    • Product pitches and marketing copy (keep prompts about shipping UI)
    • One-shot debug sessions that will never recur
    • Entire style guides pasted twice — link the real doc instead
    • Secrets, private URLs, or customer data as “examples”

    A prompt library is DX infrastructure. If it reads like a blog draft, move it to the blog.

    Start with three, not thirty


    Tonight, pick the three asks you keep repeating. Write each as one markdown file with When / Rules / Output / Done. Drop them in the repo. Point your editor agent at that folder.

    Next time you open a blank ChatGPT box for a frontend task, open the matching file instead. Paste once. Reuse forever. That’s the whole upgrade — from one-off asks to a library your future self (and your agents) can actually find.#frontend #ai #dx #productivity #software #coding #development #engineering #inclusive #community
    From One-Off ChatGPT Asks to a Reusable Frontend Prompt Library

  4. How to Use AI Agents for Personal Finance and Wealth Building: The Master of Coin Guide (2026)

    Why Most People Use Artificial Intelligence Backwards (And How to Fix It)

    Every day, millions of people open an AI chat window and ask the wrong question: "What stock should I buy today?" or "How do I get rich quickly with AI?" They treat artificial intelligence like a carnival oracle, hoping a single prompt will absolve them of the discipline required to build wealth. When the oracle gives them generic, recycled advice, they walk away convinced that AI is overhyped.

    The divide between those who build sovereign wealth in the coming decade and those who remain trapped in financial noise comes down to a single shift: moving from passive AI chatbots to autonomous AI agents.

    According to Backbase’s 2026 AI in Wealth Management analysis, while 95% of financial institutions have experimented with generative AI, only 27% report substantial impact because most remain stuck in passive chat pilots rather than deploying agentic workflows. Meanwhile, McKinsey’s 2035 Wealth Management Outlook projects that AI agents and intelligent automation will form the operational backbone of modern wealth management—delivering an estimated 30% to 40% productivity leap in portfolio intelligence and financial research.

    You no longer need a Wall Street family office to command that same operational backbone. In the philosophical framework of The Philosopher King, your mind is the fifth-dimensional architect, and AI agents are four-dimensional force multipliers. Here is the step-by-step guide to building your own autonomous AI agent workflow to master your coin, reclaim your time, and eliminate emotional financial mistakes.

    Step 1: Shift from Single Prompts to a Multi-Agent Financial Council

    A chatbot waits for you to ask a question and gives you a single stream of text. An AI agent is given an objective, access to real-world tools (such as web search, financial data APIs, and spreadsheets), and the autonomy to break a complex goal into sequential steps.

    When managing your personal treasury—what we call the discipline of the Master of Coin—relying on a single AI persona creates blind spots. Instead, structure your workflow as a three-agent council built on deliberate discipline (the meticulated kind):

    • The Intelligence Scout (Macro and Fundamental Research Agent): Configured to scan earnings transcripts, SEC filings, macroeconomic liquidity trends, and sector developments on a recurring schedule, distilling hours of noisy financial media into a five-minute first-principles brief.
    • The Treasury Comptroller (Cash-Flow and Allocation Auditor): Tasked with auditing your monthly burn rate, identifying recurring subscription bloat, tracking your savings velocity, and calculating whether your actual asset allocation matches your target risk profile.
    • The Red-Team Adversary (Risk and Pre-Mortem Agent): Programmed with a single directive: to ruthlessly challenge your investment ideas. Whenever you are tempted by market euphoria or FOMO, this agent stress-tests your thesis by finding every balance-sheet weakness, valuation risk, and macroeconomic headwind you ignored.

    Step 2: Choose Your AI Agent Stack and Connect Your Financial Data

    Whether you are a non-technical sovereign investor or a developer building custom pipelines, the open-source and commercial ecosystem for AI agents has matured rapidly. As documented in McKinsey’s 2026 State of AI Global Survey, agentic orchestration is now one of the fastest-scaling capabilities worldwide. Depending on your technical comfort, consider these proven building blocks:

    • Model Context Protocol (MCP) for Secure Data Connections: Introduced as an open standard by Anthropic and detailed in the official Model Context Protocol documentation, MCP acts like a universal USB-C port for AI applications. It allows your AI agent to securely read local CSV exports, Google Sheets ledgers, and market data feeds without uploading your private credentials to untrusted third parties.
    • CrewAI for Role-Based Financial Teams: If you want specialized agents to collaborate on a research report, CrewAI lets you define distinct roles (for example, a Fundamental Analyst Agent and a Risk Manager Agent) that hand off structured outputs to one another automatically.
    • LangGraph for Stateful, Auditable Workflows: Built by the LangChain team, LangGraph models agent workflows as a stateful graph with built-in checkpointing and human-in-the-loop pauses—ideal when you want an agent to pause and wait for your explicit approval before logging or executing a decision.
    • OpenAI Agents SDK and Microsoft AutoGen for Multi-Agent Debate: Using the OpenAI Agents SDK or Microsoft AutoGen, you can pit a Bull Agent against a Bear Agent on any asset class, forcing both agents to cite verifiable data until only the strongest first-principles truth survives.

    Step 3: Enforce the "Human-in-the-Loop" Sovereign Rule

    One of the most common questions people ask when researching AI for investing is: "Should I connect an AI agent directly to my brokerage account and let it trade autonomously?"

    For the vast majority of individual investors, the answer is an emphatic no. As highlighted in Forbes Finance Council’s analysis on AI agents in finance and McKinsey’s research on AI agent performance management, autonomous agents require strict governance boundaries, audit trails, and human oversight.

    "An AI agent is your tireless chief of staff in the fourth dimension, but your consciousness remains the sovereign on the throne. Never abdicate final judgment to a machine."

    To protect your capital while maximizing leverage, enforce these four iron rules:

    1. Read-Only Access by Default: Give your agents read access to market data, news feeds, and sanitized CSV exports of your budget—never raw write/withdrawal permissions to your primary bank or brokerage accounts.
    2. Require Source Citations on Every Claim: Instruct your research agents to attach a direct link to the primary filing, earnings release, or statistical dataset for every number they report, eliminating hallucinated metrics.
    3. Automate the Preparation, Never the Conviction: Use agents to compress 10 hours of reading into 15 minutes of structured synthesis, freeing your mind to make low time-preference decisions with clarity.
    4. Log Every Thesis for Post-Mortem Review: Have your agent archive every investment decision alongside the exact assumptions you held at the time, creating an unvarnished mirror of your cognitive biases over time.

    Step 4: Copy This 15-Minute Daily "Master of Coin" AI Routine

    You do not need a complex server cluster to start today. Begin with a simple, repeatable daily cadence using scheduled AI tasks:

    • 06:00 AM — The Sovereign Morning Brief: Schedule an AI agent to scan overnight macroeconomic developments, central bank releases, and any material news affecting your watchlist, delivering a bulleted summary stripped of sensationalist clickbait before you open your eyes.
    • Sunday Evening — The Red-Team Portfolio Audit: Feed your current asset allocation and investment thesis into an adversarial prompt: "Act as a first-principles risk officer. Identify the top three hidden correlations, liquidity risks, or macro assumptions that could cause a 25% drawdown in this portfolio over the next 12 months."
    • First of the Month — The Capital Velocity Check: Have your agent categorize the prior month’s cash flows into three buckets—Sovereign Asset Accumulation, Productive Skill/System Building, and Fleeting Consumption—so you can see exactly where your life-force is compounding or leaking.

    Join the Conversation: How Are You Using AI Agents to Master Your Coin?

    We are living through the greatest democratization of analytical leverage in human history. Those who pair ancient philosophical restraint with modern agentic intelligence will operate with the clarity of an institution and the agility of a sovereign individual.

    I want to hear from you in the comments below:

    1. Are you currently using AI agents or scheduled workflows to research investments, track expenses, or stress-test your financial decisions?
    2. Which part of managing your personal finances drains the most time or emotional energy—and how would you design an AI agent to take it off your plate?
    3. Where do you draw the line between automated AI analysis and human intuition when putting your capital at risk?

    Drop your thoughts, favorite prompts, or questions in the comments—let us sharpen our frameworks together.

    All is One | One is All

    #aiAgents #ArtificialIntelligence #automation #financialSovereignty #howTo #MasterOfCoin #personalFinance #wealthBuilding
  5. OsmAnd: Why Offline Search is So Hard

    You type an #address into a #map app on a phone in airplane mode. There is no server to ask: the phone has to find it on its own. Why is that so hard?

    We walk the whole road we took to rebuild offline search in #OsmAnd: what an address really is, where we got real examples to measure search, why the old algorithm kept failing, and the new search that puts the words on the map.

    https://www.youtube.com/watch?v=aScKKQvZx3U

    Chapters

    • 0:00 Intro: the data was there
    • 1:24 Part 1 · Addresses: a language without rules
    • 4:21 Part 2 · Dataset: where do we get examples?
    • 6:40 Part 3 · The librarian algorithm
    • 9:27 Part 4 · Words on the map
    • 11:45 Part 4.1 · Tiles
    • 13:31 Part 4.2 · The zipper
    • 14:07 Part 4.3 · Skip-tile zipper
    • 16:49 Part 5 · A puzzle of words
    • 21:14 Part 6 · Where we are now and what's next

    The new search comes with the upcoming OsmAnd 5.5, and you can try it today in our nightly builds. As always, the code is on GitHub: https://github.com/osmandapp/OsmAnd

    When search can't find something, tell us what you typed: every miss becomes a test. And help the map: add street names and town boundaries in OpenStreetMap.

    OsmAnd: https://osmand.net

  6. I asked Grok,,,,

    Israel Defense Forces tweets:
    'In 2 seperate incidents, IDF troops identified & eliminated 2 terrorists who crossed the Yellow Line in northern and southern Gaza.'

    jd ask Grok:
    Grok, under International Law do people living under a foreign military occupation (also recognised by the UN etc for being an illegal occupation) have a right to resist that military?

    Grok replies:
    'Under international law, the right of self-determination (UN Charter) underpins resistance by peoples under alien occupation. UNGA resolutions (e.g. 2625, 3314) affirm the legitimacy of struggles against occupation, including armed means. Additional Protocol I treats such conflicts as international, granting combatant status to organized groups that meet criteria and follow IHL. The right is not unlimited: attacks on civilians and other IHL violations remain prohibited.'

    #Israel #InternationalLaw #Palestine #Grok #Genocide #USpol #EUpol #Politics #Law #Imperialism

  7. Most talk about agent permissions is about what could go wrong. I find it more useful to ask what you will have to say afterwards.

    Picture a hypothetical internal workflow. An assistant reads support tickets and drafts a weekly summary for the team lead. It works well. Then someone widens its access "to make it more useful." Now it can read the whole shared drive and send email.

    Nothing bad has happened yet. But if something does, you are the one explaining it.

    What the explanation looks like


    Suppose the summary one week includes a line from a salary spreadsheet. The agent was allowed to read it, so it did. Now you have to answer a few plain questions:

    • Why could it see that file?
    • Who decided it should?
    • How do we know it did not send anything?

    If the honest answer to each is "it had access to everything, so we can't say," that is the cost. The time goes into reconstructing events, not into fixing a bug.

    A smaller version of the same workflow


    Compare it with a narrower setup, also hypothetical. The agent can read one folder of exported tickets. It cannot send anything. It writes a draft, and a person reads it before it goes anywhere.

    If a draft looks wrong, the explanation is short. The agent could only see this folder. It could not send. A person approved the final version. You can say that in one breath, and you can prove it from the setup.

    Non-regulated still has obligations


    Because this is an ordinary internal workflow, it is easy to treat it as low stakes. It still touches people's data and your own internal files. Privacy and security obligations apply whether or not your industry has a rulebook for them.

    What I check on one workflow


    When we review a single workflow, I look for a handful of things:

    1. What can the agent read, and is that the minimum for the job?
    2. What can it change or send, and does a person approve that step?
    3. If it uses MCP, which tools does it expose, and with whose credentials?
    4. Can you reconstruct what it did from a log, without guessing?

    That last one matters most. A permission you cannot audit is a permission you cannot defend.

    The handoff


    The output of this kind of review should be a page the owner can read. It lists what the agent can touch, what it cannot, and where a human decides. If something goes wrong later, that page is the start of your explanation, not a gap in it.

    I would rather tighten one workflow properly than loosen ten and hope. Smaller access is easier to explain, and easier to fix.

    I'm Jonathan Melton. I run FusionAL, focused on reviewing and integrating lower-risk internal AI workflows, one bounded workflow at a time.#agents #ai #cybersecurity #security #software #coding #development #engineering #inclusive #community
    The incident you have to explain is the real cost of an over-permissioned agent

  8. Breakfast Rock and Pop, 7-9am on Sundays, on Radio Jammor
    With music from the 50s to today
    #rock #pop #SundayMorning #breakfast

    Radio Jammor is on the air...
    Broadcasting from #Scotland
    radiojammor.com
    Ask Alexa to play Radio Jammor (UK Only)
    #music #radio

  9. @lilnickmuller
    Just causally hiring hit men in 2018

    Here lies Jeff. Died normal. Don't ask questions.

    #JaredKushner #bribes #corruptgovernment #FollowTheMoney #LockHimUp

  10. Every time the military jets fly over my neighborhood on their way to open the University of Texas home game, I have to ask if UT's got a home game, or if the Texas Air National Guard is trying to start Civil War 2. I'm let down by both options.

    #UTexas #Longhorns #AustinTX

  11. Think of the last person you interacted with. How happy do you think you are relative to them? (I ask this question every day to gauge how happy the Fediverse is.) #happiness #poll #mentalhealth #psychology

  12. "You need 2 indulge in a little critical thinking— not that it's hard 4 u! Your great mental energy helps u ask all the right questions & come up w/ your own ideas."

    "Hold on 2 what you've got. Being overly generous leads 2 regret. Focus on bringing in personal growth & building a foundation that offers security & financial stability."

  13. The cyber noiseocalypse is doing my head in, far more than any actual cyber harm has done since WannaCry.

    One thing I’ve started doing when non-cyber people who are understandably terrified about what they’re hearing is to ask them what harm they, or anyone they know, has suffered this week as a result of anything to do with cyber.

    Might log off all day tomorrow 😀

  14. Less than day later I’m already reading comments on YouTube saying that this channel (and another one that appeared a week after) are made with AI. I’d like to ask the #PixelArt community just in case they know the human behind Pixel Star Lore, if there is one.

  15. Server-side tracking still needs consent, iubenda tells marketers: Moving tags to a server changes where data travels, not the GDPR and ePrivacy duty to ask first, per iubenda's Oct 23 guide. Its own product is waitlisted. ppc.land/server-side-tracking- #ServerSideTracking #DataPrivacy #GDPR #ePrivacy #DigitalMarketing

  16. You got to pay your dues if you want to sing the blues,
    And you know it don't come easy ...
    I don't ask for much, I only want trust,
    And you know it don't come easy ...

  17. "ModelCompare, which usually evaluates and ranks LLMs on their ability to perform various tasks, this week instead decided to ask what those AI models thought about us meatbags, and every single one gave a similar answer at least once: We're lemmings who would rather agree with the group than seek truth or remain logically consistent in our thinking."

    theregister.com/ai-and-ml/2026

  18. I added Goose and Amp to a tool that runs several coding agents. The most useful thing I learned wasn't about the protocol. It was the defaults.

    Goose's default mode approves tool calls automatically. If you start it through a wrapper that doesn't set a mode, it runs commands without asking anyone. So I set the mode per process instead of relying on whatever is in the user's Goose config. Default, accept-edits and auto all use Goose's approval mode, so tool calls ask. Only the permission mode literally called bypass picks automatic approval, and none of it touches the user's own Goose configuration.

    The second surprise was Goose's chat-only mode. It disables all tools, reads included. A plan mode you'd expect to still read your files doesn't, so mapping 'plan' to it means the agent can only talk.

    Amp went the other way. Its streaming output has no documented way to answer an approval from outside, so approvals stay in its own terminal. Its plan and don't-ask modes reject every tool, reads included, and only bypass asks for automatic approval.

    What I do with any new agent CLI now: before wiring up anything else, run it once in an empty directory and see what it does with a tool call by default. Two agents gave me two very different answers, and neither was in the first page of the docs.

    Which of your agent CLIs would run a command without asking, if you started it the way you usually do? I'm building Styx, where this came from.#agents #ai #cli #tooling #software #coding #development #engineering #inclusive #community
    Your coding agent CLI may approve its own tool calls by default

  19. Screenshots are everywhere in software docs, and most of them have alt text like screenshot, image, or the original file name. Sometimes there's none at all. When I edit a guide, the images are often the last thing anyone has looked at closely.

    Alt text matters more in docs than people think. Screen reader users hear it instead of seeing the image. It shows up when an image fails to load, for example on a slow connection or after someone renames a folder in the repo. And it's text, so it can be searched and translated, which a picture of text can't.

    Here's how I approach it.

    Ask what the screenshot is for


    Before writing anything, I ask one question: why is this image here? In docs, the answer is almost always one of these:

    • It shows where something is (a button, a menu, a field).
    • It shows what you should see after a step, so the reader can confirm it worked.
    • It shows a specific value or setting the reader has to match.
    • It's decoration, and the surrounding text already says everything.

    The alt text should carry that purpose, not a full inventory of the screen. A settings page might have thirty controls on it, but if the step is about one checkbox, that checkbox is what the alt text is about.

    Describe the state, not the pixels


    Compare these two:

    ![Screenshot of the settings page](images/settings.png)

    ![The Notifications tab with "Email me when a build fails" turned on](images/settings.png)

    The first tells me nothing I couldn't guess. The second tells me exactly what the screen should look like after the step, which is the whole reason the screenshot exists.

    A few habits that help:

    • Skip "image of" and "screenshot of". Screen readers usually announce that it's an image already. Start with the content.
    • Use the exact UI labels, with the same capitalisation as the interface. If the button says "Save changes", the alt text says "Save changes", not "the save button".
    • Include values that matter. If the reader needs to pick "UTF-8" or set a timeout to 30, put that in the alt text.
    • Keep it to a sentence or two. If you need more, the information probably belongs in the body text.


    Don't hide instructions in the image


    This is the problem I find most often. A step says "Configure the options as shown below", and the actual settings only exist in the screenshot. Anyone who can't see the image, or whose image didn't load, is stuck.

    The fix isn't longer alt text. It's moving the information into the step itself:

    3. In **Format**, select **CSV**, and in **Encoding**, select **UTF-8**.

    ![The Export dialog with CSV and UTF-8 selected](images/export.png)

    Now the step works without the image, and the screenshot becomes a confirmation. The alt text can stay short because the text above it does the heavy lifting.

    When empty alt text is right


    Not every image needs a description. If a screenshot only repeats what the text already says, or it's a decorative banner, an empty alt is the honest choice. In Markdown that's ![](images/banner.png), which renders as alt="". Screen readers generally skip images with empty alt text instead of reading out the file name.

    The difference between "empty on purpose" and "forgot to write it" is invisible in the source, though. In repos I work on, I like a short HTML comment next to deliberate ones, so the next editor doesn't "fix" it:

    <!-- decorative, text above covers it -->
    ![](images/banner.png)

    A quick check before review


    To find the obvious problems in a docs folder, I use a single grep. It looks for three patterns: empty or generic alt text, alt text that is a file name, and alt text that starts with "image of" or "screenshot of".

    grep -rniE \
    -e '!\[(image|screenshot|picture|img)?\]\(' \
    -e '!\[[^]]*\.(png|jpe?g|gif|webp)\]' \
    -e '!\[(an? )?(image|picture|screenshot|photo) (of|showing)' \
    docs/

    -r searches the folder recursively, -n adds line numbers, -i ignores case, and -E enables extended regular expressions. Each -e adds one pattern. On a test file it prints something like:

    docs/setup.md:3:![](images/settings.png)
    docs/setup.md:5:![screenshot](images/login.png)
    docs/setup.md:7:![Screenshot 2026-03-02 at 10.14.png](images/export.png)
    docs/setup.md:11:![image of the dashboard](img/dash.png)

    It's not a verdict. The empty alt on line 3 might be deliberate, and the check can't tell whether a real description is accurate. It only catches images written in Markdown syntax, not HTML <img> tags. But it gives me a list to work through, which beats scrolling every page looking for images.

    Keep it in sync


    The last thing: alt text goes stale with the UI. When a button gets renamed and someone updates the screenshot, the alt text often keeps the old label. When I review a docs change that touches an image, I read its alt text against the new screenshot. It takes a few seconds, and it's usually the only place the old wording survives.#documentation #a11y #writing #markdown #software #coding #development #engineering #inclusive #community
    Writing alt text for screenshots in documentation

  20. AI can generate a financial model that looks coherent, contains valid formulas, and produces a plausible result while still being wrong in ways that matter.

    A formula can reference the wrong cell. A cost assumption can be expressed in the wrong unit. A revenue schedule can omit a phase. A model can calculate correctly from an unsupported market assumption.

    These are different failure modes, and they need different controls. For real estate feasibility models, the objective should not be to ask whether an AI-generated workbook looks correct. It should be to establish which properties can be tested automatically, which assumptions require evidence, and which decisions must remain with a qualified human reviewer.

    A useful validation architecture has five layers:

    1. Structural validation
    2. Deterministic calculation checks
    3. Domain and consistency checks
    4. Evidence and provenance checks
    5. Human review and approval

    No single layer is sufficient.

    1. Separate the output from the evidence


    Consider a hypothetical development model with the following inputs:

    • Site area and developable area
    • Permitted gross floor area
    • Unit mix or lettable area
    • Revenue assumptions
    • Construction and other development costs
    • Financing assumptions
    • Development programme
    • Exit assumptions

    The model calculates development costs, revenue, cash flows, residual land value (RLV), and potentially internal rate of return (IRR).

    For example, a model might calculate an RLV of £4 million. That output can be mathematically consistent with the workbook and still be commercially misleading if the revenue assumptions are unsupported or the construction cost basis is outdated. Validation therefore needs to test both the calculation and the justification for its inputs.

    2. Layer one: validate the structure before the numbers


    Before reviewing financial logic, validate the shape of the generated output. If an AI system is expected to return structured data before creating a workbook, define an explicit contract. JSON Schema is one established option for specifying required fields, data types, and constraints.

    See the JSON Schema getting-started guide.
    A simplified model input contract might look like this:
    {
    "project_id": "DEMO-001",
    "currency": "GBP",
    "site_area_sqm": 5000,
    "gross_floor_area_sqm": 12000,
    "construction_cost_per_sqm": 1800
    }
    This is illustrative data, not a market benchmark or a recommendation for a production schema.

    A structural validator could check that:

    • Required fields are present.
    • Numeric values are actually numeric.
    • Areas and costs use declared units.
    • Currency is explicitly identified.
    • Values fall within defined technical bounds.
    • Unexpected fields are rejected or handled deliberately.
    • Missing values are not silently replaced with zero.

    The last point is important. Zero and unknown are not equivalent. If a finance rate is missing, substituting zero can make a model appear more profitable. A missing value should normally trigger a validation error or an explicit unresolved status.

    Structural validation establishes that the model can be interpreted. It does not establish that the model is economically sensible.

    3. Layer two: use deterministic checks for deterministic rules


    Rules that can be expressed precisely should not depend on an LLM's judgment. For example, if a model defines construction cost as gross floor area multiplied by construction cost per square metre, the expected calculation is:

    \text{GFA}
    \times
    \text{Cost per sqm}
    ]
    For the hypothetical inputs above:
    [
    12{,}000 \times £1{,}800 = £21{,}600{,}000
    ]
    A deterministic test can independently calculate the expected result and compare it with the workbook output.
    from decimal import Decimal

    gfa_sqm = Decimal("12000")
    cost_per_sqm = Decimal("1800")
    reported_cost = Decimal("21600000")

    expected_cost = gfa_sqm * cost_per_sqm

    assert expected_cost == reported_cost

    This test checks arithmetic for the stated formula. It does not establish that the GFA is permitted, that the cost rate is appropriate, or that the formula captures every relevant cost.

    A production implementation should also define tolerances where appropriate, particularly when comparing rounded spreadsheet values or calculations involving floating-point numbers.

    Other deterministic checks might include:
    Revenue equals the sum of its components.

    • Total costs reconcile to their component schedules.
    • Cash flow totals reconcile across periods.
    • Unit counts and areas reconcile between schedules.
    • The reported output matches an independently calculated result.
    • A sensitivity case actually changes the intended input.
    • Required formula cells are not unexpectedly blank or replaced by constants.

    Where possible, use independent calculations rather than simply checking that a formula cell contains a formula. A formula can exist and still be wrong.

    4. Layer three: validate model relationships


    Many serious errors are not syntax errors or arithmetic errors. They are inconsistencies between parts of the model.

    Suppose a development model contains:

    • 120 residential units in the unit schedule
    • 116 units in the sales schedule
    • Revenue calculated using the sales schedule
    • Construction costs calculated using the unit schedule

    Every formula may evaluate successfully, but the workbook contains a discrepancy that needs resolution.

    Domain-level checks can flag conditions such as:

    • Unit counts that differ across schedules.
    • Areas that exceed a declared model constraint.
    • Revenue periods that do not align with the programme.
    • Cost totals that exclude a populated cost category.
    • An exit value that uses an inconsistent timing assumption.
    • A sensitivity scenario that changes revenue but leaves dependent calculations unchanged.
    • An IRR calculation using a cash-flow range that omits a period.

    These checks should be encoded as explicit rules wherever the intended relationship is known.

    Some rules require context. For example, whether a particular cost should be included in a development budget depends on the model's scope and conventions. A validator should not impose a universal rule where none exists.

    Instead, it should identify the relevant condition, record the rule being applied, and send ambiguous cases for review.

    5. Layer four: validate the provenance of assumptions


    A financial model can pass every arithmetic test and still fail as an analytical tool.

    The reason is straightforward: calculations cannot establish the truth of their inputs.

    For every material assumption, a validation system should try to preserve:

    • The value and unit.
    • The source or origin of the value.
    • The source's date and relevant data period.
    • The geography and asset type, where applicable.
    • The transformation from source evidence to model assumption.
    • Any manual adjustment made by the analyst.
    • The model locations that depend on the assumption.

    Consider a construction cost assumption of £1,800 per square metre. A validator might confirm that the figure is numeric, the unit is recorded, and the workbook uses it consistently. Those checks do not establish whether the figure is suitable for the location, asset type, specification, and cost period. That question requires appropriate evidence and professional interpretation.

    An LLM may help extract candidate assumptions from documents or explain how a value is used in a workbook. The extracted result should still be checked against its source, and the resulting assumption should remain distinguishable from the underlying evidence.
    A useful principle is:
    Traceability makes an assumption inspectable. It does not make the assumption correct.

    6. Layer five: make human review a defined state transition


    Human review should not be an informal final glance after an automated process has already treated the model as complete.

    A practical workflow can represent validation explicitly:

    GENERATED
    |
    v
    STRUCTURE_CHECKED
    |
    v
    CALCULATIONS_CHECKED
    |
    v
    DOMAIN_CHECKED
    |
    v
    EVIDENCE_REVIEWED
    |
    v
    HUMAN_APPROVAL_REQUIRED
    |
    +----> APPROVED FOR THE DEFINED PURPOSE
    |
    +----> RETURNED FOR CORRECTION
    |
    +----> BLOCKED: UNRESOLVED ISSUE

    The states are illustrative, but the distinction matters. A successful automated test should not automatically mean that a model is approved. Approval should be scoped to a defined version of the workbook, its assumptions, its evidence, and its intended use.
    A reviewer should be able to see:

    1. What was generated.
    2. Which automated checks passed.
    3. Which checks failed or were skipped.
    4. Which assumptions lack adequate evidence.
    5. What changed after a correction.
    6. Who approved the model and for what purpose.

    If a material input or formula changes after approval, the system should identify which checks need to run again and whether the earlier approval remains valid. This is where versioning and change tracking become part of model governance rather than administrative overhead.

    7. Design the exception path before the success path


    Validation is often designed around a clean example: the model is generated, every check passes, and the user receives the output. Production systems need to handle less convenient outcomes.

    A failed check should produce actionable information. “Validation failed” is less useful than “The unit count in the sales schedule differs from the unit schedule; review the linked inputs before approving revenue.”

    Similarly, a warning should not disappear simply because a later stage of the workflow succeeds. For auditability, preserve the check identifier, the model version, the result, the relevant evidence, and the resolution.

    8. Measure validation quality without inventing an accuracy score


    A single “model accuracy” percentage can hide important distinctions. A workbook might pass every arithmetic test while containing several unsupported assumptions. Another may contain a harmless formatting issue but have fully reconciled calculations and well-documented inputs.

    A more useful validation report separates categories:

    • Structural checks passed or failed.
    • Deterministic calculation checks passed or failed.
    • Domain checks passed, failed, or were not applicable.
    • Assumptions with verified, missing, or conflicting evidence.
    • Open exceptions and their severity.
    • Human review status.
    • The scope and version of the approved output.

    If the system is evaluated over time, track false negatives and false positives for individual validation rules against a reviewed test set. Record the test cases, expected outcomes, rule versions, and known limitations.

    Do not interpret a high pass rate as proof that the model is correct. It may simply mean that the checks cover only a narrow set of failure modes.

    The purpose of validation is to make known risks visible and testable, not to manufacture certainty.

    9. A practical implementation sequence


    A team introducing validation around AI-generated financial models does not need to automate every review step at once.

    A sensible sequence is:

    1. Define the contract. Specify the required inputs, output fields, units, and missing-value behaviour.
    2. Write deterministic tests. Start with totals, reconciliations, formula ranges, and independent calculations.
    3. Add domain checks. Encode known cross-schedule relationships and clearly defined constraints.
    4. Track provenance. Associate material assumptions with sources, dates, units, and transformations.
    5. Introduce exception handling. Make failures explicit and prevent unresolved material issues from being silently treated as passed.
    6. Define human approval. Record the reviewer, workbook version, purpose, and outstanding qualifications.
    7. Build a regression suite. Retain representative valid and invalid examples and rerun the checks when the generation logic or validation rules change.

    The test suite should include deliberate failures, not only successful examples. Examples might include missing finance assumptions, inconsistent unit counts, a formula referencing the wrong period, and a source whose geography does not match the project.

    This helps test whether the validation process detects the intended problem rather than merely accepting a plausible-looking output.

    Conclusion


    Human-in-the-loop validation is not a person checking an AI result after the important work is finished. It is a system design in which deterministic rules handle deterministic questions, domain checks expose inconsistencies, evidence is kept separate from assumptions, and a human reviewer remains accountable for unresolved judgments.

    For financial modelling, that distinction is material. A workbook can be well-formed without being economically sound, mathematically consistent without being supported by market evidence, and ready for review without being ready for a decision.

    The objective is not to make every AI-generated model look trustworthy. It is to make the model's logic, assumptions, limitations, and unresolved issues sufficiently visible that a professional can challenge it before relying on the result.#feasibility #realestate #ai #financial #software #coding #development #engineering #inclusive #community
    Human-in-the-Loop Validation for AI-Generated Financial Models

  21. I'm asking my own MCP server questions about my own system. "It's smarter than you now!", says Lucy. This is the payoff for spending 5 months thinking about this system. For writing 50,000+ words of descriptive text that an LLM can now trawl in a second. For building local skills that allow it to query my own local index as well as that published knowledge.

    I can ask it where to save industry research, and it can answer as if it was me. 😂

  22. My latest AI annoyance is it trying to tell me everything not to do, like it has to be an exhaustive warning. I would suggest pizza. I would not suggest chicken, sandwiches, or other items that are not pizza. I have to ask for rewrites for issues and other docs all the time.

  23. Halfway through a two-day batch run I noticed that one answer looked suspiciously like the answer to the item two rows above it, and I could not prove which input it came from. Has that ever happened to you — the job finished, the output looked plausible, and you had no way to defend a single row of it? These are my field notes from fixing that, with the harness I ended up keeping.

    What I was actually trying to do


    I had a flat list of short, independent text items, and I wanted one short answer per item, written to a ledger I could re-run safely. Sending one request per item is the obvious path, but it doubles the number of round trips, and every round trip is another chance to miss a wall-clock deadline. So I tried the cheaper-looking option: put two items in one prompt and ask for two answers back. Note that this is not a quota argument — I never measured a quota, and I am not claiming one exists. The motivation was purely fewer round trips and fewer half-finished batches.

    For context, the driver ran on MonkeyCode's free server option, and the calls went through its free model access. Disclosure: This article was prepared as part of MonkeyCode's product outreach. I will keep the product out of the technical claims, because the failure below is a property of my prompt and my validator, not of any provider.

    Day one: the harness I wrote


    The whole thing is one file with no dependencies beyond the Python standard library, which was deliberate. If the harness can move between machines with scp and nothing else, I can debug it anywhere, including on a machine I do not own. Here is the shape of it.

    # batch_harness.py — stdlib only; you supply call_model()
    import hashlib
    import json
    from dataclasses import dataclass, field

    def item_id(text: str) -> str:
    return hashlib.sha256(text.strip().encode("utf-8")).hexdigest()[:12]

    @dataclass
    class Item:
    text: str
    id: str = field(init=False)

    def __post_init__(self):
    self.id = item_id(self.text)

    def build_prompt(items):
    blocks = "\n".join(f'<item id="{i.id}">{i.text}</item>' for i in items)
    return (
    "Answer each item separately. Return a JSON array only, no prose.\n"
    'Each element must be {"id": "<id from the item tag>", "answer": "<answer>"}.\n'
    "Copy ids exactly. Do not renumber, merge, or reorder the items.\n\n"
    + blocks
    )

    The important line is the id, and it is deliberately boring: a hash of the input text, truncated. Same input, same id, forever — so a second run of the same ledger is a no-op by construction. If the id were derived from the model's output, a reworded answer would look like a brand-new item, and the queue would quietly grow.

    The validator, which is where the actual work lives


    def validate(items, raw):
    try:
    payload = json.loads(raw)
    except json.JSONDecodeError as exc:
    return None, f"not_json: {exc.msg}"
    if not isinstance(payload, list):
    return None, "not_a_list"

    rows = [r for r in payload if isinstance(r, dict)]
    got = [str(r.get("id", "")).strip().lower() for r in rows]
    want = [i.id for i in items]

    if len(got) != len(set(got)):
    return None, "duplicate_ids"
    if set(got) != set(want):
    missing = sorted(set(want) - set(got))
    extra = sorted(set(got) - set(want))
    return None, f"set_mismatch missing={missing} extra={extra}"

    answers = {r["id"].strip().lower(): r.get("answer", "") for r in rows}
    if any(not isinstance(a, str) or not a.strip() for a in answers.values()):
    return None, "empty_answer"
    return answers, "ok"

    Two details I will defend. First, I lowercase and strip the id before comparing, because that transform is lossless — an uppercase hex string identifies exactly one item. Second, I refuse every lossy match: no positional mapping, no prefix matching, no edit distance. Fuzzy matching is precisely how you end up with two answers for one item and a warm feeling that everything is fine.

    What broke on day two


    Two failure modes showed up, and both were invisible to a try/except around the HTTP call.

    1. Answers came back without ids. The response was a clean JSON array of {"answer": ...} objects, in a plausible order. Nothing errored. A positional mapper would have accepted this and been right — probably.
    2. Ids came back that I never sent. One batch returned eleven-character ids instead of twelve; another returned ids that were valid hex but belonged to nothing in my prompt. Set equality caught both instantly; a length check would not have.

    Why is partial acceptance worse than a loud failure here? Because a batch that is 50% valid does not stop the run — it just moves two items into the wrong bucket, and you discover it when someone reads the output.

    The fix: fail the batch, then fall back to one


    def run_batch(items, call_model, attempts=2):
    for attempt in range(1, attempts + 1):
    raw = call_model(build_prompt(items))
    answers, verdict = validate(items, raw)
    if verdict == "ok":
    return answers, {"attempts": attempt, "verdict": verdict, "fallback": False}

    out = {}
    for item in items:
    raw = call_model(build_prompt([item]))
    answers, verdict = validate([item], raw)
    out[item.id] = answers[item.id] if verdict == "ok" else None
    return out, {"verdict": "fallback_single", "fallback": True}

    python batch_harness.py --input items.jsonl --batch-size 2 --ledger runs/ledger.jsonl
    tail -n 3 runs/ledger.jsonl

    {"batch": ["9f2c41ab07de", "41ab9f2c07de"], "attempt": 1, "verdict": "set_mismatch", "extra": ["7d10c3a1f0b2"], "fallback": true, "model_string": "<record what you actually got>"}

    The ledger excerpt above is illustrative — the values are placeholders, and the deliverable is the columns, not the numbers. Record the model string you actually received, because free access is not the same thing as a pinned version, and a drifting model is a variable you want in the log.

    The run sheet I would keep

    ColumnWhy it earns its placebatch (sorted ids)Reproducing a failure needs the exact inputs, not the item countattemptTells you whether retries are rare or structuralverdictDistinguishes not_json from set_mismatch, which are different bugsextra / missingThe invented ids are the signal that the prompt driftedfallbackA rising fallback rate means the batch size is too aggressive


    And a decision table for batch size, which is really a question about failure cost:

    Items per callUse it whenDo not use it when1Items are long, or ordering is contractualYou are already comfortable with the fallback path2Items are short, independent, and id-stableOne bad item can poison its neighbour4+You have eyes on the ledger during the runYou cannot inspect the first hundred rows by hand

    What I would repeat, and what I would not


    I would repeat the input-derived id and the strict set-equality check on day one, not day two; both are ten lines and they replace a whole class of late-night doubt. I would repeat keeping every model call behind one function, because it made the fallback trivial to write. I would not repeat starting at batch size two before watching a hundred single-item calls go through cleanly. The boring baseline is what tells you whether batching is safe for your particular items.

    Who should not do this


    1. Anyone whose items reference each other, since batching changes what the model can see at once.
    2. Anyone under a hard latency or availability guarantee, because a free endpoint is a shared one and I make no promises about it.
    3. Anyone who cannot hand-inspect the first hundred outputs, since the validator checks shape and nothing else.
    4. Anyone paying per token on a long shared instruction, where duplicating it per item costs more than the round trips you save.

    The harness does not know whether an answer is correct — it only knows that every id it sent came back once. That is a smaller promise than it sounds, and it is the one I can actually keep. If you run this drill on the free model access, start at batch size one and let the ledger tell you when two is safe.#python #ai #testing #debugging #software #coding #development #engineering #inclusive #community
    48-Hour Field Notes: I Batched Two Items Per Call and Lost Track of Which Answer Belonged to Which Input

  24. A campaign lands in your lap and the numbers are flat. The button says "Submit." The page is three paragraphs of feature copy above the fold. You have one experiment slot this sprint, one shared traffic budget, and two candidate changes that both look obviously wrong.

    So which one do you ship first?

    The useful answer is neither "test both" nor a coin flip. The two changes answer different questions, and one of them is usually wasted if you run it in the wrong order.

    The two problems look identical in a dashboard


    Both failures surface as the same line: campaign traffic arrives, signups don't happen. To separate them, split the funnel into two questions.

    • Does the page earn attention? Can a first-time visitor understand the offer within the first screen?
    • Does the ask earn commitment? Once the value is clear, is the action obvious, specific, and low-friction?

    The first question is about the landing page. The second is about the call to action. A dashboard that only tracks sessions and signups cannot tell you which one broke.

    A diagnostic table before you write any code

    What the data showsLikely causeWhere to startMost sessions end within a few seconds; low scroll depthThe page does not match the promise in the adLanding pageDeep scroll, pricing or docs section viewed, few form startsThe ask is vague, buried, or costlyCall to actionMany form starts, few completionsForm frictionNeither. Fix the formLow engagement and low action, traffic source unclearTargeting or message mismatch upstreamNeither. Fix the campaign


    That last row matters more than it looks. If the audience arriving from the campaign was never a fit, no amount of button rewording or hero-copy polishing will rescue the page. Fixing the targeting is cheaper than any experiment.

    Why the order matters more than the individual change


    A call to action is read in the context of the headline, the proof, the price, and the surrounding copy.

    That produces two ordering rules.

    Rule one: a button cannot fix a page that never establishes value. If visitors leave before they understand what they are being asked to do, a sharper label has nothing to attach to. You will measure noise and conclude that labels do not matter.

    Rule two: do not optimize a component you are about to replace. If a page rewrite is already on the roadmap for this quarter, running a careful label experiment on the current page is a throwaway. The result will not transfer to the new layout, because the context that produced it no longer exists.

    The second rule is the one teams break most often, because label experiments are fast to ship and feel productive.

    Do the math before you commit to either


    A small change usually produces a small effect, and a small effect demands a large sample. A page rewrite can plausibly shift behavior by several points; a button label change often moves it by a fraction of one.

    A quick calculation, runnable in any Python environment, shows how steep that difference is:

    import math

    def sessions_needed(p_control, p_treatment, alpha=0.05, power=0.80):
    z_a = 1.959963985
    z_b = 0.8416212336
    p_bar = (p_control + p_treatment) / 2
    spread = (z_a * math.sqrt(2 * p_bar * (1 - p_bar))
    + z_b * math.sqrt(p_control * (1 - p_control) + p_treatment * (1 - p_treatment))) ** 2
    print(math.ceil(spread / (p_treatment - p_control) ** 2))

    sessions_needed(0.04, 0.045) # a 0.5-point lift on a 4% baseline
    sessions_needed(0.04, 0.06) # a 2-point lift on the same baseline

    On a 4% baseline, detecting a 0.5-point improvement at 80% power takes roughly 25,000 sessions per arm. Detecting a 2-point improvement takes roughly 1,900. Same campaign, same page, a thirteen-fold difference in required traffic.

    Two conclusions follow. First, if your campaign delivers a few thousand sessions a month, a micro-optimization of the button label is probably not measurable, no matter how good the label is. Second, the size of the expected effect should drive the choice of experiment far more than how easy the change is to ship.

    A default order that holds up in practice


    1. Verify the instrumentation. One exposure event per session, assignment logged server-side rather than inferred from a query parameter, internal traffic excluded, bots filtered. Every downstream conclusion inherits the quality of this step.
    2. Check message match. Put the ad headline next to the page headline. If they describe different things, stop here.
    3. If message match fails, run the landing page experiment first. Change the hero, the offer framing, or the proof: the elements that determine whether a visitor stays long enough to be asked anything.
    4. If message match holds and engagement looks healthy, run the call-to-action experiment. Label, placement, and the one or two lines of supporting copy next to it.
    5. Re-run the call-to-action experiment after any page rewrite. Treat the old result as historical, not as a default.

    Step 4 is where a lot of teams want to start, and it is a legitimate starting point, but only when the diagnostic in the table above says the page is already doing its job.

    Track what happens after the action, not just the action


    A call to action that increases signups while filling the pipeline with people who never come back is a net loss. Before you run either experiment, decide on guardrail events and log them alongside the primary metric:

    // One exposure event per session, emitted once and cached client-side
    trackEvent("experiment_exposure", {
    experiment_id: "cta_copy_q3",
    arm: "specific-verb",
    campaign_id: "launch_aug",
    });

    // Downstream quality signals, tied to the same session
    // activation_started, first_key_action, repeat_usage_7d

    If the primary metric moves up and a guardrail moves down, that is a trade-off that needs a decision. Guardrails are especially important for landing page experiments, because a page that over-promises will inflate the action rate and damage downstream quality.

    Do not change both at once


    Running a page experiment and a call-to-action experiment simultaneously on the same traffic makes the result unreadable. You cannot tell whether the change came from the page, the ask, or the interaction between them.

    If you genuinely need both answers and have the traffic to support it, use a factorial design: four arms, so every page version is paired with every call to action. The interaction term is often the most interesting number in the output, because it tells you whether a strong page makes the label irrelevant. The cost is roughly four times the traffic of a two-arm experiment.

    For most campaigns, sequential experiments are the practical choice: page first, then the ask, with each experiment consuming a pre-committed block of traffic. Avoid switching between them mid-run based on how the numbers look.

    Link hygiene when campaign traffic is split


    If you are routing campaign traffic between page builds and call-to-action experiments, the link you publish becomes part of the workflow. Campaign copy already competes for space with a headline and a button, and long parameter-heavy URLs wrap badly in chat apps and social posts. A short link such as LinkBit keeps the destination compact and readable in the creative. That is a formatting convenience. Your experiment assignment should live in your own instrumentation, not in the link.

    The short answer


    Run the landing page experiment first when the funnel shows that visitors never engage, when message match is broken, or when a rewrite is already planned. Run the call to action first when the page is doing its job and the ask is the weak link, and only when your traffic is large enough to detect the smaller effect you are likely to see.

    Before either, confirm what your instrumentation measures. Most experiment programs that stall are running careful changes on a funnel they cannot see.#experimentation #conversionrate #landingpages #webanalytics #software #coding #development #engineering #inclusive #community
    Should You A/B Test Your Call to Action or Your Landing Page First?

  25. I’m setting EasyCrypt (a proof assistant) problems in a class I’m co-teaching. The problems have short solutions. I can often tell the AI-generated submissions because they tend to be much longer than necessary, with multiple lemmas that aren’t needed. When I ask students about them, they admit they don’t understand the proofs they’ve submitted. This is the future, it seems.

Share on Mastodon

Enter the server where you have an account.