feat(canopy-applications): validate programs_requested against canopy_reference::Program enum

Source: application-intake plan Potential Improvements.

POST /v1/applications accepts programs_requested as Vec<String> and writes the values verbatim. A typo ("snap" vs "Snap" vs "SNAP") will be persisted and silently ignored downstream by the orchestrator's enum-typed dispatch. Add server-side validation: parse each value through canopy_reference::Program::from_str (or the equivalent serde deserialization) and reject the request with 422 listing the bad values.

Acceptance: invalid program string returns 422 Unprocessable Entity with field-level errors; valid programs parse + canonicalise on write.