Files
codex/prs/bolinfest/study/PR-2595-study.md
2025-09-02 15:17:45 -07:00

4.4 KiB
Raw Blame History

DOs

  • Keep PRs Focused: Limit changes to moving models.rs and the required import updates; defer unrelated protocol/API additions to a separate PR.
// Good: only path + import updates

// core/src/lib.rs
- mod models;
+ // models moved to protocol

// any module using models
- use crate::models::ResponseItem;
+ use codex_protocol::models::ResponseItem;
  • Update Imports Consistently: Replace crate::models::* with codex_protocol::models::* across the codebase.
- use crate::models::{ContentItem, ResponseItem, ReasoningItemContent};
+ use codex_protocol::models::{ContentItem, ResponseItem, ReasoningItemContent};
  • Use Fully Qualified Paths In Matches When Helpful: Avoid ambiguity after the move, especially in pattern matches.
let is_assistant_delta = matches!(
    &item,
    codex_protocol::models::ResponseItem::Message { role, .. } if role == "assistant"
);
  • Justify Protocol Dependencies: Add deps (e.g., base64, mime_guess, tracing) to protocol only if models.rs truly needs them for serialization or type helpers; note why in the PR.
# codex-rs/protocol/Cargo.toml
[dependencies]
base64 = "0.22.1"      # encoding attachments in models
mime_guess = "2.0.5"   # inferring content-types for file items
tracing = "0.1.41"     # protocol-level diagnostics (if unavoidable)
// Example: encoding a payload inside protocol models
let encoded = base64::encode(&bytes);
  • Preserve Behavior While Relocating: Moves should not change runtime logic or filtering; keep conversions and aggregations identical.
// Keep existing content mapping behavior intact when moving code.
content: items
    .iter()
    .filter_map(|i| match i {
        InputItem::Text { text } => Some(ContentItem::InputText { text: text.clone() }),
        // keep prior arms and catch-alls as-is to avoid behavior drift
        _ => None,
    })
    .collect(),
  • Validate With Targeted Tests First: Run protocol and core tests after changes; then run the full suite if common types changed.
# Format + lint (from codex-rs/)
just fmt
just fix -p codex-protocol
cargo test -p codex-protocol
cargo test -p codex-core
cargo test --all-features
  • Be Explicit When Constructing Moved Types: Build items using the new module path to make intent obvious.
let aggregated = codex_protocol::models::ResponseItem::Message {
    id: None,
    role: "assistant".to_string(),
    content: vec![codex_protocol::models::ContentItem::OutputText {
        text: buffer,
    }],
};

DONTs

  • Dont Introduce Unrelated Protocol Ops/Events: Avoid adding new variants like Op::GetHistory or EventMsg::ConversationHistory in a “move-only” PR.
// Bad: out-of-scope for a file move
pub enum Op {
    Compact,
    Shutdown,
    GetHistory, // <-- why in this PR?
}

pub enum EventMsg {
    ShutdownComplete,
    ConversationHistory(ConversationHistoryEvent), // <-- unrelated addition
}
  • Dont Add New API Variants Without Rationale: Adding ResponseItem::CustomToolCall expands the wire protocol—separate PR with justification and downstream updates.
// Bad: new wire variant slipped into a refactor
pub enum ResponseItem {
    Message { /* ... */ },
    ToolCall { /* ... */ },
    FunctionCallOutput { /* ... */ },
    CustomToolCall { /* ... */ }, // <-- why now?
}
  • Dont Expand Protocol Responsibilities Needlessly: Keep business logic out of protocol; it should define types and minimal helpers only.
// Bad: complex aggregation/business logic in protocol
impl ResponseItem {
    pub fn aggregate_streaming_reasoning(...) -> Self { /* non-protocol logic */ }
}
  • Dont Create Dependency Drag: If a helper can live in core, dont add a dependency to protocol just to support it.
# Bad: protocol now depends on a heavy crate used only by core features
some-heavy-crate = "1"
  • Dont Change Formatting/Behavior While Moving: Avoid incidental logic edits (e.g., removing a match arm) that alter filtering or emitted items.
// Bad: removing a catch-all subtly changes behavior
- _ => None,
+ // (removed) now non-matching items are silently dropped differently
  • Dont Leave Type Names Ambiguous: After the move, dont rely on old paths or shadowed names.
// Bad
use crate::models::*; // no longer valid, confusing after the move

// Good
use codex_protocol::models::{ResponseItem, ContentItem};