.claude/skills/lifecycle/SKILL.md
# Component Lifecycle Tracking Skill This skill provides guidance for working with component lifecycle tracking in the lib-electronic-components library. ## Overview Component lifecycle tracking helps manage obsolescence risk by tracking: - Current manufacturing status (Active, NRFND, Last Time Buy, Obsolete, EOL) - Important dates (Last Time Buy deadline, End of Life date) - Replacement part suggestions with compatibility levels - Status change history for audit trail ## Core Classes ### C
npx skillsauth add Cantara/lib-electronic-components .claude/skills/lifecycleInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
This skill provides guidance for working with component lifecycle tracking in the lib-electronic-components library.
Component lifecycle tracking helps manage obsolescence risk by tracking:
ACTIVE // In production, available
NRFND // Not Recommended For New Designs
LAST_TIME_BUY // Final order window
OBSOLETE // No longer manufactured
EOL // Complete end of life
UNKNOWN // Status not determined
Key Methods:
isAvailable() - Returns true for ACTIVE, NRFND, LAST_TIME_BUYshouldAvoidForNewDesigns() - Returns true for all except ACTIVE and UNKNOWNrequiresAttention() - Returns true for LAST_TIME_BUY, OBSOLETE, EOLFields:
status - Current lifecycle statusstatusDate - When status was set/verifiedlastTimeBuyDate - LTB deadline (if applicable)endOfLifeDate - EOL datereplacementParts - List of suggested replacementssource - Where lifecycle info came fromnotes - Additional notesstatusHistory - Audit trail of status changesFactory Methods:
ComponentLifecycle.active() // Creates ACTIVE status
ComponentLifecycle.lastTimeBuy(LocalDate deadline) // Creates LTB with deadline
ComponentLifecycle.obsoleteWithReplacement(mpn, mfr) // Creates OBSOLETE with replacement
Key Methods:
isAvailable() // Status allows purchasing
shouldAvoidForNewDesigns() // Status indicates avoid for new designs
requiresAttention() // Status needs action (LTB/OBSOLETE/EOL)
isLtbApproaching(int days) // LTB deadline within threshold
isLtbExpired() // LTB deadline has passed
getPrimaryReplacement() // First replacement in list
getReplacementsByCompatibility() // Filter by compatibility level
Fields:
mpn - Replacement part numbermanufacturer - Replacement manufacturercompatibility - Compatibility level enumnotes - Additional notesCompatibilityLevel Enum:
FORM_FIT_FUNCTION // Drop-in replacement
FUNCTIONAL_EQUIVALENT // Same function, different form
SIMILAR // Similar specs, may need changes
CROSS_REFERENCE // Equivalent from different manufacturer
UPGRADE // Better specs than original
Records status transitions for audit:
fromStatus - Previous statustoStatus - New statuschangeDate - When change occurredreason - Optional reason for changeElectronicPart part = new ElectronicPart()
.setMpn("STM32F407VGT6")
.setManufacturer("STMicroelectronics")
.setLifecycle(ComponentLifecycle.active());
BOMEntry entry = new BOMEntry()
.setMpn("MC34063ADR")
.setManufacturer("Texas Instruments")
.setQty("10")
.setLifecycle(ComponentLifecycle.lastTimeBuy(LocalDate.of(2024, 9, 30)));
// Simple check
if (part.isLifecycleAtRisk()) {
System.out.println("Component needs replacement planning");
}
// Detailed check
ComponentLifecycleStatus status = part.getLifecycleStatus();
switch (status) {
case ACTIVE -> System.out.println("OK");
case NRFND -> System.out.println("Consider alternatives for new designs");
case LAST_TIME_BUY -> {
if (part.getLifecycle().isLtbApproaching(90)) {
System.out.println("URGENT: LTB deadline within 90 days");
}
}
case OBSOLETE, EOL -> System.out.println("CRITICAL: Find replacement");
case UNKNOWN -> System.out.println("Update lifecycle info");
}
ComponentLifecycle lifecycle = new ComponentLifecycle(ComponentLifecycleStatus.OBSOLETE);
// Add drop-in replacement
lifecycle.addReplacementPart("NEW-001", "Same Corp",
ReplacementPart.CompatibilityLevel.FORM_FIT_FUNCTION);
// Add cross-reference
lifecycle.addReplacementPart("ALT-001", "Other Corp",
ReplacementPart.CompatibilityLevel.CROSS_REFERENCE);
// Add upgrade
ReplacementPart upgrade = new ReplacementPart()
.setMpn("BETTER-001")
.setManufacturer("Premium Corp")
.setCompatibility(ReplacementPart.CompatibilityLevel.UPGRADE)
.setNotes("2x the current rating");
lifecycle.addReplacementPart(upgrade);
// Get primary (first) replacement
ReplacementPart primary = lifecycle.getPrimaryReplacement();
// Get only drop-in replacements
List<ReplacementPart> dropIns = lifecycle.getReplacementsByCompatibility(
ReplacementPart.CompatibilityLevel.FORM_FIT_FUNCTION);
ComponentLifecycle lifecycle = ComponentLifecycle.active();
// Status changes are automatically recorded
lifecycle.setStatus(ComponentLifecycleStatus.NRFND);
lifecycle.setStatus(ComponentLifecycleStatus.LAST_TIME_BUY);
// Review history
for (StatusChange change : lifecycle.getStatusHistory()) {
System.out.printf("%s: %s → %s%n",
change.getChangeDate(),
change.getFromStatus(),
change.getToStatus());
}
Lifecycle data serializes cleanly with Jackson 3:
JsonMapper mapper = JsonMapper.builder().build();
String json = mapper.writeValueAsString(part);
ElectronicPart deserialized = mapper.readValue(json, ElectronicPart.class);
Output format:
{
"mpn": "MC34063ADR",
"manufacturer": "Texas Instruments",
"lifecycle": {
"status": "LAST_TIME_BUY",
"statusDate": "2026-01-12",
"lastTimeBuyDate": "2024-09-30",
"replacementParts": [
{
"mpn": "MC34063ADR-NEW",
"manufacturer": "Texas Instruments",
"compatibility": "FORM_FIT_FUNCTION"
}
],
"source": "Manufacturer PCN"
}
}
public class BOMLifecycleAnalyzer {
public void analyzeRisk(BOM bom) {
List<BOMEntry> atRisk = bom.getBomEntries().stream()
.filter(ElectronicPart::isLifecycleAtRisk)
.toList();
if (!atRisk.isEmpty()) {
System.out.println("Components requiring attention:");
for (BOMEntry entry : atRisk) {
ComponentLifecycle lc = entry.getLifecycle();
System.out.printf(" %s (%s): %s%n",
entry.getMpn(),
entry.getManufacturer(),
lc.getStatus().getDisplayName());
if (lc.getLastTimeBuyDate() != null) {
System.out.printf(" LTB Deadline: %s%n", lc.getLastTimeBuyDate());
}
ReplacementPart primary = lc.getPrimaryReplacement();
if (primary != null) {
System.out.printf(" Suggested: %s (%s)%n",
primary.getMpn(), primary.getCompatibility().getDisplayName());
}
}
}
}
}
// BAD - NPE if lifecycle is null
if (part.getLifecycle().getStatus() == ComponentLifecycleStatus.OBSOLETE) { ... }
// GOOD - Use convenience method
if (part.getLifecycleStatus() == ComponentLifecycleStatus.OBSOLETE) { ... }
// GOOD - Check first
if (part.hasLifecycleInfo()) {
ComponentLifecycle lc = part.getLifecycle();
// ...
}
// Common thresholds
lifecycle.isLtbApproaching(30); // Urgent - 1 month
lifecycle.isLtbApproaching(90); // Warning - 3 months
lifecycle.isLtbApproaching(180); // Planning - 6 months
// First added = primary replacement
lifecycle.addReplacementPart("BEST-001", ...); // getPrimaryReplacement() returns this
lifecycle.addReplacementPart("ALT-001", ...);
lifecycle.addReplacementPart("ALT-002", ...);
lifecycle.setSource("Manufacturer PCN #12345");
lifecycle.setSource("DigiKey obsolescence notice");
lifecycle.setSource("Manual review 2026-01-12");
// Each setStatus() call automatically adds to statusHistory
// No need to manually track changes
lifecycle.setStatus(ComponentLifecycleStatus.NRFND); // Recorded
lifecycle.setStatus(ComponentLifecycleStatus.LTB); // Recorded
// UNKNOWN status means "we have lifecycle data but status is unknown"
new ComponentLifecycle() // status defaults to UNKNOWN
// Null lifecycle means "no lifecycle data at all"
part.getLifecycle() // may return null
// getLifecycleStatus() safely handles both
part.getLifecycleStatus() // returns UNKNOWN if lifecycle is null
See ComponentLifecycleTest.java for comprehensive test coverage including:
ComponentLifecycleStatus.java - Status enumComponentLifecycle.java - Main lifecycle class with inner classesElectronicPart.java - Base class with lifecycle fieldBOMEntry.java - BOM entry with lifecycle inheritanceComponentLifecycleTest.java - Unit testssetStatus() automatically adds to history, no manual tracking neededactive(), lastTimeBuy(), obsoleteWithReplacement() all set current datedata-ai
Cost-effective task delegation strategy using Haiku model for straightforward work. Use when planning how to approach simple, pattern-following tasks to minimize costs.
tools
Use when working with component similarity calculations - comparing MPNs, finding equivalent parts, implementing new similarity calculators, or understanding how component matching works.
testing
Use when working with transistor similarity calculations - comparing BJT MPNs, understanding NPN/PNP polarity matching, equivalent groups like 2N2222/PN2222, or transistor-specific similarity logic.
testing
Use when working with sensor similarity calculations - comparing temperature/accelerometer/humidity sensor MPNs, understanding sensor families, equivalent parts, or sensor-specific similarity logic.