feat: implement conditional bond type for mol bond (bd-kzda)

Conditional bonds now work as documented: "B runs only if A fails".

Implementation:
- Add DepConditionalBlocks dependency type to types.go
- Add IsFailureClose() helper to detect failure keywords in close_reason
- Update blocked cache to handle conditional-blocks:
  - B is blocked while A is open
  - B stays blocked if A closes with success
  - B becomes unblocked if A closes with failure

Failure keywords: failed, rejected, wontfix, cancelled, abandoned,
blocked, error, timeout, aborted (case-insensitive)

Updated bondProtoProto, bondProtoMol, bondMolMol to use
DepConditionalBlocks for conditional bond type.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Steve Yegge
2025-12-23 00:26:29 -08:00
parent aa1ce63156
commit 7fb92ff78c
9 changed files with 261 additions and 30 deletions

View File

@@ -712,8 +712,8 @@ func (t *sqliteTxStorage) AddDependency(ctx context.Context, dep *types.Dependen
}
}
// Invalidate blocked cache for blocking dependencies (bd-1c4h)
if dep.Type == types.DepBlocks || dep.Type == types.DepParentChild {
// Invalidate blocked cache for blocking dependencies (bd-1c4h, bd-kzda)
if dep.Type.AffectsReadyWork() {
if err := t.parent.invalidateBlockedCache(ctx, t.conn); err != nil {
return fmt.Errorf("failed to invalidate blocked cache: %w", err)
}
@@ -730,10 +730,10 @@ func (t *sqliteTxStorage) RemoveDependency(ctx context.Context, issueID, depends
SELECT type FROM dependencies WHERE issue_id = ? AND depends_on_id = ?
`, issueID, dependsOnID).Scan(&depType)
// Store whether cache needs invalidation before deletion
// Store whether cache needs invalidation before deletion (bd-1c4h, bd-kzda)
needsCacheInvalidation := false
if err == nil {
needsCacheInvalidation = (depType == types.DepBlocks || depType == types.DepParentChild)
needsCacheInvalidation = depType.AffectsReadyWork()
}
result, err := t.conn.ExecContext(ctx, `