v1.2.2 — H3: unknown stream-json roles forward-compat
v1.2.2 — H3: unknown stream-json roles are forward-compat
A future kimi-code release may add a new top-level message role. Until now an unrecognized role was flagged malformed (error framing + diagnostic noise for a legitimate-but-new record). This closes the last open piece of H3.
Change
parseLine now routes a non-empty string role it doesn't model (assistant/tool/meta) to a dedicated out-of-band channel — StreamJsonOutcome.unknownRecord ({role, raw}), the same posture as meta/goalSummary — instead of malformed. cli-client logs it (event:"unknown_record") and keeps it out of records[] and onRecord. A role-less line that isn't goal.summary, an empty-string role, or a non-string role all stay malformed (genuinely unexpected); genuinely-broken lines (non-JSON, non-object, no role) are unaffected.
Why out-of-band (not in records[])
The consumer sweep found the only records[] consumer is reassembleProseFromRecords, which reads role === "assistant" exclusively (onRecord has no production caller). So routing unknown roles out-of-band is behavior-preserving for every command's output, and avoids churning the role-keyed StreamJsonRecord union. Since unknown roles were previously malformed (never in records[]), this is strictly neutral-or-better for all consumers.
Tests
454 pass. stream-json.test.ts (unknownRecord-vs-malformed matrix incl. empty-string + non-string role), cli-client.test.ts (out-of-band, not malformed, assistant still captured). Reviewed clean (code-reviewer: correct + behavior-preserving, no blocker).