Files
AirCoding/packages/runtime/test/e2e/direct-mode-fixture.test.ts
AirCoding 7d3b2b4a4c fix(regression): repair 5 regressions from second round, close B10/B12/B15/B16
Round 2 regression fixes:
- B10 (INV-2 outbox, CRITICAL): wiring.ts — switch durable events
  from eventBus.publish (live-only) to eventIngestor.ingest (persistent)
  for debug.record.created and memory.promoted. Add required RuntimeEvent
  fields (id, source, route).
- B12 (Scheduler events, CRITICAL): Scheduler.ts — replace all 4
  eventBus.publish calls with eventIngestor.ingest + registered event
  types (task.started/task.failed/agent.lost/agent.cancelled).
  Remove unregistered task.status.changed references.
- B15 (duplicate ProjectionClient): remove orphan tui/src/ProjectionClient.ts
  (zero references, superseded by runtime/src/projection/ProjectionClient.ts
  re-exported via @aircoding/runtime barrel).
- RuntimeApp: wire Scheduler→WorkerManager in constructor; document
  start() bootstrap→recover→hydrate→ready sequence (DD §22.2).
- createRuntime: read project_id from .air/shared/project.json
  (DD §6.1 stable UUID), fallback to Date.now() only if not initialized.
- B16 (api_key strict): ProviderManager.get_or_create_adapter now calls
  ModelConfigLoader.validate() before passing raw api_key to adapter.

Also fix from R1 regression:
- ArchitectureDesigner: replace broken additive-heuristic risk scoring
  (single runtime file→replan, large refactor→confirmation only) with
  change-scope classification (contracts→confirmation, breaking→escalate,
  large→replan, safe→silent_continue). Remove dead evaluate_risk().
- MainAgent test: update confirmation test from old state name
  AWAITING_CONFIRMATION to canonical CONFIRMING (B13 state machine fix).

Test: 148/148 pass (regression + e2e + llm + toolchain-cpp).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 17:19:36 +08:00

75 lines
2.6 KiB
TypeScript
Executable File

/**
* Direct-mode fixture E2E test — P7 gate
* Test: MainAgent direct-mode lifecycle.
*
* @module packages/runtime/test/e2e/direct-mode-fixture.test
*/
import { describe, it, expect } from 'bun:test'
import { MainAgent } from '../../src/agents/main/MainAgent.js'
describe('Direct Mode Fixture (P7 gate)', () => {
const config = {
session_id: 'test-session',
project_id: 'test-project'
}
describe('MainAgent lifecycle', () => {
it('should start in IDLE state', () => {
const agent = new MainAgent(config)
expect(agent.state).toBe('IDLE')
})
it('should classify implementation requests as DELEGATING', async () => {
const agent = new MainAgent(config)
const result = await agent.handle_user_message('implement a new feature X')
expect(result.action).toBe('delegate')
expect(agent.state).toBe('DELEGATING')
})
it('should classify questions as ANSWERING', async () => {
const agent = new MainAgent(config)
const result = await agent.handle_user_message('what does this function do?')
expect(result.action).toBe('answer')
expect(agent.state).toBe('ANSWERING')
})
it('should handle confirmation and transition states', async () => {
const agent = new MainAgent(config)
agent.state = 'CONFIRMING'
await agent.handle_confirmation(true)
expect(agent.state).toBe('DELEGATING')
})
it('should summarise and return to IDLE', () => {
const agent = new MainAgent(config)
agent.state = 'DELEGATING'
agent.summarize()
expect(agent.state).toBe('IDLE')
})
})
describe('ArchitectureDesigner', () => {
it('should assess impact and return silent_continue for low-risk changes', async () => {
const { ArchitectureDesigner } = await import('../../src/agents/architecture/ArchitectureDesigner.js')
const arch = new ArchitectureDesigner()
const impact = arch.assess_impact({
description: 'Add a new helper function',
files: ['packages/runtime/src/utils/helper.ts']
})
expect(impact.result).toBe('silent_continue')
})
it('should escalate high-risk contract changes', async () => {
const { ArchitectureDesigner } = await import('../../src/agents/architecture/ArchitectureDesigner.js')
const arch = new ArchitectureDesigner()
const impact = arch.assess_impact({
description: 'BREAKING: remove the session event type',
files: ['packages/contracts/src/event.ts', 'packages/runtime/src/events/EventStore.ts', 'packages/runtime/src/events/EventBus.ts']
})
expect(impact.result).toBe('reject_or_escalate')
})
})
})