Expert guidance for Tellurian.Trains.Dispatch .NET library - model railway train dispatching system with broker, dispatchers, and block signal state management
Expert guidance for working with the Tellurian.Trains.Dispatch .NET library for model railway train dispatching.
Provides Claude Code with deep context about the Tellurian.Trains.Dispatch codebase architecture, domain model, and conventions. Enables accurate code modifications, feature additions, and debugging for this specialized train dispatching system.
1. **Broker** - Central singleton component
- Holds state of each train's calls at specific stations
- Manages collection of DispatchStretch (track sections)
- Manages collection of StationDispatcher (one per station)
- Manages TrainSection instances representing active dispatching
2. **Dispatcher** - Presents state of arriving and departing trains
- **StationDispatcher** - Presents state for a specific named station
- Queries the Broker for arrivals and departures
Planned → Manned → Running → [Completed | Canceled | Aborted]
None → Requested → [Accepted | Rejected] → Departed → [PassBlockSignal*] → Arrived
(or Accepted → Revoked)
Expected → Passed (or Canceled)
**Critical Rules:**
1. **N block signals** create **N+1 blocks** (segments)
2. Each block can hold **only one train** at a time
3. Trains must pass block signals **in sequence**
4. Train's current block index = count of passed BlockSignalPassages
5. Arrival is only allowed **after all block signals have been passed**
**Block Occupancy:**
**Control:**
The dispatcher who controls a block signal (`BlockSignal.ControlledBy`) is presented with the action to mark the passage.
1. **Follow Extension Method Pattern**
- Organize behavior into extension method classes
- Maintain separation of concerns
2. **Use Option<T> for Error Handling**
- Operations that can fail should return `Option<T>`
- Include descriptive error messages
3. **Respect Thread Safety**
- Use `Interlocked` for auto-incrementing IDs
- Maintain thread-safe patterns in shared state
4. **Dependency Injection Interfaces**
- `IBrokerConfiguration`
- `IBrokerStateProvider`
- `ITimeProvider`
- Keep implementations flexible for integration
5. **Target .NET 10.0**
- Project targets .NET 10.0 SDK
- Framework version defined globally in `Directory.Build.props`
- **Do NOT** add `<TargetFramework>` to individual `.csproj` files
6. **Test Projects**
- Use **MSTest.Sdk**
- Use **Microsoft Testing Platform**
- **Do NOT** use VS Test framework
1. Verify impact on state machines
2. Check block signal logic if touching DispatchStretch
3. Ensure thread-safety for shared Broker state
4. Add extension methods for new behaviors
5. Update README.md if adding public API surface
1. Check state machine transitions for invalid flows
2. Verify block signal sequence constraints
3. Inspect BlockSignalPassage counts for arrival logic
4. Review thread safety in ID generation and state updates
5. Validate Option<T> error messages for clarity
```csharp
// Train must have passed all block signals on the stretch
var requiredPassages = dispatchStretch.BlockSignals.Count;
var actualPassages = trainSection.BlockSignalPassages.Count(p => p.State == BlockPassageState.Passed);
var canArrive = actualPassages >= requiredPassages;
```
```csharp
// Find the next expected passage for this dispatcher
var nextPassage = trainSection.BlockSignalPassages
.FirstOrDefault(p => p.State == BlockPassageState.Expected
&& p.BlockSignal.ControlledBy == dispatcher);
if (nextPassage != null) {
nextPassage.MarkPassed(timeProvider.Now);
}
```
```csharp
public Option<TrainSection> RequestDispatch(Train train, DispatchStretch stretch) {
if (!train.IsManned) {
return Option<TrainSection>.Error("Train must be manned before dispatch");
}
// ... success path
return Option<TrainSection>.Success(trainSection);
}
```
Leave a review
No reviews yet. Be the first to review this skill!
# Download SKILL.md from killerskills.ai/api/skills/tellurian-trains-dispatch/raw