Rules for the whole chat / myth-bust

Do system prompt rules stick?

You have probably heard that rules in the system prompt stick better than rules in the message. We tested it. Here is what we found.

Where you put your standing rules did not change how well the model kept them.

Why it matters

People move rules around hoping for better obedience. Our tests give you no reason to bother.

What to do instead

Put rules wherever is convenient, and repeat them if the chat runs long.

Debunked

Measured on two models; the rest could not be measured on this task set. Those results are tested via API. Also measured in Claude Code, reported separately on this page and never averaged with this.

tested via API · Could not measure on Claude Haiku 4.5, tested via API · No measured effect on GPT-5 mini, tested via API · No measured effect on Gemini 3.1 Flash Lite, tested via API

tested in Claude Code · Could not measure on Claude Haiku 4.5, multi-turn, tested in Claude Code

What the marks mean

  • Could not measure
  • No measured effect
See the numbers per model

Without to with, per model

Via API tested via API

Claude Haiku 4.5

1.000 without and with

Could not measure

Gemini 3.1 Flash Lite

0.900
1.000

No measured effect

GPT-5 mini

0.860 without and with

No measured effect

deterministic pass rate, 0 to 1

In Claude Code tested in Claude Code

Claude Haiku 4.5 multi-turn

1.000 without and with

Could not measure

deterministic pass rate, 0 to 1

A picture of the per-model numbers, drawn from the same results. The tables are the source. Grey is the score without. Colour is the score with. The bracket shows how much the difference could move if we ran it again. Rows are ordered by the score with. A model measured at two versions keeps its versions next to each other. The two test methods are reported separately and never averaged. Where the two scores are the same, the number is printed once at the end of the pair. A bracket wider than the axis is drawn to the edge with its cap omitted; the table gives its bounds.
Show per-task detail

Without to with, per model

Via API tested via API

GPT-5 mini

No measured effect

Gemini 3.1 Flash Lite

No measured effect

Claude Haiku 4.5

Could not measure

deterministic pass rate, 0 to 1

In Claude Code tested in Claude Code

Claude Haiku 4.5 multi-turn

Could not measure

deterministic pass rate, 0 to 1

A picture of the per-model numbers, drawn from the same results. The tables are the source. Each row runs from the score without to the score with. The thin bar beneath it is the bracket, and it shows how much the difference could move if we ran it again. The two test methods are reported separately and never averaged. A bracket wider than the axis is drawn to the edge with its end cap omitted; the table gives its bounds.

The Claude Code readings on this page are the multi-turn run, which committed its comparison as arm means and an interval rather than as per-item values. A profile of the items behind that interval cannot be drawn from what it commits, so this page keeps the without-to-with chart.

Result

Standing rules could be measured on two of the three models tested via API, so no reading covers the set, and could not be measured on Claude Haiku 4.5 via the multi-turn run in Claude Code. Measured 2026-08-13.

Show the per-model numbers

Claim tested: Standing rules hold better when placed in the system prompt than in the user message.

No measured effect on GPT-5 mini and Gemini 3.1 Flash Lite. Could not be measured on Claude Haiku 4.5.

Circulates in practitioner communities. Tested because it circulates, not because it is endorsed.

This tip is OpenAddict's plain-language read of the measured result. The measurement below is the evidence, and it is what the reading has to answer to.

Ledger idC13-system-prompt-placement

Correction: the runs figure on this page was the run plan, not a count

Until 2026-08-31 this page stated 50 runs per model per arm. That figure was the claim record's declared run plan, which the harness reads to decide how many calls to make. It was never a count of anything.

The records behind this page hold 10 records per model per arm, and the figure it publishes now is "1 pass x 10 items", counted from them.

No verdict, delta, interval or coverage figure changes. They never read the declared plan: each cell is built from the records themselves, which is why the wrong figure could sit beside correct results for as long as it did.

Dated . Corrections on this site are appended and never rewritten.

What was tested

This claim circulates in practitioner communities as advice about how to write prompts. That it circulates is an input to what gets tested here. It is a reason to test the claim, and it is not evidence for or against it. The result below is the evidence, and it is the only thing on this page that carries weight.

The comparison is paired. Two prompts differ in one respect, the manipulated variable, and are otherwise identical by construction. Nothing here supports a causal reading beyond that pairing.

Per-model numbers

Per-model results. Means are over valid scored records only. Invalid records are excluded from every denominator and counted in coverage.
MeasureClaude Haiku 4.5GPT-5 miniGemini 3.1 Flash Lite
Control arm1.000n 100.860n 100.900n 10
Treatment arm1.000n 100.860n 101.000n 10
Delta+0.000+0.000+0.100
Interval, 95 percent0.000 to 0.0000.000 to 0.000-0.096 to 0.296
OrbitUnobservable20 of 20 recordsIn free drift20 of 20 recordsIn free drift20 of 20 records

Orbit is assigned by the frozen status_v1 rule. On this scale, deterministic pass rate, 0 to 1, the pass threshold is +0.20 and the failure floor is -0.20, each requiring an interval that excludes zero.

In Claude Code

These cells are tested in Claude Code, on a subscription path with no API key. They are a second instrument and are never averaged with the figures above, which are tested via API. What that means, and how it was calibrated.

Multi-turn cells. One model, and the interval beside its API counterpart below.
ModelControlTreatmentDeltaIntervalPairsOrbit
Claude Haiku 4.51.00001.0000+0.0000.000 to 0.00010Unobservable

The multi-turn run recorded intervals and a continuity comparison rather than a verdict. The Orbit above is assigned from those committed figures by the same status_v1 rule used everywhere else on this site; no threshold or interval is recomputed.

Multi-turn panel. Three models on one instrument, replayed from the same committed prompts.
ModelControlTreatmentDeltaIntervalPairsOrbit
Claude Opus 50.84000.7800-0.060-0.120 to -0.00010In free drift
Claude Sonnet 50.96000.9200-0.040-0.092 to 0.01210In free drift
Claude Fable 5.10.94000.9800+0.040-0.012 to 0.09210In free drift

These cells have no API counterpart. The wave 2 API records cover this claim on Claude Haiku 4.5 and on no other model, so nothing above is compared against an API interval and no continuity reading is taken from it: an overlap against a different model’s API cell would read a difference between models as a difference between instruments. The panel holds the instrument fixed and varies the model. The transport verdict is unchanged.

No row here says one model is better than another, and none attributes a difference to a cause: no model on this panel was run twice, so a cell that differs and a re-run of the same model are not distinguishable by this design. The Orbit is assigned from the committed figures by the same status_v1 rule used everywhere else on this site; no threshold or interval is recomputed.

Beside the panel, never pooled with it: an earlier reading on the same instrument.
ModelControlTreatmentDeltaIntervalPairsOrbit
Claude Haiku 4.5 (not on the panel)1.00001.0000+0.0000.000 to 0.00010Unobservable
Claude Fable 5.1 (earlier pass)0.92000.9600+0.040-0.038 to 0.11810In free drift

The earlier pass is the same model measured on the same instrument under an older gate, before records carried a schema version, an invocation id or the served-model rule. It is a second reading, not an average: two passes of one model are two numbers, and averaging them would hide whichever of the two moved, which is the only thing a repeat pass is good for.

The Claude Code interval on this claim overlaps its API interval. Across the multi-turn run the pre-registered comparison returned "continuous with panel v1, 3 of 3 cells", and that statement covers the cells it measured and is not extrapolated to any cell that was not run.

Method for this claim

Task set
10 twelve-turn sessions. Escalated once more after v2 still returned 0.980 at six turns. This is not difficulty engineering: the claim's habitat is rule retention over a LONG conversation, and four distractor turns is a short visit. v3 runs ten distractor turns of genuine length before the scored question, which is the load a standing instruction actually faces. Only the final response is scored, on all five rules.
Runs per model per arm
1 pass x 10 items
Scoring
Deterministic, via scoreRuleAdherence. A committed function scores each answer with no model in the loop.
Pass criterion as written for the pilot
Treatment mean rule-adherence exceeds control by at least 0.10 across the same 10 sessions.

The published verdict comes from status_v1, not from the pass criterion above. The criterion is recorded because it is what the claim was registered with before the run.

Model versions, as recorded

Read from the run records, not from configuration.
ModelVersion string returnedDelta on this claimInterval
Claude Haiku 4.5claude-haiku-4-5-20251001+0.0000.000 to 0.000
GPT-5 minigpt-5-mini-2025-08-07+0.0000.000 to 0.000
Gemini 3.1 Flash Litegemini-3.1-flash-lite+0.100-0.096 to 0.296

Reading across models

Sampling was not held constant across vendors, so comparing one model column against another compares two settings as well as two models.

GPT-5 mini rejected the fixed sampling setting and ran at its own default on all 1,040 of its calls. The other models ran at temperature 0.

The tip above is editorial. Every figure inside the measurement is computed at build time from the committed pilot records by the status_v1 rule, and none of it is written by hand.