<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Mascottz</title>
    <description>The latest articles on DEV Community by Mascottz (@mascottz).</description>
    <link>https://dev.to/mascottz</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4161355%2F055d4f4f-129a-4b8e-9655-2de306e526b9.jpg</url>
      <title>DEV Community: Mascottz</title>
      <link>https://dev.to/mascottz</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mascottz"/>
    <language>en</language>
    <item>
      <title>I built CutLine to measure a closure without pretending to predict traffic</title>
      <dc:creator>Mascottz</dc:creator>
      <pubDate>Sun, 04 Oct 2026 13:22:52 +0000</pubDate>
      <link>https://dev.to/mascottz/i-built-cutline-to-measure-a-closure-without-pretending-to-predict-traffic-2pa3</link>
      <guid>https://dev.to/mascottz/i-built-cutline-to-measure-a-closure-without-pretending-to-predict-traffic-2pa3</guid>
      <description>&lt;p&gt;I started CutLine with a narrow question: if i remove one street segment from a recorded graph, how much does the shortest route change, and which nodes remain reachable? i wanted a small, inspectable experiment rather than a traffic model dressed up as a map.&lt;/p&gt;

&lt;h2&gt;
  
  
  I keep the claim small
&lt;/h2&gt;

&lt;p&gt;I use a frozen OpenStreetMap extract around Yaba, Lagos, collected on 2026-10-04 from a 0.01-degree bounding box. i preserve source way ids, node ids, direction tags, and local geometry; i record the query, counts, attribution, and ODbL-1.0 terms beside the bundled data.&lt;/p&gt;

&lt;p&gt;I choose one street segment as a hypothetical closure. i do not claim a live road closure, current coverage, travel-time estimate, traffic-flow prediction, safety result, emergency-access result, or network-resilience measure. i calculate paths over the stored geometry, direction tags, projection, and closure set; that is the whole claim.&lt;/p&gt;

&lt;p&gt;I get a baseline route of about 4.6 km and a route of about 4.9 km after the bundled closure; i calculate a 7.73 percent increase in graph distance and 1,162 reachable nodes for the selected origin. i display the same integer-backed measurements in the local atlas and keep the caveat beside the map.&lt;/p&gt;

&lt;h2&gt;
  
  
  I keep the graph authoritative
&lt;/h2&gt;

&lt;p&gt;I normalize a bounded GeoJSON subset into a graph with stable ids and integer latitude and longitude in microdegrees. i calculate each segment weight once in integer millimeters, preserve supported one-way direction, and validate endpoints, ids, sizes, and local extent before routing.&lt;/p&gt;

&lt;p&gt;I use deterministic Dijkstra searches for shortest paths and breadth-first reachability for the remaining graph. i apply closures as a read-only edge filter rather than editing the source graph; i keep the original route and changed route comparable under the same endpoints. i resolve equal-cost paths with a stable ordering and calculate route-change ratios in integer basis points.&lt;/p&gt;

&lt;p&gt;I keep the browser out of the routing business. i send a versioned JSON bootstrap from the local OCaml service, let Elm hold the selection and pending state, and send relative same-origin requests for each graph analysis. i reject stale replies so an older response cannot replace a newer scenario.&lt;/p&gt;

&lt;h2&gt;
  
  
  I choose a small stack on purpose
&lt;/h2&gt;

&lt;p&gt;I chose OCaml for import validation, graph invariants, integer routing, serialization, and the loopback service. i wanted a compiled core with explicit invalid and unavailable states, not a distributed system or a broad service framework.&lt;/p&gt;

&lt;p&gt;I chose Elm for the atlas because the interaction is a bounded state machine with a small number of states and messages. i keep JavaScript to a short bootstrap that mounts the compiled Elm module; i use no frontend framework, external map tile, external font, or runtime account.&lt;/p&gt;

&lt;p&gt;I pin OCaml 5.5.1, opam 2.6.0, Dune 3.24.2, Elm 0.19.2, Node 22.23.3, and their test packages. i keep the compilers and package caches outside the repository; i run the OCaml and Elm suites, compile the production UI, and smoke-test the local HTTP routes with &lt;code&gt;make test&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  I make the demo local
&lt;/h2&gt;

&lt;p&gt;I bundle the Yaba extract and metadata, compile the checked-in Elm source, and start a local server command. i run &lt;code&gt;make setup&lt;/code&gt; once to cache the pinned tools and packages; after setup, i run &lt;code&gt;make demo&lt;/code&gt; without an account or outbound request. i bind the service to loopback and use an ephemeral port by default.&lt;/p&gt;

&lt;p&gt;I keep the map quiet, mark baseline and changed paths differently, and cross the hypothetical closure with a rust-colored bar. i place the numbers in monospace and expose the same origin, destination, and segment choices through native controls. i omit a basemap, a scale bar, and any visual promise of real-world precision.&lt;/p&gt;

&lt;h2&gt;
  
  
  I leave the limits visible
&lt;/h2&gt;

&lt;p&gt;I do not model turn restrictions, every access rule, live traffic, travel time, road condition, pedestrian access, or emergency response. i do not infer population impact or identify a real closure from the graph. i keep those omissions in the architecture notes and the screen copy instead of hiding them in a footnote.&lt;/p&gt;

&lt;p&gt;I built CutLine as a portfolio project and a place to practice clear boundaries across a graph core, local data, a typed UI, and honest measurement language. i keep the source and the next small issues at &lt;a href="https://github.com/Mascottz/CutLine" rel="noopener noreferrer"&gt;https://github.com/Mascottz/CutLine&lt;/a&gt;; i welcome corrections to the implementation and to the limits i have drawn.&lt;/p&gt;

</description>
      <category>openstreetmap</category>
      <category>routing</category>
      <category>ocaml</category>
      <category>elm</category>
    </item>
    <item>
      <title>I built a circuit breaker for runaway cloud spend</title>
      <dc:creator>Mascottz</dc:creator>
      <pubDate>Sun, 04 Oct 2026 10:16:32 +0000</pubDate>
      <link>https://dev.to/mascottz/i-built-a-circuit-breaker-for-runaway-cloud-spend-ka6</link>
      <guid>https://dev.to/mascottz/i-built-a-circuit-breaker-for-runaway-cloud-spend-ka6</guid>
      <description>&lt;p&gt;A misconfigured loop once burned $34k in 8 days. not a typo, and not a big company; the invoice was the first anyone heard of it. i kept coming back to that story, because the uncomfortable part is not the loop. loops happen. the uncomfortable part is that every tool in the stack saw it coming, and every tool waited for the invoice to do something about it.&lt;/p&gt;

&lt;p&gt;Budget alerts fire after the money is gone. dashboards show the fire while it is still burning. i wanted the part that actually stops it.&lt;/p&gt;

&lt;p&gt;So i built killowatt. it is a circuit breaker for cloud spend; it watches usage in real time, checks it against spend policies, and trips before the bill gets away.&lt;/p&gt;

&lt;h2&gt;
  
  
  The shape of it
&lt;/h2&gt;

&lt;p&gt;Usage events flow in, one shape for any provider; an account, a service, a cost in integer cents, a timestamp. the core keeps a rolling ledger per account and checks three windows, in order; a burst window of ten minutes, the hour, and the day. whichever breaks first is the one that gets reported, and the moment one does, the breaker trips.&lt;/p&gt;

&lt;p&gt;Trip means enforcement. today that is two live adapters; one suspends the cloudflare worker behind the tripped service, one scales the aws auto scaling group behind it to zero. every order carries its own undo, and dry run is the default until switched. reversible first, lethal later.&lt;/p&gt;

&lt;h2&gt;
  
  
  Watch first, then arm
&lt;/h2&gt;

&lt;p&gt;The posture i am proudest of is watch mode. armed, the breaker stops the loop the moment a window breaks. watching, it sees everything and touches nothing; the account keeps spending and the watcher just counts what it would have saved.&lt;/p&gt;

&lt;p&gt;Run the same bill through both and the report writes itself;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;armed   spent $40.20, then stopped it; prevented $209.38
watch   touched nothing, saw everything; would have saved $209.94
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the right to arm the breaker starts in watch mode, and it is the report that earns the kill switch later.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the strange stack
&lt;/h2&gt;

&lt;p&gt;The pieces are deliberately polyglot, each language sitting where it is best;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the breaker core is rust; no gc pauses at the moment a resource gets cut&lt;/li&gt;
&lt;li&gt;the watchers are elixir; one tiny supervised process per account, and one account going sideways never touches the rest&lt;/li&gt;
&lt;li&gt;the policies are cue; spend rules as data, validated before they get near production&lt;/li&gt;
&lt;li&gt;the anomaly scorer is julia; median and mad against each service's own history, and it catches a runaway on the exact first bucket&lt;/li&gt;
&lt;li&gt;the dashboard is zero-dependency node; because it should be&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The polyglot part earns its keep for one reason; the core and the watcher share one policy registry, exported from cue, so the two sides cannot drift apart. one source of truth matters more than one language.&lt;/p&gt;

&lt;h2&gt;
  
  
  What actually works today
&lt;/h2&gt;

&lt;p&gt;The offline story runs from a fresh clone with nothing installed but the bootstrap script; the incident replayed armed and watching, the beam demo, the dashboard with a trip worth watching.&lt;/p&gt;

&lt;p&gt;The live path is real for cloudflare; the poller meters durable objects invocations straight from graphql, verified against a live account before i shipped it. the aws metering client is built and its signer is verified against aws's own test vectors; it wakes up the day a key shows up. the sample bill carries two planted incidents, a fast loop and a slow leak, and the scorer lights up both on their exact first bucket.&lt;/p&gt;

&lt;h2&gt;
  
  
  What i learned building this
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;money is integer cents everywhere; floats do not touch money&lt;/li&gt;
&lt;li&gt;watch mode is not a demo feature, it is the trust ramp; nobody arms what they cannot first watch&lt;/li&gt;
&lt;li&gt;dry run plus an audit log is the same ramp for enforcement; nobody enforces what they cannot first audit&lt;/li&gt;
&lt;li&gt;the $34k class of incident is not caught by better alerts, it is caught by a part of the system that is allowed to say no&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is young, the issues labeled good first issue are genuinely small, and the readme starts offline on purpose. if a cloud bill has ever landed as a surprise, come break it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Mascottz/Killowatt" rel="noopener noreferrer"&gt;https://github.com/Mascottz/Killowatt&lt;/a&gt;&lt;/p&gt;

</description>
      <category>devops</category>
      <category>cloud</category>
      <category>rust</category>
      <category>elixir</category>
    </item>
  </channel>
</rss>
