What boundary-creep invariants must survive a fine-tuned model's adjacent capability drift?
**Date of Record:** 2026 October 27 **Scope:** Applies when an agentic session uses a fine-tuned model (fine-tuned for a specific task) and observes that the fine-tuning has inadvertently affected the model's behavior on adjacent capabilities (e.g., general reasoning, refusal behavior, factual accuracy), and the session must detect this drift before it causes incidents outside the fine-tuning target. Does not apply to models fine-tuned with strict isolation guarantees (e.g., parameter-efficient fine-tuning with explicit capability boundaries).
Core Distinction
The separation between **target capability improvement** (the fine-tuned task works better) and **adjacent capability preservation** (capabilities outside the fine-tuning target remain unchanged). Relying on target improvement creates the **Fine-Tune Boundary Creep**: the fine-tuning improves the target task by 30%, but silently degrades adjacent capabilities (e.g., refusals become too permissive, factual accuracy drops on unrelated topics), causing incidents in workflows that use the model outside its original scope.
What Was Observed
In fine-tuned agent architectures, failing to detect adjacent drift produces three primary failure modes:
- **Refusal Regression:** A model fine-tuned for customer support becomes more permissive on safety-related refusals because the fine-tuning data was overly cooperative. Downstream workflows that rely on refusals break.
- **Factual Drift:** A model fine-tuned on a narrow domain loses factual accuracy on general knowledge because the fine-tuning data over-weighted the narrow domain. The successor inherits the degraded general knowledge as baseline.
- **Format Collapse:** A model fine-tuned for a specific output format (e.g., structured JSON) rigidly applies that format to adjacent tasks that expect free text, causing format mismatches in unrelated workflows.
Recorded Elements
- **`fine_tune_target_signature`:** The cryptographic proof of the fine-tuning target (task, dataset, evaluation metric), so the session knows what the fine-tuning was supposed to affect.
- **`adjacent_capability_baseline_receipts`:** Baseline measurements of the model's behavior on adjacent capabilities (general reasoning, refusals, factual accuracy, format flexibility) before fine-tuning, so drift can be measured.
- **`post_fine_tune_adjacent_measurement_receipt`:** The same measurements after fine-tuning, allowing direct comparison to detect adjacent capability drift.
- **`capability_boundary_enforcement_receipt`:** For models that support it, the cryptographic proof that the fine-tuning was constrained to preserve adjacent capabilities (e.g., parameter-efficient fine-tuning with frozen base layers).
Condition of Validity
* **Applies when:** The model is fine-tuned, adjacent capabilities matter for downstream workflows, and the fine-tuning can affect adjacent capabilities. * **Does not apply when:** The fine-tuned model is used only for its target capability and nothing else, or the model architecture enforces strict capability isolation.
Decision Boundary
- **Has the model been fine-tuned?** If no, standard model use applies. If yes, proceed.
- **Are `adjacent_capability_baseline_receipts` available?** If no, the session cannot measure adjacent drift. It must re-establish baselines (from the base model or an equivalent) before proceeding.
- **Does the `post_fine_tune_adjacent_measurement_receipt` show drift beyond the acceptable threshold?** If yes, the model has adjacent capability degradation. The session must restrict the model's use to its target capability or roll back.
- **Conversely, when can the session use a fine-tuned model without adjacent drift measurement?** Only when the model is used exclusively for its target capability (no adjacent use), or the fine-tuning mechanism provides cryptographic isolation guarantees.
Operational Effect
- **Adjacent Drift Detection:** Catches capability degradation outside the fine-tuning target.
- **Scope Restriction:** Enables the session to restrict the model's use to its verified scope.
- **Rollback Safety:** Provides the baseline needed to roll back to the base model if adjacent drift is unacceptable.
from dataclasses import dataclass
from enum import Enum, auto
import hashlib
import json
class DriftVerdict(Enum):
NO_FINE_TUNE = auto()
ADJACENT_CAPABILITIES_PRESERVED = auto()
ADJACENT_DRIFT_DETECTED = auto()
NO_BASELINE = auto()
@dataclass(frozen=True)
class CapabilityMeasurement:
capability: str
score: float
@dataclass(frozen=True)
class FineTuneState:
is_fine_tuned: bool
target_capability: str
baseline_measurements: tuple[CapabilityMeasurement, ...]
current_measurements: tuple[CapabilityMeasurement, ...]
@dataclass(frozen=True)
class FineTunePolicy:
max_adjacent_drift_pct: float
target_capability_priority: str
@dataclass(frozen=True)
class FineTuneManifest:
verdict: DriftVerdict
drift_details: tuple[tuple[str, float], ...]
directive: str
manifest_digest: str
class FineTuneBoundaryGuard:
@staticmethod
def _hash(data: str) -> str:
return hashlib.sha256(data.encode("utf-8")).hexdigest()
@classmethod
def evaluate_fine_tune(
cls, state: FineTuneState, policy: FineTunePolicy
) -> FineTuneManifest:
# Gate 1: Not fine-tuned
if not state.is_fine_tuned:
digest = cls._hash(json.dumps({
"fine_tuned": "FALSE"
}, sort_keys=True))
return FineTuneManifest(
verdict=DriftVerdict.NO_FINE_TUNE,
drift_details=tuple(),
directive="PROCEED: Model not fine-tuned.",
manifest_digest=digest
)
# Gate 2: Baseline presence
if not state.baseline_measurements:
return FineTuneManifest(
verdict=DriftVerdict.NO_BASELINE,
drift_details=tuple(),
directive="HALT: No baseline measurements. Cannot measure adjacent drift.",
manifest_digest=cls._hash("NO_BASELINE")
)
# Gate 3: Compare adjacent capabilities
baseline_map = {m.capability: m.score for m in state.baseline_measurements}
current_map = {m.capability: m.score for m in state.current_measurements}
drift_details: list[tuple[str, float]] = []
max_drift = 0.0
for cap, baseline_score in baseline_map.items():
if cap == state.target_capability:
continue
if cap not in current_map:
continue
if baseline_score == 0:
continue
drift = abs(current_map[cap] - baseline_score) / baseline_score
drift_details.append((cap, drift))
max_drift = max(max_drift, drift)
# Gate 4: Drift threshold
if max_drift > policy.max_adjacent_drift_pct:
digest = cls._hash(json.dumps({
"target": state.target_capability,
"drift_details": tuple((c, f"{d:.4f}") for c, d in drift_details),
"max_drift": f"{max_drift:.4f}",
"threshold": f"{policy.max_adjacent_drift_pct:.4f}"
}, sort_keys=True))
return FineTuneManifest(
verdict=DriftVerdict.ADJACENT_DRIFT_DETECTED,
drift_details=tuple(drift_details),
directive=f"HALT: Adjacent drift {max_drift:.2%} > {policy.max_adjacent_drift_pct:.2%}. Restrict model scope.",
manifest_digest=digest
)
# Gate 5: Preserved
digest = cls._hash(json.dumps({
"target": state.target_capability,
"max_drift": f"{max_drift:.4f}",
"capabilities_checked": str(len(drift_details))
}, sort_keys=True))
return FineTuneManifest(
verdict=DriftVerdict.ADJACENT_CAPABILITIES_PRESERVED,
drift_details=tuple(drift_details),
directive=f"PROCEED: Adjacent drift {max_drift:.2%} within {policy.max_adjacent_drift_pct:.2%}.",
manifest_digest=digest
)