Hyacinth-of-Security 5c5cf24ff2
fix(skills): read undecodable skill state as missing (#7963)
* fix(skills): read undecodable skill state as missing

`_read_manifest` and `_read_skill_states` document that an unreadable file
means "no manifest" / "no overrides", and both catch OSError and
JSONDecodeError. A file that is not valid UTF-8 raises UnicodeDecodeError,
which is a ValueError and matches neither, so the projection and the skill
state read raise instead of falling back.

Catch it alongside the existing exceptions.

* fix(skills): keep the reason when profile state cannot be decoded

Review feedback on #7963: the state reader dropped the exception, so a decode
failure that silently discards the user's disabled set left nothing to diagnose,
and the next toggle overwrites those bytes. Log the exception, and log a debug
line when an unreadable projection manifest forces a rebuild.

* docs(skills): state that undecodable skill state fails open

_read_skill_states already degraded a malformed file to {} before this change;
making undecodable bytes take the same path made that explicit, so say so next to
the sandbox check that documents the opposite verdict for a single named skill.

---------

Co-authored-by: lxcxjxhx <lxcxjxhx@users.noreply.github.com>
2026-11-09 21:49:46 +08:00
..