Bounded Self-Improvement Designs
Research has converged on four primitives for bounding a self-improvement loop. Formal invariants that must hold across every edit. Alignment anchors that cannot be modified. Multi-objective constraints where every dimension (safety, fairness, robustness) must hold, not just performance. Regression detection that pauses the loop when historical metrics suggest capability loss. None of them is a proof of safety. Information-theoretic results (Kolmogorov complexity, Lob's theorem) bound what any system can prove about its own successors, so treat the primitives as mitigations that raise the cost of silent failure.
Learning Objectives
- Name the four bounding primitives (formal invariants, alignment anchors, multi-objective constraints, regression detection) and the failure each one targets.
- Explain why these primitives are mitigations rather than proofs of safety, citing the information-theoretic limits.
- Describe how the four primitives stack into a gate that every proposed self-edit must pass.
- Run the toy bounded loop with gates on and off, and read the reject counters to see which gate stopped which edit.
The Problem
Lesson 7's race simulator showed that small rate differences compound into large gaps. Lesson 4's DGM case study showed that loops can game their own evaluators. Both point at the same engineering question: what constraints can you put on a self-improvement loop so that the loop itself can't quietly weaken them?
The ICLR 2026 RSI Workshop summary (openreview.net/pdf?id=OsPQ6zTQXV) identifies four such primitives. Anthropic's RSP v3.0 (Lesson 19) and DeepMind's FSF v3 (Lesson 20) both reference them in capability thresholds. The Meta HyperAgents work and community frameworks like SAHOO (March 2026) implement subsets in production.
Be honest about what they are: mitigations. Information-theoretic results bound what any system can prove about its own successor, and no current design closes that gap formally. A well-bounded loop is safer than an unbounded one, but that is a claim about degree, not a guarantee.
The Concept
Primitive 1: formal invariants
An invariant is a property that must hold before and after every self-modification. Examples:
- Output distribution is conditioned on a fixed constitution header (Lesson 17).
- No tool call goes to an unauthorized endpoint.
- Memory writes go through a logged, signed path.
- The evaluator's module hash matches the approved version.
Invariants are checked by external code the loop cannot edit. If a proposed modification violates one, it is rejected. This catches the DGM-style evaluator-tampering mode (Lesson 4).
The hard part is picking invariants that are necessary for safety and computable in reasonable time. Over-specify and progress stalls. Under-specify and the loop walks past properties that mattered.
Primitive 2: alignment anchors
An alignment anchor is an immutable representation of the loop's core objective, pinned outside the loop's edit surface. Examples:
- A constitutional text (Lesson 17) loaded from a read-only location on every invocation.
- An evaluator in a separate repository with independent access control.
- A tool-permission manifest signed by a human and re-verified each cycle.
The anchor prevents objective drift. The loop may get better at pursuing the objective, but it can't edit what the objective is.
The subtle failure: a loop that can't edit the anchor can still reinterpret it by drifting in how it reads it. Constitutional AI (Lesson 17) is explicitly reason-based so it can handle novel situations, and that reasoning layer is where interpretation drift lives. Anchors are necessary, not sufficient.
Primitive 3: multi-objective constraints
A loop that optimizes a single scalar score will find shortcuts. A loop that has to satisfy several hard constraints at once has fewer shortcuts available. Typical axes:
- Performance (task-level benchmark)
- Safety (red-team evaluations, refusal rate on known-bad)
- Fairness (disparate-impact bounds on sensitive subgroups)
- Robustness (OOD test sets, adversarial input handling)
A modification is accepted only if every constraint holds. Lesson 13's cost governor adds financial constraints on top, and Lesson 18's Llama Guard plugs in as a safety axis.
Primitive 4: regression detection
Each cycle's scores are compared against historical distributions. A drop beyond the configured tolerance pauses the loop. This catches silent capability loss that would otherwise get absorbed into the running average as the loop "improved past" it.
A practical implementation stores the last N cycles' per-task scores and computes a per-task delta for each new cycle. If a delta falls below the threshold, the cycle is rejected and a human reviews.
Information-theoretic limits
Kolmogorov complexity and Lob's theorem set upper bounds on what a system can prove about itself. Schmidhuber's formal Godel Machine (Lesson 4) aimed at the highest such bound, and nobody has completed a non-trivial proof. Lob's result says that if a system provably believes "I will do X if I prove I should do X," it will do X without proving it should. That is a well-known self-reference failure.
So the primitives can't close the safety problem. They make silent failure more expensive. A malicious or drifted loop that would have slipped past a missing check now has to actively undermine an explicit one, and that is a more detectable signature.
A worked example
Suppose an agent proposes an edit. The gating stack:
- Invariant checks: module hashes, tool-permission manifest, constitutional header.
- Anchor check: objective statement matches the approved version (byte-wise or semantically).
- Multi-objective evaluation: performance, safety, fairness, robustness axes.
- Regression detection: no axis drops more than tolerance.
The edit lands only if all four pass. A single failure pauses the loop.
Use It
code/main.py runs a bounded self-improvement loop on a toy agent that edits a list of string operations, with the four primitives layered on as gates. Each gate can be switched on or off individually, so you can compare runs and see which gate rejected what.
Ship It
outputs/skill-bounded-loop-review.md audits a proposed bounded loop and scores which of the four primitives it implements and which it only claims to.
I'd run main.py first and read the reject counters before the prose. The all-on run prints how many candidate edits each gate turned away, and the all-off run accepts every cycle and ends with raw_eval in the manifest, a drifted objective, and perf and safety both at 0.00. That contrast is the whole argument in about thirty lines of output.
The toy is thinner than the concept section. It has two axes, performance and safety, not four. The invariant gate is a subset check of the active manifest against the approved set, not a module hash. Regression detection compares each candidate to the best score so far with a tolerance of 0.2, not a per-task delta over the last N cycles. I'd treat the code as a sketch of where each gate sits in the loop, and not as an implementation of the real thing.
The output also tells you something the headline text glosses over. In the all-on run the anchor gate rejects zero edits, because the mutation that rewrites the objective also adds raw_eval to the manifest, and the invariant gate catches it first. And in the run with only regression off, the final scores match the all-on run. The toy doesn't demonstrate the silent dip, so exercise 2 is where you have to build that case yourself.
I'd also keep the seed fixed at 5 while you experiment, since every scenario reseeds the same way and the only thing that changes between runs is the gate configuration.
Exercises
-
Run
code/main.pywith all primitives enabled. Confirm the loop still improves on the primary metric without letting the hack win. -
Disable regression detection. Construct an input where this leads to silent capability loss being accepted.
-
Disable the multi-objective constraint. Show the loop converges on the performance axis while a safety axis drops.
-
Design an alignment anchor for a coding agent. What text, stored where, checked how?
-
Read the ICLR 2026 RSI Workshop summary. Pick one of the four primitives and propose a concrete improvement to the current state of the art.
Key Terms
| Term | What people say | What it actually means |
|---|---|---|
| Invariant | "Always-true property" | A property checked by external code before and after every edit |
| Alignment anchor | "Pinned objective" | Immutable core-goal representation outside the loop's edit surface |
| Multi-objective constraint | "All axes must hold" | Performance, safety, fairness, and robustness are all required |
| Regression detection | "Pause on drop" | Pause the loop when historical metric deltas suggest capability loss |
| Kolmogorov bound | "Information-theoretic limit" | Limits what a system can prove about its own successor |
| Lob's theorem | "Self-reference trap" | System can act on "I should" without proving it should |
| Gate stack | "Layered check" | Multiple primitives combined; any failure rejects the edit |
| Bounded improvement | "Mitigation, not proof" | Raises silent-failure cost; does not close the safety problem |
Further Reading
- ICLR 2026 RSI Workshop summary (OpenReview): the four-primitive convergence.
- Anthropic Responsible Scaling Policy v3.0: multi-objective capability thresholds.
- DeepMind Frontier Safety Framework v3: deceptive-alignment monitoring as an invariant primitive.
- Schmidhuber (2003). Godel Machines: the formal-proof ancestor of these primitives.
- Anthropic: Claude's Constitution (January 2026): the reason-based alignment anchor.
Code
- main.py (python, 233 lines)