feat: add pour warning for vapor-phase formulas, improve help text, add doctor check
- Add Phase field to Formula type to indicate recommended instantiation phase - Add warning in 'bd mol pour' when formula has phase="vapor" - Improve pour/wisp help text with clear comparison of when to use each - Add CheckPersistentMolIssues doctor check to detect mol- issues in JSONL - Update beads-release.formula.json with phase="vapor" This helps prevent accidental persistence of ephemeral workflow issues.
This commit is contained in:
@@ -350,3 +350,78 @@ func resolveBeadsDir(beadsDir string) string {
|
||||
|
||||
return target
|
||||
}
|
||||
|
||||
// CheckPersistentMolIssues detects mol- prefixed issues that should have been ephemeral.
|
||||
// When users run "bd mol pour" on formulas that should use "bd mol wisp", the resulting
|
||||
// issues get the "mol-" prefix but persist in JSONL. These should be cleaned up.
|
||||
func CheckPersistentMolIssues(path string) DoctorCheck {
|
||||
beadsDir := resolveBeadsDir(filepath.Join(path, ".beads"))
|
||||
jsonlPath := filepath.Join(beadsDir, "issues.jsonl")
|
||||
|
||||
if _, err := os.Stat(jsonlPath); os.IsNotExist(err) {
|
||||
return DoctorCheck{
|
||||
Name: "Persistent Mol Issues",
|
||||
Status: StatusOK,
|
||||
Message: "N/A (no JSONL file)",
|
||||
Category: CategoryMaintenance,
|
||||
}
|
||||
}
|
||||
|
||||
// Read JSONL and count mol- prefixed issues that are not ephemeral
|
||||
file, err := os.Open(jsonlPath) // #nosec G304 - path constructed safely
|
||||
if err != nil {
|
||||
return DoctorCheck{
|
||||
Name: "Persistent Mol Issues",
|
||||
Status: StatusOK,
|
||||
Message: "N/A (unable to read JSONL)",
|
||||
Category: CategoryMaintenance,
|
||||
}
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
var molCount int
|
||||
var molIDs []string
|
||||
decoder := json.NewDecoder(file)
|
||||
|
||||
for {
|
||||
var issue types.Issue
|
||||
if err := decoder.Decode(&issue); err != nil {
|
||||
break
|
||||
}
|
||||
// Skip deleted issues (tombstones)
|
||||
if issue.DeletedAt != nil {
|
||||
continue
|
||||
}
|
||||
// Look for mol- prefix that shouldn't be in JSONL
|
||||
// (ephemeral issues have Ephemeral=true and don't get exported)
|
||||
if strings.HasPrefix(issue.ID, "mol-") && !issue.Ephemeral {
|
||||
molCount++
|
||||
if len(molIDs) < 3 {
|
||||
molIDs = append(molIDs, issue.ID)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if molCount == 0 {
|
||||
return DoctorCheck{
|
||||
Name: "Persistent Mol Issues",
|
||||
Status: StatusOK,
|
||||
Message: "No persistent mol- issues",
|
||||
Category: CategoryMaintenance,
|
||||
}
|
||||
}
|
||||
|
||||
detail := fmt.Sprintf("Example: %v", molIDs)
|
||||
if molCount > 3 {
|
||||
detail += fmt.Sprintf(" (+%d more)", molCount-3)
|
||||
}
|
||||
|
||||
return DoctorCheck{
|
||||
Name: "Persistent Mol Issues",
|
||||
Status: StatusWarning,
|
||||
Message: fmt.Sprintf("%d mol- issue(s) in JSONL should be ephemeral", molCount),
|
||||
Detail: detail,
|
||||
Fix: "Run 'bd delete <id> --force' to remove, or use 'bd mol wisp' instead of 'bd mol pour'",
|
||||
Category: CategoryMaintenance,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user