<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Operations Research Bit - Medium]]></title>
        <description><![CDATA[Insights and applications of OR for the everyday reader. We publish articles on how to solve problems, improve decision-making, case studies, interviews, and tutorials. Accepting writers. ORB is a commercial subsidiary of Global Institute for Optimization TM 24&#39; - Medium]]></description>
        <link>https://medium.com/operations-research-bit?source=rss----63c2b5fa10f7---4</link>
        <image>
            <url>https://cdn-images-1.medium.com/proxy/1*TGH72Nnw24QL3iV9IOm4VA.png</url>
            <title>Operations Research Bit - Medium</title>
            <link>https://medium.com/operations-research-bit?source=rss----63c2b5fa10f7---4</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Fri, 13 Nov 2026 16:05:07 GMT</lastBuildDate>
        <atom:link href="https://medium.com/feed/operations-research-bit" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[Rebuilding the Iberian Day-Ahead Electricity Price from OMIE’s Order Books]]></title>
            <description><![CDATA[<div class="medium-feed-item"><p class="medium-feed-image"><a href="https://medium.com/operations-research-bit/rebuilding-the-iberian-day-ahead-electricity-price-from-omies-order-books-6cebd3f5da00?source=rss----63c2b5fa10f7---4"><img src="https://cdn-images-1.medium.com/max/1031/0*IWGWOYO7lOmN6FSk.png" width="1031"></a></p><p class="medium-feed-snippet">51,198 linear programmes solved from every published bid step, and what they say about non-convex orders, zero-priced supply and the&#x2026;</p><p class="medium-feed-link"><a href="https://medium.com/operations-research-bit/rebuilding-the-iberian-day-ahead-electricity-price-from-omies-order-books-6cebd3f5da00?source=rss----63c2b5fa10f7---4">Continue reading on Operations Research Bit »</a></p></div>]]></description>
            <link>https://medium.com/operations-research-bit/rebuilding-the-iberian-day-ahead-electricity-price-from-omies-order-books-6cebd3f5da00?source=rss----63c2b5fa10f7---4</link>
            <guid isPermaLink="false">https://medium.com/p/6cebd3f5da00</guid>
            <category><![CDATA[electricity-market]]></category>
            <category><![CDATA[linear-programming]]></category>
            <category><![CDATA[energy-economics]]></category>
            <category><![CDATA[data-science]]></category>
            <category><![CDATA[optimization]]></category>
            <dc:creator><![CDATA[Diogo Ribeiro]]></dc:creator>
            <pubDate>Fri, 30 Oct 2026 03:36:42 GMT</pubDate>
            <atom:updated>2026-10-30T03:36:40.802Z</atom:updated>
        </item>
        <item>
            <title><![CDATA[The Next Evolution of Data Systems]]></title>
            <description><![CDATA[<div class="medium-feed-item"><p class="medium-feed-image"><a href="https://medium.com/operations-research-bit/the-next-evolution-of-data-systems-acbb9de52c43?source=rss----63c2b5fa10f7---4"><img src="https://cdn-images-1.medium.com/max/2600/0*bFL30Q_oD49dWDfu" width="5000"></a></p><p class="medium-feed-snippet">Traditional databases are designed to answer questions. Agentic databases are being designed to help solve problems.</p><p class="medium-feed-link"><a href="https://medium.com/operations-research-bit/the-next-evolution-of-data-systems-acbb9de52c43?source=rss----63c2b5fa10f7---4">Continue reading on Operations Research Bit »</a></p></div>]]></description>
            <link>https://medium.com/operations-research-bit/the-next-evolution-of-data-systems-acbb9de52c43?source=rss----63c2b5fa10f7---4</link>
            <guid isPermaLink="false">https://medium.com/p/acbb9de52c43</guid>
            <category><![CDATA[operations-management]]></category>
            <category><![CDATA[optimization]]></category>
            <category><![CDATA[data-science]]></category>
            <category><![CDATA[operations-research]]></category>
            <category><![CDATA[artificial-intelligence]]></category>
            <dc:creator><![CDATA[ORB, Operations Research Bit]]></dc:creator>
            <pubDate>Tue, 27 Oct 2026 16:15:07 GMT</pubDate>
            <atom:updated>2026-10-27T16:17:49.767Z</atom:updated>
        </item>
        <item>
            <title><![CDATA[The Foundation of Every Successful Information System]]></title>
            <description><![CDATA[<div class="medium-feed-item"><p class="medium-feed-image"><a href="https://medium.com/operations-research-bit/the-foundation-of-every-successful-information-system-e845e008e3f7?source=rss----63c2b5fa10f7---4"><img src="https://cdn-images-1.medium.com/max/2600/0*vSBe9IqKrDAkhKQJ" width="7680"></a></p><p class="medium-feed-snippet">Most people interact with database design every day without realizing it.</p><p class="medium-feed-link"><a href="https://medium.com/operations-research-bit/the-foundation-of-every-successful-information-system-e845e008e3f7?source=rss----63c2b5fa10f7---4">Continue reading on Operations Research Bit »</a></p></div>]]></description>
            <link>https://medium.com/operations-research-bit/the-foundation-of-every-successful-information-system-e845e008e3f7?source=rss----63c2b5fa10f7---4</link>
            <guid isPermaLink="false">https://medium.com/p/e845e008e3f7</guid>
            <category><![CDATA[artificial-intelligence]]></category>
            <category><![CDATA[database]]></category>
            <category><![CDATA[optimization]]></category>
            <category><![CDATA[operations-management]]></category>
            <category><![CDATA[operations-research]]></category>
            <dc:creator><![CDATA[ORB, Operations Research Bit]]></dc:creator>
            <pubDate>Mon, 26 Oct 2026 13:59:26 GMT</pubDate>
            <atom:updated>2026-10-26T14:00:05.782Z</atom:updated>
        </item>
        <item>
            <title><![CDATA[The Governance Spreadsheet Is Where Good Decisions Disappear]]></title>
            <link>https://medium.com/operations-research-bit/the-governance-spreadsheet-is-where-good-decisions-disappear-d292b966b4d3?source=rss----63c2b5fa10f7---4</link>
            <guid isPermaLink="false">https://medium.com/p/d292b966b4d3</guid>
            <category><![CDATA[togaf]]></category>
            <category><![CDATA[itil]]></category>
            <category><![CDATA[data]]></category>
            <category><![CDATA[cobol]]></category>
            <category><![CDATA[architecture]]></category>
            <dc:creator><![CDATA[Mohammed Brückner]]></dc:creator>
            <pubDate>Fri, 23 Oct 2026 14:47:07 GMT</pubDate>
            <atom:updated>2026-10-23T14:47:05.819Z</atom:updated>
            <content:encoded><![CDATA[<h4>TOGAF, COBIT, ITIL 4, and NIST CSF 2.0 become useful when one decision crosses the gaps.</h4><p>A shared support account is still active because nobody wants to delay an urgent production fix.</p><p>Somewhere above that account sits a governance spreadsheet. TOGAF sits beside COBIT. ITIL sits beside NIST. Every cell contains a plausible relationship, every term has an owner from a central team, and nobody can tell which production decision changed because the spreadsheet exists.</p><p>This is the trap in large-scale governance work. We produce a map of terms because the map is easier to review than a service. Then the map becomes the deliverable. The business objective, the person with decision authority, and the operating evidence sit outside it.</p><p><strong>Traceability needs a direction.</strong> Start with one decision that matters and follow it into operation. The reference models help at different points. None of them owns the whole chain.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*--HPTc3l6Kzfj3RsL-Hp7g.png" /></figure><h4>Give each body of practice one job</h4><p>TOGAF structures architecture work. It helps a team identify the required change, develop architecture artifacts, and record decisions through the Architecture Development Method. It does not prove that the resulting service operates well.</p><p>COBIT 2019 addresses governance and management of enterprise information and technology. It helps identify the relevant objective, the decision authority, and accountability for risk. A COBIT label does not demonstrate that a technical control works.</p><p>ITIL 4 connects decisions to service management. Its practices describe work such as assessing and authorizing a change or maintaining configuration relationships. A practice name does not establish that the architecture was strategically sound.</p><p>NIST Cybersecurity Framework 2.0 supplies cybersecurity outcomes and a common taxonomy for discussing them. Selecting an outcome gives the decision a security destination. The selection alone supplies no evidence of progress.</p><p>These working boundaries matter because overlap invites false equivalence. Risk governance, change authorization, and identity-related security outcomes touch the same decision. They still represent different kinds of work.</p><p>A good trace keeps those differences visible. A bad one turns four vocabularies into a row of interchangeable badges.</p><h4>Start at the ends</h4><p>Two fields deserve attention before any terminology enters the record: the business objective and the evidence.</p><p>An objective such as “improve security” gives the team no decision to make. “Let external support engineers resolve production incidents without giving them standing privileged accounts” creates a constraint that architecture and operations can use.</p><p>Evidence deserves the same precision. A policy PDF proves that somebody wrote a policy. It does not show that temporary access expires, that approvals precede elevation, or that administrative actions belong to identifiable people.</p><p><strong>Objective → architecture → governance decision → service operation → cybersecurity outcome → evidence.</strong></p><p>This is a trace, not an approval sequence. Governance constraints and evidence requirements should shape the architecture from the start. Each arrow represents a relationship that somebody can challenge. If the architecture record does not name an owner, the gap remains visible. If the selected security outcome has no corresponding test or operating record, the claim stops there.</p><p>This is deliberately smaller than an enterprise-wide mapping exercise. One complete trace gives reviewers concrete gaps to challenge.</p><h4>A privileged-access trace</h4><p>Take an illustrative customer analytics platform. External service engineers help resolve production incidents. Today, a shared support account remains active because nobody wants to delay an urgent fix. The company wants faster support without permanent shared privilege.</p><p>The example below is a design illustration. It does not describe a client or a production system.</p><h4>Business objective</h4><p>The platform product owner wants external engineers to support incident resolution while every privileged session remains attributable to one person and bounded in time.</p><p>That sentence gives the team something to falsify. If an engineer can use a shared account for a week, the design has failed even if every governance document uses the right terminology.</p><h4>Architecture decision</h4><p>An architecture decision record establishes a small set of rules:</p><ul><li>Shared privileged accounts are prohibited.</li><li>Every engineer authenticates with an individual identity.</li><li>Access elevation requires approval and has a fixed expiry.</li><li>The identity service issues the temporary privilege.</li><li>Administrative actions are logged with the individual identity and the related incident.</li><li>Emergency access follows a separate, reviewed path rather than an undocumented exception.</li></ul><p>An ArchiMate view can connect the support process, identity component, analytics platform, and requirements. The decision record carries the rationale and the prohibited pattern. The diagram helps reviewers see the affected relationships; it does not replace the decision.</p><h4>Governance decision and owner</h4><p>The service owner approves the operating change. A named risk owner accepts any residual risk and the conditions that require reconsideration. The record identifies who can approve the policy, who can authorize an individual elevation, and who reviews emergency use.</p><p>COBIT 2019’s EDM03, Ensured Risk Optimization, may be relevant to governance oversight of risk. APO12, Managed Risk, may be relevant to management of the response. Those are candidate objectives for this scenario, selected with a stated rationale. They are not universal answers to privileged access.</p><p>“Security owns it” would leave the record unfinished. A department has responsibilities. Accountability needs an authorized role and an accountable person or organization in the system of record.</p><h4>Service operation</h4><p>ITIL 4’s Change Enablement practice covers assessment and authorization of the service change. Service Configuration Management maintains information about the configuration items and relationships among the external support arrangement, identity service, and analytics platform.</p><p>Those practices give the decision an operational home. The authorized change record points to the implemented access policy. The configuration record shows which identity service governs privileged elevation for this platform. An incident record supplies the reason and duration for a specific session.</p><p>Other practices may contribute. Add them when they carry a decision or produce evidence. A longer list does not improve the trace.</p><h4>Cybersecurity outcome</h4><p>NIST CSF 2.0’s GV.RR category addresses cybersecurity roles, responsibilities, and authorities. PR.AA addresses identity management, authentication, and access control. Both provide useful destinations for the access decision.</p><p>The relationship needs a sentence of reasoning. GV.RR applies because the design assigns approval, risk acceptance, and emergency-review authority. PR.AA applies because temporary privilege depends on individual identity, controlled elevation, and expiry.</p><p>That explanation prevents keyword matching from masquerading as analysis. It also lets a security reviewer reject the relationship without rejecting the whole record.</p><h4>Operating evidence</h4><p>The claim “privileged access is individual and temporary” now has practical tests.</p><p>A reviewer can inspect the approved architecture decision and the authorized change. The current configuration record should connect the platform to the identity service. Test results should show that shared privileged accounts cannot authenticate and that elevated access expires at the configured time. Access records should link each elevation to an approval, an incident, and one identity. Administrative logs should show what happened during the session. Emergency access should produce a later review record with an owner and a conclusion.</p><p>The exact records depend on the implementation. Their job remains stable: they let another person test the claim without trusting the architecture team’s presentation.</p><h4>The official mapping has a version</h4><p>ISACA publishes <em>Implementing the NIST Cybersecurity Framework Using COBIT 2019</em>. It is useful background for connecting governance objectives to cybersecurity work. The official ISACA page also makes its scope plain: the publication maps COBIT 2019 to <strong>NIST CSF 1.1</strong>.</p><p>That does not make it useless for a CSF 2.0 discussion. It means a team cannot present the publication as an official CSF 2.0 crosswalk.</p><p>Version awareness sounds pedestrian until a report inherits an old relationship and presents it as current truth. Keep the release beside the relationship. Record why the relationship applies to the decision. Give a reviewer the chance to challenge that reasoning.</p><p>The same discipline applies to ITIL 4 and the TOGAF Standard, 10th Edition. Vocabulary changes across releases. A register that hides versions forces readers to guess which definition the author used.</p><p>I built the <a href="https://mohammed-brueckner.com/enterprise-architecture/togaf-cobit-itil-nist/">TOGAF, COBIT, ITIL 4, and NIST CSF 2.0 traceability guide</a> around a six-part canvas for this reason. It keeps the official references and the version caveat beside the worked method.</p><h4>Evidence should discipline the language</h4><p>A trace becomes stronger when the team writes down what would falsify its claim before choosing impressive terminology.</p><p>For privileged access, a shared account that still authenticates falsifies the design. An elevation without an expiry falsifies it. A log that shows the shared identity rather than the engineer falsifies the evidence claim even if the login page looks modern.</p><p>This approach changes review behavior. People stop defending the completeness of the spreadsheet and start inspecting the conditions under which the service fails.</p><p>If an automated assistant participates in approval or routing, the <a href="https://mohammed-brueckner.com/enterprise-architecture/archimate-ai-agents/">AI-agent Roles guide</a> keeps the performer and accountable owner separate.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*4EQUE_yCOX4ITq7xD3pvBw.png" /></figure><h4>Scale after the first review</h4><p>A second decision should reuse the discipline, not inherit the answers. Privileged vendor access and customer identity verification may share an identity service and a CSF category. Their business owners, exception paths, and evidence can differ completely.</p><p>This is where a template helps and where it starts lying. Empty fields remind a team to supply an owner and an operational record. Pre-filled reference labels short-circuit the reasoning that makes those entries useful.</p><p>Keep the first trace small enough for a product owner, an architect, a service manager, and a security reviewer to inspect together. Their disagreements identify the missing relationships. A risk owner may discover that operations has no record of emergency access. A service manager may discover that the architecture assumes an expiry mechanism the identity service does not provide.</p><p>Those findings are the method working. The review has connected a decision to its implementation before an auditor or an incident does it under worse conditions.</p><p>Only then does a second team have something worth copying: a sequence of questions and a standard of evidence, rather than a row of somebody else’s conclusions.</p><h4>Automate the checks after the trace works</h4><p>A generated crosswalk can quickly produce many plausible relationships. Plausibility is the problem. Keyword similarity does not establish accountability, and document retrieval does not prove control operation.</p><p>Useful automation starts later. It can flag an expired exception, detect a missing evidence link, check whether a required field is empty, or show that a referenced configuration record has not been reviewed. Those checks preserve a decision structure that humans have already tested.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*lNSCT-qiyU9PJ2fc" /><figcaption>Photo by <a href="https://unsplash.com/@alanaprilio?utm_source=medium&amp;utm_medium=referral">Alan Aprilio</a> on <a href="https://unsplash.com/?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p>When a control change passes through a managed lifecycle, <a href="https://mohammed-brueckner.com/apiops/">APIOps as Code</a> shows how specifications, checks, publication, operation, and retirement stay connected.</p><p>In <em>Platform Economies</em>, I describe the Operating Model Line as the place where API programs die when funding and governance depend on one sponsor’s memory. The answer is to institutionalize ownership, role definitions, compliance evidence, and the other conditions that let work survive personnel changes. Traceability serves the same purpose here.</p><p>Take one live decision into a joint review with product, architecture, service management, and security. Leave with the missing owners, relationships, and evidence recorded. The <a href="https://mohammed-brueckner.com/enterprise-architecture/">Enterprise Architecture hub</a> collects the adjacent methods.</p><p><a href="https://platformeconomies.com/"><em>Platform Economies: How AI Is Rewriting the Rules of Platforms, APIs, and Partnerships</em></a><em> is out now.</em></p><p><a href="https://mohammed-brueckner.com/">← mohammed-brueckner.com</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d292b966b4d3" width="1" height="1" alt=""><hr><p><a href="https://medium.com/operations-research-bit/the-governance-spreadsheet-is-where-good-decisions-disappear-d292b966b4d3">The Governance Spreadsheet Is Where Good Decisions Disappear</a> was originally published in <a href="https://medium.com/operations-research-bit">Operations Research Bit</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Surprising Human Side of Objective Functions at Work and in Everyday Life]]></title>
            <description><![CDATA[<div class="medium-feed-item"><p class="medium-feed-image"><a href="https://medium.com/operations-research-bit/surprising-human-side-of-objective-functions-of-everyday-life-a119b1c8a8cb?source=rss----63c2b5fa10f7---4"><img src="https://cdn-images-1.medium.com/max/2600/0*9E53lgPLhmpFp4ZI" width="5616"></a></p><p class="medium-feed-snippet">Organizations are developing layered control systems shaped by intelligent machines where analytics remains uniquely...</p><p class="medium-feed-link"><a href="https://medium.com/operations-research-bit/surprising-human-side-of-objective-functions-of-everyday-life-a119b1c8a8cb?source=rss----63c2b5fa10f7---4">Continue reading on Operations Research Bit »</a></p></div>]]></description>
            <link>https://medium.com/operations-research-bit/surprising-human-side-of-objective-functions-of-everyday-life-a119b1c8a8cb?source=rss----63c2b5fa10f7---4</link>
            <guid isPermaLink="false">https://medium.com/p/a119b1c8a8cb</guid>
            <category><![CDATA[data-science]]></category>
            <category><![CDATA[operations-research]]></category>
            <category><![CDATA[software-engineering]]></category>
            <category><![CDATA[operations-management]]></category>
            <category><![CDATA[optimization]]></category>
            <dc:creator><![CDATA[ORB, Operations Research Bit]]></dc:creator>
            <pubDate>Thu, 22 Oct 2026 01:17:36 GMT</pubDate>
            <atom:updated>2026-10-22T03:57:14.008Z</atom:updated>
        </item>
        <item>
            <title><![CDATA[Microsoft’s latest E-Book on AI Strategy and what it reveals]]></title>
            <link>https://medium.com/operations-research-bit/microsofts-latest-e-book-on-ai-strategy-and-what-it-reveals-cfbf872cdb23?source=rss----63c2b5fa10f7---4</link>
            <guid isPermaLink="false">https://medium.com/p/cfbf872cdb23</guid>
            <category><![CDATA[learning]]></category>
            <category><![CDATA[artificial-intelligence]]></category>
            <category><![CDATA[strategy]]></category>
            <dc:creator><![CDATA[Mohammed Brückner]]></dc:creator>
            <pubDate>Tue, 20 Oct 2026 12:51:45 GMT</pubDate>
            <atom:updated>2026-10-20T12:51:44.579Z</atom:updated>
            <content:encoded><![CDATA[<h4>The nineteen tools problem.</h4><p>The procurement system found nineteen generative AI tools inside one company. No duplicates flagged. No shared learning. No single owner for outcomes. Each tool had arrived through a different department, a different budget line, and a different pilot charter. The stack was not chaotic in the way a failed IT project is chaotic. It was worse: it was locally rational. Every pilot had a sponsor. Every pilot had a success metric. Every pilot was, by its own narrow definition, working.</p><p>That discovery comes from a 2026 account published by the executive who lived it, and it is the most useful artefact in the enterprise AI conversation right now because it is not a story about technology failure. It is a story about a governance structure doing exactly what it was designed to do. The pilot is the unit of innovation in the modern enterprise. It is also the unit of fragmentation. Those two facts sit inside the same governance artefact, and most leadership teams have not yet separated them.</p><p>Microsoft’s 2026 Work Trend Index supplies the number that makes the separation urgent. Organizational factors — culture, manager support, talent practices — account for 67% of reported AI impact. Individual mindset and behaviour account for 32%. The research draws on telemetry from Microsoft 365, a survey of 20,000 AI users across ten countries, and leadership perspectives from a cohort of fourteen organizations. A company that sells AI infrastructure is telling its buyers, with unusual directness, that the infrastructure is the minority variable.</p><p>The number has travelled quickly because it confirms what operators already suspect. What it has not yet done is force the harder question. If organizational factors dominate, which organizational artefact is producing the failure? The answer is not culture in the abstract. It is the pilot. The pilot is where the operating model becomes visible, and where it refuses to change.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*Zj6GVTTqpAYlxwo-" /><figcaption>Photo by <a href="https://unsplash.com/@lilartsy?utm_source=medium&amp;utm_medium=referral">lilartsy</a> on <a href="https://unsplash.com/?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><h4>The Pilot Is a Theory of Value</h4><p>A pilot is never a neutral experiment. It is a governance technology with embedded assumptions. It assumes that value can be proven locally before it is scaled globally. It assumes that a bounded team, a bounded budget, and a bounded time window are sufficient to demonstrate causal impact. It assumes that the organization can evaluate the result and then decide whether to propagate it.</p><p>Those assumptions worked for software procurement, for process improvement, for channel testing. They fail for AI because AI value compounds across workflows, data loops, and decision rights rather than residing inside a single deployment. A pilot can prove that a model produces a plausible output. It cannot prove that the organization has the incentives, the role design, the data permissions, and the managerial capacity to absorb that output into daily work. The pilot measures the wrong layer and then declares victory at that layer.</p><p>McKinsey’s 2025 State of AI survey puts the resulting gap in plain terms. Eighty-eight percent of companies use AI in at least one function. Roughly one third have begun to scale it across the organization. Among companies testing AI agents, 62% are in trial mode; fewer than 10% have deployed them at scale in even a single department. Only 6% qualify as high performers, defined as achieving EBIT improvement of 5% or more that they can attribute directly to AI.</p><p>The ratio is the diagnosis. Experimentation is abundant. Absorption is scarce. The pilot is the mechanism that produces the first condition while simulating the second.</p><h4>Strength Becomes Blindness</h4><p>The pilot did not become the default because executives are timid. It became the default because it is the competence that built the modern enterprise. Disciplined stage-gating, decentralized experimentation, rapid proof-of-concept cycles, portfolio management of innovation bets: these are genuine strengths. They allow large organizations to explore without committing irreversible capital. They create optionality.</p><p>Optionality has a cost that does not appear on the pilot’s business case. Every pilot leaves behind a residue: a data connector, a vendor relationship, a prompt library, a set of permissions, a team that now knows a tool nobody else uses. Nineteen tools is not a failure of discipline. It is the residue of nineteen disciplined decisions, each made inside a local frame that was rational at the moment of approval.</p><p>The residue accumulates into an integration surface that nobody owns. The operating model that made decentralized piloting possible is the same operating model that now makes consolidation politically expensive. Each pilot has a sponsor who can defend it. Each tool has a user group that has adapted its workflow around it. The organization has optimized for exploration and, in doing so, has made the cost of the platform pivot rise with every additional experiment.</p><p>This is where the 67% figure stops being a statistic and becomes a structural claim. Organizational factors dominate AI impact because the organization has built a machine for producing isolated local successes. That machine is excellent at generating activity and structurally incapable of generating compounding capability. The bottleneck is not the model. The bottleneck is the governance artefact that decides what counts as progress.</p><h4>The Evidence Is Contested, and That Helps</h4><p>The most cited number in enterprise AI is the claim that 95% of pilots fail to deliver measurable financial return, drawn from a 2025 MIT report. The figure spread because it fit a narrative. It also deserves scrutiny. A detailed methodological critique published by the Marketing AI Institute found that the finding rested on 52 interviews that the report itself described as only “directionally accurate,” that success was defined narrowly as deployment beyond the pilot phase with an ROI measurement six months after completion, and that efficiency gains, churn reduction, and pipeline velocity were not counted.</p><p>That critique matters for the argument here because it removes the laziest version of the case. The pilot problem does not depend on a 95% failure rate. The McKinsey scaling gap alone is sufficient: near-universal adoption, one-third scaling, 6% high performers. The S&amp;P Global data cited across 2026 analyses shows the share of companies abandoning most AI initiatives rising from 17% to 42% in a single year, with an average enterprise scrapping 46% of pilots before production. The direction is consistent across sources even where the precise figures differ. The pilot is producing abandonment at scale.</p><p>What the methodological critique also reveals is the deeper problem with the pilot as an evaluation instrument. If a six-month P&amp;L window is the wrong test for AI value, then the pilot is measuring the wrong thing by design. AI value arrives through workflow redesign, role redefinition, and data-loop accumulation. Those are operating-model variables. A pilot charter that excludes them from the success definition will produce a predictable result: local proof, global nothing.</p><h4>The Compression Clock</h4><p>The cost of leaving the operating model unchanged is not static. It rises with the capability of the technology. Microsoft reports that active agents in its 365 ecosystem grew 15-fold year over year, and 18-fold among large enterprises. Agent proliferation changes the governance requirement. A single chatbot pilot requires a user group and a licence. A fleet of agents touching permissions, identities, and workflow state requires lifecycle management, auditability, and policy enforcement at a layer the pilot never had to consider.</p><p>This is the compression dynamic described in <em>Platform Economies</em>: AI collapses the distance between a feature, a platform, and the infrastructure beneath it. A feature that once required a team can now be produced by a model. A workflow that once required integration can now be assembled by an agent. The middle ground erodes. The organization that responds by running more pilots is accelerating compression inside its own boundary while capturing none of the structural value. It is producing more surface area for the platform owner to absorb.</p><p>The pilot trap and the compression clock are the same phenomenon viewed from different angles. The pilot keeps the organization busy at the feature layer. Compression moves the value to the platform layer. The longer the organization stays busy, the less bargaining power it retains when the platform layer arrives.</p><h4>What the Structural Pivot Actually Requires</h4><p>The prescription does not follow from a better pilot. It follows from a different unit of organizational design. The operating model has to treat AI as a foundational capability with shared infrastructure, shared data permissions, shared evaluation standards, and shared ownership of outcomes across functions. That is a structural commitment, not a tooling decision.</p><p>Three design moves distinguish the organizations that escape the pilot trap from those that do not.</p><ul><li><strong>A single evaluation layer for AI value.</strong> The pilot measures its own output. A foundational capability measures the change in workflow cycle time, decision latency, error rate, and role capacity across functions. The metric moves from “did the model perform” to “did the operating model absorb the output.”</li><li><strong>A named owner of the integration surface.</strong> Every pilot leaves residue. The residue needs an owner with the authority to consolidate, retire, and standardize. Without that authority, the nineteen-tool problem compounds silently until it becomes a security and cost crisis that forces a panic consolidation.</li><li><strong>Role redesign as a precondition, not a follow-on.</strong> Gartner’s 2026 CHRO survey found that 78% of HR leaders agree workflows and roles must change significantly to capture AI value; roughly half have redesigned a single role. The pilot can proceed without role redesign because the pilot sits beside the role. A foundational capability cannot. The workflow is the role, and the role is the workflow.</li></ul><p>None of these moves is technologically sophisticated. Each of them is politically expensive. That is the 67% in operational form. The organizational factors dominate because the organizational factors are the ones that require someone to give up local control, local budget, and local credit. The model does not resist. The org chart does.</p><h4>The Question the Pilot Cannot Answer</h4><p>The pilot asks whether the technology works. The evidence now says the technology works well enough to generate measurable value inside almost any bounded deployment. The harder question is whether the organization can stop treating bounded deployment as the destination.</p><p>A pilot that succeeds and is then retired has not failed by the pilot’s own logic. It has succeeded at producing a local proof and leaving the operating model untouched. The failure is structural and it is invisible in the pilot’s own reporting. That is why the 67% figure keeps surprising people who have a dashboard full of green pilot results. The dashboard is measuring the wrong unit.</p><p>The organisations that will capture compounding value from AI are not the ones running better pilots. They are the ones willing to make the pilot an endangered species: to replace a portfolio of local experiments with a small number of structural bets, each backed by a named operating-model change and a shared capability layer. That requires a kind of courage that does not appear in any business case. It is the courage to stop proving and start rebuilding.</p><p>The unresolved question is not whether the technology will keep improving. It will. The unresolved question is whether the governance structure that produced the pilot trap can be changed by the same people who were promoted because they were good at running it. The pilot is a mirror. The reflection is an operating model that has been optimized for local proof and has no mechanism for the kind of collective commitment that a platform pivot demands. Until that mechanism is designed, the nineteen tools will keep multiplying, and the value will keep concentrating somewhere else.</p><p>Here is the e-book from Microsoft: <a href="https://marketingassets.microsoft.com/adobe/assets/urn:aaid:aem:8ed7feaf-d9d0-4063-a6bf-d1970bc5e15b/original/as/Ebook-The-AI-Strategy-Roadmap.pdf">https://marketingassets.microsoft.com/adobe/assets/urn:aaid:aem:8ed7feaf-d9d0-4063-a6bf-d1970bc5e15b/original/as/Ebook-The-AI-Strategy-Roadmap.pdf</a></p><p>More actionable advice over at <a href="https://mohammed-brueckner.com/publications">https://mohammed-brueckner.com/publications</a> — and discover the playbook for surviving the compression in the agentic era with my book at <a href="https://platformeconomies.com/">https://platformeconomies.com</a> — out now and ready to buy in both Kindle and hardcover. Direct Amazon links:</p><ul><li>Amazon US: <a href="https://www.amazon.com/dp/B0H3VVNPZ3">https://www.amazon.com/dp/B0H3VVNPZ3</a></li><li>Amazon UK: <a href="https://www.amazon.co.uk/dp/B0H3VVNPZ3">https://www.amazon.co.uk/dp/B0H3VVNPZ3</a></li><li>Amazon DE: <a href="https://www.amazon.de/dp/B0H3VVNPZ3">https://www.amazon.de/dp/B0H3VVNPZ3</a></li></ul><p><a href="https://mohammed-brueckner.com/">← mohammed-brueckner.com</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=cfbf872cdb23" width="1" height="1" alt=""><hr><p><a href="https://medium.com/operations-research-bit/microsofts-latest-e-book-on-ai-strategy-and-what-it-reveals-cfbf872cdb23">Microsoft’s latest E-Book on AI Strategy and what it reveals</a> was originally published in <a href="https://medium.com/operations-research-bit">Operations Research Bit</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Operational Research in Python, 2026: The Solver Stack and a Two-Stage Depot Example]]></title>
            <description><![CDATA[<div class="medium-feed-item"><p class="medium-feed-image"><a href="https://medium.com/operations-research-bit/operational-research-in-python-2026-the-solver-stack-and-a-two-stage-depot-example-f614ad9c25ae?source=rss----63c2b5fa10f7---4"><img src="https://cdn-images-1.medium.com/max/2378/1*bEQrYqlc8YppxDlt1d4bdA.png" width="2378"></a></p><p class="medium-feed-snippet">Where the open-source optimisation stack stands today, and a worked stochastic program in which the distribution of demand, rather than&#x2026;</p><p class="medium-feed-link"><a href="https://medium.com/operations-research-bit/operational-research-in-python-2026-the-solver-stack-and-a-two-stage-depot-example-f614ad9c25ae?source=rss----63c2b5fa10f7---4">Continue reading on Operations Research Bit »</a></p></div>]]></description>
            <link>https://medium.com/operations-research-bit/operational-research-in-python-2026-the-solver-stack-and-a-two-stage-depot-example-f614ad9c25ae?source=rss----63c2b5fa10f7---4</link>
            <guid isPermaLink="false">https://medium.com/p/f614ad9c25ae</guid>
            <category><![CDATA[supply-chain]]></category>
            <category><![CDATA[data-science]]></category>
            <category><![CDATA[python]]></category>
            <category><![CDATA[optimization]]></category>
            <category><![CDATA[operations-research]]></category>
            <dc:creator><![CDATA[Diogo Ribeiro]]></dc:creator>
            <pubDate>Thu, 15 Oct 2026 09:23:29 GMT</pubDate>
            <atom:updated>2026-10-15T09:23:27.940Z</atom:updated>
        </item>
        <item>
            <title><![CDATA[Deutsche Bahn — this is for you.]]></title>
            <link>https://medium.com/operations-research-bit/deutsche-bahn-this-is-for-you-93eccfcf4d4b?source=rss----63c2b5fa10f7---4</link>
            <guid isPermaLink="false">https://medium.com/p/93eccfcf4d4b</guid>
            <category><![CDATA[technology]]></category>
            <category><![CDATA[coding]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[transportation]]></category>
            <category><![CDATA[api]]></category>
            <dc:creator><![CDATA[Mohammed Brückner]]></dc:creator>
            <pubDate>Fri, 09 Oct 2026 16:20:12 GMT</pubDate>
            <atom:updated>2026-10-09T16:20:11.372Z</atom:updated>
            <content:encoded><![CDATA[<h4>Take the chance to meet what your customers demand. (Developers, specifically.)</h4><p>Four hundred milliseconds is how long my code waits, every single morning, to guess whether a stream of German train data has finished sending or has quietly died.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*DXRmBp9m99b0g16d" /><figcaption>Photo by <a href="https://unsplash.com/@alexanderbagno?utm_source=medium&amp;utm_medium=referral">Alexander Bagno</a> on <a href="https://unsplash.com/?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><h4>The Monitor That Worked for One Week</h4><p>I built a small machine recently. Its entire job is to watch one line of the Munich S-Bahn, the S4, between Leienfelsstraße and Puchheim, on weekday mornings from 06:30 to 07:50. Four departure slots. Delay alerts once a train slips past three minutes. Three summary cards to my phone. A dead-man ping confirming that each evaluation cycle completed. Integration architects build these things for themselves the way railway staff ride trains on their days off, with professional interest and strong opinions about how the job should be done.</p><p>It worked. A full week of clean cycles, correct alerts, sensible summaries. A toy in the best sense of the word: one job, done well.</p><p>Then, somewhere past the one-week mark, the board went blank. No exception. Nothing red in any log. The app kept running, kept sending its dead-man ping, kept reporting healthy cycles about a world in which no S4 existed. My code was green. The data underneath it had stopped arriving, and nothing anywhere had noticed.</p><p>Every minute, before all this, my code had opened a WebSocket to a commercial geo-data aggregator and sent one plain-text frame:</p><pre>GET timetable_8004133</pre><p>The number is the station’s EVA identifier in Deutsche Bahn’s station register. The reply arrives as a burst: eight to twelve JSON frames within roughly half a second, covering the next ninety minutes of departures, then nothing at all. The protocol defines no end-of-data frame and no request-response correlation. A consumer cannot tell a finished stream from a stalled one except through waiting. So my code waits 400 milliseconds and cuts the read, with a three-second hard ceiling on top. That number appears in no specification anywhere. It is a folk remedy, tuned against observed behaviour, and folk remedies rot.</p><p>The frames themselves carry field names like ris<em>aimed</em>time and ris<em>estimated</em>time. RIS is Deutsche Bahn&#39;s Reisenden-Informationssystem, the industrial-grade realtime platform that feeds the operator&#39;s own departure boards. The national railway&#39;s operational truth was reaching a private laptop in Munich through a reseller&#39;s evaluation-grade key. I never had a contract with Deutsche Bahn. I had a contract-shaped hope with a middleman.</p><h4>Three Sources and None of Them an Offering</h4><p>The monitor consults three sources, and the formally interesting thing about all three is what each one is: nothing. No documentation promises any of them to me, no terms bind any of them to me. They are surfaces that happened to be reachable, and I built on them the way you cross a frozen lake, testing every step.</p><p>When something breaks on the Munich S-Bahn network, the control centre, the Leitstelle, publishes incident prose on Bluesky under the account @s-bahn-muenchen.de. No API of the operator carries this text. The machine-readable path runs through the social network’s public relay:</p><pre>https://public.api.bsky.app/xrpc/app.bsky.feed.getAuthorFeed?actor=s-bahn-muenchen.de&amp;limit=15</pre><p>My code polls that endpoint and matches post text against a keyword list, S4 and PASING and PUCHHEIM and a dozen more, to catch trouble on the eastern feeder lines before it reaches my western platform. An incident’s resolution is signalled by the word ENDMELDUNG appearing in the post body. That word is my incident-closure protocol. The most operationally honest account of what is wrong with the network travels as social media, read as JSON from a relay whose operator is in the attention business, on the goodwill of everyone involved.</p><p>When the WebSocket produces nothing at all, the code falls back to the MVV departure monitor, an EFA endpoint (the departure-monitor protocol used across German transport authorities) that answers a departure request given a full litany of parameters and one header in particular:</p><pre>Referer: https://efa.mvv-muenchen.de/</pre><p>Without that header, the endpoint answers with HTTP 200 and an empty departure list. With it, thirty departures arrive. Sit with that mechanism for a moment: the service checks whether the caller appears to be its own website and shares data accordingly. That is a door that opens inward, for people already inside the building. The header is MVV’s sin, and MVV is not Deutsche Bahn. The reason my code speaks to any transport authority’s website backend at all is the hole where an official channel should be. I lie politely, every minute, to obtain a public timetable.</p><p>The three sources cannot even agree on the name of my station. Deutsche Bahn’s register calls it 8004133. The MVV system knows it as 1001700 in its stateless scheme, or de:09162:1700 as a global identifier. Neither side resolves the other’s numbers, so every consumer maintains a private crosswalk between two public numbering systems describing the same platform in the same city.</p><p>Down at field level, the honesty gets stranger. departureDelay arrives as null for trains beyond the realtime horizon, and the consumer recomputes it from the paired aimed and estimated timestamps. Cancellation is visible in exactly one field of one source, a state value of CANCELLED or DELETED; the EFA endpoint exposes no equivalent, so a cancelled train is invisible there. Train runs get renumbered on the fly, a 64xx service one day and an 84xx the next, so my code never matches on train numbers at all. Departures are matched to commute slots purely by their planned minute falling inside a time window. Run identity is decorative.</p><p>All three sources share the one property that eventually killed the app: they fail as success. The aggregator key revokes, the EFA endpoint gains a bot-protection rule, the relay starts answering 429, and the consumer sees HTTP 200 with a body containing nothing, or a socket that connected and went quiet. I have started calling this shape success-shaped emptiness. The absence of an error is the most expensive error to handle, and no dashboard catches it, for the embarrassingly plain reason that nothing red ever appears anywhere.</p><h4>What a Week of Uptime Actually Measured</h4><p>The easy read on all this goes: free APIs are flaky, you get what you pay for, next case. That read is wrong in an instructive direction. Whether a free thing can be depended on depends on why it is free.</p><ul><li><strong>Free by mandate:</strong> a public obligation to publish, in standard formats, under an open licence, through channels someone is paid to keep working.</li><li><strong>Free by freemium:</strong> a vendor’s evaluation lane, generous until the pricing page changes, which pricing pages do.</li><li><strong>Free by goodwill:</strong> volunteers running infrastructure they love, with no promise attached and every right to stop.</li></ul><p>None of my three sources was free by mandate. The one flavour of free that carries dependability properties was the one flavour unavailable for the exact data my monitor needed: Deutsche Bahn’s own realtime output, for a line the company operates under public commission in Bavaria.</p><p>Here is the mental model I pulled out of the wreckage, stolen directly from the data itself. The realtime stream has a horizon: past roughly ninety minutes, departureDelay comes back null, and the consumer is expected to recompute from the pair of timestamps, planned against estimated. Institutions have the same geometry. Past the edge of any contract (documentation, terms, a status page, a deprecation policy), reliability comes back null, and the consumer recomputes from observation. My first week of flawless cycles was that recomputation: paired observations of worked-yesterday against works-today, mistaken for a property of the system. Call it the contract horizon. Inside it, data is a fact. Beyond it, data is archaeology.</p><p>No service level was breached when the frames stopped arriving, for the simple reason that none existed. What I had was a train door somebody had propped open, and doors like that get closed eventually, without malice, on a schedule nobody publishes.</p><h4>The Decisions That Were on the Table</h4><p>None of this was weather. Identifiable choices were available at identifiable moments, and the accumulated effect of declining them is the world my monitor died in.</p><p>The European Union adopted Regulation 2017/1926 on multimodal travel information services, the MMTIS regulation, obliging member states to make travel data accessible through national access points in standard formats, with delegated acts refining quality expectations in the years since. Germany’s access point exists, the Mobilitätsdatenmarktplatz, and federal-state programmes like DELFI have spent years harmonising nationwide travel information on top of that plumbing. The policy decision to publish, in standard formats, as a public duty, was taken at European level years before my monitor was a glimmer in a cron job.</p><p>The S-Bahn München is commissioned by the Free State of Bavaria, procured through the Bayerische Eisenbahngesellschaft. BEG publishes real-time data for the Bavarian regional services it commissions as GTFS-RT, and has done so for years, in standard formats under an open licence. GTFS itself began in the mid-2000s as a volunteer collaboration between Google and TriMet, the transit agency of Portland, Oregon, and grew into the de facto global standard for this exact kind of publishing. The decision to publish realtime for trains like mine has, in effect, already been made. It was made at state level, in procurement, where nobody outside the mobility-data scene goes looking.</p><p>Read the current licence and coverage notes before you build on any of this. My war story is not a datasheet, and coverage details shift. The structural point stands regardless.</p><p>Deutsche Bahn’s own posture is the strange one. The company publishes static timetable and station datasets openly; the station register I pull EVA numbers from is one of them. The realtime layer, the RIS stack behind the company’s own boards, sits behind a developer portal whose commercial terms have wandered across the years: registration walls, beta labels, quota regimes, paid tiers, relaunches. I will not quote today’s pricing, since I would be quoting a moving target. The pattern is the finding. Static data as open data. Realtime data as a product. A decade of ambiguous signals in between, and that ambiguity is itself a decision, the decision to keep the question open. Open questions have running costs, and my blank board paid one.</p><p>A decade of non-decision inside a competent organisation needs an explanation, and three stand out.</p><ul><li><strong>The category error:</strong> operational telemetry treated as inventory. A departure estimate is exhaust from running a railway. The marginal cost of distributing it read-only sits near zero, and yet the mental model prices it like stock. You cannot build a moat out of exhaust.</li><li><strong>The organisational seams:</strong> Deutsche Bahn operates, the Länder commission, MVG runs the city network, and realtime rights fragment along precisely those boundaries. Nobody owns the seam. My crosswalk table between EVA numbers and EFA stop identifiers is what a seam looks like from a consumer’s chair.</li><li><strong>The risk instincts:</strong> liability, brand control, the discomfort of third parties displaying your delays prominently. Each fear is legible, and each has a boring answer, from licence terms to the plain fact that the station boards already display those delays to everyone standing on the platform.</li></ul><p>The result is an operator with an industrial-grade realtime platform whose public distribution surfaces are, in practice, a social media feed and a reseller’s demo keys. That sentence should be uncomfortable to read inside DB. I mean it as a compliment to the platform and an indictment of the doorway.</p><h4>The Compensation Code Is the Requirement Document</h4><p>Integration architects learn to read workarounds the way geologists read rock strata. Every compensating mechanism in my little system is the fossil of a missing promise. The inventory:</p><ul><li><strong>The silence timeout from the opening line:</strong> the protocol ships no end-of-snapshot marker, no heartbeat, no sequence number. Every consumer invents a silence heuristic, tunes it against folklore, and gets burned when latency creeps.</li><li><strong>The null-delay recompute:</strong> departureDelay is null past the realtime horizon, so the consumer subtracts aimed from estimated timestamps and hopes the pair arrives complete. The source pushed its own arithmetic onto everyone downstream.</li><li><strong>Time-window slot matching:</strong> train numbers are renumbered at will, so identity is decorative and matching happens by planned minute. The consumer rebuilt identity out of time.</li><li><strong>The timezone rebase:</strong> the EFA endpoint returns Munich wall-clock with no zone marker, and every consumer re-implements CET and CEST arithmetic to recover an epoch. The October clock change, arriving weeks after I wrote the system, was my next scheduled failure, pre-announced by the data model itself.</li><li><strong>The absence invariant:</strong> when the board is trustworthy and a train is still missing, my code records a state called SUSPENDED and refuses to call it a cancellation. That rule was learned the hard way, during a Stammstrecke closure, when the realtime feed dropped every westbound S4 — and the physical trains kept running, and people kept boarding them. A blank board during an incident is indistinguishable from a cancelled service unless somebody states which one it is. So blank means unknown, on principle.</li><li><strong>The dead-man ping:</strong> I built a private status page for somebody else’s service. Multiply me by every quiet integrator in the country and you get a distributed monitoring system, uncoordinated and invisible to the providers it watches, observability rebuilt from below one cron job at a time.</li></ul><h4>The Free Offering That Would Survive Contact</h4><p>So what would the right thing look like, priced at zero, dependable anyway? Written from the trenches, as requirements:</p><ul><li><strong>Standard formats:</strong> GTFS static plus GTFS-RT, with TripUpdates for delays, VehiclePositions for locations, ServiceAlerts for incidents, mirrored on the institutional side in NeTEx and SIRI. ServiceAlerts alone would retire my entire keyword-matching layer: informed<em>entity binds an alert to a stop and a route, </em><em>active</em>period says when it applies, and ENDMELDUNG becomes an expired period instead of a German word my code greps for.</li><li><strong>One identity spine:</strong> DHID codes (the German harmonised stop identifiers), my station being de:09162:1700, as the canonical key, with EVA numbers published as aliases in a versioned station dataset. The crosswalk table becomes a download.</li><li><strong>Errors that are errors:</strong> 401 for a bad key, 403 for a revoked one, 429 with rate-limit headers for quota, 5xx for outage, and a 200 that can honestly mean zero departures, distinguishable from all of the above. Silence should never carry meaning.</li><li><strong>Stream semantics:</strong> heartbeats, sequence numbers, an end-of-snapshot frame, resumption in the style of Server-Sent Events with Last-Event-ID. Then the silence heuristic retires with dignity.</li><li><strong>Explicit cancellation:</strong> an affirmative schedule_relationship: CANCELLED, never inference from absence. My SUSPENDED state stays on as defence in depth, and I will be glad to keep it.</li><li><strong>Timestamps with zones:</strong> UTC epochs or offset-bearing ISO-8601. Naive wall-clock belongs in a museum, next to the departure boards with flipping plastic letters.</li><li><strong>An operational contract for the free tier:</strong> a self-service key, a published quota, a status page, a changelog feed, versioned endpoints, published schemas, a bug channel, and a deprecation runway counted in months. Each clause carries its consequence: no status page, and consumers improvise their own health checks; no changelog, and they build canaries; no deprecation runway, and they quietly build nothing at all and leave.</li><li><strong>An open licence:</strong> dl-de/by-2.0 or CC-BY 4.0, attribution required, no field-of-use veto over small commercial reuse. That boundary is where the interesting builders live.</li></ul><p>Some of this exists today. The Bavarian feeds and the national access point carry mandated-tier realtime for commissioned services. Community projects such as transport.rest wrap official sources with genuine kindness and zero commitment. Aggregators sell convenience with a demo lane attached. The tooling is there. The front door is missing, and Deutsche Bahn’s own authoritative realtime stack has no entry a private person can walk through with a clear conscience and a durable contract.</p><h4>Why the Railway Comes Out Ahead</h4><p>The business case writes itself, which is the frustrating part. I ride an architect’s elevator between engine rooms and boardrooms for a living, and this is one of those rare cases where the same sentence is true on both floors.</p><ul><li><strong>Marginal cost:</strong> RIS already produces this data for DB’s own boards. A read-only distribution layer is thin infrastructure laid over a running system. The expensive part underneath already exists and already works.</li><li><strong>Distributed quality assurance:</strong> my Stammstrecke observation, that the feed drops westbound services during incidents as physical trains keep running, is a bug report the operator’s internal telemetry plausibly missed. A thousand consumers watching the feed are a thousand sensors. Give them a bug channel, reward the reports, and the testing pays for the plumbing.</li><li><strong>Less scraping:</strong> every dependable official channel drains the swamp of scripts hammering website backends and lying with Referer headers. My own code is part of that load. I am not proud of the header it sends, and I would stop sending it tomorrow.</li><li><strong>Public money:</strong> the S-Bahn München is commissioned by Bavaria with public funds. The operations that generate this data were paid for once already, by the people standing on the platform. The Länder hold the leverage and the policy mandate, and the railway can lead or be led.</li><li><strong>Regulation arrives anyway:</strong> MMTIS obligations are on the books. Meeting them with grace and a status page costs less than meeting them under duress.</li><li><strong>Brand placement at the decision moment:</strong> every third-party board that renders a source line reading Deutsche Bahn puts the brand in front of a commuter at the precise moment that commuter is judging the railway, which is during the delay. That placement cannot be bought. It can be published.</li></ul><p>To be fair to the cost side: bandwidth, keys, and abuse are real expenses, and free lanes attract their share of hammering. Quotas and registration answer most of that, and they are the cheap kind of answer.</p><p>And the one prohibition: the cancellation flag must never sit behind a paywall. The single most commuter-critical fact in the dataset, whether the train runs or is gone, is the last thing that belongs in a paid tier. Gate it, and the scrapers come back, angrier and better funded.</p><h4>The Blank Board at the Institutional Level</h4><p>I wrote the architecture down, every workaround and every missing promise, and mailed the result to dbopendata@deutschebahn.com in the spirit of the thing.</p><p>My monitor’s most important rule treats a blank board as unknown, never as cancelled, held on evidence that trains keep running when feeds go dark. Institutions earn the same courtesy and the same skepticism. A blank channel from Deutsche Bahn is ambiguous between two readings: a company that has decided against open realtime, or a company that wants it and keeps stalling between operators, commissioners, and portal relaunches. A blank board is a fact about the board; the trains are a separate question, and someone has to answer it out loud.</p><p>The mailbox is the test. What comes back, and in what shape, resolves the ambiguity the way an ENDMELDUNG resolves an incident: a structured signal that someone closed the loop. Silence resolves it too, in the other direction, and more slowly.</p><p>One last observation from the trenches. My code learned not to trust train numbers, so it matches departures by time window: whatever shows up between 06:26 and 06:45 is the 06:36, whatever it calls itself today. Builders match institutions the same way. Nobody outside the company reads the org chart or the number on the livery; they match what arrives in the window when they look. The window is open every weekday morning, and the monitor is still running. So here is the question I am leaving open on purpose: when the tinkerers look into the 06:26 to 06:45 slot, what shows up — a service with a timetable behind it, or silence wearing a 200?</p><p>Either way, we keep matching. That is what time windows are for.</p><p>More actionable advice over at <a href="https://mohammed-brueckner.com/publications">https://mohammed-brueckner.com/publications</a> — and discover the playbook for surviving the compression in the agentic era with my book at <a href="https://platformeconomies.com/">https://platformeconomies.com</a> — out now and ready to buy in both Kindle and hardcover. Direct Amazon links:</p><ul><li>Amazon US: <a href="https://www.amazon.com/dp/B0H3VVNPZ3">https://www.amazon.com/dp/B0H3VVNPZ3</a></li><li>Amazon UK: <a href="https://www.amazon.co.uk/dp/B0H3VVNPZ3">https://www.amazon.co.uk/dp/B0H3VVNPZ3</a></li><li>Amazon DE: <a href="https://www.amazon.de/dp/B0H3VVNPZ3">https://www.amazon.de/dp/B0H3VVNPZ3</a></li></ul><p><a href="https://mohammed-brueckner.com/">← mohammed-brueckner.com</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=93eccfcf4d4b" width="1" height="1" alt=""><hr><p><a href="https://medium.com/operations-research-bit/deutsche-bahn-this-is-for-you-93eccfcf4d4b">Deutsche Bahn — this is for you.</a> was originally published in <a href="https://medium.com/operations-research-bit">Operations Research Bit</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Fine-Tuning vs RAG: When to Retrieve, When to Train, and How to Decide]]></title>
            <link>https://medium.com/operations-research-bit/fine-tuning-vs-rag-when-to-retrieve-when-to-train-and-how-to-decide-2d6d33cf6754?source=rss----63c2b5fa10f7---4</link>
            <guid isPermaLink="false">https://medium.com/p/2d6d33cf6754</guid>
            <category><![CDATA[artificial-intelligence]]></category>
            <category><![CDATA[fine-tuning]]></category>
            <category><![CDATA[genai]]></category>
            <category><![CDATA[data]]></category>
            <category><![CDATA[agentic-rag]]></category>
            <dc:creator><![CDATA[Sopan Deole]]></dc:creator>
            <pubDate>Thu, 08 Oct 2026 05:09:09 GMT</pubDate>
            <atom:updated>2026-10-08T05:09:08.166Z</atom:updated>
            <content:encoded><![CDATA[<h4><em>Last time we scaled RAG for production with partitioned indexes, layered caching, and graceful degradation.</em></h4><blockquote><em>This week we step back and ask a question every team hits eventually: is RAG even the right tool, or should we be fine-tuning instead?</em></blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*ksGFdJH9iuZaVehb" /><figcaption>Photo by <a href="https://unsplash.com/@growtika?utm_source=medium&amp;utm_medium=referral">Growtika</a> on <a href="https://unsplash.com/?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><blockquote>RAG changes what the model knows. Fine-tuning changes how the model behaves. Confusing the two is the most expensive mistake in Gen AI.</blockquote><h3><strong>Introduction</strong></h3><p>After months of building retrieval pipelines, it is tempting to treat RAG as the answer to every quality problem. It is not. Some problems are knowledge problems: the model does not have the right facts. Others are behavior problems: the model has the facts but responds in the wrong format, tone, or reasoning style. RAG solves the first. Fine-tuning solves the second. Most production systems eventually need a clear rule for which tool fits which problem, and occasionally both.</p><h3><strong>What Each Approach Actually Does</strong></h3><p>RAG injects external knowledge at query time. The model stays the same. You change what it sees in the context window. Updates are instant: add a document, re-index, done.</p><p>Fine-tuning adjusts the model’s weights using examples. The model itself changes. It learns patterns, formats, terminology, and response styles. Updates require a new training run.</p><p>A useful mental model: RAG is giving the model an open book during the exam. Fine-tuning is teaching it how to write the answer.</p><h3><strong>When RAG Is the Right Choice</strong></h3><p>Your knowledge changes frequently, such as policies, pricing, product docs, or support articles.</p><p>You need citations and traceability back to source documents.</p><p>Different users need different data, with tenant or access-level scoping.</p><p>You need to remove or correct information quickly. Deleting a document from an index takes minutes. Removing knowledge from fine-tuned weights is nearly impossible.</p><p>You do not have a large, high-quality labeled dataset.</p><h3><strong>When Fine-Tuning Is the Right Choice</strong></h3><p>You need a consistent output format or structure that prompting alone cannot reliably enforce.</p><p>You need domain-specific tone, vocabulary, or style, such as clinical notes, legal drafting, or your brand voice.</p><p>You want a smaller, cheaper model to match a larger model’s performance on a narrow, repetitive task.</p><p>Your prompts have grown long with instructions and few-shot examples. Fine-tuning can bake that behavior in and shrink every request.</p><p>The task is classification, extraction, or routing with stable labels and thousands of examples.</p><h3><strong>When to Use Both</strong></h3><p>The strongest production setups often combine them. Fine-tune a model to follow your citation format, respect your refusal style, and use your terminology. Then use RAG to feed it current, scoped facts at query time. The fine-tuned model becomes better at using retrieved context, and RAG keeps its knowledge fresh.</p><h3><strong>The Decision Checklist</strong></h3><p>Ask these in order:</p><p>1)Is the problem missing or outdated facts? Use RAG.</p><p>2) Is the problem inconsistent format, tone, or behavior? Try better prompting first. If that fails, fine-tune.</p><p>3) Does the knowledge change more than once a quarter? Use RAG. Fine-tuning cannot keep pace.</p><p>4) Do you need citations or auditability? Use RAG.</p><p>5) Do you have at least a few hundred high-quality examples of the exact behavior you want? If not, you are not ready to fine-tune.</p><p>6) Is cost or latency the main driver on a narrow task? Consider fine-tuning a smaller model.</p><h3><strong>The Hidden Costs Nobody Mentions</strong></h3><p>Fine-tuning costs more than the training run. You need a curated dataset, an evaluation pipeline, version management for each tuned model, and a plan to re-tune when your base model provider ships a new version. A fine-tuned model can also drift out of date if facts were baked into it.</p><p>RAG costs more than a vector database. You need ingestion pipelines, chunking, re-indexing, retrieval evaluation, and ongoing monitoring of everything we have covered over the past few months. The difference is that RAG costs are operational and incremental, while fine-tuning costs come in larger, periodic chunks.</p><h3><strong>Common Pitfalls and Quick Fixes</strong></h3><p>Fine-tuning to teach facts. Fix by moving factual knowledge into RAG. Models fine-tuned on facts hallucinate confidently when those facts change.</p><p>Fine-tuning before exhausting prompting. Fix by trying structured prompts, few-shot examples, and output schemas first. They solve most behavior problems at a fraction of the cost.</p><p>Using RAG to fix format problems. Fix by recognizing that more context does not teach the model to follow a JSON schema. That is a prompting or fine-tuning problem.</p><p>Training on low-quality data. Fix by curating fewer, better examples. Five hundred clean examples beat five thousand noisy ones.</p><p>No evaluation after fine-tuning. Fix by running your golden set against the base model and the tuned model side by side before switching traffic.</p><h3><strong>Try It Now</strong></h3><p>List your top three Gen AI quality complaints from the past month.</p><p>Label each as a knowledge problem or a behavior problem.</p><p>For knowledge problems, check whether RAG retrieval is the real gap using the failure-mode checklist.</p><p>For behavior problems, write one stricter prompt or output schema and test it on 20 cases.</p><p>Only if prompting fails, estimate how many labeled examples you could realistically gather for fine-tuning.</p><h3><strong>Conclusion</strong></h3><p>RAG and fine-tuning are not competitors. They solve different problems. Retrieve when the model needs to know something. Train when the model needs to behave differently. Prompt first, retrieve for knowledge, and fine-tune only when you have stable tasks and clean examples. Get the diagnosis right and you will spend your budget on the fix that actually works.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=2d6d33cf6754" width="1" height="1" alt=""><hr><p><a href="https://medium.com/operations-research-bit/fine-tuning-vs-rag-when-to-retrieve-when-to-train-and-how-to-decide-2d6d33cf6754">Fine-Tuning vs RAG: When to Retrieve, When to Train, and How to Decide</a> was originally published in <a href="https://medium.com/operations-research-bit">Operations Research Bit</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[LeetCode 2442: You Don’t Need to Build the Array, Just the Set]]></title>
            <link>https://medium.com/operations-research-bit/leetcode-2442-you-dont-need-to-build-the-array-just-the-set-203b3dc269c8?source=rss----63c2b5fa10f7---4</link>
            <guid isPermaLink="false">https://medium.com/p/203b3dc269c8</guid>
            <category><![CDATA[coding-interviews]]></category>
            <category><![CDATA[data-science]]></category>
            <category><![CDATA[leetcode]]></category>
            <category><![CDATA[java]]></category>
            <category><![CDATA[algorithms]]></category>
            <dc:creator><![CDATA[Anish More]]></dc:creator>
            <pubDate>Wed, 07 Oct 2026 14:33:03 GMT</pubDate>
            <atom:updated>2026-10-07T14:33:02.465Z</atom:updated>
            <content:encoded><![CDATA[<h4>Some LeetCode problems hide a clever algorithm.</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*JH5opK9slOvRPFdc" /><figcaption>Photo by <a href="https://unsplash.com/@anoofc?utm_source=medium&amp;utm_medium=referral">ANOOF C</a> on <a href="https://unsplash.com/?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><h3>Article</h3><p>Others hide a small detail in the statement. Problem 2442 is the second kind, and the detail is a single line: <em>“for the integer 10, after reversing it, it becomes 01 which is just 1.”</em></p><p>Miss that line and you will spend time debugging an answer that is off by one. Read it carefully and the whole problem collapses into a few lines of Java.</p><h3>The problem in plain English</h3><p>You get an array nums of positive integers. For every number, reverse its digits and append the result to the array. Then count how many distinct values the final array contains.</p><pre>Input:  nums = [1, 13, 10, 12, 31]<br>Output: 6<br>Final array: [1, 13, 10, 12, 31, 1, 31, 1, 21, 13]<br>Distinct:    1, 10, 12, 13, 21, 31  -&gt; 6</pre><pre>Input:  nums = [2, 2, 2]<br>Output: 1</pre><p>Constraints: 1 &lt;= nums.length &lt;= 10^5 and 1 &lt;= nums[i] &lt;= 10^6.</p><h3>Step 1: How to think about it</h3><p>Three questions I ask on almost every counting problem:</p><ol><li>Is there a hidden trick? Only the trailing-zero rule. 10 -&gt; 1, 100 -&gt; 1. Reversing by arithmetic handles it for free.</li><li>What state do I actually need? Not the final array. The question is only “how many distinct values”, so I need a collection that ignores duplicates. That is a HashSet.</li><li>What do the constraints allow? nums[i] is at most 10^6, so a number has at most 7 digits. Reversing one number is basically constant work. Even with 10^5 numbers, a single pass is fine.</li></ol><h3>Step 2: The straightforward solution</h3><p>Do exactly what the statement says. Build the longer array, then count distinct values.</p><pre>class BruteForce {<br>    public int countDistinctIntegers(int[] nums) {<br>        int n = nums.length;<br>        int[] all = new int[2 * n];<br>        for (int i = 0; i &lt; n; i++) {<br>            all[i] = nums[i];<br>            all[n + i] = Integer.parseInt(<br>                new StringBuilder(String.valueOf(nums[i])).reverse().toString());<br>        }<br>        return (int) java.util.Arrays.stream(all).distinct().count();<br>    }<br>}</pre><p>Integer.parseInt(&quot;01&quot;) returns 1, so the leading-zero rule is handled by the parser.</p><p>Time: O(n * d), where d is the number of digits (at most 7 here), plus the cost of distinct(). Space: O(n) for the doubled array, plus a String per number.</p><p>It is correct. It is also wasteful: a second array and a String per element, just to throw most of it away.</p><h3>Step 3: The version that tracks only what matters</h3><pre>class Solution {<br>    public int countDistinctIntegers(int[] nums) {<br>        HashSet&lt;Integer&gt; obj = new HashSet&lt;&gt;();<br>        int len = nums.length, temp, rev;<br>        for (int i = 0; i &lt; len; i++) {<br>            obj.add(nums[i]);<br>            if (nums[i] &gt; 9) {<br>                temp = nums[i];<br>                rev = 0;<br>                while (temp &gt; 0) {<br>                    rev = rev * 10 + (temp % 10);<br>                    temp /= 10;<br>                }<br>                obj.add(rev);<br>            }<br>        }<br>        return obj.size();<br>    }<br>}</pre><p>What changed compared to the brute force:</p><ul><li>No second array. Each number and its reverse go straight into the set.</li><li>No Strings. The reverse is built with % 10 and / 10.</li><li>The set removes duplicates as we go, so the final answer is just obj.size().</li></ul><h4>Key Observation: why the nums[i] &gt; 9 check is safe</h4><p>A single-digit number reversed is itself. 7 reversed is 7, and 7 is already in the set from the line above. So skipping the reverse adds nothing and removes nothing from the answer.</p><p>It is a small optimization, not a requirement. If you delete the if, the code is still correct, because the loop would compute rev = 7 and the set would ignore the duplicate. I checked both versions against a brute force on random input and they agree. Keeping the check saves a loop for numbers that cannot change the result.</p><h4>Why trailing zeros need no special code</h4><p>Take 10. The loop does this:</p><ul><li>temp = 10: rev = 0 * 10 + 0 = 0, temp = 1</li><li>temp = 1: rev = 0 * 10 + 1 = 1, temp = 0</li></ul><p>The leading zero of the reversed number is just a 0 added to rev = 0, which changes nothing. So 10 -&gt; 1 and 100 -&gt; 1 come out right with no extra rule.</p><h4>Dry run on Example 1</h4><p>nums = [1, 13, 10, 12, 31]</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*KKZi_47AHfOfVxeahnCl1g.png" /></figure><p>obj.size() = 6. Matches the expected output.</p><p>Notice step 4. The numbers 13 and 31 are reverses of each other, so by the time we reach 31 both are already in the set. That is where the HashSet earns its place.</p><h3>Does anything overflow?</h3><p>The reverse of a number up to 10^6 is at most 999999, which fits in an int with plenty of room. I enumerated every value from 1 to 1,000,000 to confirm the largest reverse is 999,999. (1000000 reverses to 1.)</p><h3>Complexity</h3><p>Time: O(n * d). Each number needs at most d = 7 loop iterations to reverse, and a HashSet insert is O(1) on average. With d capped at 7, this is effectively O(n).</p><p>Space: O(n). The set holds at most 2n values.</p><h3>Brute force vs the HashSet version</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*kf4aFgmtnMEp9PLfWDXibQ.png" /></figure><p>Both have the same big-O. The difference is the constant factor: fewer allocations and no String churn. For this problem, either passes. I would still write the brute force first on paper, because it tells you what the optimized version has to reproduce.</p><h3>Edge cases I tested</h3><p>I ran the HashSet solution against the brute force on these, plus 200,000 random arrays. Zero mismatches.</p><ul><li>[7] -&gt; 1 (single digit)</li><li>[10] -&gt; 2 (10 and 1)</li><li>[100] -&gt; 2 (100 and 1)</li><li>[10, 1, 100] -&gt; 3 (10, 1, 100; the reverses all land on 1)</li><li>[121, 121] -&gt; 1 (palindrome, duplicate)</li><li>[12, 21] -&gt; 2 (each is the other&#39;s reverse)</li><li>[1000000] -&gt; 2 (1000000 and 1)</li><li>[999999, 1000000] -&gt; 3</li></ul><h3>Final Takeaways</h3><ul><li>Read the statement for the one odd rule. Here it was 10 -&gt; 1.</li><li>Ask what you need to <em>count</em>, not what you need to <em>build</em>. The answer was a set, not an array.</li><li>Reverse with % 10 and / 10 instead of Strings when you can.</li><li>Check the constraints for overflow before you pick int.</li><li>Write the obvious solution first. It is your test oracle for the clever one.</li></ul><p>The smartest solution is not the longest one. Here it is a loop, a set, and one careful reading of the problem.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=203b3dc269c8" width="1" height="1" alt=""><hr><p><a href="https://medium.com/operations-research-bit/leetcode-2442-you-dont-need-to-build-the-array-just-the-set-203b3dc269c8">LeetCode 2442: You Don’t Need to Build the Array, Just the Set</a> was originally published in <a href="https://medium.com/operations-research-bit">Operations Research Bit</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>