* fix: Make strict-BPS ack key a rotating attestation phrase
The static opaque token invited two failures: an agent misread the
extract-and-replay round-trip as prompt injection and refused gated
writes until the user disabled strict mode (#1924), and a static
literal in a public repo can satisfy the gate from training data or a
stale session summary without any actual read. The key is now a
plain-English read-receipt phrase with a per-process random suffix,
the BestPracticeKey schema description documents the protocol (public
value, not a credential, obtained by reading the skill via
ha_get_skill_guide), and the ack line carries matching framing.
Fixes #1924
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* fix: Rotate strict-BPS ack key hourly with previous-hour grace
An add-on process can run for weeks, so a restart-scoped key is nearly
static and an agent could save it to persistent memory and reuse it
without re-reading the guide. Derive the suffix from a per-process salt
and the current hour bucket (stateless: salt + clock), honor the
previous hour's key as a grace window so a read just before rotation
does not strand the write that follows it, and replace the import-time
constant with current_strict_bps_ack_key().
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* fix: Harden strict-BPS gate from review findings
- Treat a non-string BestPracticeKey as missing: the middleware reads
raw transport arguments before pydantic validation, so an unhashable
value crashed the set-membership check with a TypeError instead of
raising the actionable block error.
- State in the block error that the key rotates and must be refreshed
by re-reading, so an agent holding an expired key re-reads instead
of replaying the stale value in a loop.
- Widen the key suffix to 8 hex chars and pin the salt/clock in the
derivation tests: tests are deterministic and a wrong-but-well-formed
key no longer has 1-in-32768 odds against the two-key set.
- Refresh comments left stale by the rotation change; pin the 3600s
period and the per-tool schema protocol phrases.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
---------
Co-authored-by: kingpanther13 <kingpanther13@users.noreply.github.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>