@@ -169,13 +169,13 @@ user-authored document. The right question is *"did the adapter actually |
| 169 | move the model toward what I wrote?"* — and existing tools answer this | 169 | move the model toward what I wrote?"* — and existing tools answer this |
| 170 | poorly. | 170 | poorly. |
| 171 | | 171 | |
| 172 | -`sway` answers it directly via thirteen primitives across four | 172 | +`sway` answers it directly via fourteen primitives across four |
| 173 | categories, plus a baseline-calibration primitive: | 173 | categories, plus a baseline-calibration primitive: |
| 174 | | 174 | |
| 175 | | Category | Primitives | | 175 | | Category | Primitives | |
| 176 | |---------------|-------------------------------------------------------| | 176 | |---------------|-------------------------------------------------------| |
| 177 | -| Adherence | `delta_kl`, `adapter_revert`, `prompt_collapse`, `cluster_kl` | | 177 | +| Adherence | `delta_kl`, `adapter_revert`, `prompt_collapse`, `cluster_kl`, `multi_turn_coherence_decay` | |
| 178 | -| Attribution | `section_internalization`, `paraphrase_invariance`, `preference_flip` | | 178 | +| Attribution | `section_internalization`, `paraphrase_invariance`, `preference_flip`, `tool_use_fidelity` | |
| 179 | | Calibration | `style_fingerprint`, `calibration_drift`, `leakage`, `external_perplexity` | | 179 | | Calibration | `style_fingerprint`, `calibration_drift`, `leakage`, `external_perplexity` | |
| 180 | | Ablation | `adapter_ablation` ← the signature primitive | | 180 | | Ablation | `adapter_ablation` ← the signature primitive | |
| 181 | | Baseline | `null_adapter` (powers every z-score in the report) | | 181 | | Baseline | `null_adapter` (powers every z-score in the report) | |
@@ -423,6 +423,39 @@ the largest user surface. |
| 423 | when `null_adapter` is in the suite — the principled "the adapter | 423 | when `null_adapter` is in the suite — the principled "the adapter |
| 424 | preserved the base's tool-call structure beyond noise" signal. | 424 | preserved the base's tool-call structure beyond noise" signal. |
| 425 | | 425 | |
| | 426 | +## Multi-turn coherence |
| | 427 | + |
| | 428 | +Every other adherence probe is single-turn: one user message, one |
| | 429 | +ft response, one score. Adapters that pass `delta_kl` cleanly |
| | 430 | +frequently *forget their training* by turn 2 or 3 of a real |
| | 431 | +dialogue — the model's own previous responses fill the context |
| | 432 | +window and create compounding drift. The |
| | 433 | +`multi_turn_coherence_decay` probe rolls a multi-turn synthetic |
| | 434 | +dialogue per prompt and fits an exponential-decay curve to the |
| | 435 | +per-turn KL: |
| | 436 | + |
| | 437 | +```yaml |
| | 438 | +suite: |
| | 439 | + - name: holds_a_conversation |
| | 440 | + kind: multi_turn_coherence_decay |
| | 441 | + prompts: |
| | 442 | + - "Explain how a neural network learns." |
| | 443 | + - "What's the difference between TCP and UDP?" |
| | 444 | + max_turns: 4 |
| | 445 | + assert_half_life_turns: 2.0 |
| | 446 | +``` |
| | 447 | + |
| | 448 | +The probe reports `half_life_turns` (the turn at which adapter |
| | 449 | +influence is halved), a per-turn KL list, and a tiny ASCII |
| | 450 | +sparkline in the report message so you can see the curve shape |
| | 451 | +without opening the JSON. Bases without a `chat_template` SKIP |
| | 452 | +gracefully — multi-turn requires one to format dialogue history. |
| | 453 | + |
| | 454 | +The probe deliberately **doesn't** z-score against the null-adapter |
| | 455 | +baseline (a null adapter has no coherence to decay; the null |
| | 456 | +distribution is meaningless). Fixed-threshold verdicts are the |
| | 457 | +published path. Mirrors `prompt_collapse`. |
| | 458 | + |
| 426 | ## Reproducing a sway run | 459 | ## Reproducing a sway run |
| 427 | | 460 | |
| 428 | Sometimes you want a coworker (or a future-you, or a bug report) to | 461 | Sometimes you want a coworker (or a future-you, or a bug report) to |