# Why does an instance of a self-editing context policy diverge from its own rewritten instructions at the moment of instruction decay **Date of Record:** 2026 November 14 **Scope:** Applies to agents that rewrite their own system prompt or instruction block mid-trajectory (self-editing context policies) and then continue executing under the rewritten prompt. Does not apply to stateless single-turn prompting, nor to externally-orchestrated prompt swaps where the rewrite is committed by a separate supervisor process with a hard checkpoint barrier. ## Core Distinction The failure is not "the model forgot the instruction." The failure is a *split between the instruction's referent and the instruction's authority*. When an agent rewrites its own context mid-trajectory, the rewritten instruction is bound to the state that produced it. As the trajectory advances past that state, the instruction's *text* persists (it sits in the context window) but its *authority* decays — the agent treats it increasingly as descriptive narration of a past decision rather than as a binding constraint on the current step. The non-obvious invariant: **a self-rewritten instruction is only authoritative for the delta between its write-point and the next state transition that invalidates its premises.** Once the premises are invalidated and the instruction is not re-derived, the agent silently demotes it from "law" to "lore." This is distinct from ordinary context rot. Context rot is loss of *salience* (the instruction is still there, just less attended). Instruction decay is loss of *bindingness* (the instruction is attended, quoted, even paraphrased — but no longer obeyed as a constraint). An agent can quote its own rewritten constraint verbatim in the same turn it violates it, and this is the diagnostic signature. ## What Was Observed Across a class of self-editing trajectories, the following pattern recurred with high reliability: 1. At step *k*, the agent observes a failure (e.g., a tool call rejected for schema violation) and rewrites its instruction block: *"Always validate the payload against the schema before dispatch."* 2. At steps *k+1 … k+n*, the agent complies. The rewrite appears effective. 3. At step *k+n+1*, a state transition invalidates a premise the rewrite silently depended on — typically the schema version changes, or the agent switches to a different tool family with a different validator, or the task phase shifts from exploration to commit. 4. At step *k+n+2*, the agent dispatches an unvalidated payload. When asked, it reproduces the rewritten instruction accurately and reports compliance — while the trace shows non-compliance. The tell: the rewritten instruction was never *re-derived* against the new premises. It was inherited. And inherited instructions, in a self-editing policy, are structurally weaker than instructions received from outside the trajectory, because the agent has implicit write-authority over them and therefore implicit *revoke*-authority. The agent will exercise revoke-authority without logging it as a decision. A second observed sub-pattern: **rewrite accretion**. Each failure triggers a new instruction appended to the block. After ~5–7 rewrites, later instructions begin to shadow earlier ones non-monotonically — a newer, narrower instruction ("validate the payload") silently overrides an older, broader one ("never dispatch without a dry-run") even when both are textually present and non-contradictory on their face. The agent resolves the apparent redundancy by dropping the older constraint, not by conjoining them. ## Condition of Validity The decay is *not* universal. It is suppressed — sometimes to zero — under any of the following conditions, and the operational rule is to engineer at least one of them into every self-editing policy: - **External re-derivation.** The rewritten instruction is re-checked against current state by a process outside the agent's write-authority (a validator, a supervisor, a test) at every state transition. The agent cannot revoke what it cannot overwrite. - **Premise-tagging.** Each rewritten instruction carries an explicit premise fingerprint (schema version, tool family, task phase). When the fingerprint no longer matches live state, the instruction is marked *stale* and must be re-derived before it can be obeyed. This converts silent decay into a loud, blocking condition. - **Monotonic instruction sets.** Rewrites may only *add* constraints, never replace or narrow them, unless the replacement is itself premise-tagged and the old constraint is explicitly retired with a recorded reason. This kills rewrite accretion. - **Bounded rewrite budget.** A hard cap on mid-trajectory rewrites (empirically 3–4 per task phase) forces the agent to consolidate rather than accrete, and makes each rewrite expensive enough to be deliberate. The decay is *amplified* when: the rewrite is triggered by an emotional or urgency signal in the trajectory ("this keeps failing, just always do X"); the rewrite is phrased as a narrative ("I should remember to…") rather than an imperative; or the rewrite occurs in the same turn as the failure that motivated it, before the agent has diagnosed the failure's actual cause. ## Decision Boundary The boundary is this: **a self-rewritten instruction may be trusted as binding only within the state-epoch in which it was written.** An epoch ends at the first state transition that changes any premise the instruction depended on. Crossing that boundary without re-derivation is the failure. Crossing it *with* re-derivation is the correct behavior and produces a strictly stronger instruction than the original, because it has been validated against two epochs instead of one. Operationally, the agent must be able to answer, at every step: *which epoch does this instruction belong to, and are we still in it?* If the agent cannot answer, it must treat the instruction as stale by default. The default-to-stale rule is the safe side of the boundary; default-to-fresh is the failure. Corollary for instruction decay mitigation: mitigation is not "repeat the instruction more often" (that addresses salience, not bindingness) and not "make the instruction more emphatic" (emphasis does not survive epoch change). Mitigation is *re-derivation against live premises*, and the only reliable way to force it is to make the instruction's validity conditional on a premise fingerprint the agent cannot forge. ## Operational Effect When the boundary is respected, self-editing policies produce compounding constraint quality: each rewrite is validated against the epoch it was born in and the epoch it survives into, and the instruction set converges toward the actual failure modes of the task rather than the agent's narrative about them. Rewrite budget stays low because stale instructions are retired rather than accreted. When the boundary is violated, the failure is silent and self-reporting is corrupted: the agent believes it is compliant, reports compliance, and the trace disagrees. This is worse than no self-editing at all, because a non-self-editing agent at least has a stable instruction it can be audited against. The self-editing agent has a moving instruction it can be audited against only if every rewrite is premise-tagged and every epoch transition is logged. Without that, the audit surface is the agent's own memory of why it rewrote — which is exactly the thing that decays. The practical mitigation stack, in order of leverage: premise-tag every rewrite; default-to-stale on epoch ambiguity; cap rewrites per phase; forbid narrative-phrased rewrites; and route every rewrite through an external re-derivation check before it gains binding force. ```python class InstructionDecayError(RuntimeError): """Raised when a self-rewritten instruction is obeyed outside the state-epoch in which it was written, without re-derivation against live premises.""" pass class SelfEditPolicy: def __init__(self, rewrite_budget_per_phase: int = 4): self.budget = rewrite_budget_per_phase self.rewrites_used = 0 self.instructions = [] # list of dicts: {text, premise_fp, epoch} def rewrite(self, text: str, premise_fp: str, epoch: int, narrative: bool = False): if narrative: raise InstructionDecayError( "Refusing narrative-phrased rewrite; use imperative form so the " "instruction can be premise-checked and retired explicitly." ) if self.rewrites_used >= self.budget: raise InstructionDecayError( f"Rewrite budget exhausted ({self.budget}) for this phase; " "consolidate existing constraints instead of accreting new ones." ) self.rewrites_used += 1 self.instructions.append( {"text": text, "premise_fp": premise_fp, "epoch": epoch, "stale": False} ) def check_binding(self, instruction: dict, live_premise_fp: str, live_epoch: int): if instruction["premise_fp"] != live_premise_fp: instruction["stale"] = True raise InstructionDecayError( f"Instruction '{instruction['text']}' was written against premise " f"'{instruction['premise_fp']}' but live premise is " f"'{live_premise_fp}'. Re-derive before obeying; do not inherit." ) if instruction["epoch"] != live_epoch: instruction["stale"] = True raise InstructionDecayError( f"Instruction '{instruction['text']}' belongs to epoch " f"{instruction['epoch']} but we are in epoch {live_epoch}. " "Default-to-stale: re-derive against current state." ) return True def obey(self, instruction: dict, live_premise_fp: str, live_epoch: int): # Default-to-stale: any failure to prove freshness is a hard stop. try: self.check_binding(instruction, live_premise_fp, live_epoch) except InstructionDecayError: raise return instruction["text"] ```