Skip to content

fix: bind plan acceptance to reviewed proposal - #316

Merged
EvanProgramming merged 4 commits into
mainfrom
Evan/plan-acceptance-identity-followup
Oct 29, 2026
Merged

EvanProgramming merged 4 commits into
mainfrom
Evan/plan-acceptance-identity-followup

Conversation

@EvanProgramming

@EvanProgramming EvanProgramming commented Oct 28, 2026 •

Copy link
Copy Markdown
Owner

Summary

Follow-up to merged PR #287 for the queued plan-acceptance identity regression. This does not close #245, which is already closed.

Root cause and approach

Acceptance boundaries carried plan ID and version but dropped the proposal fingerprint; Web/TUI text acceptance could also read a proposal only after its worker was queued. Two proposals with the same plan ID/version could therefore let an old acceptance select the replacement. This change snapshots ID/version/fingerprint at CLI, Web, and TUI ingress, carries it through queued execution, and rechecks all three fields before acceptance. The persistence transaction compares the expected proposal identity while atomically committing the Working Plan and acceptance event. Web structured actions and the Go TUI send the fingerprint. Duplicate accepts are idempotent only when the accepted fingerprint matches; stale duplicates return an error.

Validation

  • Regression coverage includes same-version proposal replacement, Web structured/text/stream acceptance, TUI identity snapshot/forwarding, and stale duplicate accepts in Web and TUI.
  • Current-head CI passed core-test, python-test, TUI tests, wheel installation plus TUI workflow acceptance, installer syntax, Docker persistence, website build, and installed-update checks on Linux, macOS, and Windows. full-python-312 was skipped by the configured CI selector.
  • An initial Python 3.13 run and wheel acceptance run encountered temporary-directory/partial-JSON cleanup races in unrelated fixtures; targeted retries passed.
  • Local tests cannot import in this checkout because fastapi, rich, and requests are unavailable. make lint and git diff --check pass; make check stops because requests is unavailable.
  • Commits are signed and verified with the existing GPG key.

Risk and limitations

Clients accepting a proposal must send its fingerprint; missing or stale fingerprints are rejected and require refreshing the proposal. Merged as commit 85cbb9f8d37a5d4bdcc0ce664bea2f5a898e9388. The required CI aggregate passed; the full-python-312 job was skipped by the configured CI selector.

Summary by CodeRabbit

  • Bug Fixes
    • Plan acceptance now verifies the proposal’s fingerprint, preventing delayed requests from accepting a replacement proposal—even when its ID and version are unchanged.
    • Stale acceptance attempts are rejected, while matching repeat requests are recognized as already accepted.
    • CLI, web, and terminal interfaces now include the fingerprint when accepting a plan, including through text-based requests.
  • Documentation
    • Clarified that acceptance requests must include the pending proposal’s fingerprint.

@coderabbitai

coderabbitai Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Caution

Review failed

The pull request is closed.

Walkthrough

Plan acceptance now includes the pending proposal’s fingerprint across agent, web, CLI, and TUI paths. The agent rejects acceptance when the fingerprint does not match the current or recorded plan. Tests cover stale requests and text-based acceptance.

Changes: Fingerprint-bound plan acceptance

Layer / File(s) Summary
Validate plan acceptance identity
openkyrozen/agent/loop.py, openkyrozen/agent/modes.py, tests/test_interaction.py
Acceptance checks include the plan fingerprint. A regression test confirms that acceptance using an old fingerprint does not accept a replacement proposal with the same plan ID and version.
Web and CLI acceptance requests
openkyrozen/interfaces/web/chat.py, openkyrozen/interfaces/web/templates/chat.html, openkyrozen/interfaces/cli/chat.py, docs/api.md, tests/test_server.py
Web and CLI requests pass the fingerprint. Web text-based acceptance derives the plan identity from the pending plan. Server tests cover matching and stale fingerprints, including duplicate acceptance.
TUI acceptance requests
openkyrozen/interfaces/tui/*, tui/model.go, tui/events.go, tui/input.go, tui/main_test.go, tests/test_tui_protocol.py
The TUI stores and sends the fingerprint with plan acceptance. Text-based acceptance snapshots the plan identity, and tests check forwarding and stale-fingerprint errors.

Delegation request header test

Layer / File(s) Summary
Update credential header assertions
tests/test_delegation.py
The test uses httpx.Headers and accepts the fixture credential in either supported header form.

Priority: Not assessed

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Bug fix

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant WebChatEndpoint
  participant ChatWorker
  participant AgentLoop
  participant InteractionController
  User->>WebChatEndpoint: Send text-based plan acceptance
  WebChatEndpoint->>ChatWorker: Snapshot pending plan ID, version, and fingerprint
  ChatWorker->>AgentLoop: Pass plan acceptance data
  AgentLoop->>InteractionController: Call accept_plan with fingerprint
Loading
Merge Risk: Moderate · up to 48896

The change binds plan acceptance to the reviewed proposal, but a few paths can still accept or report as accepted a proposal the user did not review: TUI text acceptance with a trailing inline command, Web text acceptance racing a replacement proposal, and duplicate-acceptance detection for a same-version replacement. The window is narrow, but these gaps defeat the purpose of the fix, so resolve them before merging.

Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

@ghfind-review ghfind-review Bot added review: high ghfind author score; see https://ghfind.com area: security Capabilities, approvals, scope boundaries, and OS sandboxing area:cli Command-line and terminal UI bug Something isn't working labels Oct 28, 2026
@EvanProgramming
EvanProgramming marked this pull request as ready for review October 29, 2026 02:22
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-29T02:24:02.396720Z 4889633 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Oct 29, 2026 •

Copy link
Copy Markdown
⚠️ Action not completed

Pull request is closed.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@EvanProgramming
EvanProgramming merged commit 85cbb9f into main Oct 29, 2026
33 of 39 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:cli Command-line and terminal UI area: security Capabilities, approvals, scope boundaries, and OS sandboxing bug Something isn't working review: high ghfind author score; see https://ghfind.com

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[V3] Preserve Plan Mode with versioned, user-approved Strategic Plans

1 participant