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

182 lines
6.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
**Streaming Markdown PR #1920 — Reviewer Takeaways (bolinfest)**
**DOs**
- Boldly separate unrelated changes: land independent fixes in their own commits/PRs.
- Why: Keeps review focused and reduces risk. Example: handle a new SSE event in core separately from UI streaming changes.
- Example:
```rust
// Commit A (core): precise SSE handling
match event_name.as_str() {
"response.reasoning_summary_part.added" => { /* intentionally ignored */ }
"response.reasoning_summary_text.done" => {
let event = ResponseEvent::ReasoningSummaryDelta("\n\n".to_string());
if tx_event.send(Ok(event)).await.is_err() { return; }
}
other => debug!(other, "sse event"),
}
// Commit B (tui): markdown streaming mechanics
// ... all UI-only code here ...
```
- Be precise about where logic belongs: put new behavior on the exact event arm intended.
- Why: Avoids accidental logging/no-op paths and makes intent obvious.
- Example:
```rust
match event_name.as_str() {
// Correct: “part.added” is handled (ignored) distinctly,
// so it doesnt fall into `other` logging.
"response.reasoning_summary_part.added" => { /* ignore */ }
// Correct: the “text.done” terminator emits a separator.
"response.reasoning_summary_text.done" => {
let e = ResponseEvent::ReasoningSummaryDelta("\n\n".to_string());
if tx_event.send(Ok(e)).await.is_err() { return; }
}
other => debug!(other, "sse event"),
}
```
- Implement fenced code parsing per Markdown rules: detect fences of length ≥ 3 and require an exact-length match to close; support both backticks and tildes.
- Why: Real markdown allows longer fences; closing fence length must equal opening length.
- Example:
```rust
fn fence_open(line: &str) -> Option<(&'static str, usize, Option<String>)> {
let t = line.trim_start();
for token in ["`", "~"] {
let count = t.chars().take_while(|&c| c.to_string() == token).count();
if count >= 3 {
let rest = &t[count..];
let lang = rest.trim().split_whitespace().next()
.filter(|s| !s.is_empty()).map(|s| s.to_string());
return Some((token, count, lang));
}
}
None
}
fn fence_close(line: &str, token: &str, len: usize) -> bool {
let t = line.trim();
t.chars().take_while(|&c| c.to_string() == token).count() == len
&& t.chars().skip(len).all(char::is_whitespace)
}
```
- Guard streaming against partial fences: buffer inside an open fence and emit only after the closing fence arrives.
- Why: Prevents stray backticks and malformed code in history.
- Example:
```rust
if in_fence {
if fence_close(delta_line, fence_token, fence_len) {
in_fence = false;
commit(render_code_block(&buffered_code));
buffered_code.clear();
} else {
buffered_code.push_str(delta_line);
}
continue;
}
```
- Add tight tests for edge cases the spec permits: longer fences, mismatched closers, mixed tildes/backticks, and headings or lists adjacent to code blocks.
- Example:
```rust
// open with 5 backticks, close with exactly 5
assert!(fence_open("`````rust").is_some());
assert!(fence_close("`````", "`", 5));
assert!(!fence_close("```", "`", 5)); // wrong length
// support tildes too
assert!(fence_open("~~~~~").is_some());
```
- Keep comments crisp and intent-focused: explain “why” (spec/contract) where non-obvious, not “what”.
- Example:
```rust
// Markdown: closing fence must equal opening fence length (CommonMark).
if fence_close(line, token, len) { /* ... */ }
```
**DONTs**
- Dont couple orthogonal fixes to UI refactors.
- Anti-pattern:
```rust
// Mixed in the streaming PR:
// - add new SSE event handling in core
// - change TUI streaming, animation, and tests
// Reviewers cant isolate the behavioral change from UI changes.
```
- Preferred: land the SSE event handling first (or separately), then the TUI work.
- Dont place new logic on the wrong match arm (or hide it behind “other” logging).
- Anti-pattern:
```rust
match event_name.as_str() {
// Oops: both events lumped into the ignored set
"response.reasoning_summary_part.added"
| "response.reasoning_summary_text.done" => { /* ignored */ }
other => debug!(other, "sse event"),
}
```
- Fix:
```rust
"response.reasoning_summary_part.added" => { /* ignore */ }
"response.reasoning_summary_text.done" => { /* emit separator */ }
```
- Dont assume fences are exactly three backticks; dont allow mismatched closers.
- Anti-pattern:
```rust
if line.trim_start().starts_with("```") { in_fence = true; }
// ...
if line.trim() == "```" { in_fence = false; } // wrong: ignores 4+, mismatch
```
- Fix:
```rust
if let Some((tok, len, _)) = fence_open(line) {
fence_token = tok.to_string();
fence_len = len;
in_fence = true;
}
if fence_close(line, &fence_token, fence_len) { in_fence = false; }
```
- Dont stream incomplete fenced content or fence markers into history.
- Anti-pattern:
```rust
history.push(format!("```{}", lang).into()); // shows the opening fence
history.push(current_partial_code_line.into()); // before fence closes
```
- Fix:
```rust
if !in_fence { history.extend(committed_lines); }
// When fence closes:
history.extend(render_code_block_exact(&buffered_code));
```
- Dont rely on default logging to signal correctness for ignored events.
- Anti-pattern:
```rust
// Let it fall into `other => debug!`
```
- Fix:
```rust
"response.reasoning_summary_part.added" => { /* intentionally ignored */ }
// Ensures no misleading warnings/logging elsewhere.
```
- Dont leave tests ambiguous about intent (e.g., “works” without spec reference).
- Anti-pattern:
```rust
#[test]
fn fence_parsing_works() { /* vague, brittle */ }
```
- Fix:
```rust
#[test]
fn closes_only_with_equal_length_fence() {
let (tok, n, _) = fence_open("````txt").unwrap();
assert!(fence_close("````", tok, n));
assert!(!fence_close("```", tok, n));
}
```