{"id":6196,"date":"2026-10-20T05:01:30","date_gmt":"2026-10-20T08:01:30","guid":{"rendered":"https:\/\/tucumandevelopers.com\/index.php\/2026\/10\/20\/can-you-bake-maven-into-a-neural-network\/"},"modified":"2026-10-20T05:01:30","modified_gmt":"2026-10-20T08:01:30","slug":"can-you-bake-maven-into-a-neural-network","status":"publish","type":"post","link":"https:\/\/tucumandevelopers.com\/index.php\/2026\/10\/20\/can-you-bake-maven-into-a-neural-network\/","title":{"rendered":"Can you bake Maven into a neural network?"},"content":{"rendered":"<div>\n<div>\n<section data-clarity-region=\"article\">\n<div>\n<h2 id=\"major-updates\">Can you bake Maven into a neural network?<\/h2>\n<p><strong>We tried, and it builds.<\/strong> We compiled the decision-making part of a Maven-style build tool into a fixed weight matrix and used it to build a real Java library. The output matches Apache Maven&#8217;s byte for byte. A clean build with tests took 1.49\u00d7 as long as the same logic written in Python (95% interval 1.4\u00d7 to 1.54\u00d7, 30 paired runs).<\/p>\n<figure><video autoplay=\"\" loop=\"\" muted=\"\" playsinline=\"\" poster=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2026\/10\/neural-maven-hero-poster.jpg\" preload=\"metadata\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2026\/10\/neural-maven-hero.mp4\"><\/video><figcaption>The network\u2019s weight table, one bar per row. Bar height is how often a row ran during one ZXing build; the bright point replays real stretches of that build, one step at a time.<\/figcaption><\/figure>\n<p>Every Java developer has watched Maven think. It resolves, compiles, tests and packages. Most of that time belongs to javac and JUnit, but threaded through it is a small, fussy piece of logic that decides what happens next. Which version of a library wins when two modules disagree. Which files go to the compiler, and with which flags. Whether a failing test stops the build.<\/p>\n<p>We wanted to know if that piece could live inside a neural network. Not a model trained to guess what Maven usually does next: that kind of model is right most of the time, and a build tool that is right most of the time is broken. We wanted the decision logic itself, compiled into weights, so the network gets the answer exactly right or refuses to answer.<\/p>\n<p>The video at the top of this post is that network. Each of its 26,626 bars is one row of its weight table (model <code>nmvn-exact-v2<\/code>, explained in the section on making it cheaper), bar height is how often that row ran during one ZXing build, and the bright point replays real stretches of that build, one step at a time. Everything that decides how the build goes is in there.<\/p>\n<h2 id=\"how\">From a program to a weight table<\/h2>\n<p>The trick comes from <a href=\"https:\/\/github.com\/chenglou\/handwired\" target=\"_blank\" rel=\"noopener\">Handwired<\/a>: you can write a program and then set a network\u2019s weights so the network <em>is<\/em> that program. We wrote a small Maven-compatible build controller in a restricted subset of Python and compiled it into a table of 29,625 \u00d7 7 numbers, plus 7,382 cells of constants (that\u2019s the first version, v1; a later section shrinks the table to the 26,626 rows you see above). No training, no gradient descent: zero optimizer steps.<\/p>\n<p>Running it is a loop. Each step, the network looks up one row of its table with two matrix multiplications, does the arithmetic that row encodes on a small register file, and writes the result back to memory. The network can\u2019t open files or start javac. When it needs to, it writes a request into a fixed slot in its memory, and a thin bridge carries the request out and writes back the raw answer. The bridge never decides anything. Every choice comes out of the weights.<\/p>\n<p role=\"img\" aria-label=\"The network reads raw project files, runs one instruction per step, and emits requests that a bridge carries out; raw results flow back into the network's memory.\">\n<p>The test subject was <a href=\"https:\/\/github.com\/zxing\/zxing\/tree\/zxing-3.5.3\" target=\"_blank\" rel=\"noopener\">ZXing 3.5.3<\/a>, the barcode library: its parent project and the <code>core<\/code> and <code>javase<\/code> modules, built with <code>clean package<\/code> and the tests on.<\/p>\n<h2 id=\"worked\">Does it actually build?<\/h2>\n<p>Yes. The JARs it produced match Apache Maven\u2019s byte for byte, built inside a sandbox where Maven can\u2019t run, the network is off, and neither the Python version of the logic nor Maven\u2019s own outputs can be read. All 549 upstream tests ran and passed, and the freshly built JARs encoded and decoded QR codes correctly in 27 of 27 checks.<\/p>\n<div>\n<p><strong>519<\/strong><span>hand-written build cases passed, each checked against real Maven<\/span><\/p>\n<p><strong>10,000<\/strong><span>generated project cases passed<\/span><\/p>\n<p><strong>33<\/strong><span>other small projects built correctly with the same weights<\/span><\/p>\n<p><strong>4,796,191<\/strong><span>network steps for one full ZXing build<\/span><\/p>\n<\/div>\n<p>Two checks convinced us the work really happens in the weights. The CPU and GPU versions of the network made exactly the same 1,731 requests, in the same order, for a full build. And when we deleted or corrupted the weight file, no build happened at all.<\/p>\n<figure><figcaption>A QR code written by the freshly built ZXing JARs and read back by them.<\/figcaption><\/figure>\n<h2 id=\"watch\">Watch it build<\/h2>\n<p>Left: the controller as ordinary Python. Right: the same controller as a neural network. Both build ZXing for real, one after the other on the same Mac, played back at real speed.<\/p>\n<figure><video controls=\"\" muted=\"\" playsinline=\"\" poster=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2026\/10\/neural-maven-poster.jpg\" preload=\"metadata\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2026\/10\/neural-maven-side-by-side.mp4\"><\/video><figcaption>One recorded build on each side, played back in real time. Grey on the timelines is time spent in javac, JUnit, bnd and zip.<\/figcaption><\/figure>\n<h2 id=\"speed\">The bill<\/h2>\n<p>It\u2019s slower, in every scenario we measured. Python runs the controller\u2019s logic directly; the network spends a full round of matrix arithmetic on every tiny instruction, and one ZXing build costs it 4,796,191 of them.<\/p>\n<figure>\n<table>\n<thead>\n<tr>\n<th>What was timed<\/th>\n<th>Classic Python<\/th>\n<th>Neural, CPU<\/th>\n<th>Neural, GPU (Metal)<\/th>\n<th>Apache Maven 3.9.11<\/th>\n<th>Neural CPU \/ Python<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Decisions only (no Java work)<\/td>\n<td>146.54 ms<\/td>\n<td>4.15 s<\/td>\n<td>27.97 s<\/td>\n<td>\u2013<\/td>\n<td><strong>28.3\u00d7<\/strong><\/td>\n<\/tr>\n<tr>\n<td>Cold start to first decisions<\/td>\n<td>385.94 ms<\/td>\n<td>4.80 s<\/td>\n<td>28.25 s<\/td>\n<td>\u2013<\/td>\n<td><strong>12.4\u00d7<\/strong><\/td>\n<\/tr>\n<tr>\n<td>Clean build with tests<\/td>\n<td>15.52 s<\/td>\n<td>23.12 s<\/td>\n<td>70.11 s<\/td>\n<td>15.29 s<\/td>\n<td><strong>1.49\u00d7<\/strong><\/td>\n<\/tr>\n<tr>\n<td>Build that stops at a compile error<\/td>\n<td>1.74 s<\/td>\n<td>4.41 s<\/td>\n<td>22.19 s<\/td>\n<td>2.81 s<\/td>\n<td><strong>2.53\u00d7<\/strong><\/td>\n<\/tr>\n<\/tbody>\n<\/table><figcaption>Median wall time (lower is better). Last column: neural CPU time divided by Python time.<\/figcaption><\/figure>\n<figure><figcaption>Clean build with tests, median seconds. Bar = median; whisker = p25 to p75.<\/figcaption><\/figure>\n<p>On decisions alone the network is far behind. In a whole build the gap shrinks to about one and a half times, because most of the time goes to javac and JUnit and both versions use the same ones. Running the network on the GPU made things worse, not better. A program that executes one instruction after another gives a GPU nothing to do in parallel.<\/p>\n<figure>\n<blockquote>\n<p>So this is not a faster build tool. It\u2019s a build tool you can hold as a tensor.<\/p>\n<\/blockquote>\n<\/figure>\n<h2 id=\"v2\">Making it cheaper without touching the network<\/h2>\n<p>The time is roughly <em>steps \u00d7 cost per step<\/em>, so we counted where the steps go. We replayed a full ZXing build in an instruction-level simulator and tallied every instruction it executed. Of v1\u2019s 4,796,191 steps, 652,773 (14%) just copied a value from one register to another, and 553,333 more (12%) loaded a constant or jumped back to the top of a loop. That\u2019s compiler glue, not build logic.<\/p>\n<p>So we left the network alone and fixed the compiler. Results now land directly in the register that needs them, constants ride inside the instruction that uses them, conditions compile straight to branches, and loops test at the bottom instead of jumping back to the top. The machine, its step graph and the GPU kernel are unchanged. Only the table of numbers is different, and smaller.<\/p>\n<div>\n<p><strong>23%<\/strong><span>fewer network steps for a full ZXing build (4,796,191 \u2192 3,676,728)<\/span><\/p>\n<p><strong>10%<\/strong><span>fewer rows in the weight table (29,625 \u2192 26,626)<\/span><\/p>\n<p><strong>identical<\/strong><span>decisions: fed v1\u2019s recorded inputs, v2 makes the same 1,731 requests in the same order, on CPU and GPU<\/span><\/p>\n<p><strong>2 of 2<\/strong><span>correctness gates re-passed by v2 (same suites, sandboxed build, byte-identical JARs)<\/span><\/p>\n<\/div>\n<figure><figcaption>Every step of one full ZXing build, by instruction class (instruction-set simulator replaying the recorded build; the action sequence is identical for both models).<\/figcaption><\/figure>\n<figure>\n<table>\n<thead>\n<tr>\n<th>What was timed<\/th>\n<th>Neural CPU, v1<\/th>\n<th>Neural CPU, v2<\/th>\n<th>Python (v2 run)<\/th>\n<th>v1 \/ Python<\/th>\n<th>v2 \/ Python (95% CI)<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Decisions only (no Java work)<\/td>\n<td>4.15 s<\/td>\n<td>3.40 s<\/td>\n<td>140.81 ms<\/td>\n<td>28.3\u00d7<\/td>\n<td><strong>24.2\u00d7<\/strong> (23.6\u00d7 to 25.2\u00d7)<\/td>\n<\/tr>\n<tr>\n<td>Cold start to first decisions<\/td>\n<td>4.80 s<\/td>\n<td>4.14 s<\/td>\n<td>402.38 ms<\/td>\n<td>12.4\u00d7<\/td>\n<td><strong>10.3\u00d7<\/strong> (10.1\u00d7 to 10.7\u00d7)<\/td>\n<\/tr>\n<tr>\n<td>Clean build with tests<\/td>\n<td>23.12 s<\/td>\n<td>21.09 s<\/td>\n<td>14.83 s<\/td>\n<td>1.49\u00d7<\/td>\n<td><strong>1.42\u00d7<\/strong> (1.40\u00d7 to 1.43\u00d7)<\/td>\n<\/tr>\n<tr>\n<td>Build that stops at a compile error<\/td>\n<td>4.41 s<\/td>\n<td>3.70 s<\/td>\n<td>1.78 s<\/td>\n<td>2.53\u00d7<\/td>\n<td><strong>2.08\u00d7<\/strong> (2.05\u00d7 to 2.11\u00d7)<\/td>\n<\/tr>\n<\/tbody>\n<\/table><figcaption>Neural CPU, v1 vs v2 (median wall time). Ratios are neural time \/ Python time from paired runs in the same session; v1 from nmvn-bench-v0, v2 from the follow-up protocol.<\/figcaption><\/figure>\n<p>The GPU gains more, because it pays almost purely per step: decisions only took 27.97 s with v1 and 21.61 s with v2 (23% less), close to the cut in steps. It is still the slowest engine.<\/p>\n<p>We re-ran the whole correctness chain on the new weights: every test suite, the sandboxed build that has to produce byte-identical JARs, the negative controls and the CPU\/GPU replay. The cut is real but modest where it counts. Java tooling still owns most of a full build, so trimming the network\u2019s share moves the end-to-end number less than the step count suggests.<\/p>\n<h2 id=\"maze\">It isn\u2019t only Maven<\/h2>\n<p>To check the compiler isn\u2019t secretly tuned to one program, we gave it something unrelated: a maze solver (breadth-first search, <code>programs\/maze\/maze_nml.py<\/code>). It compiled to 279 rows of weights. A small app starts the classic and the neural version at the same moment, as separate processes, and draws each cell as soon as that program reports it.<\/p>\n<figure><video controls=\"\" muted=\"\" playsinline=\"\" poster=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2026\/10\/neural-maven-maze-mid.png\" preload=\"metadata\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2026\/10\/neural-maven-maze.mp4\"><\/video><figcaption>Recording of the app window, which saves its own frames as it runs;, neural side on CPU. The <a href=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2026\/10\/neural-maven-maze-metal.mp4\">GPU version<\/a> takes longer.<\/figcaption><\/figure>\n<p>On 3 different 171\u00d7121 mazes, plain Python, the Python debug shim, the neural CPU run and the neural GPU run produced identical event sequences: every visited cell, in the same order, with the same distances. The first maze took 2,572,288 network steps. Neural on CPU took 161\u00d7 to 168\u00d7 as long as plain Python, and on GPU 791\u00d7 to 812\u00d7 (each program\u2019s own timer, one run per maze, so treat these as rough).<\/p>\n<h2 id=\"useful\">So it\u2019s slower. Is it even useful?<\/h2>\n<p>Fair question. We asked it too. If you want a faster build, no: keep using Maven. And a bigger GPU won\u2019t rescue it, because the network runs one instruction at a time and nothing in a build controller can be spread across thousands of cores.<\/p>\n<p>Speed was never the interesting part, though. What we ended up with is a neural network where every weight has a known meaning, and that is rare. Here\u2019s where we think it\u2019s worth something, most convinced first.<\/p>\n<h3>An answer key for people who take networks apart<\/h3>\n<p>Interpretability research tries to work out what a network does from its weights alone. The hard part is grading the answer, because for a trained model nobody knows the truth. This network ships with the truth. Apart from a seven-row start-up stub, every one of its 26,626 rows belongs to a known function among the controller\u2019s 249, and we know what each of those functions does. So we can point at the rows of <code>do_surefire<\/code>, the part that runs the tests and decides whether a failure stops the build. If a tool claims to have found \u201cthe dependency-resolution circuit\u201d, you can check it. Hand-built test networks tend to be small toys. This one does a real job on a real codebase, and we think that\u2019s its best use.<\/p>\n<h3>Exact parts inside models that guess<\/h3>\n<p>A model that picks the right library version 99% of the time is wrong once every hundred builds. Compiled weights are a way to put an exact subroutine in the same form as a learned model: same tensors, same runtime, same hardware. To be clear, we haven\u2019t joined one to a trained model. That\u2019s the next experiment, not a result. It\u2019s the direction we find most exciting all the same.<\/p>\n<h3>Decision logic you can hash<\/h3>\n<p>The whole policy is one file of numbers. Move it from CPU to GPU and it makes the same 1,731 decisions in the same order; feed it a recorded build and it replays it exactly. That\u2019s how we compared v1 and v2 decision by decision in the section on making it cheaper. You can diff it, sign it, and show that a given build came from it. In fairness, ordinary code with a lockfile gets you most of the way. What the tensor version adds is that the thing running the policy is the same fixed loop of lookups and arithmetic for any program you compile into it, and a smaller runtime is a smaller thing to trust.<\/p>\n<p>One more thing in its favour: the cost shrinks when the decisions are a thin layer over heavy tools. In a full ZXing build, javac and JUnit do most of the work, which is why the network costs about one and a half times the Python time there instead of twenty-odd times. Glue logic around expensive steps pays that same modest price.<\/p>\n<div>\n<div>\n<p>Wrong tool for<\/p>\n<ul>\n<li>Faster builds, or anything where milliseconds matter<\/li>\n<li>Throwing more GPU at the problem<\/li>\n<li>Replacing Maven<\/li>\n<\/ul>\n<\/div>\n<div>\n<p>Worth a look for<\/p>\n<ul>\n<li>Testing interpretability tools against a network with a known answer<\/li>\n<li>Exact subroutines living next to learned models<\/li>\n<li>Decision logic you can hash, replay and compare<\/li>\n<\/ul>\n<\/div><\/div>\n<h2 id=\"limits\">What we\u2019re not claiming<\/h2>\n<ul>\n<li>This isn\u2019t all of Maven. It handles one build (<code>clean package<\/code>) of one real project, with Enforcer, Checkstyle, Javadoc and source JARs skipped. Signing, deployment and everything that only runs in <code>verify<\/code> are out of scope. The plugins aren\u2019t neural: javac, JUnit, bnd and zip run as ordinary programs.<\/li>\n<li>This isn\u2019t machine learning. The weights were compiled from a program, not learned. We didn\u2019t try a trained version, and we\u2019d expect one to fail on projects it hadn\u2019t seen.<\/li>\n<\/ul>\n<h2 id=\"more\">Check our work<\/h2>\n<p>The weights, the runtime and the full results are on Hugging Face at <a href=\"https:\/\/huggingface.co\/shirman\/neural-maven\" target=\"_blank\" rel=\"noopener\">shirman\/neural-maven<\/a>: the method, all eleven scenarios, memory use, the environment and evidence hashes, plus the raw measurements, both protocols, the analysis code and checksums. That\u2019s enough to recompute every number in this post.<\/p>\n<\/p><\/div>\n<p> <a href=\"#\"><\/a> <\/section>\n<div>\n<p><h2>Discover more<\/h2>\n<\/p><\/div>\n<\/p><\/div>\n<\/div>\n<\/div>\n<\/div>\n<p>Fuente: <a href=\"https:\/\/blog.jetbrains.com\/ai\/2026\/10\/can-you-bake-maven-into-a-neural-network\/\">Art\u00edculo original<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Can you bake Maven into a neural network? We tried, and it builds. We compiled the decision-making part of a Maven-style build tool into a fixed weight matrix and used it to build a real Java library. The output matches Apache Maven&#8217;s byte for byte. A clean build with tests took 1.49\u00d7 as long as [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":6195,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"webixso_pending_account_ids":""},"categories":[46],"tags":[],"class_list":["post-6196","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-jetbrain"],"jetpack_publicize_connections":[],"_links":{"self":[{"href":"https:\/\/tucumandevelopers.com\/index.php\/wp-json\/wp\/v2\/posts\/6196","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/tucumandevelopers.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/tucumandevelopers.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/tucumandevelopers.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/tucumandevelopers.com\/index.php\/wp-json\/wp\/v2\/comments?post=6196"}],"version-history":[{"count":0,"href":"https:\/\/tucumandevelopers.com\/index.php\/wp-json\/wp\/v2\/posts\/6196\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/tucumandevelopers.com\/index.php\/wp-json\/wp\/v2\/media\/6195"}],"wp:attachment":[{"href":"https:\/\/tucumandevelopers.com\/index.php\/wp-json\/wp\/v2\/media?parent=6196"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/tucumandevelopers.com\/index.php\/wp-json\/wp\/v2\/categories?post=6196"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/tucumandevelopers.com\/index.php\/wp-json\/wp\/v2\/tags?post=6196"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}