Files
Profa 2253d05618 feat: flatten project structure — archive v2, promote v3 to root
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>
2026-03-01 11:35:41 +00:00

5.2 KiB

SPEC-036-B: Format-Specific Serializers

Field Value
Specification ID SPEC-036-B
Parent ADR ADR-036
Version 1.0
Status Implemented
Last Updated 2026-01-10
Author Architecture Team

Overview

This specification defines the serializer implementations for converting task results into standard formats (SARIF, LCOV, JSON, Markdown).


Result Saver Interface

export interface ResultSaver {
  /** Save task result in appropriate format(s) */
  save(taskId: string, taskType: TaskType, result: unknown, options: SaveOptions): Promise<SavedResult>;

  /** Get saved results by task type */
  getResults(taskType: TaskType, options?: QueryOptions): Promise<SavedResult[]>;

  /** Compare two result sets */
  diff(resultA: string, resultB: string): Promise<ResultDiff>;

  /** Generate aggregate report */
  generateReport(taskTypes: TaskType[], dateRange: DateRange): Promise<Report>;
}

export interface SaveOptions {
  /** Target language for test generation */
  language?: string;

  /** Target framework */
  framework?: string;

  /** Output directory override */
  outputDir?: string;

  /** Include secondary formats */
  includeSecondary?: boolean;

  /** Custom filename prefix */
  filenamePrefix?: string;
}

export interface SavedResult {
  taskId: string;
  taskType: TaskType;
  timestamp: Date;
  files: SavedFile[];
  summary: ResultSummary;
}

export interface SavedFile {
  path: string;
  format: OutputFormat;
  size: number;
  checksum: string;
}

SARIF Serializer

export class SarifSerializer implements ResultSerializer {
  serialize(result: SecurityScanResult): string {
    return JSON.stringify({
      $schema: 'https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json',
      version: '2.1.0',
      runs: [{
        tool: { driver: { name: 'agentic-qe-v3', version: '3.0.0' } },
        results: result.vulnerabilities.map(v => this.toSarifResult(v)),
      }],
    }, null, 2);
  }

  private toSarifResult(vuln: Vulnerability): SarifResult {
    return {
      ruleId: vuln.ruleId,
      level: this.mapSeverity(vuln.severity),
      message: { text: vuln.message },
      locations: vuln.locations.map(loc => ({
        physicalLocation: {
          artifactLocation: { uri: loc.file },
          region: { startLine: loc.line, startColumn: loc.column }
        }
      }))
    };
  }
}

LCOV Serializer

export class LcovSerializer implements ResultSerializer {
  serialize(result: CoverageResult): string {
    return result.files.map(f => this.toSection(f)).join('\n');
  }

  private toSection(file: FileCoverage): string {
    return `TN:
SF:${file.path}
${file.lines.map((hit, i) => `DA:${i + 1},${hit}`).join('\n')}
LF:${file.lines.length}
LH:${file.lines.filter(h => h > 0).length}
end_of_record`;
  }
}

Test Code Generator

export class TestCodeGenerator implements ResultSerializer {
  constructor(private language: string, private framework: string) {}

  serialize(result: TestGenerationResult): Map<string, string> {
    const files = new Map<string, string>();
    for (const test of result.tests) {
      const filename = this.getFilename(test);
      const code = this.generateTestCode(test);
      files.set(filename, code);
    }
    return files;
  }

  private getFilename(test: GeneratedTest): string {
    const pattern = TEST_FILE_PATTERNS[this.language]?.[this.framework]
      || TEST_FILE_PATTERNS[this.language]?.default
      || '.test.ts';
    return test.targetFile.replace(/\.\w+$/, pattern);
  }
}

Result Index Schema

// .agentic-qe/results/index.json
interface ResultIndex {
  version: '1.0';
  created: string;  // ISO timestamp
  updated: string;  // ISO timestamp
  results: ResultEntry[];
  trends: Record<string, TrendData>;
}

interface ResultEntry {
  id: string;
  type: TaskType;
  timestamp: string;
  files: string[];
  summary: Record<string, unknown>;
}

interface TrendData {
  improving: boolean;
  delta: number;
}

Implementation Files

File LOC Description
v3/src/coordination/result-saver.ts 780 Main ResultSaver implementation
v3/src/coordination/task-executor.ts - Integration point

Validation Rules

Rule ID Description Severity
SPEC-036-B-001 SARIF output must validate against 2.1.0 schema Error
SPEC-036-B-002 LCOV must include all required fields (SF, DA, LF, LH) Error
SPEC-036-B-003 Result index must be updated atomically Warning

Changelog

Version Date Author Changes
1.0 2026-01-10 Architecture Team Initial specification

References