## Why
Rebuilding a truncated message from its content fields can drop passthrough
metadata and leave positional content classifications out of sync with the
items that remain.
## What changed
- Convert message content and its classifications into `AnnotatedContent`
before applying the token budget, then write both back together.
- Preserve other message and envelope metadata during truncation.
- Assign the `unknown` classification to content from legacy messages that do
not provide classifications.
## Testing
Expanded truncation coverage to verify that retained text and image items keep
their matching classifications and that unrelated passthrough metadata is
preserved.
GitOrigin-RevId: f84e2ebc3e97392e45f321dec3c171713864bdcd
## What changed
- Require each `ContextualUserFragment` to provide a stable `<feature>.<name>`
`ContentItemKind`.
- Add `AnnotatedContent` and `RenderedFragment` so rendered text, its role, and
its classification can travel together to API boundaries.
- Derive extension-owned world-state classifications from the extension ID and
keep the skills catalog classification with its fragment implementation.
## Testing
- Verify that an extension-owned world-state section renders with an
`<extension-id>.instructions` content kind.
GitOrigin-RevId: e46b74a0bb41e0b6112667c9d36bc9e7f2714451