Remove the nested v3/ subdirectory by moving all active source code, tests, configs, and assets directly to the project root. Archive v2/ (dead code, 847MB) to v2-archive.tar.gz. Key changes: - Move v3/src/ → src/, v3/tests/ → tests/, v3/packages/ → packages/ - Move v3/tsconfig.json, v3/vitest.config.ts to root - Merge v3/package.json into root package.json (ESM, scripts, deps, exports) - Merge v3/scripts/ into scripts/, v3/implementation/ into docs/implementation/ - Update all CI workflows to remove "cd v3 &&" and v3/ path prefixes - Fix all init installer path resolution (3-level-up → 2-level-up) - Fix hooks to use "node ./dist/cli/bundle.js" instead of bare "aqe" - Update settings.json ADR/DDD directories to docs/implementation/ - Fix helper scripts (statusline, adr-compliance, ddd-tracker, guidance-hooks) - Update 58 agent definitions: aqe/v3/ → aqe/ memory namespaces - Update 15 guidance shards: v3/src/ → src/ path references - Fix sync interfaces: remove v3/ and v2/ path references - Fix test path calculations (process.cwd() + '..' no longer needed) - Fix flaky perf test threshold (500ms → 1000ms for CI environments) - Fix complexity-analyzer test to match ADR-051 keyword-based eligibility Build passes, 17,901 tests pass, CLI and MCP bundles verified. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
11 KiB
Requirements Validation Domain
Bounded Context Overview
Domain: Requirements Validation
Responsibility: Pre-development requirements analysis, BDD generation, testability scoring, SFDIPOT assessment
Location: src/domains/requirements-validation/
The Requirements Validation domain ensures requirements are testable before development begins, generates BDD scenarios, and applies James Bach's SFDIPOT product factors for comprehensive test ideation.
Ubiquitous Language
| Term | Definition |
|---|---|
| Testability Score | Measure of how testable a requirement is (0-100) |
| BDD Scenario | Gherkin-format test scenario |
| Acceptance Criteria | Conditions for requirement completion |
| SFDIPOT | Structure, Function, Data, Interfaces, Platform, Operations, Time |
| Test Idea | Generated test concept from SFDIPOT analysis |
| Ambiguity | Unclear or vague requirement language |
| Clarifying Question | Question surfaced during analysis |
Domain Model
Aggregates
RequirementAnalysis (Aggregate Root)
Complete analysis of a requirement.
interface RequirementAnalysis {
requirement: Requirement;
testabilityScore: TestabilityScore;
validationErrors: ValidationError[];
ambiguityReport: AmbiguityReport;
suggestedImprovements: string[];
}
SFDIPOTAssessment (Aggregate Root)
Full SFDIPOT product factors assessment.
interface SFDIPOTAssessment {
id: string;
epicId: string;
epicTitle: string;
timestamp: Date;
qualityScore: number;
testIdeas: TestIdea[];
clarifyingQuestions: ClarifyingQuestion[];
categoryAnalysis: CategoryAnalysis[];
domainDetection: DomainDetection;
priorityDistribution: PriorityDistribution;
automationDistribution: AutomationDistribution;
outputFormats: ('html' | 'json' | 'markdown' | 'gherkin')[];
}
Entities
Requirement
User story or requirement to validate.
interface Requirement {
id: string;
title: string;
description: string;
acceptanceCriteria: string[];
type: 'user-story' | 'functional' | 'non-functional' | 'technical';
priority: 'critical' | 'high' | 'medium' | 'low';
status: 'draft' | 'reviewed' | 'approved' | 'implemented';
}
BDDScenario
Gherkin-format test scenario.
interface BDDScenario {
id: string;
feature: string;
scenario: string;
given: string[];
when: string[];
then: string[];
tags: string[];
examples?: DataTable;
}
TestIdea
Generated test idea from SFDIPOT analysis.
interface TestIdea {
id: string;
description: string;
category: SFDIPOTCategory;
subcategory: string;
priority: TestPriority; // p0 | p1 | p2 | p3
automationFitness: AutomationFitness; // unit | integration | e2e | human-exploration | performance | security
reference?: string;
humanReason?: string; // Required for human-exploration
}
Value Objects
TestabilityScore
Immutable testability assessment.
interface TestabilityScore {
readonly value: number; // 0-100
readonly category: 'excellent' | 'good' | 'fair' | 'poor';
readonly factors: TestabilityFactor[];
}
TestabilityFactor
Individual factor in testability calculation.
interface TestabilityFactor {
readonly name: string;
readonly score: number;
readonly weight: number;
readonly issues: string[];
}
ValidationError
Requirement validation issue.
interface ValidationError {
readonly code: string;
readonly message: string;
readonly severity: 'error' | 'warning' | 'info';
readonly suggestion?: string;
}
AmbiguityReport
Analysis of ambiguous language.
interface AmbiguityReport {
readonly ambiguousTerms: AmbiguousTerm[];
readonly overallScore: number;
readonly suggestions: string[];
}
SFDIPOT Categories
| Category | Description | Example Test Ideas |
|---|---|---|
| Structure | Internal architecture | Component boundaries, module dependencies |
| Function | What it does | Core features, edge cases, error handling |
| Data | Information processed | Data validation, transformations, persistence |
| Interfaces | External connections | APIs, UI elements, integrations |
| Platform | Environment | OS, browsers, hardware dependencies |
| Operations | Usage patterns | Installation, configuration, maintenance |
| Time | Temporal aspects | Concurrency, scheduling, timeouts |
Domain Services
IRequirementsValidationCoordinator
Primary coordinator for the domain.
interface IRequirementsValidationCoordinator {
analyzeRequirement(requirementId: string): Promise<Result<RequirementAnalysis>>;
generateTestArtifacts(requirementId: string): Promise<Result<TestArtifacts>>;
validateSprintRequirements(requirementIds: string[]): Promise<Result<SprintValidation>>;
setMinCutBridge(bridge: QueenMinCutBridge): void;
isTopologyHealthy(): boolean;
isConsensusAvailable(): boolean;
}
ITestabilityScoringService
Evaluates requirement testability.
interface ITestabilityScoringService {
scoreRequirement(requirement: Requirement): Promise<Result<TestabilityScore>>;
scoreRequirements(requirements: Requirement[]): Promise<Result<Map<string, TestabilityScore>>>;
suggestImprovements(requirement: Requirement, score: TestabilityScore): Promise<Result<string[]>>;
meetsThreshold(score: TestabilityScore, threshold: number): boolean;
}
IBDDGenerationService
Generates Gherkin scenarios.
interface IBDDGenerationService {
generateScenarios(requirement: Requirement): Promise<Result<BDDScenario[]>>;
generateScenariosWithExamples(requirement: Requirement, exampleCount: number): Promise<Result<BDDScenario[]>>;
toGherkin(scenarios: BDDScenario[]): string;
parseGherkin(gherkinText: string): Result<BDDScenario[]>;
}
ISFDIPOTAssessmentService
SFDIPOT product factors analysis.
interface ISFDIPOTAssessmentService {
assess(input: AssessmentInput, config?: Partial<SFDIPOTConfig>): Promise<Result<SFDIPOTAssessment>>;
analyzeCategory(input: AssessmentInput, category: SFDIPOTCategory): Promise<Result<CategoryAnalysis>>;
generateTestIdeas(analysis: CategoryAnalysis, config?: Partial<SFDIPOTConfig>): Promise<Result<TestIdea[]>>;
generateClarifyingQuestions(assessment: SFDIPOTAssessment): Promise<Result<ClarifyingQuestion[]>>;
export(assessment: SFDIPOTAssessment, format: 'html' | 'json' | 'markdown' | 'gherkin'): Promise<Result<string>>;
}
ITestIdeaRewritingService
Transforms "Verify" patterns to active test actions.
interface ITestIdeaRewritingService {
rewrite(inputPath: string, outputPath?: string): Promise<Result<RewritingResult>>;
rewriteTestIdea(testIdea: string): Promise<Result<TestIdeaTransformation>>;
validate(content: string): Promise<Result<{ isClean: boolean; remainingPatterns: string[] }>>;
batchRewrite(inputDir: string, outputDir: string, pattern?: string): Promise<Result<RewritingResult[]>>;
}
Domain Events
| Event | Trigger | Payload |
|---|---|---|
RequirementAnalyzedEvent |
Analysis complete | { requirementId, testabilityScore, improvements } |
BDDScenariosGeneratedEvent |
Scenarios created | { requirementId, scenarios, coverageEstimate } |
RequirementValidatedEvent |
Validation done | { requirementId, isValid, errors } |
SFDIPOTAssessmentCompletedEvent |
SFDIPOT done | { assessmentId, testIdeasCount, qualityScore } |
Repositories
interface IRequirementRepository {
findById(id: string): Promise<Requirement | null>;
findByStatus(status: Requirement['status']): Promise<Requirement[]>;
findByPriority(priority: Requirement['priority']): Promise<Requirement[]>;
save(requirement: Requirement): Promise<void>;
delete(id: string): Promise<void>;
}
interface IBDDScenarioRepository {
findByRequirementId(requirementId: string): Promise<BDDScenario[]>;
findByFeature(feature: string): Promise<BDDScenario[]>;
findByTag(tag: string): Promise<BDDScenario[]>;
save(scenario: BDDScenario): Promise<void>;
saveAll(scenarios: BDDScenario[]): Promise<void>;
}
Context Integration
Upstream Dependencies
- External requirement sources (Jira, Linear, Azure DevOps)
Downstream Consumers
- Test Generation: Uses BDD scenarios as input
- Quality Assessment: Testability in quality gates
Anti-Corruption Layer
The domain uses adapters to import requirements from different systems (Jira, Linear, etc.) and normalize them to the Requirement interface.
Task Handlers
| Task Type | Handler | Description |
|---|---|---|
analyze-requirement |
analyzeRequirement() |
Full requirement analysis |
generate-bdd |
generateTestArtifacts() |
BDD scenario generation |
validate-sprint |
validateSprintRequirements() |
Sprint readiness check |
sfdipot-assess |
assess() |
SFDIPOT analysis |
Testability Scoring Algorithm
function calculateTestability(requirement: Requirement): TestabilityScore {
const factors: TestabilityFactor[] = [];
let totalScore = 0;
let totalWeight = 0;
// Factor 1: Clear acceptance criteria (weight: 0.3)
const acScore = scoreAcceptanceCriteria(requirement.acceptanceCriteria);
factors.push({ name: 'acceptance-criteria', score: acScore, weight: 0.3, issues: [] });
totalScore += acScore * 0.3;
totalWeight += 0.3;
// Factor 2: Measurable outcomes (weight: 0.25)
const measurableScore = scoreMeasurability(requirement.description);
factors.push({ name: 'measurability', score: measurableScore, weight: 0.25, issues: [] });
totalScore += measurableScore * 0.25;
totalWeight += 0.25;
// Factor 3: Specificity (weight: 0.25)
const specificityScore = scoreSpecificity(requirement);
factors.push({ name: 'specificity', score: specificityScore, weight: 0.25, issues: [] });
totalScore += specificityScore * 0.25;
totalWeight += 0.25;
// Factor 4: Ambiguity (weight: 0.2)
const ambiguityScore = 100 - detectAmbiguity(requirement).overallScore;
factors.push({ name: 'clarity', score: ambiguityScore, weight: 0.2, issues: [] });
totalScore += ambiguityScore * 0.2;
totalWeight += 0.2;
const finalScore = totalScore / totalWeight;
return {
value: Math.round(finalScore),
category: mapScoreToCategory(finalScore),
factors,
};
}
ADR References
- ADR-047: MinCut topology awareness
- MM-001: Consensus for requirement validation