· Davide Padeletti · Insights · 7 min read
Our product doesn't use AI. That was a decision, not an omission.
We build artificial-intelligence systems for our clients, and yet in the product we are building for ourselves, at the very point where anyone would expect to find a model, we put a deterministic algorithm a few dozen lines long: here is the reasoning that led us there.

There was, in this project, an obvious place to put a model, and it is precisely the place where we decided not to put one.
Metroquadro, the storage-space marketplace we are building, asks operators to list their facility unit by unit, so that anyone looking for space sees the real inside of the building rather than the usual photograph of the front door; the first task they face, however, is also the most thankless, because before they can rent anything at all they have to draw the floor plan — the outline of the building, the corridors, and the units they intend to carve out of it. That is where the demo would write itself: you upload the dimensions, you type “draft me the best possible layout”, and within seconds something plausible appears on screen, so much so that in 2026 nobody even bothers to ask how it works. We chose not to do it.
What we put there instead of a model
In its place there is a row-packing algorithm — deterministic, a few dozen lines of Python, entirely free of network calls — whose opening comment states with some candour what it means to be and, above all, what it does not:
“A starting point the seller then edits, not an optimiser. No randomness — same input always yields the same layout.”
You enter the footprint, the corridor width and the desired unit mix, and the units are laid out in rows in the order they were requested; whatever does not fit, moreover, does not quietly vanish but comes back as an explicit list grouped by size — three six-square-metre units don’t fit — and this is not an edge case handled gracefully, it is half the value of the feature. It is not a clever algorithm, admittedly; but the problem was not asking for cleverness, it was asking for predictability.
Why that was the wrong place
There are three reasons, and all of them are duller than the idea of a language model drawing warehouses.
The first is that the draft exists in order to be edited: the operator receives it and starts working on it straight away, dragging, rotating, moving the pillar to where it actually stands and widening the corridor because a forklift has to get through, so that if regenerating it produced a different result each time, that draft would stop being a starting point and become an oracle, something you consult rather than something you build on; and reproducibility, in a setting like this, is not a technical nicety but the very condition of the tool being usable at all.
The second is that the result has to be explainable to the person paying the rent, since “why do six units fit in this corridor and not seven?” is a question the operator will sooner or later be asked, and one that has to be answered with a rule — the width, the tolerance, the minimum clearance to be preserved — rather than with an embarrassed “the system suggested it”.
The third, and the most concrete, is that in this trade an error is geometric and final: a unit overlapping a pillar is not a slightly worse answer than the others but a square metre that does not exist, rented to someone holding a contract, and there is no confidence threshold that makes an output of that kind acceptable.
The criterion, stripped to the bone
Artificial intelligence earns its keep where the input is varied and the cost of an error is low, and an assistant that rewrites a listing description is the perfect example, because you can feed it anything and at worst a mistake costs a second read; the same holds for an extractor pulling data out of heterogeneous documents, which has exactly the same shape. Here the opposite is true, since the input is three numbers and a list — metres, corridor width, unit mix — with nothing ambiguous about it, nothing resembling free text and no need whatever to be interpreted, while the error, as we have seen, costs a contract. In our product document the layout optimiser nonetheless remains on the list of post-MVP candidates, accompanied by a note that works as a general rule — a constraint solver first; machine learning only if justified — because leaving the door open is not the same as having already walked through it.
Where we did put the constraints
In this product, certainty is not bought with model horsepower but with constraints, and only on condition that they sit where nobody can bypass them. The two geometric rules — no unit overlapping another, nothing protruding beyond the footprint — hold in the browser as much as on the server, and while the first check is a courtesy to whoever is drawing, the second is the one that really counts; in the same way, double bookings are impossible because the database says so and not because the code is being careful, given that an exclusion constraint in Postgres rejects two overlapping bookings on the same unit whatever the application does and under any concurrency, so that two clients clicking at the very same instant get a handled error and a clear message, and never two contracts on the same unit.
The part people usually leave out
This story has an ending at our own expense, and it happened on these very pages. The chatbot that answers questions about our site is a RAG system and, asked about Metroquadro, it cheerfully explained that the product offers “an editor with intelligent constraints”, contradicting the knowledge card we had given it ourselves, and in which it is written in black and white that there is no artificial-intelligence component anywhere in here. The fault, however, lay not with the model but with the way we had cut the text up, into fixed-length windows blind to the sections: the qualification sat at the bottom of the card, that is, in the second fragment, while semantic search, prompted by a question about the editor, returned only the first, so that the model received the claim stripped of the constraint that qualified it and filled the gap with the handiest adjective within reach. The fix, as one might guess, was editorial rather than architectural, and consisted in moving the constraint into the same fragment as the claim it constrains.
It is the principle we have carried with us ever since: a model does not know what we did not give it, and that gap will not stay empty, because it will be filled with something plausible, often with the very word one meant to rule out.
Where we are
Metroquadro is in pilot: payments and identity verification are simulated behind an interface already shaped for the real integration, there is no price because a revenue model does not yet exist, and it is therefore not a product you can buy, which is something we would rather say now than later. What we are looking for is three to five Italian self-storage operators, on terms simple enough to fit in a single line: you bring us a real facility, we map it onto Metroquadro and we run it together; how it behaves, for that matter, takes a couple of minutes to grasp — floor plan, isometric view, booking — on the product page.
Got a problem where you are not certain a model is the answer? Get in touch: sometimes the honest answer is no, and it is still worth talking through.