One thing worth checking on that Modelfile: the TEMPLATE only uses .Prompt, with no .Messages and no .Response. Going by template.go in the Ollama repo, a template with neither gets {{ .Response }} appended at parse time and then runs once per user/assistant pair in legacy mode. So from turn two on, the earlier answer lands right after the bare <|start|>assistant with no channel header and no <|end|>, and the hard-coded system block repeats in front of every pair (a SYSTEM line in the Modelfile is ignored too, since .System is never referenced). Single-shot ollama run would look fine, multi-turn chat is where I'd expect it to drift. Ranging over .Messages and writing each past assistant turn as a final-channel message closed with <|end|> should avoid it. I read this from the source, I haven't run it against a gpt-oss GGUF.
You were right, thanks for reading it that closely. I checked template.go and rendered both templates on Ollama 0.40.7 with _debug_render_only: the old one put the first answer straight after a bare <|start|>assistant, with no channel header and no <|end|>, repeated the system block, and dropped SYSTEM. The post and the Modelfile in the GGUF repo now range over .Messages, send earlier answers back as final-channel messages closed with <|end|>, and turn SYSTEM into a developer message, the way Ollama's own gpt-oss template does. A single prompt renders byte for byte the same as before, which is why ollama run never showed it. I've credited you in the post.
One thing worth checking on that Modelfile: the TEMPLATE only uses .Prompt, with no .Messages and no .Response. Going by template.go in the Ollama repo, a template with neither gets {{ .Response }} appended at parse time and then runs once per user/assistant pair in legacy mode. So from turn two on, the earlier answer lands right after the bare <|start|>assistant with no channel header and no <|end|>, and the hard-coded system block repeats in front of every pair (a SYSTEM line in the Modelfile is ignored too, since .System is never referenced). Single-shot ollama run would look fine, multi-turn chat is where I'd expect it to drift. Ranging over .Messages and writing each past assistant turn as a final-channel message closed with <|end|> should avoid it. I read this from the source, I haven't run it against a gpt-oss GGUF.