Summary
docs/SERVICE_REGISTRY.yaml is increasingly serving as a declarative contract for ACP/MCP flow behavior, but runtime access is still ad hoc and only lightly validated.
We recently added a small isolated helper for case_causal_review sanitization pass-through keys. That solved the immediate need without touching other services, but it exposed a broader improvement opportunity: service registry loading, validation, and typed access should be centralized.
Problem
Today the registry has these limitations:
- Runtime consumers can read YAML shape directly instead of going through a single validated access layer
- There is no schema validation on load
- Invalid or malformed sections may be silently ignored and replaced by fallbacks
- Flow-specific contract metadata such as sanitization pass-through keys can drift from tool signatures and docs
- Future additions will likely duplicate parsing logic unless we establish a shared pattern now
Goal
Create a validated, centralized service-registry access layer that can safely support runtime behavior, not just /services documentation.
Proposed scope
- Introduce a shared service-registry helper/module as the single runtime access point
- Validate
SERVICE_REGISTRY.yaml structure on load
- Provide typed helpers for common access patterns, for example:
- service definition lookup
- validation rules lookup
- controlled identifier pass-through keys
- declared MCP tool dependencies
- Fail closed or emit explicit warnings for malformed registry sections
- Add tests for:
- valid registry load
- malformed registry structure
- missing file behavior
- env override behavior via
STUDY_AGENT_SERVICE_REGISTRY
Non-goals
- No full migration of every ACP/MCP caller in the first PR
- No broad schema redesign unless needed for validation
- No behavior changes to unrelated flows unless they opt into the helper
Motivation / examples
Concrete current use cases include:
case_causal_review sanitization pass-through keys for controlled identifiers like ingred_rxcui and adverse_event_meddra_id
- service registration consistency between docs and runtime wiring
- future flow-specific validation metadata that should be declared once and consumed safely
Suggested implementation approach
- Start with a schema-light but strict validator
- Normalize known fields on load
- Keep conservative code-side fallbacks during rollout
- Migrate flows incrementally rather than all at once
Acceptance criteria
- Registry loading is centralized in one helper/module
- Malformed registry content is detected explicitly
- At least one existing runtime use case is powered by the validated helper
- Tests cover success, malformed input, env override, and fallback behavior
Summary
docs/SERVICE_REGISTRY.yamlis increasingly serving as a declarative contract for ACP/MCP flow behavior, but runtime access is still ad hoc and only lightly validated.We recently added a small isolated helper for
case_causal_reviewsanitization pass-through keys. That solved the immediate need without touching other services, but it exposed a broader improvement opportunity: service registry loading, validation, and typed access should be centralized.Problem
Today the registry has these limitations:
Goal
Create a validated, centralized service-registry access layer that can safely support runtime behavior, not just
/servicesdocumentation.Proposed scope
SERVICE_REGISTRY.yamlstructure on loadSTUDY_AGENT_SERVICE_REGISTRYNon-goals
Motivation / examples
Concrete current use cases include:
case_causal_reviewsanitization pass-through keys for controlled identifiers likeingred_rxcuiandadverse_event_meddra_idSuggested implementation approach
Acceptance criteria