feat(types): remove Gas Town types from core built-in types

Core beads built-in types now only include work types:
- bug, feature, task, epic, chore

Gas Town types (molecule, gate, convoy, merge-request, slot, agent,
role, rig, event, message) are now "well-known custom types":
- Constants still exist for code convenience
- Require types.custom configuration for validation
- bd types command shows core types and configured custom types

Changes:
- types.go: Separate core work types from well-known custom types
- IsValid(): Only accepts core work types
- bd types: Updated to show core types and custom types from config
- memory.go: Use ValidateWithCustom for custom type support
- multirepo.go: Only check core types as built-in
- Updated all tests to configure custom types

This allows Gas Town (and other projects) to define their own types
via config while keeping beads core focused on work tracking.

Closes: bd-find4

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
beads/crew/emma
2026-01-17 05:07:11 -08:00
committed by Steve Yegge
parent 88a6438c80
commit 4f0f5744a6
14 changed files with 189 additions and 67 deletions

View File

@@ -476,13 +476,20 @@ func (s Status) IsValidWithCustom(customStatuses []string) bool {
// IssueType categorizes the kind of work
type IssueType string
// Issue type constants
// Core work type constants - these are the built-in types that beads validates.
// All other types require configuration via types.custom in config.yaml.
const (
TypeBug IssueType = "bug"
TypeFeature IssueType = "feature"
TypeTask IssueType = "task"
TypeEpic IssueType = "epic"
TypeChore IssueType = "chore"
)
// Well-known custom types - constants for code convenience.
// These are NOT built-in types and require types.custom configuration for validation.
// Used by Gas Town and other infrastructure that extends beads.
const (
TypeBug IssueType = "bug"
TypeFeature IssueType = "feature"
TypeTask IssueType = "task"
TypeEpic IssueType = "epic"
TypeChore IssueType = "chore"
TypeMessage IssueType = "message" // Ephemeral communication between workers
TypeMergeRequest IssueType = "merge-request" // Merge queue entry for refinery processing
TypeMolecule IssueType = "molecule" // Template molecule for issue hierarchies
@@ -495,10 +502,12 @@ const (
TypeSlot IssueType = "slot" // Exclusive access slot (merge-slot gate)
)
// IsValid checks if the issue type value is valid
// IsValid checks if the issue type is a core work type.
// Only core work types (bug, feature, task, epic, chore) are built-in.
// Other types (molecule, gate, convoy, etc.) require types.custom configuration.
func (t IssueType) IsValid() bool {
switch t {
case TypeBug, TypeFeature, TypeTask, TypeEpic, TypeChore, TypeMessage, TypeMergeRequest, TypeMolecule, TypeGate, TypeAgent, TypeRole, TypeRig, TypeConvoy, TypeEvent, TypeSlot:
case TypeBug, TypeFeature, TypeTask, TypeEpic, TypeChore:
return true
}
return false
@@ -569,8 +578,7 @@ func (t IssueType) RequiredSections() []RequiredSection {
{Heading: "## Success Criteria", Hint: "Define high-level success criteria"},
}
default:
// Chore, message, molecule, gate, agent, role, convoy, event, merge-request
// have no required sections
// Chore and custom types have no required sections
return nil
}
}

View File

@@ -539,20 +539,24 @@ func TestIssueTypeIsValid(t *testing.T) {
issueType IssueType
valid bool
}{
// Core work types are always valid
{TypeBug, true},
{TypeFeature, true},
{TypeTask, true},
{TypeEpic, true},
{TypeChore, true},
{TypeMessage, true},
{TypeMergeRequest, true},
{TypeMolecule, true},
{TypeGate, true},
{TypeAgent, true},
{TypeRole, true},
{TypeConvoy, true},
{TypeEvent, true},
{TypeSlot, true},
// Gas Town types require types.custom configuration
{TypeMessage, false},
{TypeMergeRequest, false},
{TypeMolecule, false},
{TypeGate, false},
{TypeAgent, false},
{TypeRole, false},
{TypeConvoy, false},
{TypeEvent, false},
{TypeSlot, false},
{TypeRig, false},
// Invalid types
{IssueType("invalid"), false},
{IssueType(""), false},
}