Detail Bug Report
https://app.detail.dev/org_89d327b3-b883-4365-b6a3-46b6701342a9/bugs/bug_0b819e13-abcf-4013-a11b-8c633c22ff07
Introduced in #103 by @infiniteregrets on Jan 28, 2026
Summary
- Context: The Trim and Fence commands in the S2 CLI append command records to a stream and display the resulting tail position.
- Bug: Both commands incorrectly use
out.start (position of the appended command record) instead of out.tail (the actual stream tail position) in their output messages.
- Actual vs. expected: The output label says "tail:" but displays the sequence number of the command record itself, not the sequence number that will be assigned to the next record on the stream.
- Impact: Users receive misleading output showing an incorrect tail position, which could cause confusion when verifying stream state or debugging concurrent operations.
Code with Bug
// `cli/src/main.rs`
Command::Trim(args) => {
let trim_point = args.trim_point;
let out = ops::trim(&s2, args).await?;
eprintln!(
"{}",
format!(
"✓ [APPENDED] trim to {} // tail: {}",
trim_point,
format_position(out.start.seq_num, out.start.timestamp) // <-- BUG 🔴 prints start (record position), not stream tail
)
.green()
.bold()
);
}
Command::Fence(args) => {
let fencing_token = args.new_fencing_token.clone();
let out = ops::fence(&s2, args).await?;
eprintln!(
"{}",
format!(
"✓ [APPENDED] new fencing token \"{}\" // tail: {}",
fencing_token,
format_position(out.start.seq_num, out.start.timestamp) // <-- BUG 🔴 prints start (record position), not stream tail
)
.green()
.bold()
);
}
Explanation
AppendAck.tail is defined as “sequence number that will be assigned to the next record on the stream” (same concept returned by check_tail()). The CLI’s Append command already follows this contract by printing ack.batch.tail under the "tail:" label.
- Trim and Fence also append records and receive an
AppendAck, but they print out.start while still labeling it as "tail:". This is incorrect and becomes clearly observable under concurrency where out.tail.seq_num can be greater than out.start.seq_num + 1.
Codebase Inconsistency
The Append command output establishes the intended meaning of "tail:" as AppendAck.tail:
// `cli/src/main.rs`
eprintln!(
"{}",
format!(
"✓ [APPENDED] {}..{} // tail: {}",
ack.batch.start.seq_num,
ack.batch.end.seq_num,
format_position(ack.batch.tail.seq_num, ack.batch.tail.timestamp)
)
.green()
.bold()
);
Recommended Fix
Update Trim and Fence output to use out.tail:
- Replace
format_position(out.start.seq_num, out.start.timestamp) with format_position(out.tail.seq_num, out.tail.timestamp) in both command handlers.
History
This bug was introduced in commit dc3bd4e when s2-cli was initially added: Trim/Fence printed out.start while labeling it "tail:", while Append printed ack.batch.tail.
Detail Bug Report
https://app.detail.dev/org_89d327b3-b883-4365-b6a3-46b6701342a9/bugs/bug_0b819e13-abcf-4013-a11b-8c633c22ff07
Introduced in #103 by @infiniteregrets on Jan 28, 2026
Summary
out.start(position of the appended command record) instead ofout.tail(the actual stream tail position) in their output messages.Code with Bug
Explanation
AppendAck.tailis defined as “sequence number that will be assigned to the next record on the stream” (same concept returned bycheck_tail()). The CLI’s Append command already follows this contract by printingack.batch.tailunder the "tail:" label.AppendAck, but they printout.startwhile still labeling it as "tail:". This is incorrect and becomes clearly observable under concurrency whereout.tail.seq_numcan be greater thanout.start.seq_num + 1.Codebase Inconsistency
The Append command output establishes the intended meaning of "tail:" as
AppendAck.tail:Recommended Fix
Update Trim and Fence output to use
out.tail:format_position(out.start.seq_num, out.start.timestamp)withformat_position(out.tail.seq_num, out.tail.timestamp)in both command handlers.History
This bug was introduced in commit
dc3bd4ewhens2-cliwas initially added: Trim/Fence printedout.startwhile labeling it "tail:", while Append printedack.batch.tail.