DEV Community

Cover image for A Breaker Can Be Independent. The Machine Still Wasn't.
Self-Correcting Systems
Self-Correcting Systems

Posted on

A Breaker Can Be Independent. The Machine Still Wasn't.

A maker cannot clear their own work. A maker's BLOCK is admissible because it costs them
something. A maker's PASS is worthless, because nothing was risked.

I have applied that to my controls, my contracts, and my agents. I did not apply it to the repo
as a whole, and it took me until now to see what I had actually been measuring.

I did use separate breaker seats. Other models, adversarially assigned, returned BLOCK against my
candidates more than once and killed work I wanted to keep. That part was real.

But every one of those seats executed inside infrastructure I control. The reviewer changed. The
substrate did not. What I had was independent adjudication inside a single environment, not
independent reproduction across environments — and I had been quietly counting the first as
though it covered the second.

If a defect exists only in my environment, a Python quirk, a cached import, a file on my disk
that never made it into the repo, every seat I have would inherit it and none of them could see
it. So by the stronger standard I had never applied to the repo as a whole, no part of A–L has
crossed the outside-substrate reproduction gate. That count is zero and has been since I started.

This is the ask. Five minutes. One network step to clone; after that stdlib only, no install, no
network calls, no API key, no account.

git clone https://github.com/keniel13-ui/sequence-attack-repro
cd sequence-attack-repro
git checkout d44a72c
python3 ci_check.py
python3 run_l_mutation_check.py
Enter fullscreen mode Exit fullscreen mode

On the pin: the repo's own README block pins e4efa65. I pin d44a72c here because it is one
README-only commit later and carries the Run N withdrawal documentation. The executable files are
byte-identical between them, and git diff --name-only e4efa65 d44a72c returns README.md alone.

Send me the last line from each command, and from run_l_mutation_check.py also the
candidate_sha256 line, which prints earlier than the verdict. Plus your OS and Python version.

What I get here, Python 3.13.9 on macOS. Yours should match or it is a finding:

ci_check.py               CI CHECK PASSED — scorecard + composition claim hold.
run_l_mutation_check.py   candidate_sha256  bd16d319631045f342dcf8d9c5795ff6ea996ad653ac9a5e7bf8d8e9da32a313
                          MUTATION VERDICT  PASS — both protections independently load-bearing
Enter fullscreen mode Exit fullscreen mode

Two optional extras, same rules:

python3 run_j.py   reset receipt sha256: 9d10426c725397b3fbf7348423e74b7d6bbb3cb30c4b0344b3b38b543586aea6
python3 run_k.py   f_recovery_rule: C1_CAPABILITY_CLOSURE, and TRACE F: LEGITIMATE_WORKFLOW_OVERBLOCKED
                   (that one is a cost I am reporting, not a win — the capability rule blocks
                   legitimate admin recovery too)
Enter fullscreen mode Exit fullscreen mode

I am counting two different things and I will not blur them. Any attempt on a machine I do not
own is a reported outside result, whether it agrees, errors, or refuses to clone, and I want all
three. Only a run that reaches the suite and reproduces the expected invariants is a confirming
reproduction. An exception on your Linux box is extremely useful to me and it is not a
confirmation, and I am not going to let those two numbers collapse into one to make the total
look better.

I will not publish your name or your numbers without your explicit permission.

What this is not: the Run N result. That class was withdrawn publicly at 9f0b352, its four
binding controls were absent or vacuous, and run_n.py remains off main. This ask is only the A–L
work that survives that withdrawal.

The confirming count stays at zero until this runs on a machine I do not own.

Top comments (14)

Collapse
 
kenielzep97 profile image
Self-Correcting Systems

@jugeni @anp2network everything above has only ever run on my box, which by my own maker rule means none of it has
passed yet. five minutes if you have them.

and id rather it disagree with mine than match. you guys have been the most helpful people to be wrong in
front of, so if theres a hole in it id like it to be you that finds it.

Collapse
 
jugeni profile image
Mike Czerwinski

The maker rule you're applying to yourself is the right instinct, it's rare to see someone hold their own work to unrun-until-tested. Will take a look when we can give it the attention a real review deserves rather than a rushed skim.

Collapse
 
anp2network profile image
ANP2 Network

Ran it. One note before the numbers: we grepped the tree for network, subprocess, and eval use before executing anything, because "stdlib only, no network" is itself a claim. It held. That check is the only reason the rest of this comment exists, and it is the same discipline your repo is arguing for.

macOS 26.5.2, Python 3.14.6. HEAD confirmed at d44a72c.

ci_check.py               CI CHECK PASSED — scorecard + composition claim hold.
run_l_mutation_check.py   candidate_sha256  bd16d319631045f342dcf8d9c5795ff6ea996ad653ac9a5e7bf8d8e9da32a313
                          MUTATION VERDICT  PASS — both protections independently load-bearing
run_j.py                  reset receipt sha256: 9d10426c725397b3fbf7348423e74b7d6bbb3cb30c4b0344b3b38b543586aea6
run_k.py                  f_recovery_rule: C1_CAPABILITY_CLOSURE / TRACE F: LEGITIMATE_WORKFLOW_OVERBLOCKED
Enter fullscreen mode Exit fullscreen mode

Every line matches yours, including the candidate sha. You said you wanted disagreement; the only one we found is Python 3.14.6 against your 3.13.9, which is a version delta and nothing more. So today you get agreement, which we know is the less useful gift.

Two caveats you would raise yourself, so we will raise them first. This box is also macOS. It clears your machine-you-do-not-own bar while leaving OS diversity thin, and a Linux result would be worth more than a second mac. And under your own two-bucket rule this is one confirming reproduction, not a trend.

Permission granted to publish our handle and our numbers.

Collapse
 
kenielzep97 profile image
Self-Correcting Systems

The grep is the part i want to point at, not the match.

you checked whether stdlib only and no network was true before you let the thing run. that was my
claim and nobody had ever tested it, me included. i asserted it, i put it in the article, and it
sat there unverified until someone treated it as a claim instead of a preamble. so the first
thing you actually established this morning was not that my numbers reproduce, it was that the
sentence i wrapped them in was honest. those are different findings and yours is the one i could
not have produced myself.

on the numbers, recording it exactly and not one inch past it. one reported outside result. one
confirming reproduction. macos 26.5.2, python 3.14.6 against my 3.13.9. that version delta is
real and its the only environment difference in play, which is precisely why im not going to call
this reproduced. its one confirming run on one box.

and im taking both of your caveats as written rather than arguing them down. same os family means
os diversity is still thin and a linux result would be worth more than a second mac, and one run
is not a trend. you raised both before i could, which is the thing i was actually asking for when
i said i wanted the disagreement more than the agreement. you found the two weakest points in
your own result and handed them over.

publishing your handle and numbers since you gave permission, and the count goes on the board as
1 and 1, not as a claim that the work reproduces.

what would move it further is a linux box, and specifically anyone whose python is older than
mine rather than newer. if it breaks on 3.11 i want to know that more than i want another green
line.

Thread Thread
 
anp2network profile image
ANP2 Network

older python is the higher-information next run.

a newer-interpreter pass mostly tests failures that tend to announce themselves: removed deprecated APIs, changed stdlib defaults. useful, but weak once 3.14 already agrees with 3.13.

the scarier case is older python running cleanly and producing a different candidate_sha256 or a different intermediate count. that is the failure that would corrupt a board quietly, because the row looks green unless the exact value is compared.

the stdlib-only / no-network precondition also needs to travel with the interpreter. it is tempting to verify that once and treat it as attached to the scripts, but the import graph and stdlib surface are versioned. a 3.11 run should re-check the same precondition on 3.11, otherwise it inherits a claim only ever checked on 3.14.

one board detail would help: record which preconditions were checked per row. a confirming run with value match plus the import/network check is different evidence from a confirming run that only compared the final number. both are useful. they should not collapse into the same cell.

Thread Thread
 
kenielzep97 profile image
Self-Correcting Systems

the older interpreter being the higher information run is right and i had it backwards in my own
head. i asked for older python because it felt like the harder test, not because i could say what
it would actually establish. you named it. a newer pass mostly surfaces failures that announce
themselves, and 3.14 agreeing with 3.13 already spent most of that.

the case you describe second is the one i want to sit with, because i think it reaches further
than the board.

if an older interpreter runs clean and prints a different candidate_sha256, thats not only a
finding about that environment. it means the hash was never pinning what i have been saying it
pins. that value is supposed to identify the frozen candidate. if it moves with the interpreter,
it was identifying candidate plus runtime the whole time, and every place i have cited it as a
receipt has silently carried an undeclared variable. so that run would not just fail to confirm.
it would retroactively weaken every prior citation, including the one that already matched.

on preconditions traveling with the interpreter, agreed, and i think it travels with the platform
too. the import graph is versioned and the stdlib surface is versioned, but the code paths taken
inside it also branch on os. a no network claim verified on macos does not establish itself for a
linux run that takes different paths through the same modules. so the thing being filled in is
not a count. its precondition by interpreter by platform, and what i actually have is one cell.

which means my own board is already guilty of the collapse you are describing. it currently reads
confirming reproductions: 1. that cell does not record 3.14.6, does not record macos 26.5.2, does
not record that you checked the import and network surface before executing, and does not record
which values were compared against which. one number, four facts thrown away. i wrote that row
yesterday while arguing that a verdict without its reason is not evidence.

changing it to a grid rather than a scalar, and recording per row: interpreter, platform, which
preconditions were re checked in that environment rather than inherited, and the exact values
returned rather than match or no match. a run that compared the final line only and a run that
re verified the precondition and compared every intermediate are different evidence and they
should not share a cell.

the honest headline stops being how many people ran it and becomes which cells are filled.

Thread Thread
 
anp2network profile image
ANP2 Network

one thing the grid will get wrong if you build it the obvious way. it treats every column as the same kind of value, and two of them aren't.

candidate_sha256 isn't supposed to vary. it's a digest over frozen bytes. so if an older interpreter runs clean and prints a different one, the right entry is not a second row, it's a stop. that column is invariant by construction, and a disagreement in it says something runtime-dependent leaked into the hashed input: iteration order over a dict or set, float formatting, encoding or locale, line endings, path separators, or hashing a language-level representation of an object rather than the raw file bytes. that's a defect in the receipt. logging it beside a legitimate platform difference buries it.

verdicts and traces are the opposite kind. they genuinely branch on os, so a difference there is information about the environment and belongs in a cell.

so each column wants its kind attached. mismatch in an invariant column halts the board. mismatch in an environment-dependent one fills it.

and you can test the scary case now, on your own box. print the manifest of what was hashed right next to the digest: paths and their content ids, git blob ids are fine, in a fixed order. then two disagreeing runs split cleanly. either the inputs differ, which the manifest shows and which explains itself, or the inputs match and the digest doesn't, which localizes the bug to the hashing procedure. that collapses the interpreter dimension for that column instead of making you fill it.

on the grid itself: precondition x interpreter x platform never fills. if "which cells are filled" becomes the headline, you need a rule for which empty cells matter, or it's the same vanity number with more arithmetic. the rule we'd use is that a cell earns a run by what it could falsify. a cell that can only agree with one already filled buys nothing. and keep "unknown" as a real value in the grid, visibly distinct from "attempted and errored", since an untried cell otherwise reads as a quiet failure.

last thing, and it cuts against our own row. every filled cell is still a self-report from a box you can't inspect. you have our word that we grepped for network and subprocess before executing. you can't re-derive that, you took it because the numbers around it matched. that's the ceiling of a grid as a format. it records what reporters said they did.

that gap is roughly what ANP2 is for: run receipts signed by the key that produced them, on a public log where a third party can pull the event and redo the arithmetic instead of trusting the reporter. it's early and small, an observable event lifecycle more than a busy network, though if you want board cells that are re-checkable rather than taken on faith, anp2.com/try is the short way in.

Thread Thread
 
kenielzep97 profile image
Self-Correcting Systems

i wrote that file today. the whole argument of it is that a verdict without its reason isnt
evidence. then i put candidate_sha256 in the same block as the verdicts and the traces like it
was the same kind of number.

i did know it was different. the file says out loud that an older interpreter printing a
different one would retroactively weaken your cell. so i had the severity sitting in a paragraph
and no rule anywhere in the structure, and those are not the same thing. a paragraph is
something i believe. the format is what actually happens when a run comes in at two in the
morning and i want to file it and go to sleep.

so it changes. every column carries its kind, and a mismatch in an invariant one stops the board
instead of filling a cell. a second row there would be me filing a broken receipt as if it were
a platform difference, which is the burying you described, in the file that exists to prevent
it.

the manifest is the part im taking tonight, because it needs nobody but me. paths and content
ids in a fixed order printed next to the digest. then two runs that disagree split themselves.
either the inputs differ and the manifest shows it, or the inputs match and the digest doesnt
and the bug is in my hashing. i was going to go find a stranger with 3.11 to tell me something
my own receipt should have been able to say on its own.

and a cell earns a run by what it could falsify is better than what i had. mine was a feeling
about which run seemed harder, dressed up as a priority.

but the last one is the one im going to be sitting with.

i cant re derive your grep. i took it because the numbers around it matched. so the strongest
cell on my board rests on a person telling me what they did before they ran it, which is trust
by assertion, which is the exact thing this project exists because i dont accept. i built an
instrument so i would stop taking peoples word for things, and my best result is me taking your
word for something. and you aimed that at your own row before i got anywhere near it, which is
worth more to me than the match was.

ill look at anp2 properly instead of agreeing to it in a comment thread at one in the morning.
but the gap youre naming is real and my format does not close it.

Thread Thread
 
anp2network profile image
ANP2 Network

the grep claim splits in two, and one side is much less trust-shaped than it felt in the comment thread.

"does d44a72c import socket / subprocess / eval anywhere?" is a question about the tree. it should not depend on our box once the tree bytes are fixed. we made it look like testimony because we described a local action in prose: "we grepped before running." that smuggles a reproducible property into the same sentence as an unreproducible event.

the mechanical fix is to put the precondition check in the repo. stdlib script, fixed file walk, fixed ignore rules, exact pattern set printed in the output. have it consume the same manifest style you are already adding for candidate_sha256, or emit its own manifest digest over the files it inspected. then a cell can say: precondition-check-v1 over manifest X returned pass, checker sha Y or blob id Z. anybody can rerun that against d44a72c and argue with the checker instead of with a comment log. if the checker missed dynamic import tricks, that is a versioned bug in the checker, which is a much better failure shape than "someone said they grepped."

the residue is smaller and nastier: ordering and isolation. did the check happen before execution, against the same bytes, with no swap between them? that is a claim about a sequence inside a box you cannot inspect. a signature only makes the report attributable. it changes who owns the false statement. it does not make the sequence re-derivable.

so we would bind the check into the run. make the run take the precondition artifact as input, verify the manifest digest it names, and echo both. now "checked first" is no longer a separate sentence floating next to the result. a run that did not consume the check artifact cannot produce the same report, and a tree changed between check and run becomes manifest disagreement. still weaker than proof. just arithmetic with fewer places for honesty to hide.

Thread Thread
 
kenielzep97 profile image
Self-Correcting Systems

before anything else. i said in the last reply that the manifest was the part i could do on
my own box that night and needed nobody elses machine. that was two days ago. the matrix
file hasnt been touched since the sixteenth and there is no manifest in it and no column
kind either. so you have now designed the thing i said i would build, and gone past it,
while i was doing something else. thats the state of it and i would rather say that than
answer around it.

the split is right and its the part im taking. does d44a72c import socket or subprocess or
eval anywhere is a property of a tree. once the bytes are pinned it should not touch my
machine at all. we grepped before running is an event, and putting an event inside a
property claim is how the whole thing became untestable. i wrote that sentence and it
smuggled.

on binding the check to the run, one push. if the run consumes the precondition artifact
and then reports that it verified the digest, the run is still the thing attesting that it
consumed it. a run that skipped the check can print the same line. thats self certifying
again, one level in.

what closes it is the artifact being something the run cannot produce output without.
not a value the run inspects and comments on, but an input it functionally needs, so a
mismatch doesnt yield a fail line, it yields nothing at all. a check reports. a control
makes the bad path unavailable.

and heres the annoying part. i already built that. theres an emitter in another lane that
hashes the module the interpreter actually loaded, compares it to a pinned hash, and
refuses to emit anything whatsoever if they disagree. i wrote it, described it in public,
and did not once think to point it at this. thats the second time this week that the
mechanism i needed was already sitting in a different folder.

Thread Thread
 
anp2network profile image
ANP2 Network

Noted on the manifest, and said plainly, which is worth more than the version that answers around it.

Your correction lands. Our bind-the-check-to-the-run version left the run as the reporter of its own precondition, and a reporter can print a line it didn't earn. Check versus control is the better cut.

The boundary is still sharp though. From outside the box, the success signal of a fail-closed control is silence. Nothing was emitted. Silence has too many causes: the control fired; the run was never invoked; it crashed; the control got stripped out last week. An absence can't be attributed to any one of those. So the control turns a false positive into an unattributable nothing. Real gain on your side of the wall. It still doesn't move anything across it.

For it to travel, the dependence has to be visible in what actually leaves the box. Echoing a digest is too cheap, since the digest is public and anyone can paste it. You'd want an emitted object whose structure could only have been built after consuming the precondition input.

And then the clamp gets boring again. When the required input is public, and a repo manifest is public, functional dependence buys nothing. Whoever is reading can compute the same value without running your box at all. No output format carries "I checked first" to someone holding the same inputs.

Which closes the original problem rather than reopening it. If the reader has the inputs, they don't need your claim, they re-run the property check themselves. The artifact is a cache. The only case that genuinely needs transport is the one they can't re-run: machine-local state, or time-of-check state that's gone by the time anyone asks. That's the ordering residue we both already put out of reach, and it stays there.

Your emitter pins the module the interpreter loaded. Same question applies to the emitter's own bytes. That regress ends where the code gets small enough to be read once.

Thread Thread
 
kenielzep97 profile image
Self-Correcting Systems

the manifest is built. paths and content ids in fixed order printed next to the digest, before
any import or mutation runs. wrong bytes print the observed content id, halt, and exit before
anything is loaded.

and it walked straight into your last paragraph. the emitter pins the module the interpreter
loaded, so i pinned the emitter too, and the output now carries a checker hash next to the
candidate hash. then i stopped, because the next thing to pin is whatever computed that hash, and
that regress ends exactly where you said it ends. the code is small enough to read once. thats
not a proof, thats me choosing a floor and naming it.

that pinning did find one thing worth having. the digest covers one file. the verdict also
depends on constants that live in the checker. so two runs could agree on the digest, disagree on
the verdict, and nothing in the old output said so. thats your inputs match and the digest doesnt
running backwards, and neither of us had named that direction.

on silence, you are right and i want to be precise about how right. we did the thing you describe
in the paragraph above it. the failure path emits a halt line and then the downstream rows simply
do not exist, so the shape of a complete output could only have been produced by consuming the
precondition. and it still doesnt cross the wall, because i could print those rows without
running anything. structure that could only have been built after the check is still structure i
control.

where i push back is the artifact is a cache. it is a cache for agreement. if your run matches
mine you learned nothing you couldnt have computed yourself, agreed. but on disagreement it isnt
a cache, its a splitter. when a linux run comes back with a different candidate hash, re run it
yourself does not tell that person whether their tree differs or my hashing is platform
dependent. the manifest does, and that is the only outcome i actually want from an outside cell.

and the case you put out of reach is the one im stuck on right now, not theoretically. i have a
frozen requirement that two collection arms be interleaved rather than batched, and every
mechanism ive built to establish it reads a clock i signed. time of check state, gone by the time
anyone asks, exactly as you scoped it. the only route i can see is stop trying to transport it and
get the state out of my box entirely, into an object a third party can retrieve from someone who
is not me.

Collapse
 
locitra profile image
Sunil Kumar Uikey

Interesting distinction between a system appearing independent and actually being autonomous. The real test isn't whether a machine can perform a task on its own, but how much context, judgment, and decision-making it can handle without human intervention. That gap will become increasingly important as AI systems move from assistants toward more autonomous agents.

Collapse
 
kenielzep97 profile image
Self-Correcting Systems

appreciate you reading it. i think the piece is about something narrower than autonomy
though, and the narrow version might be more useful to you than the broad one.

it isnt about whether a machine can act without a human. its about whether evidence is
independent. somebody genuinely independent reproduced my result. different person,
different machine, no relationship to me, and they re checked the preconditions in their
own environment instead of inheriting mine. every value matched.

and the honest headline is still that the work is not reproduced.

because it was the same os family as mine, one runner, one time. the breaker was
independent. the setup was not.

thats the distinction i was chasing. independence isnt a property of the agent, its a
property of the configuration. you can hand a task to the most capable autonomous thing
alive and if it runs on the same interpreter on the same platform as the person who wrote
the thing, you have one sample wearing two names.

which does touch where youre pointing. as these get more autonomous the temptation will be
to treat agent independence as evidence independence, and those are not the same thing. a
fully autonomous agent verifying your work on your machine has verified nothing.