Developer Self-Sufficiency Strategy¶
Overview¶
This document outlines potential failure modes when developers independently contribute to the Polaris FHIR spec and proposes defensive strategies to ensure quality while maintaining velocity.
Potential Failure Modes & Defenses¶
1. Semantic Drift: "Lost in Translation"¶
What Could Go Wrong: - Developers map EMR fields incorrectly, losing clinical meaning - Standard terminology mappings introduce subtle but dangerous changes - Raw codes get dropped, making data unrecoverable
Defenses:
Technical:
- Automated validation for dual-code storage (raw + mapped)
- Invariants that enforce raw code preservation
- Example validation that checks both coding arrays
Process:
- Require clinical scenario in every PR
- Mapping documentation template with "semantic impact" section
- Review checklist item: "Does this preserve original meaning?"
Meta:
- Version control on all mapping decisions
- Audit trail of terminology choices
- Quarterly semantic accuracy reviews
2. Profile Proliferation: "Everyone's Special"¶
What Could Go Wrong: - Developers create new profiles instead of reusing existing ones - Minor variations lead to dozens of similar profiles - Incompatible profiles for the same concept
Defenses:
Technical:
- Profile registry with search capability
- Automated similarity detection in PR checks
- Canonical URL validation to prevent duplicates
Process:
- "Profile or Extend?" decision tree in docs
- Required justification for new profiles
- Monthly profile inventory reviews
Meta:
- Profile deprecation process
- Profile consolidation sprints
- Usage metrics to identify unused profiles
3. Invariant Chaos: "Constraints Gone Wild"¶
What Could Go Wrong: - Complex FHIRPath expressions that kill performance - Contradictory invariants across profiles - Invariants that are too restrictive for real-world data
Defenses:
Technical:
- Invariant performance benchmarking in CI
- Cross-profile invariant conflict detection
- Test data generator for edge cases
Process:
- Invariant complexity scoring
- Required test cases for each invariant
- "Fail gracefully" principle documentation
Meta:
- Invariant registry with rationale
- Performance budget for profiles
- Regular invariant rationalization
4. Reference Spaghetti: "Everything Points Everywhere"¶
What Could Go Wrong: - Circular reference dependencies - References to non-existent or deprecated profiles - Inconsistent reference patterns (direct vs identifier-based)
Defenses:
Technical:
- Reference graph visualization tool
- Automated circular dependency detection
- Reference validation in build process
Process:
- Reference pattern guidelines with examples
- Dependency documentation requirement
- Reference impact analysis in PRs
Meta:
- Profile dependency matrix
- Reference pattern evolution tracking
- Quarterly architecture reviews
5. Example Drift: "Fiction Becomes Fact"¶
What Could Go Wrong: - Examples that don't reflect real clinical scenarios - Test data that validates but makes no clinical sense - Examples missing critical real-world variations
Defenses:
Technical:
- Clinical plausibility validator
- Example coverage metrics
- Automated example generation from templates
Process:
- Real EMR data sampling (anonymized)
- Clinical SME review requirement
- Example scenario documentation
Meta:
- Example library with categorization
- Real-world data comparison audits
- Clinician feedback loops
6. Documentation Decay: "Write Once, Confuse Forever"¶
What Could Go Wrong: - Documentation becomes out of sync with implementation - Critical decisions lost in commit messages - New developers can't understand the "why"
Defenses:
Technical:
- Documentation linting (broken links, missing sections)
- Automated changelog generation
- Decision record extraction from PRs
Process:
- Documentation-first development
- PR template with "Docs Updated?" checkbox
- Quarterly documentation sprints
Meta:
- Architecture Decision Records (ADRs)
- Documentation freshness metrics
- Developer onboarding feedback
Implementation Roadmap¶
Phase 1: Foundation (Immediate)¶
- PR Templates with quality checkpoints
- Pre-commit Hooks for basic validation
- Example Validator GitHub Action
- Profile Registry (simple markdown to start)
Phase 2: Automation (1-2 months)¶
- Invariant Performance Testing
- Reference Graph Validator
- Clinical Plausibility Checker
- Automated Similarity Detection
Phase 3: Governance (3-6 months)¶
- Architecture Decision Records
- Profile Lifecycle Management
- Semantic Accuracy Reviews
- Developer Metrics Dashboard
Quick Wins We Can Implement Today¶
1. PR Template (.github/pull_request_template.md)¶
## What This PR Does
Brief description of changes
## Clinical Scenario
Describe the real-world use case this addresses
## Checklist
- [ ] FSH builds without errors
- [ ] Examples validate
- [ ] Raw codes preserved alongside mapped codes
- [ ] Documentation updated
- [ ] No new profiles without justification
- [ ] Invariants have test cases
- [ ] References use identifier pattern
## Semantic Impact
Does this change how data is interpreted? If yes, explain:
## Questions for Reviewer
What specific aspects need extra attention?
2. Pre-commit Hook (.husky/pre-commit)¶
#!/bin/sh
# Check FSH syntax
npx sushi . --snapshot
# Check for common issues
grep -r "Reference(" input/fsh | grep -v "identifier" && \
echo "Warning: Direct references found. Use identifier-based references."
# Check for raw code preservation
grep -r "coding\[" input/examples | grep -v "userSelected" && \
echo "Warning: Examples may be missing raw codes"
3. Validation GitHub Action¶
name: Enhanced Validation
on: [push, pull_request]
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Check Profile Uniqueness
run: |
# Detect duplicate profile URLs
find input/fsh -name "*.fsh" -exec grep "^* ^url = " {} \; | \
sort | uniq -d | \
grep . && echo "ERROR: Duplicate profile URLs found!" && exit 1 || true
- name: Validate Examples Have Raw Codes
run: |
# Ensure examples include original codes
for file in input/examples/*.json; do
jq '..|.coding?|select(.)|.[]|select(.userSelected==true)' "$file" > /dev/null || \
echo "Warning: $file may be missing raw codes"
done
- name: Check Invariant Complexity
run: |
# Flag overly complex FHIRPath expressions
grep -r "Expression:" input/fsh | \
awk '{print length, NR, $0}' | \
sort -rn | \
head -5 > complex_invariants.txt
echo "Most complex invariants:"
cat complex_invariants.txt
Metrics for Success¶
Quality Metrics¶
- Build success rate > 95%
- PR first-time approval rate > 70%
- Average time to merge < 3 days
- Zero semantic drift incidents
Developer Experience Metrics¶
- Time to first successful PR < 1 week
- Documentation helpfulness score > 4/5
- Developer retention rate > 80%
- Questions per PR < 2
Technical Debt Metrics¶
- Profile reuse rate > 60%
- Invariant performance impact < 100ms
- Documentation staleness < 30 days
- Example coverage > 90%
The Nuclear Options¶
If things go really wrong, we have these emergency measures:
- Profile Freeze: Temporarily lock new profile creation
- Semantic Review Board: Clinical panel for complex mappings
- Compatibility Mode: Version lock for breaking changes
- Rollback Protocol: Quick reversion process
Final Thoughts¶
The goal isn't to create bureaucracy - it's to create guardrails that let developers move fast with confidence. Every defense should:
- Catch issues early (shift left)
- Provide clear guidance (not just "no")
- Automate the tedious parts
- Learn from failures (blameless postmortems)
With these defenses in place, developers can confidently contribute knowing that: - The build will catch technical issues - The process will catch semantic issues - The reviews will catch the subtle stuff - And Shawn only needs to review the interesting parts
Remember: The best defense is making the right thing the easy thing.