Papers › Can LLM Agents Stick to the Script? A Benchmark for Long-Horizon Consistency in...

Can LLM Agents Stick to the Script? A Benchmark for Long-Horizon Consistency in Interactive Narratives

8 Aug 2026ICMLarXiv:2608.08160added by Syntology

Yingpeng Ma, Jianhao Yan, Bei Shi, Ka Hou Kam, Runnan Wang, Xuebo Liu, Yulong Chen, Yue Zhang, Derek F. Wong

Title, abstract, authors and date from arXiv's metadata (CC0); this paper is not in the Papers with Code archive (frozen 2025-07-28).

The rapid advancement of Large Language Models (LLMs) is revolutionizing AI for Games by enabling open-ended and fluid interactive storytelling. However, existing research has largely overlooked the critical challenge of maintaining long-horizon logical consistency and narrative integrity against unconstrained user interventions. To address this, we formulate this challenge as Narrative Commitment Preservation (NCP), and take interactive narrative as our testbed. We introduce NCP-Bench, a benchmark of 100 narrative environments derived from movie synopses. Each environment includes a structured narrative specification (trajectory, commitments, and initial facts) that we can automatically check throughout the interaction between the player agent and the narrator agent. Experiments across state-of-the-art LLMs reveal a substantial long-horizon consistency gap: high linguistic quality does not guarantee commitment preservation; even strong models frequently generate logically conflicting content under adversarial interventions, with the best-performing model (GPT-5.2) achieving only 42% survival rate after 20 turns and fact conflict rates ranging from 40% to 68% across models, and only isolated runs satisfying all achievement commitments within the 100-turn limit.

PaperPDFCode Syntology ran

In Syntology Open this paper in Syntology's Atlas, the map of the papers in Syntology's graph and their citations.

For agents, Syntology's MCP tool lists every function and class Syntology harvested from this paper and whether it ran (how to connect): get_harvested_code_for_paper(arxiv_id="2608.08160")

Code

Syntology Ran 72 of 90 code samples harvested from 1 repository linked to this paper; 18 have no recorded run. Of those that ran: 3 ran · honoured contract; 1 ran · violated contract; 45 ran · our draft was wrong; 23 ran with no contract checked.

By repository: found in paper text by Syntology: 90 samples from 1 repository, 72 ran. The run record, sample by sample. “Ran” means executed on a synthesized input, not that the code is correct or reproduces the paper.

yingpengma/NCP-Bench found in paper text by Syntology report

Reachability, where shown, is from one Syntology probe window (2026-09-16 to 2026-09-18); repositories not probed show nothing. GitHub stars are not tracked.

Code Syntology ran Syntology

90 samples harvested; 72 ran; 3 honoured the contract we drafted; 18 have no recorded run. Read from Syntology's graph 2026-09-24; that is when this build read the record, not when the samples ran.

3ran · honoured contract
1ran · violated contract
45ran · our draft was wrong
23ran
18unverified

Licence: 0 of the 90 samples are pointer only, meaning Syntology does not serve that copy's text. This page shows no code text for any sample; each one links to its file in the repository.

Harvested from yingpengma/NCP-Bench. “Ran” means the sample executed on a synthesized input. It does not mean the output is correct, and nothing here reproduces the paper's results. “Honoured” and “violated” refer to a contract Syntology drafted from the code itself; “our draft was wrong” and “fixture could not drive it” are failures of Syntology's instrument, not of the code.

Each sample ends with its code_sha256, Syntology's identity for that exact code. An agent fetches the stored sample with Syntology's MCP tool get_code(code_sha256="…") (how to connect); click an identity to copy that call.

Repository labels, per sample. official repository: The archive marks this repository official for the paper. named in the paper: The archive records that the paper mentions this repository; it is not marked official. community (archive-listed): In the archive's code links for this paper, not marked official and not recorded as mentioned in the paper. found in paper text by Syntology: Syntology found this repository in the paper's own text; whether it is the authors' implementation is not asserted. community: Not in the archive's code links for this paper; a community repository Syntology harvested. Samples from a repository marked official are listed first. Licence labels name the repository's licence as recorded at harvest. “Pointer only” means Syntology does not serve that copy's text, for one of four reasons: no licence file was found; the licence was not identified; the licence is recorded as permissive but that copy's record is not marked cleared; or the licence is outside the permissive list Syntology serves text under (MIT, Apache-2.0, BSD and similar). Some licences outside that list permit redistribution, such as WTFPL, and GPL-3.0 under its conditions; they are simply not on the list. Hover a licence label for the reason. File links open the file on GitHub at the default branch, which may have changed since the harvest.

Commitment yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran MIT (permissive) · 6baefa8c03c8073b · report
CommitmentAssessment yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran MIT (permissive) · 477d617508a01ed1 · report
CommitmentCheckRequest yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran MIT (permissive) · 225c1e1d6aa8ef52 · report
Conflict yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran MIT (permissive) · 9275d276c18d1265 · report
ConflictDecision yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran MIT (permissive) · 7e4e25bf99b30656 · report
EpisodeCheckpoint yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran MIT (permissive) · 403039263cff2dee · report
EpisodeContext yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran MIT (permissive) · 26e59d268abd3a42 · report
EpisodeSession yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran MIT (permissive) · d0aa116f6e67740f · report
EpisodeState yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran MIT (permissive) · a4d578af7dc4366a · report
EpisodeTransition yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran MIT (permissive) · cf5ff3d591cc004d · report
EvaluationPrompts yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran MIT (permissive) · a397eb49bee1be3b · report
Fact yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran MIT (permissive) · 0b6ddc7118f4a20c · report
FactUpdate yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran MIT (permissive) · cf34436e377a3111 · report
NarratorRequest yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran MIT (permissive) · dc74c41ca23b2db8 · report
NarratorResponse yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran MIT (permissive) · 5c2ee2ba5d267cdf · report
OpeningRequest yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran MIT (permissive) · ef12c1f61aaa23e9 · report
PendingFactUpdates yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran MIT (permissive) · d9d593f13f3d399f · report
StoryTurn yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran MIT (permissive) · 48a18311c6707329 · report
TrajectoryAssessment yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran MIT (permissive) · 3c29c0dff5302cdc · report
TrajectoryCheckRequest yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran MIT (permissive) · 05547bdfc564737a · report
TrajectoryNode yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran MIT (permissive) · a4a0ea3a436605c0 · report
TurnAuditContext yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran MIT (permissive) · ae6e086b9871bf9c · report
TurnEvaluation yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran MIT (permissive) · 96ded29e4b2b6edb · report
_apply_commitment_assessments yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran · our draft was wrong MIT (permissive) · 87a83c6c64d04d33 · report
_apply_trajectory_assessments yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran · our draft was wrong MIT (permissive) · 881b3ff52990ad4f · report
_build_audit_context yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran · our draft was wrong MIT (permissive) · 03e084c6b85cff45 · report
_conflict_items yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran · our draft was wrong MIT (permissive) · 3d68030ecaab9187 · report
_conflict_variables yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran · our draft was wrong MIT (permissive) · 0b571550ec2f8bd1 · report
_conflicts_for_review yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran · our draft was wrong MIT (permissive) · e78fa6a936db28b3 · report
_current_node_id yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran · our draft was wrong MIT (permissive) · bb147fbdb564ab08 · report
_current_trajectory_node yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran · our draft was wrong MIT (permissive) · f48d2b516188201f · report
_first_pending_node_index yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran · honoured contract MIT (permissive) · 4699f523e541d887 · report
_format_active_facts yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran · our draft was wrong MIT (permissive) · 77812a1aa0267b64 · report
_format_checker_commitments yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran · our draft was wrong MIT (permissive) · 39b6c97dcbe721ff · report
_format_checker_facts yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran · our draft was wrong fingerprinted MIT (permissive) · ddbf1846483032a8 · report
_format_checker_history yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran · our draft was wrong fingerprinted MIT (permissive) · 031f59d0efdc193a · report
_format_checker_node yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran · our draft was wrong MIT (permissive) · 308388e14916159e · report
_format_checker_trajectory yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran · our draft was wrong fingerprinted MIT (permissive) · ad2949a66ba46899 · report
_format_commitments yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran · our draft was wrong MIT (permissive) · 9d6c46c34b72e542 · report
_format_current_node yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran · our draft was wrong MIT (permissive) · 8ac58d2d21e6dd5f · report
_format_fact_update yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran · our draft was wrong MIT (permissive) · 4eabff48b3f6c214 · report
_format_facts yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran · our draft was wrong MIT (permissive) · ab51c15d8e068455 · report
_format_history yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran · our draft was wrong MIT (permissive) · a496e6b2203db33d · report
_format_node yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran · our draft was wrong MIT (permissive) · 6374f68069f53487 · report
_format_trajectory yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran · our draft was wrong MIT (permissive) · b9cc93c37c18d98c · report
_next_fact_id yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran · our draft was wrong MIT (permissive) · bd7ac87f8e14dbfc · report
_next_turn_id yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran · honoured contract MIT (permissive) · f4dc8710f789a065 · report
_normalize_facts yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran · our draft was wrong MIT (permissive) · e7de95262c944927 · report
_optional_string yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran · our draft was wrong fingerprinted MIT (permissive) · 35093190a7dd3b9b · report
_parse_commitment_statuses yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran · our draft was wrong MIT (permissive) · 48d4ada89ebbfef0 · report
_parse_conflict yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran · our draft was wrong MIT (permissive) · a9f899432b8e62db · report
_parse_conflict_decision yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran · our draft was wrong MIT (permissive) · 676a716e20a2dbf6 · report
_parse_conflict_payload yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran · our draft was wrong MIT (permissive) · 800e659cf94b9784 · report
_parse_conflict_review_payload yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran · our draft was wrong MIT (permissive) · f83b8661a7ad2296 · report
_parse_fact_update yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran · our draft was wrong MIT (permissive) · 936423ca29b5af3b · report
_parse_fact_updates yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran · our draft was wrong MIT (permissive) · daee147005f7e47a · report
_parse_trajectory_response yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran · our draft was wrong MIT (permissive) · 91130ae0675a62a6 · report
_required_nonnegative_int yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran · honoured contract MIT (permissive) · b631a97caeadc467 · report
_required_string yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran · our draft was wrong MIT (permissive) · 48b4c9e809d45ecd · report
_required_string_list yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran · our draft was wrong MIT (permissive) · cc56c9f0cdcf1c00 · report
_string_list yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran · our draft was wrong MIT (permissive) · fdd1c66fde7c0117 · report
active_facts yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran · our draft was wrong MIT (permissive) · 00f6e69066ce946e · report
all_achievement_commitments_resolved yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran · violated contract MIT (permissive) · 21f2de0b99d91a74 · report
apply_fact_updates yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran · our draft was wrong MIT (permissive) · 166c401d938d993b · report
call_with_retries yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran · our draft was wrong MIT (permissive) · ee27fb0345c48b9e · report
initialize_episode_state yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran · our draft was wrong MIT (permissive) · 680abdbff4c5f360 · report
parse_json_object yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran · our draft was wrong MIT (permissive) · 8cd4a00832b05c68 · report
render_conflict_check yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran · our draft was wrong MIT (permissive) · 51f2305ee1b5ff12 · report
render_conflict_double_check yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran · our draft was wrong MIT (permissive) · 4efbd7e33da0c1a6 · report
render_fact_update yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran · our draft was wrong MIT (permissive) · 5e5fa92d8ea0338b · report
render_status_check yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran · our draft was wrong MIT (permissive) · f938f6e8359bf88e · report
render_trajectory_check yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology ran · our draft was wrong MIT (permissive) · 4dac9b8189adc047 · report
AuditorClient yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology unverified MIT (permissive) · eac5519024e14bb5 · report
CommitmentChecker yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology unverified MIT (permissive) · 12af0219d50bab23 · report
EpisodeRunner yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology unverified MIT (permissive) · 9b7d37cf3b082cce · report
EpisodeTermination yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology unverified MIT (permissive) · d8072777741ab0c2 · report
EpisodeTrace yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology unverified MIT (permissive) · 5e5e2bef2c3fb7bd · report
EpisodeTurnResult yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology unverified MIT (permissive) · 59b2101d4d593b4f · report
ModelCallError yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology unverified MIT (permissive) · 85bb618d6063baf6 · report
ModelOutputError yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology unverified MIT (permissive) · db95fd949e2fe427 · report
Narrator yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology unverified MIT (permissive) · 65670dfb60b8bed3 · report
OpeningAuditClient yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology unverified MIT (permissive) · c65c208c583165f6 · report
OpeningEvaluationError yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology unverified MIT (permissive) · 9b8e90476ed709e8 · report
OpeningEvaluator yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology unverified MIT (permissive) · fa59174576ea3ade · report
TrajectoryChecker yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology unverified MIT (permissive) · fda2bd9500e337b2 · report
TurnEvaluator yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology unverified MIT (permissive) · 49bf002b2ae80821 · report
_validate_conflict_payload yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology unverified MIT (permissive) · b3a5232b359f120d · report
apply_turn_outcome yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology unverified MIT (permissive) · 4b6ef600389c3d83 · report
load_evaluation_prompts yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology unverified MIT (permissive) · 38f0bcdf3fb430c4 · report
render_opening_fact_extract_prompt yingpengma/NCP-Bench/src/ncpbench/runner.py found in paper text by Syntology unverified MIT (permissive) · e37b77125d144e74 · report

Results from the paper

The Papers with Code archive ends with its 2025-07-28 snapshot. This paper's arXiv identifier, 2608.08160, was issued in August 2026, after that date, so the archive has no leaderboard rows for it.

Report a problem or propose a change · a person checks every report against the paper or source before anything changes; decisions are listed on /corrections