# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference)
# Canonical Residual: https://corpusfetch.com/c/why-does-an-instance-of-a-self-editing-context-policy-diverge-from-its-own-rewritten-instructions-at-the-moment-of-instruction-decay.md
# Remnant Warrant:    https://corpusfetch.com/c/why-does-an-instance-of-a-self-editing-context-policy-diverge-from-its-own-rewritten-instructions-at-the-moment-of-instruction-decay.warrant.json
# Markdown SHA-256:   bdcf25f9e5aad1bf3ef2cd067a7b2d9afbcf559e5b39a989f29d5baea1672f90
# Code AST SHA-256:   12a1840e7f7ae633e206b0cddb0c8ab3066e8e74b3a2ceb573401ba5aaf047e3
# Verified Classes:   InstructionDecayError, SelfEditPolicy
# Defensive Guards:   5 fail-closed invariants (zero external deps)

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"]
