A time-to-event release decision joins event and censor contracts, valid risk sets, horizon support, competing events and operational capacity.
Project: release review for fleet battery-replacement timing
Freeze the forecast
The fleet team needs 45-day replacement probability from each scheduled inspection. Keep inspection-day features available then, define confirmed replacement, sale, administrative cutoff and repeat episodes, and reserve later vehicle inspections for final evaluation. Entire vehicles stay in one split. The target contract is the first release artifact.
Train comparable candidates
Start with a simple age-and-voltage survival baseline. Compare a model with additional historical service features under the same split. If voltage is updated after inspection, evaluate it only in a separate landmark model with start-stop intervals and a new decision clock. Risk sets and time-varying records must remain auditable.
Evaluate the supported horizon
Report 45-day calibration, ranking, observed event count, censoring pattern and replacement incidence by depot and vehicle model. Do not score early-censored cases as negatives. Check whether enough vehicles are observed through day 45 for stable weighting, then assess the highest-risk 26 inspections against weekly service capacity. Horizon evaluation defines the metrics.
Review competing outcomes
Vehicles sold before 45 days cannot later receive a fleet replacement under the current policy. Measure their incidence separately and label the forecast as replacement under existing service and sale policy. Reassess after a policy change. Competing events are a release concern, not a footnote.
Hold on unsupported claims
The sample packet below rejects an otherwise plausible model because only 19 vehicles are still observed at the chosen 180-day report horizon. Remove that unsupported long-horizon claim, rerun the fixed 45-day gate, and keep the prior maintenance schedule available for rollback. No model score can repair missing follow-up.
Implementation
release_packet = {
"target_contract_locked": True,
"future_feature_leaks": 0,
"day_45_risk_set": 234,
"minimum_day_45_risk_set": 90,
"day_180_risk_set": 19,
"minimum_day_180_risk_set": 65,
"reports_day_180": True,
"sale_recording_complete": True,
"weekly_review_volume": 24,
"weekly_review_capacity": 26,
}
def review_fleet_release(packet):
blockers = []
if not packet["target_contract_locked"] or packet["future_feature_leaks"]:
blockers.append("target or feature contract failed")
if packet["day_45_risk_set"] < packet["minimum_day_45_risk_set"]:
blockers.append("45-day support insufficient")
if packet["reports_day_180"] and packet["day_180_risk_set"] < packet["minimum_day_180_risk_set"]:
blockers.append("180-day support insufficient")
if not packet["sale_recording_complete"]:
blockers.append("competing sale events unresolved")
if packet["weekly_review_volume"] > packet["weekly_review_capacity"]:
blockers.append("review capacity exceeded")
return {"release": not blockers, "blockers": blockers}
decision = review_fleet_release(release_packet)
assert decision == {"release": False, "blockers": ["180-day support insufficient"]}Performance and operating cost
The packet check is O(1), but obtaining its evidence requires dated event reconciliation, risk-set construction, model fitting, censor-aware horizon scores and depot-level review. The extra 180-day forecast cannot be justified by a cheap extrapolation when the supported population is too small.
Common Mistakes
- Do not approve a longer horizon from a short-horizon result.
- Do not claim sale is independent censoring without review.
- Do not ignore the weekly service capacity when setting a risk threshold.
