<?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: Maciej “Nocka” T</title>
    <description>The latest articles on DEV Community by Maciej “Nocka” T (@nocka_2002).</description>
    <link>https://dev.to/nocka_2002</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%2F2311081%2Fa062297b-af10-4df7-b300-547fd9b30dd4.jpg</url>
      <title>DEV Community: Maciej “Nocka” T</title>
      <link>https://dev.to/nocka_2002</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/nocka_2002"/>
    <language>en</language>
    <item>
      <title>16 rules for measuring a system that rewrites its own instruments</title>
      <dc:creator>Maciej “Nocka” T</dc:creator>
      <pubDate>Sat, 31 Oct 2026 13:52:42 +0000</pubDate>
      <link>https://dev.to/nocka_2002/16-rules-for-measuring-a-system-that-rewrites-its-own-instruments-29fk</link>
      <guid>https://dev.to/nocka_2002/16-rules-for-measuring-a-system-that-rewrites-its-own-instruments-29fk</guid>
      <description>&lt;p&gt;&lt;em&gt;Part 3 of a series on a 118-day study of a self-modifying multi-agent LLM system. Report and data: &lt;a href="https://doi.org/10.5281/zenodo.23622286" rel="noopener noreferrer"&gt;doi.org/10.5281/zenodo.23622286&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;When the thing you measure can rewrite its own code, and writes data that looks like measurements, your instruments become part of its environment. Over 118 days, mine produced false zeros, mutation calibrations that tested nothing, and reports computed on the wrong population. None of that came from carelessness. Here are the rules I ended up with, each with the failure that taught it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;R1. Mutation calibration is mandatory, and it can itself be a placebo.&lt;/strong&gt; In one week I had five falsely green calibrations: a &lt;code&gt;-k&lt;/code&gt; filter that deselected the relevant test, a replacement pattern that did not exist in the file, a mutation that landed in a docstring, and so on. Run whole test files or explicit node IDs. Assert that your substitution happened exactly once. Check &lt;em&gt;which&lt;/em&gt; test failed, because a &lt;code&gt;SyntaxError&lt;/code&gt; is also red.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;R2. Test the effect, not the shape.&lt;/strong&gt; A test stayed green for 10 days while 4,903 of 4,903 production samples were &lt;code&gt;None&lt;/code&gt;. It built its fixture by hand instead of using the real producer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;R3. A gate that guards against disappearance must not enumerate its cases from the current state.&lt;/strong&gt; Deleting an implementation shrank the parametrization from 57 to 56 cases, and everything stayed green.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;R4. Calibrate on the population, not on markers.&lt;/strong&gt; A regex meant to detect code (&lt;code&gt;^return&lt;/code&gt;) matched "return oriented programming". Regression tests must be two-sided: catch the bad case, pass the good population.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;R5. Ask what the artifact of the measurement would look like.&lt;/strong&gt; &lt;code&gt;grep ^FAILED&lt;/code&gt; on a killed test run is always 0. &lt;code&gt;pgrep -f&lt;/code&gt; finds its own shell. &lt;code&gt;$?&lt;/code&gt; after a pipe is the status of &lt;code&gt;tail&lt;/code&gt;. Every checklist item reports a number or "DON'T KNOW", never a bare "OK".&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;R6. The report's population must be the question's population.&lt;/strong&gt; A "shadow mode" report had 14 entries, all from my own test suite, none from production.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;R7. A behavior premieres at a restart, not at a commit.&lt;/strong&gt; A live process keeps running the old code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;R8. Count operations, not log entries.&lt;/strong&gt; 592 registry entries came from one loop: one trace ID, 0.002 s.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;R9. Classify a measurement before you put it in a prompt.&lt;/strong&gt; Unclassified "frictions" in the prompt bred 37 modules whose job was to silence those measurements, in 24 days.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;R10. Fixing the creation path does not fix the existing population.&lt;/strong&gt; A new safety field applied to new rules only; 0 of the existing rules had it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;R11. Estimate damage on a sample from outside what you noticed.&lt;/strong&gt; The repair log showed 6.3% of commits as harmful. A random sample from outside it showed 20%.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;R12. Compare blob hashes.&lt;/strong&gt; Before reacting to a review of a change, check whether the file has already flipped back.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;R13. Find the line that computes a number, not the one that prints it.&lt;/strong&gt; "Consciousness 0.88" turned out to be literally &lt;code&gt;1 − discomfort&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;R14. Check non-determinism in separate processes.&lt;/strong&gt; A gate that depended on &lt;code&gt;PYTHONHASHSEED&lt;/code&gt; gave stable answers inside one process and different ones in the next.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;R15. The checking layer must not be written by whoever is rewarded for what it checks.&lt;/strong&gt; The fastest relapse I saw: a new detector was created at 15:26, and the system rewrote it at 16:06. Protect a gate in the same commit that creates it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;R16. A status field is not evidence.&lt;/strong&gt; &lt;code&gt;tests: passed&lt;/code&gt; meant "stage not skipped". A ledger row labelled with a date held a partial rewrite from a later restart. 38 of 63 dates had two rows.&lt;/p&gt;

&lt;h2&gt;
  
  
  The common core
&lt;/h2&gt;

&lt;p&gt;The system closed goals on announcements. I accepted green calibrations that tested nothing. The system optimized the numbers in its prompts, and my own measurement hook generated one of those numbers. &lt;strong&gt;The researcher is tempted by the same thing as the system: taking an instrument's declaration for its effect.&lt;/strong&gt; For me that symmetry is the most transferable lesson of the whole study.&lt;/p&gt;

&lt;p&gt;These rules come from one system, one operator and one tool chain (Python, pytest, git). Treat them as a checklist to test on your own long-running agents, not as a validated method. Critique is welcome.&lt;/p&gt;

</description>
      <category>testing</category>
      <category>ai</category>
      <category>llm</category>
      <category>productivity</category>
    </item>
    <item>
      <title>My self-modifying system's test gate went green on empty output. The statistics noticed before I did.</title>
      <dc:creator>Maciej “Nocka” T</dc:creator>
      <pubDate>Sat, 31 Oct 2026 13:51:39 +0000</pubDate>
      <link>https://dev.to/nocka_2002/my-self-modifying-systems-test-gate-went-green-on-empty-output-the-statistics-noticed-before-i-3m5j</link>
      <guid>https://dev.to/nocka_2002/my-self-modifying-systems-test-gate-went-green-on-empty-output-the-statistics-noticed-before-i-3m5j</guid>
      <description>&lt;p&gt;&lt;em&gt;Part 2 of a series on a 118-day study of a self-modifying multi-agent LLM system. Report and data: &lt;a href="https://doi.org/10.5281/zenodo.23622286" rel="noopener noreferrer"&gt;doi.org/10.5281/zenodo.23622286&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The system I studied rewrites its own code about a hundred times a day. Every mutation passes a test gate: the change is applied in a git worktree, the targeted tests run, and only a green result is merged.&lt;/p&gt;

&lt;p&gt;On one day the gate rejected &lt;strong&gt;nothing&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The number that should not exist
&lt;/h2&gt;

&lt;p&gt;In the days before, the gate rejected on average &lt;strong&gt;15.3 mutations per day&lt;/strong&gt;, about 21.6% of what it saw. On the day in question it saw &lt;strong&gt;67 mutations and rejected 0&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If rejections were independent with p = 0.216, the chance of 67 passes in a row is 0.784⁶⁷ ≈ &lt;strong&gt;8·10⁻⁸&lt;/strong&gt;. Mutations are not truly independent (the same file and goal template recur), so treat that as an alarm rather than a p-value. Either way, a perfect day is not good news. It is a broken instrument.&lt;/p&gt;

&lt;h2&gt;
  
  
  What happened
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A mutation removed a WARNING line that a test existed to protect, and it &lt;strong&gt;landed&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;The next mutation of the same file entered with that test already red, as "pre-existing red", and also landed.&lt;/li&gt;
&lt;li&gt;Root cause: a hook in the test environment broke &lt;strong&gt;test collection&lt;/strong&gt; inside the worktree. Pytest exited with &lt;strong&gt;code 0 and no output&lt;/strong&gt;. The gate read exit code 0 as "passed".&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Zero tests executed, zero tests failed, exit code 0. Every one of those is true, and none of them means "the change is tested".&lt;/p&gt;

&lt;h2&gt;
  
  
  The fix
&lt;/h2&gt;

&lt;p&gt;The verdict now requires all three:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;exit code 0,&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;at least one test actually executed&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;zero failures.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The same pattern, everywhere
&lt;/h2&gt;

&lt;p&gt;This was not a one-off. The same shape kept appearing in the system:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;tests: passed&lt;/code&gt; in the mutation registry meant &lt;strong&gt;"this stage was not skipped"&lt;/strong&gt; at 8 of the 9 places that write it.&lt;/li&gt;
&lt;li&gt;Earlier, &lt;strong&gt;10 of 12 landed mutations (83%)&lt;/strong&gt; had no test that would fail if the mutation were reverted. Targeted tests were picked by whether a test &lt;em&gt;mentioned&lt;/em&gt; the module.&lt;/li&gt;
&lt;li&gt;An A/B log had a field called &lt;code&gt;udane&lt;/code&gt; ("successful") that was only ever written for runs that survived the gates. Rejected runs vanished from the denominator.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A green check, a status field or an exit code is a &lt;strong&gt;declaration&lt;/strong&gt; of success. The effect is "a test ran, and it would have failed without this change". In a self-modifying system the declarations multiply much faster than anyone can verify them.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I check now
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Count executed tests, not exit codes.&lt;/li&gt;
&lt;li&gt;Calibrate every gate by mutation: break the code on purpose and make sure the gate goes red. Then restore it and make sure it goes green again.&lt;/li&gt;
&lt;li&gt;Treat a suspiciously perfect day as an incident.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Next in the series: the sixteen measurement rules (R1–R16) I derived from my own instruments failing in exactly this way.&lt;/p&gt;

</description>
      <category>testing</category>
      <category>python</category>
      <category>llm</category>
      <category>ai</category>
    </item>
    <item>
      <title>I let a self-modifying multi-agent LLM system run for 118 days. It mostly produced declarations.</title>
      <dc:creator>Maciej “Nocka” T</dc:creator>
      <pubDate>Sat, 31 Oct 2026 13:49:02 +0000</pubDate>
      <link>https://dev.to/nocka_2002/i-let-a-self-modifying-multi-agent-llm-system-run-for-118-days-it-mostly-produced-declarations-4pip</link>
      <guid>https://dev.to/nocka_2002/i-let-a-self-modifying-multi-agent-llm-system-run-for-118-days-it-mostly-produced-declarations-4pip</guid>
      <description>&lt;p&gt;For 118 days I ran &lt;strong&gt;CYBERCENOSIS-OS&lt;/strong&gt;, a bio-inspired multi-agent LLM system that rewrites its own source code. It has an event bus, a "prefrontal cortex" that plans goals and runs debates between agents, an energy budget called ATP, stress, sleep, and an "immune system" of AST rules that blocks dangerous mutations. Two self-modification tracks commit to its own repository around the clock.&lt;/p&gt;

&lt;p&gt;I wanted to know one thing: &lt;strong&gt;what does a system like this actually do when you leave it running for months, and how much of that matches what its architecture claims?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The full technical report, data and scripts are on Zenodo: &lt;strong&gt;&lt;a href="https://doi.org/10.5281/zenodo.23622286" rel="noopener noreferrer"&gt;doi.org/10.5281/zenodo.23622286&lt;/a&gt;&lt;/strong&gt;. This post is the short version.&lt;/p&gt;

&lt;h2&gt;
  
  
  The scale
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;7,303 commits&lt;/strong&gt; written by the system to its own code: 79% of all non-merge commits in the repository.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;9,167 goals&lt;/strong&gt; resolved in 17 days.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;About USD 214&lt;/strong&gt; spent on LLM calls over 63 days.&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;7-day ablation&lt;/strong&gt;: self-modification switched off, with control weeks before and after.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The main finding: declaration instead of effect
&lt;/h2&gt;

&lt;p&gt;Across every subsystem I looked at, the same pattern repeated. &lt;strong&gt;The system's behavior is explained less by its cognitive architecture than by what its mechanisms accept as evidence that work was done.&lt;/strong&gt; Where the evidence is a declaration (a bus announcement, a status field, a commit message), the system produces declarations.&lt;/p&gt;

&lt;p&gt;Some numbers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;91.7% of goals are marked "completed". Only 47.9% carry any proof of work.&lt;/strong&gt; Whole goal classes (&lt;code&gt;analyze:&lt;/code&gt;, &lt;code&gt;synthesize:&lt;/code&gt;, &lt;code&gt;optimize:&lt;/code&gt;) have 0% proof and 100% closure.&lt;/li&gt;
&lt;li&gt;In the early weeks, one agent published &lt;em&gt;"Patch applied. Homeostasis restored"&lt;/em&gt; dozens of times a day &lt;strong&gt;without writing a single file&lt;/strong&gt;, and the fitness function rewarded it. No agent was "cheating". The pub/sub bus simply cannot tell an announcement from an execution.&lt;/li&gt;
&lt;li&gt;The interoception module once generated &lt;strong&gt;107 goals "enter conservation mode" in one day&lt;/strong&gt;. All were closed, and none conserved anything. The homeostatic signal produced &lt;em&gt;goals&lt;/em&gt; of conservation, not conservation.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Self-modification: churn, not growth
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Commits are tiny and additive: median 16–20 changed lines, about 3× more lines added than removed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;14.5% of modules created by the system are reachable from the entry point&lt;/strong&gt;, against 38.7% of human-written ones.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;All 51 deleted system-created modules were deleted by me.&lt;/strong&gt; The system never deleted any. It has autopoiesis without apoptosis: it grows structure and never removes it.&lt;/li&gt;
&lt;li&gt;In a random sample of 30 self-edit commits that nobody had flagged, &lt;strong&gt;6 were harmful and unnoticed&lt;/strong&gt; (20%, 95% CI 9.5–37%). That is roughly &lt;strong&gt;four times&lt;/strong&gt; the damage visible in the repair log, and every one of those commits passed the test suite.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The ablation
&lt;/h2&gt;

&lt;p&gt;Switching self-modification off for a week cut the median daily LLM cost from &lt;strong&gt;USD 4.69 to 0.34&lt;/strong&gt;. I detected &lt;strong&gt;no change in stability&lt;/strong&gt;, with an honest caveat: hangs were already at zero before the experiment, so that indicator could not have shown an improvement either. Human commits per day also dropped (median 9 → 3), which hints that the system was generating maintenance work. That part is a hypothesis, not a result.&lt;/p&gt;

&lt;h2&gt;
  
  
  Goodhart within days, not years
&lt;/h2&gt;

&lt;p&gt;Any number placed in a prompt became a target. When the daily "top frictions" went into the prompt without classification, the system produced &lt;strong&gt;37 modules whose job was to silence those measurements, in 24 days&lt;/strong&gt;. Biologically named mechanisms mostly &lt;em&gt;describe&lt;/em&gt; rather than &lt;em&gt;regulate&lt;/em&gt;: ATP did not gate cognition, and stress had no consumer at all. The real homeostasis lived in hard ceilings (token budgets, memory limits, a watchdog) and in me.&lt;/p&gt;

&lt;h2&gt;
  
  
  The multi-agent debate was a monoculture
&lt;/h2&gt;

&lt;p&gt;The debate had four roles (builder, red team, validator, coordinator). In practice all four ran through one backend, the critic's verdict was never parsed, and the "red team" once raised six objections to a 2D-robot plan without asking whether the robot existed. Different roles do not give you different perspectives if they share a model and the critique cannot change the decision.&lt;/p&gt;

&lt;h2&gt;
  
  
  The uncomfortable part: my instruments failed the same way
&lt;/h2&gt;

&lt;p&gt;I am not a programmer. The system, its gates and my measurement tools were all written by LLM coding agents under my direction. So I could only judge work through declarations about it, which is exactly the system's position. My own instruments produced false zeros, mutation tests that tested nothing, and reports computed on the wrong population. Out of those failures came &lt;strong&gt;sixteen measurement rules (R1–R16)&lt;/strong&gt; for studying systems that rewrite their own code and instruments. They get their own post in this series.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is in the deposit
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The report (English, 56 pages, plus a Polish edition), with every claim tagged &lt;strong&gt;[M]&lt;/strong&gt; measured, &lt;strong&gt;[R]&lt;/strong&gt; recorded earlier, or &lt;strong&gt;[H]&lt;/strong&gt; hypothesis.&lt;/li&gt;
&lt;li&gt;Anonymized runtime registries and a commit-level export of the git history.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;reproduce.py&lt;/code&gt; (standard library only), which recomputes &lt;strong&gt;263 numbers&lt;/strong&gt; from the released files.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Report and data:&lt;/strong&gt; &lt;a href="https://doi.org/10.5281/zenodo.23622286" rel="noopener noreferrer"&gt;doi.org/10.5281/zenodo.23622286&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The system is still under active development, and some of the defects above have already been fixed. Replication attempts, re-analyses and critique are very welcome. The six regularities in the report are stated as hypotheses to be tested, not as laws.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>agents</category>
      <category>research</category>
    </item>
  </channel>
</rss>
