Skip to content

fix(engine): make no-op rollback side-effect free - #566

Merged
GhostXia merged 4 commits into
mainfrom
codex/issue-140-rollback-semantics
Aug 13, 2026
Merged

fix(engine): make no-op rollback side-effect free#566
GhostXia merged 4 commits into
mainfrom
codex/issue-140-rollback-semantics

Conversation

@GhostXia

Copy link
Copy Markdown
Owner

Summary

  • define rollback to the current active leaf as a pure no-op
  • preserve updated_at, revision, and on-disk bytes for successful no-op retries
  • document the persistence contract and add legacy-load regression coverage

Validation

  • cargo test -p airp-core --lib chat_store::tests::rollback_to --locked -- --nocapture (4 passed)
  • cargo test -p airp-core --lib domain::tests::rollback --locked -- --nocapture (4 passed)
  • cargo fmt --all -- --check
  • git diff --check

Closes #140

@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@GhostXia, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 11 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: eefb532c-d6cd-4b7f-9925-0b499bf67023

📥 Commits

Reviewing files that changed from the base of the PR and between f2bea56 and 8dab0ea.

📒 Files selected for processing (3)
  • docs/audits/2026-08-13-PR-566-rollback-noop-audit.md
  • engine/README.md
  • engine/src/chat_store.rs

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown

⚠️ Agent exploration runner failed

The exploration runner exited with a non-zero status. The actual report comment may be missing or partial.

  • See the workflow run for logs.
  • Download the agent-exploration-566 artifact for any partial report/trace files.

This is a non-blocking placeholder (workflow has continue-on-error: true); merge is not blocked. Investigate the failure if it persists.

@github-actions

Copy link
Copy Markdown

⚠️ Non-blocking (阶段 2 MVP): 此报告不阻塞 PR 合并。崩溃/数据损坏/安全问题需人工确认;可用性问题仅记录。

Agent Browser Exploration Report

Run ID: run-1786545873769
Trigger: pr-566
PR: 566
Started: 2026-08-12T14:44:33.769Z
Duration: 221236ms
LLM: deepseek-v4-flash

Summary

  • Total tasks: 1
  • Passed: 0
  • Failed: 1
  • Flaky: 0

Task: edit-branch-switch-refresh

Result: Failed

Description

前置:用 API 准备一个角色 + 一个有至少 2 轮对话的 session。

步骤提示:

  1. 导航到 02-chat-space.html?character=&session=
  2. 记录当前 history 的所有 message_ids 和 active_leaf(通过 /v1/chat/history)
  3. 找到第一条 role=user 消息的 message_id
  4. 调 PUT /v1/chat/message 编辑该用户消息 content 为 'I changed my question: what is the library policy on late returns?'
  5. 由于编辑历史用户消息会触发分支语义(按 engine 当前实现:编辑 user 消息可能创建分支或原地替换;
    以 engine 实现为准),调 /v1/chat/history 确认当前 active path 状态
  6. 如果 engine 支持分支(chat_store 有 branch_tree):调 /v1/chat/branch/switch
    切换到原 active_leaf(编辑前的 leaf)
  7. 在原分支继续发一条用户消息 'Thanks.', 等待 assistant 回复
  8. 切换回新分支(编辑后的 leaf),发一条用户消息 'And the fines?', 等待 assistant 回复
  9. 多次切换两个分支(至少 3 次来回),每次确认 history 只显示当前 active path
  10. 刷新页面:await ctx.page.reload()
  11. 再次调 /v1/chat/history
  12. ASSERT: 当前 active_leaf 与刷新前一致
  13. ASSERT: 当前 active path 的消息序列与刷新前一致
  14. ASSERT: 另一分支的数据未被删除(切回另一分支验证其消息序列仍在)

Expected

编辑历史用户消息后建立的分支,与原分支共存;
多次切换后,刷新页面应保持当前 active path;
另一分支数据未被污染或删除。

Actual

Error: agent script failed after 3 revisions; last error:
Script validation failed (script NOT executed):

  • JavaScript module syntax check failed: [stdin]:2 "active_leaf": "uuid", ^ SyntaxError: Unexpected token ':' at checkSyntax (node:internal/main/check_syntax:74:5) at node:internal/main/check_syntax:45:5 at Socket. (node:internal/process/execution:234:5) at Socket.emit (node:events:536:35) at endReadableNT (node:internal/streams/readable:1698:12) at process.processTicksAndRejections (node:internal/process/task_queues:82:21) Node.js v20.20.2
  • Missing required module export: export async function run(ctx)

Fix these and re-output the complete script.
at generateAndRunScript (file:///home/runner/work/AIRP/AIRP/tools/agent-exploration/runner.mjs:470:17)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async runTask (file:///home/runner/work/AIRP/AIRP/tools/agent-exploration/runner.mjs:336:26)
at async runTasks (file:///home/runner/work/AIRP/AIRP/tools/agent-exploration/runner.mjs:184:16)
at async main (file:///home/runner/work/AIRP/AIRP/tools/agent-exploration/runner.mjs:157:9)
at async file:///home/runner/work/AIRP/AIRP/tools/agent-exploration/runner.mjs:662:3

Evidence

  • script: /home/runner/work/AIRP/AIRP/artifacts/agent-exploration/edit-branch-switch-refresh/agent-script-revision-2.mjs
  • trace: /home/runner/work/AIRP/AIRP/artifacts/agent-exploration/edit-branch-switch-refresh/trace.zip

@github-actions

Copy link
Copy Markdown

⚠️ Agent exploration runner failed

The exploration runner exited with a non-zero status. The actual report comment may be missing or partial.

  • See the workflow run for logs.
  • Download the agent-exploration-566 artifact for any partial report/trace files.

This is a non-blocking placeholder (workflow has continue-on-error: true); merge is not blocked. Investigate the failure if it persists.

@github-actions

Copy link
Copy Markdown

⚠️ Non-blocking (阶段 2 MVP): 此报告不阻塞 PR 合并。崩溃/数据损坏/安全问题需人工确认;可用性问题仅记录。

Agent Browser Exploration Report

Run ID: run-1786547312605
Trigger: pr-566
PR: 566
Started: 2026-08-12T15:08:32.605Z
Duration: 216142ms
LLM: deepseek-v4-flash

Summary

  • Total tasks: 1
  • Passed: 0
  • Failed: 1
  • Flaky: 0

Task: edit-branch-switch-refresh

Result: Failed

Description

前置:用 API 准备一个角色 + 一个有至少 2 轮对话的 session。

步骤提示:

  1. 导航到 02-chat-space.html?character=&session=
  2. 记录当前 history 的所有 message_ids 和 active_leaf(通过 /v1/chat/history)
  3. 找到第一条 role=user 消息的 message_id
  4. 调 PUT /v1/chat/message 编辑该用户消息 content 为 'I changed my question: what is the library policy on late returns?'
  5. 由于编辑历史用户消息会触发分支语义(按 engine 当前实现:编辑 user 消息可能创建分支或原地替换;
    以 engine 实现为准),调 /v1/chat/history 确认当前 active path 状态
  6. 如果 engine 支持分支(chat_store 有 branch_tree):调 /v1/chat/branch/switch
    切换到原 active_leaf(编辑前的 leaf)
  7. 在原分支继续发一条用户消息 'Thanks.', 等待 assistant 回复
  8. 切换回新分支(编辑后的 leaf),发一条用户消息 'And the fines?', 等待 assistant 回复
  9. 多次切换两个分支(至少 3 次来回),每次确认 history 只显示当前 active path
  10. 刷新页面:await ctx.page.reload()
  11. 再次调 /v1/chat/history
  12. ASSERT: 当前 active_leaf 与刷新前一致
  13. ASSERT: 当前 active path 的消息序列与刷新前一致
  14. ASSERT: 另一分支的数据未被删除(切回另一分支验证其消息序列仍在)

Expected

编辑历史用户消息后建立的分支,与原分支共存;
多次切换后,刷新页面应保持当前 active path;
另一分支数据未被污染或删除。

Actual

Error: agent script failed after 3 revisions; last error:
Script validation failed (script NOT executed):

  • JavaScript module syntax check failed: [stdin]:6 if (backLeaf !== originalLeaf) { natural? } ^ SyntaxError: Unexpected token '}' at checkSyntax (node:internal/main/check_syntax:74:5) at node:internal/main/check_syntax:45:5 at Socket. (node:internal/process/execution:234:5) at Socket.emit (node:events:536:35) at endReadableNT (node:internal/streams/readable:1698:12) at process.processTicksAndRejections (node:internal/process/task_queues:82:21) Node.js v20.20.2
  • Missing required module export: export async function run(ctx)

Fix these and re-output the complete script.
at generateAndRunScript (file:///home/runner/work/AIRP/AIRP/tools/agent-exploration/runner.mjs:470:17)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async runTask (file:///home/runner/work/AIRP/AIRP/tools/agent-exploration/runner.mjs:336:26)
at async runTasks (file:///home/runner/work/AIRP/AIRP/tools/agent-exploration/runner.mjs:184:16)
at async main (file:///home/runner/work/AIRP/AIRP/tools/agent-exploration/runner.mjs:157:9)
at async file:///home/runner/work/AIRP/AIRP/tools/agent-exploration/runner.mjs:662:3

Evidence

  • script: /home/runner/work/AIRP/AIRP/artifacts/agent-exploration/edit-branch-switch-refresh/agent-script-revision-2.mjs
  • trace: /home/runner/work/AIRP/AIRP/artifacts/agent-exploration/edit-branch-switch-refresh/trace.zip

@github-actions

Copy link
Copy Markdown

⚠️ Agent exploration runner failed

The exploration runner exited with a non-zero status. The actual report comment may be missing or partial.

  • See the workflow run for logs.
  • Download the agent-exploration-566 artifact for any partial report/trace files.

This is a non-blocking placeholder (workflow has continue-on-error: true); merge is not blocked. Investigate the failure if it persists.

@github-actions

Copy link
Copy Markdown

⚠️ Non-blocking (阶段 2 MVP): 此报告不阻塞 PR 合并。崩溃/数据损坏/安全问题需人工确认;可用性问题仅记录。

Agent Browser Exploration Report

Run ID: run-1786610452846
Trigger: pr-566
PR: 566
Started: 2026-08-13T08:40:52.846Z
Duration: 169015ms
LLM: deepseek-v4-flash

Summary

  • Total tasks: 1
  • Passed: 0
  • Failed: 1
  • Flaky: 0

Task: edit-branch-switch-refresh

Result: Failed

Description

前置:用 API 准备一个角色 + 一个有至少 2 轮对话的 session。

步骤提示:

  1. 导航到 02-chat-space.html?character=&session=
  2. 记录当前 history 的所有 message_ids 和 active_leaf(通过 /v1/chat/history)
  3. 找到第一条 role=user 消息的 message_id
  4. 调 PUT /v1/chat/message 编辑该用户消息 content 为 'I changed my question: what is the library policy on late returns?'
  5. 由于编辑历史用户消息会触发分支语义(按 engine 当前实现:编辑 user 消息可能创建分支或原地替换;
    以 engine 实现为准),调 /v1/chat/history 确认当前 active path 状态
  6. 如果 engine 支持分支(chat_store 有 branch_tree):调 /v1/chat/branch/switch
    切换到原 active_leaf(编辑前的 leaf)
  7. 在原分支继续发一条用户消息 'Thanks.', 等待 assistant 回复
  8. 切换回新分支(编辑后的 leaf),发一条用户消息 'And the fines?', 等待 assistant 回复
  9. 多次切换两个分支(至少 3 次来回),每次确认 history 只显示当前 active path
  10. 刷新页面:await ctx.page.reload()
  11. 再次调 /v1/chat/history
  12. ASSERT: 当前 active_leaf 与刷新前一致
  13. ASSERT: 当前 active path 的消息序列与刷新前一致
  14. ASSERT: 另一分支的数据未被删除(切回另一分支验证其消息序列仍在)

Expected

编辑历史用户消息后建立的分支,与原分支共存;
多次切换后,刷新页面应保持当前 active path;
另一分支数据未被污染或删除。

Actual

Error: agent script failed after 3 revisions; last error:
Error: ASSERT: user message id missing in history response
at Module.run (file:///home/runner/work/AIRP/AIRP/artifacts/agent-exploration/edit-branch-switch-refresh/agent-script-revision-2.mjs?t=1786610620133:33:30)
at async runTempScript (file:///home/runner/work/AIRP/AIRP/tools/agent-exploration/runner.mjs:624:5)
at async generateAndRunScript (file:///home/runner/work/AIRP/AIRP/tools/agent-exploration/runner.mjs:463:24)
at async runTask (file:///home/runner/work/AIRP/AIRP/tools/agent-exploration/runner.mjs:336:26)
at async runTasks (file:///home/runner/work/AIRP/AIRP/tools/agent-exploration/runner.mjs:184:16)
at async main (file:///home/runner/work/AIRP/AIRP/tools/agent-exploration/runner.mjs:157:9)
at async file:///home/runner/work/AIRP/AIRP/tools/agent-exploration/runner.mjs:662:3
at generateAndRunScript (file:///home/runner/work/AIRP/AIRP/tools/agent-exploration/runner.mjs:470:17)
at async runTask (file:///home/runner/work/AIRP/AIRP/tools/agent-exploration/runner.mjs:336:26)
at async runTasks (file:///home/runner/work/AIRP/AIRP/tools/agent-exploration/runner.mjs:184:16)
at async main (file:///home/runner/work/AIRP/AIRP/tools/agent-exploration/runner.mjs:157:9)
at async file:///home/runner/work/AIRP/AIRP/tools/agent-exploration/runner.mjs:662:3

Evidence

  • script: /home/runner/work/AIRP/AIRP/artifacts/agent-exploration/edit-branch-switch-refresh/agent-script-revision-2.mjs
  • trace: /home/runner/work/AIRP/AIRP/artifacts/agent-exploration/edit-branch-switch-refresh/trace.zip

@GhostXia
GhostXia merged commit 6e090df into main Aug 13, 2026
9 of 10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

audit(engine): define no-op rollback persistence semantics

1 participant