feat(P01): add ideation engine + ciagent ideate command — IDEATE-01,02,03,17 + MULTI-01
---ci---
phase: 1
milestone: v0.10
status: execute
decisions:
- id: D-080
decision: Three-tier ideation (mechanical, backend-enriched, cross-project)
rationale: Mechanical tier always produces output without backend
confidence: 0.92
- id: D-089
decision: No separate codebase map command
rationale: Git-native + .ciagent/ covers mapping; avoids tree-sitter dep
confidence: 0.88
requirements:
covered:
- IDEATE-01
- IDEATE-02
- IDEATE-03
- IDEATE-17
- MULTI-01
---/ci---
Add IdeationEngine core module with 15 signal collectors:
- Uncovered/partial requirements from REQUIREMENTS.md
- Coverage gaps (documented but unimplemented agents)
- Repeated lessons from git history
- Low-confidence decisions from ---ci--- blocks
- Escalation patterns from git history
- Compound solution patterns
- Architecture drift (ARCHITECTURE.md vs src/)
- Verification inversion (missing test files)
- Improvement patterns (cross-referencing lessons + requirements)
- Spec ambiguity (should/could/might patterns)
- Spec missing (common requirement categories)
- Cascade impact (--affected from git diff)
- External signals (npm audit, dependency staleness)
- Cross-project lesson mining
Add ciagent ideate CLI command with flags:
--category, --affected, --spec, --external, --cross-project, --output
Add active_projects to CIAgentConfig (backwards compatible with active_project).
Add IDEATE pipeline stage between RESEARCH and PLAN.
Update IdeationAgent to delegate to IdeationEngine.
533 tests passing.
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { BackendConfigSection } from "../backends/types.js";
|
||||
import { IdeationConfig, IdeationCategory } from "./ideation.js";
|
||||
|
||||
export type AutonomyLevel = "full" | "supervised" | "guided";
|
||||
|
||||
@@ -82,6 +83,7 @@ export interface ProjectEntry {
|
||||
export interface CIAgentConfig {
|
||||
projects: ProjectEntry[];
|
||||
active_project: string;
|
||||
active_projects: string[];
|
||||
autonomy: AutonomyConfig;
|
||||
model_profile: ModelProfile;
|
||||
parallelization: ParallelizationConfig;
|
||||
@@ -90,11 +92,13 @@ export interface CIAgentConfig {
|
||||
git: GitConfig;
|
||||
backend: BackendConfigSection;
|
||||
gitea?: GiteaConfig;
|
||||
ideation?: IdeationConfig;
|
||||
}
|
||||
|
||||
export const DEFAULT_CIAGENT_CONFIG: CIAgentConfig = {
|
||||
projects: [],
|
||||
active_project: "",
|
||||
active_projects: [],
|
||||
autonomy: {
|
||||
level: "full",
|
||||
escalation_hooks: ["deploy", "delete_data", "merge_to_main"],
|
||||
@@ -165,4 +169,23 @@ export const DEFAULT_CIAGENT_CONFIG: CIAgentConfig = {
|
||||
owner: "",
|
||||
repo: "",
|
||||
},
|
||||
ideation: {
|
||||
enabled: true,
|
||||
categories: ["security", "quality", "architecture", "coverage", "improvement"] as IdeationCategory[],
|
||||
confidence_threshold: 0.6,
|
||||
max_ideas: 20,
|
||||
external_signals: {
|
||||
npm_audit: true,
|
||||
osv_advisories: true,
|
||||
dependency_staleness: true,
|
||||
},
|
||||
cross_project: {
|
||||
enabled: false,
|
||||
similarity_weight: 0.5,
|
||||
},
|
||||
chaos: {
|
||||
enabled: true,
|
||||
scenarios: ["backend_unavailable", "requirement_change", "test_coverage_drop"],
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,105 @@
|
||||
export type IdeationSource =
|
||||
| "uncovered_requirement"
|
||||
| "repeated_lesson"
|
||||
| "low_confidence_decision"
|
||||
| "escalation_pattern"
|
||||
| "compound_pattern"
|
||||
| "partial_requirement"
|
||||
| "gap_in_coverage"
|
||||
| "improvement_pattern"
|
||||
| "architecture_drift"
|
||||
| "verification_inversion"
|
||||
| "spec_ambiguity"
|
||||
| "spec_contradiction"
|
||||
| "spec_missing"
|
||||
| "external_signal"
|
||||
| "cross_project_lesson"
|
||||
| "chaos_scenario";
|
||||
|
||||
export type IdeationCategory =
|
||||
| "security"
|
||||
| "quality"
|
||||
| "architecture"
|
||||
| "coverage"
|
||||
| "improvement"
|
||||
| "spec"
|
||||
| "chaos";
|
||||
|
||||
export type IdeationAction =
|
||||
| "add_requirement"
|
||||
| "update_architecture"
|
||||
| "update_roadmap"
|
||||
| "fix_documentation"
|
||||
| "add_test"
|
||||
| "add_security_pattern"
|
||||
| "refactor"
|
||||
| "new_milestone_phase";
|
||||
|
||||
export type IdeationTier = "mechanical" | "backend-enriched" | "cross-project";
|
||||
|
||||
export interface Idea {
|
||||
id: string;
|
||||
source: IdeationSource;
|
||||
category: IdeationCategory;
|
||||
title: string;
|
||||
rationale: string;
|
||||
confidence: number;
|
||||
relatedReq?: string;
|
||||
actions: IdeationAction[];
|
||||
tier: IdeationTier;
|
||||
}
|
||||
|
||||
export interface IdeationResult {
|
||||
project: string;
|
||||
milestone: string;
|
||||
ideas: Idea[];
|
||||
summary: IdeationSummary;
|
||||
}
|
||||
|
||||
export interface IdeationSummary {
|
||||
total: number;
|
||||
accepted: number;
|
||||
skipped: number;
|
||||
by_category: Record<string, number>;
|
||||
by_tier: Record<string, number>;
|
||||
}
|
||||
|
||||
export interface IdeationConfig {
|
||||
enabled: boolean;
|
||||
categories: IdeationCategory[];
|
||||
confidence_threshold: number;
|
||||
max_ideas: number;
|
||||
external_signals: {
|
||||
npm_audit: boolean;
|
||||
osv_advisories: boolean;
|
||||
dependency_staleness: boolean;
|
||||
};
|
||||
cross_project: {
|
||||
enabled: boolean;
|
||||
similarity_weight: number;
|
||||
};
|
||||
chaos: {
|
||||
enabled: boolean;
|
||||
scenarios: string[];
|
||||
};
|
||||
}
|
||||
|
||||
export const DEFAULT_IDEATION_CONFIG: IdeationConfig = {
|
||||
enabled: true,
|
||||
categories: ["security", "quality", "architecture", "coverage", "improvement"],
|
||||
confidence_threshold: 0.6,
|
||||
max_ideas: 20,
|
||||
external_signals: {
|
||||
npm_audit: true,
|
||||
osv_advisories: true,
|
||||
dependency_staleness: true,
|
||||
},
|
||||
cross_project: {
|
||||
enabled: false,
|
||||
similarity_weight: 0.5,
|
||||
},
|
||||
chaos: {
|
||||
enabled: true,
|
||||
scenarios: ["backend_unavailable", "requirement_change", "test_coverage_drop"],
|
||||
},
|
||||
};
|
||||
@@ -7,7 +7,7 @@ import { DEFAULT_CIAGENT_CONFIG } from "../types/config.js";
|
||||
|
||||
describe("Type exports", () => {
|
||||
it("pipeline types are importable and functional", () => {
|
||||
expect(STAGE_ORDER).toHaveLength(8);
|
||||
expect(STAGE_ORDER).toHaveLength(9);
|
||||
expect(getNextStage("specify")).toBe("clarify");
|
||||
const state = createInitialPipelineState("/tmp/test");
|
||||
expect(state.current_stage).toBe("specify");
|
||||
|
||||
@@ -8,11 +8,12 @@ import {
|
||||
} from "../types/pipeline.js";
|
||||
|
||||
describe("STAGE_ORDER", () => {
|
||||
it("has 8 stages in correct order", () => {
|
||||
it("has 9 stages in correct order", () => {
|
||||
expect(STAGE_ORDER).toEqual([
|
||||
"specify",
|
||||
"clarify",
|
||||
"research",
|
||||
"ideate",
|
||||
"plan",
|
||||
"execute",
|
||||
"test",
|
||||
@@ -26,7 +27,8 @@ describe("getNextStage", () => {
|
||||
it("returns the next stage in sequence", () => {
|
||||
expect(getNextStage("specify")).toBe("clarify");
|
||||
expect(getNextStage("clarify")).toBe("research");
|
||||
expect(getNextStage("research")).toBe("plan");
|
||||
expect(getNextStage("research")).toBe("ideate");
|
||||
expect(getNextStage("ideate")).toBe("plan");
|
||||
expect(getNextStage("plan")).toBe("execute");
|
||||
expect(getNextStage("execute")).toBe("test");
|
||||
expect(getNextStage("test")).toBe("verify");
|
||||
@@ -51,6 +53,7 @@ describe("createInitialPipelineState", () => {
|
||||
expect(state.specification_loaded).toBe(false);
|
||||
expect(state.clarify_completed).toBe(false);
|
||||
expect(state.research_completed).toBe(false);
|
||||
expect(state.ideate_completed).toBe(false);
|
||||
expect(state.plan_completed).toBe(false);
|
||||
expect(state.execute_completed).toBe(false);
|
||||
expect(state.test_completed).toBe(false);
|
||||
|
||||
@@ -4,6 +4,7 @@ export type PipelineStage =
|
||||
| "specify"
|
||||
| "clarify"
|
||||
| "research"
|
||||
| "ideate"
|
||||
| "plan"
|
||||
| "execute"
|
||||
| "test"
|
||||
@@ -18,6 +19,7 @@ export interface PipelineState {
|
||||
specification_loaded: boolean;
|
||||
clarify_completed: boolean;
|
||||
research_completed: boolean;
|
||||
ideate_completed: boolean;
|
||||
plan_completed: boolean;
|
||||
execute_completed: boolean;
|
||||
test_completed: boolean;
|
||||
@@ -61,6 +63,7 @@ export const STAGE_ORDER: PipelineStage[] = [
|
||||
"specify",
|
||||
"clarify",
|
||||
"research",
|
||||
"ideate",
|
||||
"plan",
|
||||
"execute",
|
||||
"test",
|
||||
@@ -85,6 +88,7 @@ export function createInitialPipelineState(
|
||||
specification_loaded: false,
|
||||
clarify_completed: false,
|
||||
research_completed: false,
|
||||
ideate_completed: false,
|
||||
plan_completed: false,
|
||||
execute_completed: false,
|
||||
test_completed: false,
|
||||
|
||||
Reference in New Issue
Block a user