feat: add waits-for dependency type for fanout gates (bd-xo1o.2)
Adds 'waits-for' dependency type for dynamic molecule bonding: - DepWaitsFor blocks an issue until spawner's children are closed - Two gate types: all-children (wait for all) or any-children (first) - Updated blocked_cache.go CTE to handle waits-for dependencies - Added --waits-for and --waits-for-gate flags to bd create command - Added WaitsForMeta struct for gate metadata storage - Full test coverage for all gate types and dynamic child scenarios This enables patrol molecules to wait for dynamically-bonded arms to complete before proceeding (Christmas Ornament pattern). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -72,6 +72,9 @@ type CreateArgs struct {
|
||||
EstimatedMinutes *int `json:"estimated_minutes,omitempty"` // Time estimate in minutes
|
||||
Labels []string `json:"labels,omitempty"`
|
||||
Dependencies []string `json:"dependencies,omitempty"`
|
||||
// Waits-for dependencies (bd-xo1o.2)
|
||||
WaitsFor string `json:"waits_for,omitempty"` // Spawner issue ID to wait for
|
||||
WaitsForGate string `json:"waits_for_gate,omitempty"` // Gate type: all-children or any-children
|
||||
// Messaging fields (bd-kwro)
|
||||
Sender string `json:"sender,omitempty"` // Who sent this (for messages)
|
||||
Wisp bool `json:"wisp,omitempty"` // Wisp = ephemeral vapor from the Steam Engine; bulk-deleted when closed
|
||||
|
||||
@@ -309,6 +309,46 @@ func (s *Server) handleCreate(req *Request) Response {
|
||||
}
|
||||
}
|
||||
|
||||
// Add waits-for dependency if specified (bd-xo1o.2)
|
||||
if createArgs.WaitsFor != "" {
|
||||
// Validate gate type
|
||||
gate := createArgs.WaitsForGate
|
||||
if gate == "" {
|
||||
gate = types.WaitsForAllChildren
|
||||
}
|
||||
if gate != types.WaitsForAllChildren && gate != types.WaitsForAnyChildren {
|
||||
return Response{
|
||||
Success: false,
|
||||
Error: fmt.Sprintf("invalid waits_for_gate value '%s' (valid: all-children, any-children)", gate),
|
||||
}
|
||||
}
|
||||
|
||||
// Create metadata JSON
|
||||
meta := types.WaitsForMeta{
|
||||
Gate: gate,
|
||||
}
|
||||
metaJSON, err := json.Marshal(meta)
|
||||
if err != nil {
|
||||
return Response{
|
||||
Success: false,
|
||||
Error: fmt.Sprintf("failed to serialize waits-for metadata: %v", err),
|
||||
}
|
||||
}
|
||||
|
||||
dep := &types.Dependency{
|
||||
IssueID: issue.ID,
|
||||
DependsOnID: createArgs.WaitsFor,
|
||||
Type: types.DepWaitsFor,
|
||||
Metadata: string(metaJSON),
|
||||
}
|
||||
if err := store.AddDependency(ctx, dep, s.reqActor(req)); err != nil {
|
||||
return Response{
|
||||
Success: false,
|
||||
Error: fmt.Sprintf("failed to add waits-for dependency %s -> %s: %v", issue.ID, createArgs.WaitsFor, err),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Emit mutation event for event-driven daemon
|
||||
s.emitMutation(MutationCreate, issue.ID)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user