Description
Kiro-native sessions match an incoming persisted message back to its queued
web-composer entry via resolve_matching_text() in
omnigent/runtime/pending_inputs.py. The match condition is:
needle == entry_text or needle.endswith(entry_text)
The endswith branch is an unanchored suffix check, not a word-boundary
match. If a short queued entry's text (e.g. "ok") happens to be a trailing
substring of a later, unrelated accepted prompt (e.g. "Let's continue - ok"),
the resolver matches the wrong queued entry.
Because the caller (omnigent/server/routes/_sessions/orchestration.py,
_apply_kiro_pending_match area) merges the matched entry's file/image
blocks into the persisted item, this misattributes attachments: an image
the user attached to message A ends up permanently attached to unrelated
message B in the durable transcript. Meanwhile the real message that should
have matched gets re-persisted separately, out of order, and mislabeled
with a kiro_native_prompt_not_recorded error.
This is silent data corruption in conversation history with no workaround
once persisted; transcripts aren't user-editable.
I traced this to the original Kiro harness commit (#899); the endswith
branch has no test coverage, and Kiro's own JSONL parsing
(kiro_native_session_forwarder.py) confirms it never prepends or appends
text to prompts, so there's no legitimate case that requires anything
looser than exact-text equality.
Whats supposed to be happening is that a queued entry is only ever matched to the persisted message
whose text is identical to it. A miss should fall through to the existing
"no match" path (treated as typed directly in the terminal) rather than
guessing.
Steps to reproduce
- Start a Kiro-native session.
- From the web composer, send a short message with an attached image,
e.g. "ok" + an image attachment. This queues a pending-input entry.
- Before Kiro's JSONL round-trips that specific message back through the
transcript forwarder, send a second, unrelated message whose text ends
in the same text, e.g. "Let's continue - ok".
- When Kiro mirrors "Let's continue - ok" back through the transcript,
resolve_matching_text() matches it against the queued "ok" entry
(unanchored suffix match) instead of waiting for the literal "ok"
message.
Version
0.11.0.dev0
OS
macOS 15.5
Harness
Kiro
Harness mode
Native
Platform or device
macOS
Observed impact
One narrow or edge case
Authentication type
Not authentication-related
Description
Kiro-native sessions match an incoming persisted message back to its queued
web-composer entry via
resolve_matching_text()inomnigent/runtime/pending_inputs.py. The match condition is:needle == entry_text or needle.endswith(entry_text)The
endswithbranch is an unanchored suffix check, not a word-boundarymatch. If a short queued entry's text (e.g. "ok") happens to be a trailing
substring of a later, unrelated accepted prompt (e.g. "Let's continue - ok"),
the resolver matches the wrong queued entry.
Because the caller (
omnigent/server/routes/_sessions/orchestration.py,_apply_kiro_pending_matcharea) merges the matched entry's file/imageblocks into the persisted item, this misattributes attachments: an image
the user attached to message A ends up permanently attached to unrelated
message B in the durable transcript. Meanwhile the real message that should
have matched gets re-persisted separately, out of order, and mislabeled
with a
kiro_native_prompt_not_recordederror.This is silent data corruption in conversation history with no workaround
once persisted; transcripts aren't user-editable.
I traced this to the original Kiro harness commit (#899); the
endswithbranch has no test coverage, and Kiro's own JSONL parsing
(
kiro_native_session_forwarder.py) confirms it never prepends or appendstext to prompts, so there's no legitimate case that requires anything
looser than exact-text equality.
Whats supposed to be happening is that a queued entry is only ever matched to the persisted message
whose text is identical to it. A miss should fall through to the existing
"no match" path (treated as typed directly in the terminal) rather than
guessing.
Steps to reproduce
e.g. "ok" + an image attachment. This queues a pending-input entry.
transcript forwarder, send a second, unrelated message whose text ends
in the same text, e.g. "Let's continue - ok".
resolve_matching_text() matches it against the queued "ok" entry
(unanchored suffix match) instead of waiting for the literal "ok"
message.
Version
0.11.0.dev0
OS
macOS 15.5
Harness
Kiro
Harness mode
Native
Platform or device
macOS
Observed impact
One narrow or edge case
Authentication type
Not authentication-related