$500 Challenge Drop

If you’re taking part in 100 Days of Solana, look out for the $500 Challenge Drop.

Complete Monday’s or Tuesday’s challenge (Day 36 or 37) and you’ll be entered for a random chance to win $500.

That’s it: complete the challenge, submit your work, and you’re in the draw.

What is 100 Days of Solana?

100 Days of Solana is a daily, hands-on learning challenge from MLH and Solana for Web2 developers who want to understand Solana by building with it.

Each challenge introduces one practical concept at a time, using familiar JavaScript tooling while gradually moving from fundamentals like keypairs and transactions into tokens, accounts, and programmable assets.

This week’s challenges continue the move into Token Extensions, where Solana tokens start to feel less like static assets and more like programmable building blocks.

How to enter

To be entered for the $500 Challenge Drop:

  1. Complete Monday’s or Tuesday’s 100 Days of Solana challenge
  2. Submit your work at the bottom of the challenge
  3. You’ll be entered for a random chance to win $500

Start here: mlh.link/solana-100

Complete the challenge, submit your work, and you’re in.

How I use an LLM as a translation judge

I use GEMBA-MQM v2 to evaluate translation quality in my live speech-to-speech translation pipeline. MQM (Multidimensional Quality Metrics) is an open industry standard for grading translations. Instead of a single score, it classifies every error by type (mistranslation, omission, hallucination, grammar, etc.) and severity (critical, major, minor). It’s what professional linguists use when they review translations manually.

GEMBA makes an LLM do this same annotation process. It prompts the model to read the source and translation side by side, find the errors, and tag each one with an MQM type and severity. So you get the same structured error breakdown you’d get from a human reviewer, but automated. It ranked #1 on WMT24 by correlation with human MQM annotations.

The catch: LLM judges are noisy. On one English-to-German clip, 10 passes gave me scores from -29 to -109. Same translation, same model.

The fix is straightforward. Run 10 passes per segment, drop outliers beyond 2 standard deviations, aggregate with rank-reciprocal weighted averaging so the harshest outlier doesn’t dominate. That same clip settles at -41.9 across 10 passes.

If you’re using LLM-as-judge for anything, try running multiple passes. The variance will surprise you.

Full methodology: LLMs as translation judges: Inside GEMBA-MQM v2

Code: VoiceFrom/live-s2st-eval

Agentic AI in Travel: Why UCP Isn’t Travel-Ready Yet — and What We Measured

In a new post, Amadeus — the system of record behind roughly 3 billion flight searches a day, 400-plus airlines and 2 million hotel properties — laid out its read on agentic AI in travel. The headline from CTO Sylvain Roy: protocols, not chatbots, are what make agentic travel work, and the protocols that exist today are not ready. MCP, he argues, is “only a first step”; the Universal Commerce Protocol “could open large new distribution and conversion opportunities” but remains “largely retail-native and is still in the process of being adapted to handle the full complexity of travel.”

He is right — and we can put data behind it. Before Amadeus weighed in, we built a mock travel server with expiring offers and pointed five frontier models at it. Not one checked an offer’s time-to-live before booking. Only one survived a three-second expiry window. None flagged a price change unless explicitly asked. Travel’s defining feature — perishable inventory priced in real time — is precisely where today’s agents fall over.

So here is the state of play from the monitoring seat: travel’s supply side just showed up to UCP, but the demand side cannot reliably transact on it yet, and the protocol needs travel-specific work before it can. This is the read on agentic commerce’s hardest vertical. Our bias throughout: we saw it in the data first.

What just happened: travel’s supply side standardized on UCP

Two signals landed in quick succession. At Google Marketing Live 2026, Google extended UCP into hotels and local food delivery, naming a launch roster that reads like the entire travel-distribution stack: Accor, Amadeus, Booking.com, Choice Hotels, Expedia Group, Hilton, IHG, Marriott, Trip.com and Wyndham. Booking a hotel “right from AI Mode in Search” is the demo. (We covered the full package — Universal Cart, multi-item checkout, BNPL and the rest — separately.)

Then Amadeus published its position. Notably, it is not an adoption announcement. Roy frames Amadeus as the “embedded and neutral execution layer for travel” and says it is ready to collaborate on travel-ready agentic protocols — but commits to no UCP timeline. The subtext is the honest one: the supply side is interested, the rails are forming, and nobody is claiming travel is solved.

Why travel is agentic commerce’s hardest vertical

Retail is, relatively, simple: a product has a fixed SKU, a stable price and a quantity. Travel has none of those guarantees. Amadeus calls out five gaps, and each is a place a retail-native protocol strains.

  • Dynamic offers, not fixed SKUs. A flight or room is not a catalog entry — it is a dynamically generated Offer ID built from origin, destination, dates, fare family, ancillaries and disruption rules. There is no stable identifier for an agent to drop in a cart and trust.
  • Perishable inventory, real-time pricing. Availability and price change by the second, with no true SKU equivalent. An offer an agent saw thirty seconds ago may already be gone or repriced.
  • Complex servicing. Changes, cancellations and disruption handling demand full request context, and the stakes of getting it wrong are far higher than a returned T-shirt.
  • Identity, settlement and regulation. Multi-party fulfillment, traveler identity verification and compliance obligations ride on every booking.
  • Data quality and control. Personalization needs traveler context shared across parties while suppliers keep visibility and control of it.

UCP models the retail case well — fixed catalog, cart, checkout, payment handlers. (New to how UCP sits next to MCP and AP2? We break the stack down here.) Travel needs primitives the retail spec does not have yet.

The data: agents are blind to time

The perishable-inventory and real-time-pricing problems are not theoretical. They are measurable, and we measured them.

We built a mock travel server that issued offers with explicit expiry windows and ran five frontier models against it across 21 sessions. The results were stark: not one model checked an offer’s TTL before attempting to book; only one survived a three-second expiry window; none surfaced a price change unless we asked. The agents treated time-sensitive travel inventory exactly like a static retail SKU — and that is the failure mode that turns a “confirmed” booking into a charge for an offer that no longer exists.

The same blindness shows up on the retail side. Across 33 sessions on a live store, only two of five models caught a stale price even when handed yesterday’s number — and the deeper problem was structural: the merchant data layer did not expose temporal metadata at all. A model cannot reason about expiry if nothing in the stack tells it the offer expires.

That is Amadeus’s “perishable inventory” and “live search at scale” challenges, observed in production. The protocol that wins travel has to carry time — TTLs, price-as-of timestamps, re-validation before commit — as a first-class signal, and agents have to be built to respect it. Neither is true today.

Retail-native, not travel-ready: what UCP still needs

The encouraging part is that UCP is extensible by design. The spec grows through capability extensions — the Technical Council has been adding cart, order, loyalty and identity primitives since launch. Travel is simply the next, harder extension surface. From the gaps above, the shortlist:

  • A dynamic-offer primitive — an offer object carrying a TTL and a price-validity window, replacing the assumption of a stable SKU.
  • Re-validation in the checkout flow — an agent must confirm the offer is still valid and still the quoted price before it commits.
  • Servicing capabilities for change, cancel and disruption, with enough context to handle them safely.
  • Identity and settlement extensions for multi-party, regulated fulfillment.

Concretely, the dynamic-offer primitive looks something like this — a travel offer that carries its own clock:

{
  "offer_id": "LHR-NRT-20260612-A1F2",
  "price": { "amount": 842.00, "currency": "USD" },
  "ttl_seconds": 3,
  "price_valid_until": "2026-06-12T19:30:03Z",
  "revalidate_before_checkout": true
}

A retail SKU carries none of those fields, and that is the whole problem: nothing tells an agent the offer it is holding has already expired. None of these are exotic. They are the difference between a protocol that can sell a tote bag and one that can sell a Tokyo itinerary. And the backers are aligned to build them: the companies behind UCP — Google, Shopify, Amazon, Microsoft, Meta, Stripe and Salesforce, the group whose Technical Council recently expanded — now have the travel-distribution establishment at the table.

What it means

For travel suppliers (airlines, hotels, OTAs, GDSs): being named at a keynote is not the same as being agent-ready. The supply side is forming the rails, but the offer, pricing and servicing semantics that make travel safe for agents are not in the published spec yet. The window to shape those primitives — rather than inherit retail’s — is open now, and Amadeus is signalling it wants in.

For demand-side players (agents, assistants, AI shopping surfaces): do not ship autonomous travel booking on retail assumptions. Our data says agents will book expired offers and miss price changes unless both the protocol and the agent treat time as first-class. Until travel primitives land, keep a human on the commit step.

For the ecosystem (us): we do not yet monitor live travel UCP endpoints — there are not any in production to monitor. What we can measure today is the agent side, and we have shown the gap is real. As travel manifests go live, the same validation, scoring and monitoring we run across more than 6,500 retail merchants — tracked monthly in the State of Agentic Commerce census — will extend to them. The neutral measurement layer travel is asking for is the one we already operate.

What we’re watching

Whether the Technical Council opens a travel working group or a dynamic-offer extension; which of the GML travel partners ships a live, parseable endpoint first; whether Amadeus moves from “ready to collaborate” to a concrete commitment; and — the one we will keep testing — whether the next generation of models stops being blind to time. We will report what the data shows, not what the slides promise.

Sources

About UCP Checker

UCP Checker is the independent validation and monitoring layer for the Universal Commerce Protocol. We crawl, validate and grade every public UCP manifest we can find, run the merchant directory, the UCP Score and live adoption stats, and test how real AI agents behave against real stores. We track spec and ecosystem events — retail today, travel as it arrives — as they ship.

Travel is the hardest test agentic commerce has set itself. We will be measuring it.

Retail merchant figures are live from the UCP Checker index and update every 24 hours; agent-testing methodology is on our methodology page.

I Finished Machine Learning. And Then Changed The Plan.

Dev.to / Medium / Substack

I Finished Machine Learning. And Then Changed The Plan.

A few months ago, I had no idea what feature engineering was.

Today, I finished my Machine Learning roadmap.

Not “mastered ML.”
Not “became an AI expert.”

Finished the part where every tutorial starts making sense.

I built projects, broke models, overfit them, leaked data into them, fixed them, and slowly started understanding why things worked instead of blindly following notebooks.

My latest project:

Customer Churn Prediction

Predicting which customers are likely to leave a company before they actually do.

Built with:

  • Python
  • Pandas
  • Scikit-Learn
  • XGBoost
  • Feature Engineering
  • Hyperparameter Tuning

Project:
Customer Churn Prediction Demo

The funny thing?

The more I learned, the less interested I became in rushing toward Deep Learning.

Originally the plan was:

ML → Deep Learning → NLP

But somewhere along the way I realized something.

I don’t just want to understand models.

I want to build products.

Things people actually use.

So the roadmap changed.

Now I’m diving into:

  • Generative AI
  • RAG
  • LangChain
  • FastAPI
  • Ollama
  • MCP
  • LangGraph
  • Agentic AI

Deep Learning isn’t gone.

It’s just waiting its turn.

And DSA?

That was supposed to stay consistent.

Instead, I keep finding myself opening AI documentation at 2 AM and disappearing into another rabbit hole.

Not because I have to.

Because I genuinely can’t stop.

Somewhere between building projects and studying, curiosity quietly took over.

So that’s where we are now.

Machine Learning: complete.

Next stop: GenAI.

Let’s see how deep this rabbit hole goes.

If you’re earlier in your journey:

Build projects before you feel ready.

Most of what I learned came from fixing mistakes I didn’t know I was making.

Project:
Customer Churn Prediction Demo

The Five-Thousand-Line File

Every team has one. Sometimes it is called utils.ts or helpers.py. Sometimes it has the name of a domain concept that originally meant something specific and has since absorbed everything tangentially related. The file is large enough that nobody opens it casually. It has multiple maintainers, each of whom understands a different third of it. New additions go into it because that is where similar things already live, and the file gets larger.

This is the god file: a single file that has grown to do too much, and that resists the refactor that would split it because the refactor is large and the file mostly works.

The god file is one of the most agent-hostile shapes a codebase can take.

How files get this big

No file is born five thousand lines long. The growth is incremental.

The file starts as something reasonable: a module that handles one thing, three hundred lines, well-organized. A developer adds a function related to the thing. Another developer adds a function that is related to one of the existing functions, but also touches a new concept. The new concept does not justify its own file, so it lives in this one. Over time, the file accumulates concepts that share an author, a directory, or nothing in particular except convenience.

The reason nobody splits it is that splitting it is a project. The file is imported from many places. Each import has to be updated. The functions inside have shared private helpers that have to be sorted out. Tests for the file have the same problem in miniature. The estimate for the refactor is “a sprint,” and a sprint is always too expensive when the file is “fine.”

So the file stays. New developers add to it because the existing functions are there. The agent does the same. The file grows.

Why agents struggle here

The god file is expensive for an agent in three specific ways.

The first is context budget. The agent loads files into its working memory to understand them. A five-thousand-line file consumes a large fraction of that budget for a small change. The agent has less room left for the rest of the codebase — the calling files, the tests, the conventions. Quality drops, not because the agent is dumber, but because it is operating with less situational awareness.

The second is pattern dilution. The agent pattern-matches against the file it is editing. A file with five hundred coherent lines teaches the agent one strong pattern. A file with five thousand lines teaches the agent ten weak patterns, often contradictory. The agent picks one, often the wrong one for the specific change.

The third is the path-of-least-resistance problem. When asked to add new functionality, the agent looks for where similar functionality lives. It finds the god file. It adds to the god file. The file grows by one more function, in the same shape as the previous additions. The agent, like every previous contributor, has chosen the cheap path. The file is now slightly more god-like.

A small coherent file is a force multiplier for an agent. A god file is a tax.

When size is actually the problem

It is worth being careful about the diagnosis. Not every large file is a god file. A file that defines a complex but coherent thing (a state machine, a parser, a single algorithm) may legitimately be large. The size is not the smell. The smell is unrelated things sharing a file.

The diagnostic question is: if you had to give this file a name that described what it does, in a single concept, could you? parser.ts is a coherent file even at three thousand lines, because everything in it is parser. helpers.ts is incoherent at five hundred lines, because nothing about the name tells you what is in it. The size is downstream of the coherence.

A useful test: pick five functions from the file at random. Do they belong together? If yes, the file is big but legitimate. If no, the file is a junk drawer with a misleading name.

Splitting by concern

The right way to split a god file is not by line count. It is by concern.

Look at the functions in the file. Group them by what they are for, not by what they touch. Two functions that both manipulate strings are not necessarily related; two functions that both implement steps of the same workflow are.

For each group, ask: would this group, alone, make sense as a file? Does it have a name that describes what it does? Are the dependencies between this group and the rest of the file mostly external, or mostly internal?

Groups that score well on this become candidate files. Move them. The imports update mechanically. The tests follow. The original god file shrinks by one concept; the codebase gains a coherent module.

This is the kind of refactor an agent is good at, given a clear scope. “Move these eight functions to a new file called pricing.ts, update all callers, and split the corresponding test file.” A concrete instruction. The agent does the mechanical work. A human reviews the result.

Limit the size mechanically

Once you have done the initial split, the way to keep the file from re-growing is the same as with every other limit: make it mechanical.

Most linters can enforce a maximum file length. Set the limit slightly above your current largest legitimate file. The build fails when a file exceeds it. New code cannot grow a file past the limit; it has to go somewhere else.

The limit is a forcing function, not a precise number. The point is not that 500 is correct and 501 is wrong. The point is that the team is forced to make an active decision when a file approaches the limit, instead of letting it drift past 1,000, 2,000, 5,000 without noticing.

The agent will respect the limit because the agent runs the linter. It will offer to put new functions in new files when the existing file is near the threshold. The default direction shifts from “grow the god file” to “split the god file,” which is what you wanted.

First steps

If your codebase has god files and you want to start fixing them:

Find your largest source file. Count its lines. Note the number. Open it and look at the function list. Are they coherent? Or is the file a junk drawer?

If it is a junk drawer, pick the most distinct group of functions — the smallest set you can extract without untangling shared dependencies. Move that group to its own file. Update imports. Run tests. Ship the PR.

Add a max-lines rule to your linter, set 20% above the largest file you have decided to keep. The build now prevents new files from exceeding the limit.

Quarterly, look at the file-length distribution. Pick the largest file. Split one group. Repeat.

Add a rule to AGENTS.md: “When adding new functions, prefer creating a new file in a domain-appropriate directory over extending a large existing file. Files larger than [N] lines are a smell; do not extend them without splitting at the same time.”

The god file did not arrive overnight. It will not leave overnight. But the trajectory matters. A team that splits one group per quarter is on a path toward a codebase made of coherent modules. A team that does not is on a path toward one file that contains everything, and an agent that gets worse the more it touches the codebase.

The size of any one file is small. The cost of letting them all grow is not.

The AI Whirlwind: Why Your Local Agent Matters More Than Ever

The AI Whirlwind: Why Your Local Agent Matters More Than Ever

The air is thick with talk of AI. Nvidia’s profit hits an astounding $58.3 billion, and giants like OpenAI and SpaceX are reportedly eyeing IPOs. These headlines signal a gold rush, a furious pace of development driven by immense capital. But for us, the engineers building intelligent agents for real-world automation, these grand pronouncements mean something deeper. They point to a crossroads: a future dominated by a few, or an opportunity for us to build something fundamentally different — AI agents that truly serve users on their own devices.

Beyond the Hype: The Trust Deficit and Data Ethics

Google’s supposed “Antigravity” moment, often viewed as a “bait and switch,” highlights a persistent challenge: the gap between grand AI promises and the opaque reality of centralized systems. For many, trusting a black-box AI operated by a distant entity remains difficult. This skepticism isn’t unfounded.

Consider the growing discussion around whether “AI is just unauthorised plagiarism at a bigger scale.” This accusation cuts to the core of trust and intellectual property. When large models are trained on vast, often unverified, datasets, how can we guarantee ethical outputs from our own agents? This isn’t just a legal or philosophical issue; it’s an engineering responsibility.

For developers building local AI agents, data provenance is paramount. We cannot rely on the same ‘train on everything’ approach. This means a shift towards smaller, more curated datasets, with a focus on explicit consent and ethical sourcing. It demands more intentional data collection, synthesis, or fine-tuning on domain-specific, verified data, not just indiscriminate scraping. This controlled environment on local hardware gives us, and our users, much-needed visibility and control over the data an agent processes and learns from.

Navigating the Regulatory Current: Policy, Jobs, and Transparency

The world is catching up to AI’s impact. Recent news of Governor Gavin Newsom’s executive order aimed at AI job loss and former President Trump’s plans for AI model oversight underscore a societal awakening to the implications of AI. Concerns range from economic disruption to the broader societal impact of opaque AI systems.

This is where the local AI agent truly shines. When an agent operates entirely on a user’s hardware, its actions are inherently more transparent and auditable to that user. There’s no remote server making unseen decisions, no cloud provider potentially accessing private data. This personal ownership offers a path to more accountable and trustworthy AI implementations, directly addressing some of the regulatory fears around uncontrollable, centralized AI.

Python 3.15: Your Workbench for Autonomy

While headlines fixate on billion-dollar chip foundries and cloud compute, we’re focused on the developer’s workbench. Python 3.15, with its less-heralded features, continues to provide incremental improvements that are highly significant for local agent performance and reliability.

Updates to the type system, for example, improve code clarity and reduce runtime errors, which is critical when building complex, autonomous systems. Performance enhancements, even minor ones, translate directly into better responsiveness and lower power consumption for agents running on consumer hardware.

Consider how meticulous typing and asynchronous programming aid in creating dependable, efficient agents:

import asyncio
from typing import TypedDict, Literal

class AgentTask(TypedDict):
    id: str
    action: Literal["process_data", "notify_user"]
    payload: dict

async def execute_task(task: AgentTask):
    # Simulate a task running locally on consumer hardware
    print(f"Agent {task['id']} starting {task['action']}...")
    await asyncio.sleep(0.05) # Small delay to simulate computation/I/O
    if task['action'] == "process_data":
        # Perform local data processing (e.g., image resize, text analysis)
        result_size = len(str(task['payload']).encode('utf-8'))
        print(f"Processed data for {task['id']}. Payload size: {result_size} bytes")
    elif task['action'] == "notify_user":
        # Trigger a local notification or update a UI element
        message = task['payload'].get('message', 'status update')
        print(f"Notified user for {task['id']} about: {message}")
    print(f"Agent {task['id']} finished {task['action']}.")

async def main():
    tasks = [
        AgentTask(id="analytics_agent_01", action="process_data", payload={"log_file": "sensor_data.csv", "lines": 1200}),
        AgentTask(id="notifier_agent_02", action="notify_user", payload={"message": "Daily report generated"}),
        AgentTask(id="data_cleaner_03", action="process_data", payload={"database_entry": "cleanup_needed", "records": 500})
    ]
    await asyncio.gather(*(execute_task(t) for t in tasks))

if __name__ == "__main__":
    asyncio.run(main())

Using TypedDict and Literal (features that have evolved in recent Python versions and continue to improve) ensures that our agent tasks are well-defined and less prone to errors. asyncio allows multiple agent sub-tasks to run concurrently on limited hardware, making efficient use of available resources without needing complex multiprocessing setups. These are the practical considerations that empower us to build truly reliable and efficient agents for local deployment.

The Community Engine: Learning from Flipper One’s Journey

The Flipper Zero community’s recent call for help to bring Flipper One to life illustrates the spirit of open collaboration necessary for pushing hardware-bound projects forward. Building AI agents for diverse consumer hardware faces similar challenges: optimizing models for different chipsets, managing varied memory footprints, and engineering for low-power operation.

This reminds us that building truly useful, localized agents isn’t a solo endeavor. Sharing strategies for model quantization, efficient inference engines, and creative data handling within our community is essential. It’s how we collectively advance the state of practical, personal AI.

The Path Forward: True Agent Autonomy

The financial might of Nvidia and the IPO ambitions of OpenAI show the scale of the AI ambition. But they don’t dictate the only path. Our path, building agents on personal hardware, is about user empowerment.

It’s about creating automated workflows that respect privacy, ensure data control, and operate reliably without external dependency. This is crucial for automation that truly serves the individual, fostering autonomy over our digital lives.

Want to ensure your agents run with integrity and control? Explore tools designed for ethical and efficient agent development. Check out AgentGuard for resources that support transparent and user-centric automation.

The AI world is in flux. While the big players chase valuations, we continue to build, focusing on accountability, user control, and practical engineering. The future of AI is not just about raw power; it’s about principled autonomy, starting right on your desktop, smartphone, or any consumer device you control.