xiaohongshu
xiaohongshu
constraint-preflight
Pre-flight verification for scheduling constraint development. Use when adding, modifying, or testing constraints to ensure they are properly implemented, exported, registered, and tested before commit.
Full skill instructions
Prevents the "implemented but not registered" bug where constraints are created, tested, and exported but never added to the ConstraintManager factory methods.
CRITICAL CONTEXT:
| Truth Type | Tables | Constraint Role |
|---|---|---|
| Prescriptive | rotation_templates, weekly_patterns, constraints | Define what SHOULD happen |
| Descriptive | half_day_assignments | Record what DID happen |
Constraints are part of the prescriptive layer. They define rules that the solver uses to transform templates into assignments.
┌─────────────────────────────────────────────────────────────────┐
│ PRESCRIPTIVE LAYER │
│ rotation_templates + weekly_patterns + CONSTRAINTS │
└─────────────────────────────────────────────────────────────────┘
│
▼ expansion_service + solver
┌─────────────────────────────────────────────────────────────────┐
│ DESCRIPTIVE LAYER │
│ half_day_assignments │
└─────────────────────────────────────────────────────────────────┘
Impact of constraint changes:
half_day_assignments won't auto-update - you must regenerateTesting implication:
__init__.py exportsA common failure mode in constraint development:
1. Create constraint class in backend/app/scheduling/constraints/*.py ✓
2. Write tests for constraint logic ✓
3. Export constraint in __init__.py ✓
4. Tests pass locally ✓
5. ⚠️ FORGET to register in ConstraintManager.create_default() ✗
6. Commit and push ✓
7. Schedule generation doesn't use the constraint! 💥
Run this before committing any constraint changes:
cd /home/user/Autonomous-Assignment-Program-Manager/backend
python ../scripts/verify_constraints.py
ConstraintManager.create_default()create_default() and create_resilience_aware()============================================================
CONSTRAINT PRE-FLIGHT VERIFICATION
============================================================
This script verifies constraint implementation completeness.
Run this before committing constraint changes.
============================================================
CONSTRAINT REGISTRATION VERIFICATION
============================================================
Registered constraints (23 total):
- 1in7Rule: ENABLED
- 80HourRule: ENABLED
- Availability: ENABLED
- CallSpacing: ENABLED weight=8.0
- ClinicCapacity: ENABLED
...
Block 10 Constraint Check:
[OK] CallSpacingConstraint
[OK] SundayCallEquityConstraint
[OK] TuesdayCallPreferenceConstraint
[OK] WeekdayCallEquityConstraint
[OK] ResidentInpatientHeadcountConstraint
[OK] PostFMITSundayBlockingConstraint
============================================================
WEIGHT HIERARCHY VERIFICATION
============================================================
Call equity weight hierarchy:
[OK] SundayCallEquity: weight=10.0
[OK] CallSpacing: weight=8.0
[OK] WeekdayCallEquity: weight=5.0
[OK] TuesdayCallPreference: weight=2.0
============================================================
MANAGER CONSISTENCY VERIFICATION
============================================================
Block 10 constraints in both managers:
[OK] ResidentInpatientHeadcount
[OK] PostFMITSundayBlocking
[OK] SundayCallEquity
[OK] CallSpacing
[OK] WeekdayCallEquity
[OK] TuesdayCallPreference
============================================================
SUMMARY
============================================================
Registration: PASS
Weight Hierarchy: PASS
Manager Consistency: PASS
[SUCCESS] All verifications passed!
When creating a new constraint:
# backend/app/scheduling/constraints/my_constraint.py
class MyNewConstraint(SoftConstraint):
"""
Docstring explaining the constraint's purpose.
"""
def __init__(self, weight: float = 5.0) -> None:
super().__init__(
name="MyNewConstraint",
constraint_type=ConstraintType.EQUITY,
weight=weight,
priority=ConstraintPriority.MEDIUM,
)
def add_to_cpsat(self, model, variables, context) -> None:
# CP-SAT implementation
pass
def add_to_pulp(self, model, variables, context) -> None:
# PuLP implementation
pass
def validate(self, assignments, context) -> ConstraintResult:
# Validation implementation
pass
__init__.py# backend/app/scheduling/constraints/__init__.py
from .my_constraint import MyNewConstraint
__all__ = [
# ... existing exports ...
"MyNewConstraint",
]
# backend/app/scheduling/constraints/manager.py
from .my_constraint import MyNewConstraint
class ConstraintManager:
@classmethod
def create_default(cls) -> "ConstraintManager":
manager = cls()
# ... existing constraints ...
manager.add(MyNewConstraint(weight=5.0)) # ADD THIS!
return manager
@classmethod
def create_resilience_aware(cls, ...) -> "ConstraintManager":
manager = cls()
# ... existing constraints ...
manager.add(MyNewConstraint(weight=5.0)) # ADD THIS TOO!
return manager
# backend/tests/test_my_constraint.py
from app.scheduling.constraints import MyNewConstraint, ConstraintManager
class TestMyNewConstraint:
def test_constraint_initialization(self):
constraint = MyNewConstraint()
assert constraint.name == "MyNewConstraint"
assert constraint.weight == 5.0
def test_constraint_registered_in_manager(self):
"""CRITICAL: Verify constraint is actually used!"""
manager = ConstraintManager.create_default()
registered_types = {type(c) for c in manager.constraints}
assert MyNewConstraint in registered_types
cd backend
python ../scripts/verify_constraints.py
git add .
git commit -m "feat: add MyNewConstraint for [purpose]"
The test_constraint_registration.py file provides automated CI coverage:
# Key tests that prevent the registration gap:
class TestConstraintRegistration:
def test_block10_hard_constraints_in_default_manager(self):
"""Verify hard constraints are registered."""
def test_block10_soft_constraints_in_default_manager(self):
"""Verify soft constraints are registered."""
def test_call_equity_weight_hierarchy(self):
"""Verify weights follow: Sunday > Spacing > Weekday > Tuesday."""
class TestConstraintExportIntegrity:
def test_all_call_equity_exports_registered(self):
"""All exported classes must be in manager."""
def test_inpatient_constraint_registered(self):
"""ResidentInpatientHeadcountConstraint is registered."""
# Run pre-flight verification
cd backend && python ../scripts/verify_constraints.py
# Run constraint registration tests only
cd backend && pytest tests/test_constraint_registration.py -v
# Run all constraint tests
cd backend && pytest tests/test_*constraint*.py -v
# Check manager.py for registrations
grep -n "manager.add" backend/app/scheduling/constraints/manager.py
| File | Purpose |
|---|---|
scripts/verify_constraints.py | Pre-flight verification script |
backend/tests/test_constraint_registration.py | CI tests for registration |
backend/app/scheduling/constraints/manager.py | Where constraints are registered |
backend/app/scheduling/constraints/__init__.py | Where constraints are exported |
For call equity constraints, follow this hierarchy (highest impact first):
| Constraint | Weight | Rationale |
|---|---|---|
| SundayCallEquity | 10.0 | Worst call day, highest priority |
| CallSpacing | 8.0 | Burnout prevention |
| WeekdayCallEquity | 5.0 | Balance Mon-Thu calls |
| TuesdayCallPreference | 2.0 | Academic scheduling preference |
| DeptChiefWednesdayPreference | 1.0 | Personal preference (lowest) |
┌──────────────────────────────────────────────────────────────────┐
│ CONSTRAINT PRE-FLIGHT WORKFLOW │
├──────────────────────────────────────────────────────────────────┤
│ │
│ STEP 1: Implement Constraint Class │
│ ┌────────────────────────────────────────────────┐ │
│ │ Create class in constraints/*.py │ │
│ │ Implement: __init__, add_to_cpsat, │ │
│ │ add_to_pulp, validate │ │
│ └────────────────────────────────────────────────┘ │
│ ↓ │
│ STEP 2: Export in __init__.py │
│ ┌────────────────────────────────────────────────┐ │
│ │ Add import statement │ │
│ │ Add to __all__ list │ │
│ └────────────────────────────────────────────────┘ │
│ ↓ │
│ STEP 3: Register in ConstraintManager (CRITICAL!) │
│ ┌────────────────────────────────────────────────┐ │
│ │ Import in manager.py │ │
│ │ Add to create_default() │ │
│ │ Add to create_resilience_aware() │ │
│ │ ⚠️ MUST BE IN BOTH FACTORY METHODS │ │
│ └────────────────────────────────────────────────┘ │
│ ↓ │
│ STEP 4: Write Tests │
│ ┌────────────────────────────────────────────────┐ │
│ │ Unit tests for constraint logic │ │
│ │ Registration test in manager │ │
│ │ Integration test with scheduler │ │
│ └────────────────────────────────────────────────┘ │
│ ↓ │
│ STEP 5: Run Pre-Flight Verification (MANDATORY) │
│ ┌────────────────────────────────────────────────┐ │
│ │ python ../scripts/verify_constraints.py │ │
│ │ ✓ Registration check │ │
│ │ ✓ Weight hierarchy check │ │
│ │ ✓ Manager consistency check │ │
│ └────────────────────────────────────────────────┘ │
│ ↓ │
│ STEP 6: Commit Only If All Pass │
│ ┌────────────────────────────────────────────────┐ │
│ │ All verifications PASS │ │
│ │ Tests PASS │ │
│ │ → Safe to commit │ │
│ └────────────────────────────────────────────────┘ │
│ │
└──────────────────────────────────────────────────────────────────┘
Scenario: Program director wants to minimize Friday call assignments to improve weekend coverage.
Step 1: Implement the Constraint Class
# backend/app/scheduling/constraints/friday_call_avoidance.py
"""Soft constraint to minimize Friday call assignments."""
from typing import Any, Dict, List
from app.scheduling.constraints.base import SoftConstraint, ConstraintResult
from app.scheduling.constraints.types import ConstraintType, ConstraintPriority
class FridayCallAvoidanceConstraint(SoftConstraint):
"""
Minimize Friday inpatient call assignments to improve weekend coverage.
Clinical rationale: Friday call often extends into Saturday coverage,
reducing resident availability for weekend shifts.
Weight: 3.0 (medium-low priority, below call equity constraints)
"""
def __init__(self, weight: float = 3.0) -> None:
super().__init__(
name="FridayCallAvoidance",
constraint_type=ConstraintType.PREFERENCE,
weight=weight,
priority=ConstraintPriority.MEDIUM,
)
def add_to_cpsat(
self, model: Any, variables: Dict[str, Any], context: Dict[str, Any]
) -> None:
"""Add penalty for Friday call assignments in CP-SAT solver."""
# Implementation details...
pass
def add_to_pulp(
self, model: Any, variables: Dict[str, Any], context: Dict[str, Any]
) -> None:
"""Add penalty for Friday call assignments in PuLP solver."""
# Implementation details...
pass
def validate(
self, assignments: List[Any], context: Dict[str, Any]
) -> ConstraintResult:
"""Validate Friday call distribution."""
# Implementation details...
pass
Step 2: Export in init.py
# backend/app/scheduling/constraints/__init__.py
from .friday_call_avoidance import FridayCallAvoidanceConstraint
__all__ = [
# ... existing exports ...
"CallSpacingConstraint",
"SundayCallEquityConstraint",
"TuesdayCallPreferenceConstraint",
"WeekdayCallEquityConstraint",
# NEW:
"FridayCallAvoidanceConstraint", # ← Add this!
]
Step 3: Register in ConstraintManager (CRITICAL!)
# backend/app/scheduling/constraints/manager.py
from .friday_call_avoidance import FridayCallAvoidanceConstraint
class ConstraintManager:
@classmethod
def create_default(cls) -> "ConstraintManager":
"""Create manager with standard constraint set."""
manager = cls()
# ... existing constraints ...
# Call equity constraints (weight hierarchy matters!)
manager.add(SundayCallEquityConstraint(weight=10.0))
manager.add(CallSpacingConstraint(weight=8.0))
manager.add(WeekdayCallEquityConstraint(weight=5.0))
manager.add(TuesdayCallPreferenceConstraint(weight=2.0))
# NEW: Add Friday avoidance (weight=3.0, below call equity)
manager.add(FridayCallAvoidanceConstraint(weight=3.0)) # ← Add this!
return manager
@classmethod
def create_resilience_aware(
cls,
n1_compliant: bool = True,
utilization_cap: float = 0.8,
defense_level: int = 2,
) -> "ConstraintManager":
"""Create manager with resilience-aware constraints."""
manager = cls()
# ... existing constraints ...
# Call preferences
manager.add(SundayCallEquityConstraint(weight=10.0))
manager.add(CallSpacingConstraint(weight=8.0))
manager.add(WeekdayCallEquityConstraint(weight=5.0))
manager.add(TuesdayCallPreferenceConstraint(weight=2.0))
# NEW: Add here too!
manager.add(FridayCallAvoidanceConstraint(weight=3.0)) # ← And this!
return manager
Step 4: Write Tests
# backend/tests/test_friday_call_avoidance.py
import pytest
from app.scheduling.constraints import (
FridayCallAvoidanceConstraint,
ConstraintManager,
)
class TestFridayCallAvoidanceConstraint:
def test_constraint_initialization(self):
"""Verify constraint initializes with correct values."""
constraint = FridayCallAvoidanceConstraint()
assert constraint.name == "FridayCallAvoidance"
assert constraint.weight == 3.0
assert constraint.constraint_type == ConstraintType.PREFERENCE
def test_custom_weight(self):
"""Test constraint with custom weight."""
constraint = FridayCallAvoidanceConstraint(weight=5.0)
assert constraint.weight == 5.0
def test_constraint_registered_in_default_manager(self):
"""CRITICAL: Verify constraint is in create_default()."""
manager = ConstraintManager.create_default()
registered_types = {type(c) for c in manager.constraints}
assert FridayCallAvoidanceConstraint in registered_types
def test_constraint_registered_in_resilience_manager(self):
"""CRITICAL: Verify constraint is in create_resilience_aware()."""
manager = ConstraintManager.create_resilience_aware()
registered_types = {type(c) for c in manager.constraints}
assert FridayCallAvoidanceConstraint in registered_types
def test_validate_friday_distribution(self):
"""Test validation logic for Friday call assignments."""
# Implementation...
pass
Step 5: Run Pre-Flight Verification
cd /home/user/Autonomous-Assignment-Program-Manager/backend
# Run verification script
python ../scripts/verify_constraints.py
Expected Output:
============================================================
CONSTRAINT PRE-FLIGHT VERIFICATION
============================================================
============================================================
CONSTRAINT REGISTRATION VERIFICATION
============================================================
Registered constraints (24 total): # ← Was 23, now 24
- 1in7Rule: ENABLED
- 80HourRule: ENABLED
- Availability: ENABLED
- CallSpacing: ENABLED weight=8.0
...
- FridayCallAvoidance: ENABLED weight=3.0 # ← NEW!
Block 10 Constraint Check:
[OK] CallSpacingConstraint
[OK] SundayCallEquityConstraint
[OK] TuesdayCallPreferenceConstraint
[OK] WeekdayCallEquityConstraint
[OK] FridayCallAvoidanceConstraint # ← NEW!
============================================================
WEIGHT HIERARCHY VERIFICATION
============================================================
Call preference weight hierarchy:
[OK] SundayCallEquity: weight=10.0
[OK] CallSpacing: weight=8.0
[OK] WeekdayCallEquity: weight=5.0
[OK] FridayCallAvoidance: weight=3.0 # ← NEW! Correctly positioned
[OK] TuesdayCallPreference: weight=2.0
============================================================
MANAGER CONSISTENCY VERIFICATION
============================================================
Block 10 constraints in both managers:
[OK] FridayCallAvoidance # ← In both create_default() and create_resilience_aware()
============================================================
SUMMARY
============================================================
Registration: PASS ✓
Weight Hierarchy: PASS ✓
Manager Consistency: PASS ✓
[SUCCESS] All verifications passed!
Step 6: Run Tests and Commit
# Run tests
pytest tests/test_friday_call_avoidance.py -v
pytest tests/test_constraint_registration.py -v
# All pass? Commit!
git add backend/app/scheduling/constraints/friday_call_avoidance.py
git add backend/app/scheduling/constraints/__init__.py
git add backend/app/scheduling/constraints/manager.py
git add backend/tests/test_friday_call_avoidance.py
git commit -m "$(cat <<'EOF'
feat: add FridayCallAvoidanceConstraint to minimize Friday calls
Implements soft constraint (weight=3.0) to reduce Friday inpatient
call assignments, improving weekend coverage availability.
- Constraint registered in both default and resilience-aware managers
- Weight positioned below call equity (5.0) but above Tuesday preference (2.0)
- Verified with pre-flight check and registration tests
EOF
)"
Symptom:
$ python ../scripts/verify_constraints.py
[ERROR] FridayCallAvoidanceConstraint exported but NOT registered in ConstraintManager!
Root cause: Forgot Step 3 (registering in manager.py)
Recovery:
# 1. Add to manager.py
from .friday_call_avoidance import FridayCallAvoidanceConstraint
# 2. Add to BOTH factory methods
def create_default(cls):
manager.add(FridayCallAvoidanceConstraint(weight=3.0)) # Add this!
def create_resilience_aware(cls, ...):
manager.add(FridayCallAvoidanceConstraint(weight=3.0)) # And this!
# 3. Re-run verification
python ../scripts/verify_constraints.py
# Should now PASS
Symptom:
$ python ../scripts/verify_constraints.py
[WARNING] Weight hierarchy violated:
SundayCallEquity: 10.0
CallSpacing: 8.0
FridayCallAvoidance: 9.0 ← TOO HIGH! Should be < 8.0
WeekdayCallEquity: 5.0
Root cause: Weight set too high, violating call equity hierarchy
Recovery:
# 1. Adjust weight in manager.py
# OLD:
manager.add(FridayCallAvoidanceConstraint(weight=9.0)) # Wrong!
# NEW:
manager.add(FridayCallAvoidanceConstraint(weight=3.0)) # Correct
# 2. Document rationale
# Weight must be < 5.0 (below WeekdayCallEquity)
# but > 2.0 (above TuesdayCallPreference)
# because Friday avoidance is more important than day preference
# 3. Re-run verification
python ../scripts/verify_constraints.py
Symptom:
$ python ../scripts/verify_constraints.py
[ERROR] Manager consistency check FAILED:
FridayCallAvoidance in create_default() ✓
FridayCallAvoidance in create_resilience_aware() ✗ MISSING!
Root cause: Added to create_default() but forgot create_resilience_aware()
Recovery:
# Add to BOTH methods:
@classmethod
def create_resilience_aware(cls, ...):
manager = cls()
# ... other constraints ...
manager.add(FridayCallAvoidanceConstraint(weight=3.0)) # ← Add this!
return manager
Symptom:
$ pytest tests/test_constraint_registration.py -v
FAILED test_constraint_registered_in_default_manager
AssertionError: FridayCallAvoidanceConstraint not in registered types
Root cause: Test ran before constraint was imported in manager
Recovery:
# 1. Verify import exists in manager.py
grep "FridayCallAvoidanceConstraint" backend/app/scheduling/constraints/manager.py
# 2. If missing, add import:
from .friday_call_avoidance import FridayCallAvoidanceConstraint
# 3. Clear Python cache
find . -type d -name __pycache__ -exec rm -rf {} +
find . -type f -name "*.pyc" -delete
# 4. Re-run tests
pytest tests/test_constraint_registration.py -v
Scenario: Pre-flight fails, automated-code-fixer can add registration
[constraint-preflight detects missing registration]
→ "FridayCallAvoidanceConstraint exported but not registered"
[Invoke automated-code-fixer]
→ automated-code-fixer adds manager.add() lines to both methods
→ Re-runs verification
→ All checks PASS
→ Commits fix
Workflow:
[User creates new constraint class]
[constraint-preflight activated]
Step 1-3: Implement, export, register
Step 4: Invoke test-writer skill
"Generate comprehensive tests for FridayCallAvoidanceConstraint:
- Initialization tests
- Registration tests
- Validation logic tests
- Weight hierarchy tests"
[test-writer generates test suite]
[constraint-preflight verifies tests cover registration]
Pre-commit integration:
[About to commit constraint changes]
[constraint-preflight runs verification]
→ All checks PASS
[Invoke code-review skill]
→ Reviews constraint implementation
→ Checks weight rationale is documented
→ Verifies clinical justification in docstring
→ Approves or requests changes
[Commit only after both skills approve]
PR workflow:
[PR created with new constraint]
[pr-reviewer activated]
→ Detects constraint-related changes
→ Invokes constraint-preflight automatically
→ Runs verification in CI
→ Includes verification output in PR review:
"Constraint Pre-Flight Check: PASS ✓
- Registration verified
- Weight hierarchy correct
- Manager consistency confirmed"
__init__.pymanager.pycreate_default()create_resilience_aware() (if applicable)python ../scripts/verify_constraints.pypytest tests/test_constraint_registration.py -v: ALL PASSEscalate to human if ANY of these are true:
Escalate to human when:
xiaohongshu
technical spec
product ux expert
database patterns
Conduct multi-agent task orchestration and workflow coordination.
Initialize project with Conductor artifacts (product definition,
Expert in web animations, transitions, and motion design using Framer Motion and CSS
Creates Mermaid and ASCII diagrams for flowcharts, architecture, ERDs, state machines, mindmaps, and more. Use when user mentions diagram, flowchart, mermaid, ASCII diagram, text diagram, terminal diagram, visualize, C4, mindmap, architecture diagram, sequence diagram, ERD, or needs visual docume...
PostgreSQL bindings for H3 hexagonal grid system. Use when working with H3 cells in Postgres, including spatial indexing, geometry/geography integration, and raster analysis.
Context-Driven Development skill for projects using Conductor. Use this skill when you detect a `conductor/` directory in the project, when working on tasks defined in a `plan.md` file, or when the user asks about tracks, specs, or plans. Automatically applies TDD workflow, tracks task completion...
Display project status, active tracks, and next actions
Official Stakpak application containerization standard operating procedure, a step-by-step guidline to properly dockerize applications. This is a rule book curated by the Stakpak Team.
Generate, edit, and beat-sync AI video with leading models in one workspace.
The world's fastest calendar for remote work
Transform Your Design with AI Designer by ImgCreator.ai
Revolutionizing Video Production with AI-Powered Creativity
Extend an image past the frame and let AI fill the new aspect ratio.
Discover your celebrity doppelgänger with StarByFace!
ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.
Opus.ai: Revolutionize Your Web Experience