`AcPrincipal.did: Option<String>` → `Option<guildhouse_did::Did>`.
The AuthorizationContext now carries a W3C-canonical typed DID;
malformed DIDs fail at deserialize time rather than propagating
into the corpus_check / session state.
SessionState.principal stays a String — it can also hold a Unix
username in ungoverned mode, so a typed Did would force
Option<Did> there and complicate the chain. The render at
SessionState::from_ac now goes Did → as_str() instead of cloning
the legacy String. Behaviour at the audit-leaf level is
unchanged when the AC carries a valid `did:web:...` payload.
Phase 0 of DESIGN-DID-INTEGRATION-2026-04-29 §5.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Tyler J King <tking@guildhouse.dev>