Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,4 @@ coverage.out
.unbound-force/
.muti-mind/
.mx-f/
.uf/feedback/
307 changes: 307 additions & 0 deletions internal/agentkit/agentkit_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,313 @@ func TestWorkerPrompt_HardenedStructure(t *testing.T) {
}
}

func TestForgeMD_StructuralHardening(t *testing.T) {
// Read forge.md from embedded content.
data, err := content.ReadFile("content/commands/forge.md")
if err != nil {
t.Fatalf("read forge.md: %v", err)
}
text := string(data)
lines := strings.Split(text, "\n")

// Helper: find the line index of a heading (e.g., "## Critical Invariants").
findHeading := func(heading string) int {
for i, line := range lines {
if strings.TrimSpace(line) == heading {
return i
}
}
return -1
}

// Helper: extract the section between a heading and the next same-level heading.
sectionContent := func(heading string) string {
start := findHeading(heading)
if start < 0 {
return ""
}
level := 0
for _, ch := range heading {
if ch == '#' {
level++
} else {
break
}
}
var sb strings.Builder
for i := start + 1; i < len(lines); i++ {
trimmed := strings.TrimSpace(lines[i])
if strings.HasPrefix(trimmed, strings.Repeat("#", level)+" ") && !strings.HasPrefix(trimmed, strings.Repeat("#", level+1)) {
break
}
sb.WriteString(lines[i])
sb.WriteString("\n")
}
return sb.String()
}

// Scenario 1: Critical Invariants section appears before Workflow section.
t.Run("InvariantsBeforeWorkflow", func(t *testing.T) {
invIdx := findHeading("## Critical Invariants")
wfIdx := findHeading("## Workflow")
if invIdx < 0 {
t.Fatal("Critical Invariants section not found")
}
if wfIdx < 0 {
t.Fatal("Workflow section not found")
}
if invIdx >= wfIdx {
t.Errorf("Critical Invariants (line %d) must appear before Workflow (line %d)", invIdx, wfIdx)
}
})

// Scenario 2: Review-before-complete invariant is present in Critical Invariants.
t.Run("ReviewBeforeCompleteInvariant", func(t *testing.T) {
section := sectionContent("## Critical Invariants")
if section == "" {
t.Fatal("Critical Invariants section not found")
}
lower := strings.ToLower(section)
if !strings.Contains(lower, "review") || !strings.Contains(lower, "before") {
t.Error("Critical Invariants must contain review-before-complete constraint")
}
if !strings.Contains(section, "MUST") {
t.Error("Critical Invariants must use RFC 2119 MUST language for review constraint")
}
})

// Scenario 3: Review gate mandatory constraint is present in Critical Invariants.
t.Run("ReviewGateMandatory", func(t *testing.T) {
section := sectionContent("## Critical Invariants")
if section == "" {
t.Fatal("Critical Invariants section not found")
}
// The review gate must be stated as a positive constraint (not naming bypass parameters).
if !strings.Contains(section, "MUST NOT") {
t.Error("Critical Invariants must use MUST NOT for review gate constraint")
}
if !strings.Contains(section, "NEVER") {
t.Error("Critical Invariants must use NEVER for review gate constraint")
}
lower := strings.ToLower(section)
if !strings.Contains(lower, "review gate") {
t.Error("Critical Invariants must reference 'review gate' as mandatory")
}
})

// Scenario 4: Review-before-complete constraint has redundant placement
// (present in ALL THREE sections: Critical Invariants, Workflow, and Rules).
t.Run("RedundantReviewConstraint", func(t *testing.T) {
invariants := sectionContent("## Critical Invariants")
workflow := sectionContent("## Workflow")
rules := sectionContent("## Rules")

inInvariants := strings.Contains(strings.ToLower(invariants), "review") &&
strings.Contains(strings.ToLower(invariants), "before")
inWorkflow := strings.Contains(strings.ToLower(workflow), "review") &&
strings.Contains(strings.ToLower(workflow), "before")
inRules := strings.Contains(strings.ToLower(rules), "review") &&
strings.Contains(strings.ToLower(rules), "before") &&
strings.Contains(strings.ToLower(rules), "complete")

if !inInvariants {
t.Error("review-before-complete not found in Critical Invariants")
}
if !inWorkflow {
t.Error("review-before-complete not found in Workflow section")
}
if !inRules {
t.Error("review-before-complete not found in Rules section")
}
})

// Scenario 5: Step 7 text includes explicit ordering constraint.
t.Run("Step7OrderingConstraint", func(t *testing.T) {
workflow := sectionContent("## Workflow")
if workflow == "" {
t.Fatal("Workflow section not found")
}
// Find step 7 line — require MUST AND an ordering signal.
var foundStep7 bool
for _, line := range strings.Split(workflow, "\n") {
if strings.HasPrefix(strings.TrimSpace(line), "7.") {
foundStep7 = true
lower := strings.ToLower(line)
hasMust := strings.Contains(line, "MUST")
hasOrdering := strings.Contains(lower, "first") || strings.Contains(lower, "before step 8")
if !hasMust {
t.Error("Step 7 must use RFC 2119 MUST language")
}
if !hasOrdering {
t.Error("Step 7 must contain ordering signal (FIRST or 'before step 8')")
}
break
}
}
if !foundStep7 {
t.Error("Step 7 not found in Workflow section")
}
})

// Scenario 6: Review rule is first item in Rules section.
t.Run("ReviewRuleFirstInRules", func(t *testing.T) {
rules := sectionContent("## Rules")
if rules == "" {
t.Fatal("Rules section not found")
}
// Find first bullet in Rules section.
for _, line := range strings.Split(rules, "\n") {
trimmed := strings.TrimSpace(line)
if strings.HasPrefix(trimmed, "- ") {
lower := strings.ToLower(trimmed)
if !strings.Contains(lower, "review") {
t.Errorf("first Rules bullet must be about review, got: %s", trimmed)
}
break
}
}
})

// Scenario 7: No standalone Strategy Selection, Error Recovery, or Completion sections.
t.Run("NoStandaloneSections", func(t *testing.T) {
prohibited := []string{
"## Strategy Selection",
"## Error Recovery",
"## Completion",
}
for _, heading := range prohibited {
if findHeading(heading) >= 0 {
t.Errorf("found prohibited standalone section: %s", heading)
}
}
})

// Scenario 8: Strategy selection content is inlined within step 3 (Decompose).
t.Run("StrategyInlinedInStep3", func(t *testing.T) {
workflow := sectionContent("## Workflow")
if workflow == "" {
t.Fatal("Workflow section not found")
}
// Find step 3 and its sub-items (lines between "3." and the next step "4.").
wfLines := strings.Split(workflow, "\n")
var step3Content strings.Builder
inStep3 := false
for _, line := range wfLines {
trimmed := strings.TrimSpace(line)
if strings.HasPrefix(trimmed, "3.") {
inStep3 = true
} else if inStep3 && len(trimmed) > 0 && trimmed[0] >= '1' && trimmed[0] <= '9' && len(trimmed) > 1 && trimmed[1] == '.' {
break
}
if inStep3 {
step3Content.WriteString(line)
step3Content.WriteString("\n")
}
}
s3 := step3Content.String()
if !strings.Contains(s3, "forge_get_strategy_insights") {
t.Error("Step 3 must contain forge_get_strategy_insights (strategy selection inlined)")
}
if !strings.Contains(s3, "forge_decompose") {
t.Error("Step 3 must contain forge_decompose")
}
})

// Scenario 9: Error recovery content is inlined within step 6 (Monitor).
t.Run("ErrorRecoveryInlinedInStep6", func(t *testing.T) {
workflow := sectionContent("## Workflow")
if workflow == "" {
t.Fatal("Workflow section not found")
}
wfLines := strings.Split(workflow, "\n")
var step6Content strings.Builder
inStep6 := false
for _, line := range wfLines {
trimmed := strings.TrimSpace(line)
if strings.HasPrefix(trimmed, "6.") {
inStep6 = true
} else if inStep6 && len(trimmed) > 0 && trimmed[0] >= '1' && trimmed[0] <= '9' && len(trimmed) > 1 && trimmed[1] == '.' {
break
}
if inStep6 {
step6Content.WriteString(line)
step6Content.WriteString("\n")
}
}
s6 := step6Content.String()
lower := strings.ToLower(s6)
if !strings.Contains(lower, "blocked") {
t.Error("Step 6 must contain blocked-worker recovery guidance")
}
if !strings.Contains(lower, "unblock") && !strings.Contains(lower, "reassign") {
t.Error("Step 6 must contain recovery action (unblock or reassign)")
}
})

// Scenario 10: Completion sub-steps are inlined within step 8.
t.Run("CompletionInlinedInStep8", func(t *testing.T) {
workflow := sectionContent("## Workflow")
if workflow == "" {
t.Fatal("Workflow section not found")
}
wfLines := strings.Split(workflow, "\n")
var step8Content strings.Builder
inStep8 := false
for _, line := range wfLines {
trimmed := strings.TrimSpace(line)
if strings.HasPrefix(trimmed, "8.") {
inStep8 = true
} else if inStep8 && len(trimmed) > 0 && trimmed[0] >= '1' && trimmed[0] <= '9' && len(trimmed) > 1 && trimmed[1] == '.' {
break
}
if inStep8 {
step8Content.WriteString(line)
step8Content.WriteString("\n")
}
}
s8 := step8Content.String()
required := []string{
"forge_complete",
"forge_record_outcome",
"hivemind_store",
"org_sync",
}
for _, tool := range required {
if !strings.Contains(s8, tool) {
t.Errorf("Step 8 must contain %s (completion sub-step)", tool)
}
}
})

// Scenario 11: All MCP tool references from the forge workflow are present.
t.Run("AllToolReferencesPresent", func(t *testing.T) {
allTools := []string{
"comms_init",
"hivemind_find",
"forge_decompose",
"forge_get_strategy_insights",
"org_create_epic",
"forge_spawn_subtask",
"comms_inbox",
"forge_status",
"org_cells",
"comms_read_message",
"comms_ack",
"forge_review",
"forge_complete",
"forge_record_outcome",
"hivemind_store",
"org_sync",
"comms_reserve",
}
for _, tool := range allTools {
if !strings.Contains(text, tool) {
t.Errorf("forge.md missing MCP tool reference: %s", tool)
}
}
})
}

func TestSkillTemplates_HaveNameField(t *testing.T) {
// Walk the embedded content filesystem and verify every SKILL.md
// has a "name: <directory-name>" field in its YAML frontmatter.
Expand Down
Loading