Skip to content

feat(facade): add single-core interfaces facade (F107)#372

Merged
pocky merged 1 commit into
mainfrom
feature/F107-single-core--interfaces-facade
Jun 9, 2026
Merged

feat(facade): add single-core interfaces facade (F107)#372
pocky merged 1 commit into
mainfrom
feature/F107-single-core--interfaces-facade

Conversation

@pocky

@pocky pocky commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Introduces a unified WorkflowFacade port that all interface entry points (CLI, TUI, HTTP/SSE, ACP) share, replacing the previous pattern where each interface directly called disparate application services
  • Adds the full application-layer facade stack: identifier resolver, session registry, run-session lifecycle, event projection, input bridge, and structured error codes — giving every interface a single Run/Validate/List/History contract
  • Wires the facade into CLI (run, status, resume), TUI (monitoring tab, bridge), and HTTP (SSE handler, respond handler) while plumbing ACP session service to emit facade-compatible events; ships a reusable facadetest harness so interface-layer tests can drive the facade with scripted scenarios
  • Adds conformance, e2e, resume, and agent-uniformity integration tests that enforce the facade contract end-to-end, ensuring no interface regresses to direct service calls

Changes

Domain — Facade Contract

  • internal/domain/ports/facade.go: Define WorkflowFacade port with Run, Validate, List, History methods
  • internal/domain/ports/facade_dto.go: Add RunRequest, RunResult, ListItem, HistoryEntry DTOs
  • internal/domain/ports/facade_event.go: Add typed facade event vocabulary (StepStarted, StepDone, OutputLine, Terminal, etc.)
  • internal/domain/ports/facade_contract_test.go: Contract-level tests that any implementation must satisfy
  • internal/domain/errors/codes.go: Extend domain error codes used by the facade error taxonomy

Application — Facade Implementation

  • internal/application/facade_adapter.go: Adapter struct implementing WorkflowFacade; delegates to resolver, session registry, and execution service
  • internal/application/facade_adapter_test.go: Comprehensive unit tests covering run, validate, terminal events, failure paths
  • internal/application/resolver.go: Consolidate workflow identifier resolution (name → workflow entity) into a single canonical entry point
  • internal/application/resolver_wire.go: Wire resolver with pack discoverer and repository fallback
  • internal/application/resolver_test.go, internal/application/resolver_wire_test.go: Unit tests for both resolution paths
  • internal/application/session_registry.go: In-memory registry tracking active RunSession by run ID
  • internal/application/session_registry_test.go: Concurrent-access tests for the registry
  • internal/application/run_session.go: Per-run session encapsulating event channel, cancel func, and status
  • internal/application/run_session_test.go: Session lifecycle and terminal-event semantics tests
  • internal/application/drain.go: Helper that drains an event channel after execution completes to prevent in-flight event loss
  • internal/application/drain_test.go: Drain ordering and closure-safety tests
  • internal/application/facade_projection.go: Projects domain execution events onto typed facade events
  • internal/application/facade_projection_test.go: Projection mapping unit tests
  • internal/application/input_bridge.go: Routes RunRequest inputs to the appropriate execution service method
  • internal/application/input_bridge_test.go: Tests for fresh-run, resume, and dry-run dispatch
  • internal/application/error_codes.go: Structured MapError function mapping domain errors to facade error codes
  • internal/application/error_codes_test.go: Exhaustive mapping tests for every error category
  • internal/application/acp_session_service.go: Extended to emit facade-compatible events over the ACP session channel
  • internal/application/acp_session_service_test.go: New test coverage for facade event emission paths
  • internal/application/execution_setup_recorder_factory_test.go: Minor test fixture adjustment

Infrastructure

  • internal/infrastructure/transcript/fanout.go: Add fan-out subscriber support used by the facade's mirror subscriber

Interface — CLI

  • internal/interfaces/cli/config.go: Build and lazily initialize facade in PersistentPreRun hook
  • internal/interfaces/cli/root.go: Extract root-command builder; return cleanup func; wire auto-facade mode
  • internal/interfaces/cli/run.go: Route awf run through facade when available
  • internal/interfaces/cli/run_test.go: Tests for facade-routed run command
  • internal/interfaces/cli/status.go: Route awf status through facade session registry
  • internal/interfaces/cli/status_test.go: Updated tests for facade-aware status lookup
  • internal/interfaces/cli/resume_list.go: New awf resume --list sub-command backed by facade.List
  • internal/interfaces/cli/resume_list_test.go: Tests for resume list output
  • internal/interfaces/cli/wiring_transcript.go: Adjust transcript wiring to coexist with facade recorder

Interface — TUI

  • internal/interfaces/tui/bridge.go: Implement FacadeBridge wrapping facade for Bubble Tea message dispatch
  • internal/interfaces/tui/bridge_test.go: Tests for bridge event-to-message translation
  • internal/interfaces/tui/command.go: Switch execution command to use facade bridge; remove direct service call
  • internal/interfaces/tui/command_test.go: Updated; remove tests that relied on removed stubs
  • internal/interfaces/tui/tab_monitoring.go: Handle facade event messages in the monitoring tab event loop
  • internal/interfaces/tui/tab_monitoring_test.go: Full event-loop tests for facade-driven and nil-Done-channel paths
  • internal/interfaces/tui/model.go: Thread facade reference through TUI model
  • internal/interfaces/tui/model_test.go: Updated model tests
  • internal/interfaces/tui/messages.go: Add facade event message types for Bubble Tea
  • internal/interfaces/tui/input_reader.go: Deleted — replaced by input_bridge.go in the application layer

Interface — HTTP/API

  • internal/interfaces/api/sse.go: Rewrite SSE handler to stream facade events instead of polling execution state
  • internal/interfaces/api/sse_test.go: Updated SSE tests for facade event streaming
  • internal/interfaces/api/respond_handler.go: New handler that writes a single facade terminal event as a JSON response
  • internal/interfaces/api/respond_handler_test.go: Tests for respond handler success and error cases
  • internal/interfaces/api/server.go: Register new respond route; inject facade into handlers

Test Utilities

  • internal/testutil/facadetest/facadetest.go: Scriptable FakeFacade allowing tests to pre-configure event sequences
  • internal/testutil/facadetest/doc.go: Architecture doc for the facadetest package
  • internal/testutil/facadetest/facadetest_test.go: Self-tests for the fake implementation

Integration Tests & Fixtures

  • tests/integration/features/facade_conformance_test.go: Contract conformance suite run against the real adapter
  • tests/integration/features/facade_e2e_run_test.go: End-to-end run test through facade
  • tests/integration/features/facade_resume_test.go: Resume flow integration test
  • tests/integration/features/agent_uniformity_test.go: Verify CLI/TUI/HTTP all produce equivalent event sequences
  • tests/fixtures/facade/cli-stdout.golden, tests/fixtures/facade/sse-frames.golden, tests/fixtures/facade/tui-tea-msg.golden, tests/fixtures/facade/acp-session-update.golden: Golden files for cross-interface output comparison

Configuration & Tooling

  • .go-arch-lint.yml: Register testutil-facadetest component and domain-transcript dependency edges for CLI/TUI/API
  • .specify/implementation/F107/tasks/index.json: Task manifest (T053–T065) tracking completion status
  • .zpm/kb/pr_feature_f107_single_core_interfaces_facade/journal.wal, .zpm/kb/pr_feature_f107_single_core_interfaces_facade/knowledge.pl: ZPM project memory for this PR
  • cmd/awf/main.go: Use NewRootCommandAutoFacade and call cleanup on exit
  • docs/development/architecture.md: Document the facade layer and its relationship to existing hexagonal layers

Test plan

  • make test passes with zero failures across unit and integration suites
  • make lint reports no violations (arch-lint component graph + golangci-lint)

Closes #371


Generated with awf commit workflow

- `.go-arch-lint.yml`: register testutil-facadetest component and allow domain-transcript dependency in interface layers
- `.specify/implementation/F107/tasks/index.json`: add F107 task implementation index
- `.zpm/kb/pr_feature_f107_single_core_interfaces_facade/journal.wal`: add PR knowledge base journal
- `.zpm/kb/pr_feature_f107_single_core_interfaces_facade/knowledge.pl`: add PR Prolog knowledge facts
- `cmd/awf/main.go`: wire WorkflowFacade into application bootstrap
- `docs/development/architecture.md`: document facade layer and single-core interface pattern
- `internal/application/acp_session_service.go`: integrate facade session lifecycle management
- `internal/application/acp_session_service_test.go`: add facade session service tests
- `internal/application/drain.go`: add event drain for facade output flushing
- `internal/application/drain_test.go`: add drain tests
- `internal/application/error_codes.go`: add canonical error code mapping for facade
- `internal/application/error_codes_test.go`: add error code tests
- `internal/application/execution_setup_recorder_factory_test.go`: update for facade wiring
- `internal/application/facade_adapter.go`: add WorkflowFacade adapter implementing ports.WorkflowFacade
- `internal/application/facade_adapter_test.go`: add facade adapter tests
- `internal/application/facade_projection.go`: add event-to-DTO projection for facade output
- `internal/application/facade_projection_test.go`: add projection tests
- `internal/application/input_bridge.go`: add input bridge translating CLI/API inputs to domain
- `internal/application/input_bridge_test.go`: add input bridge tests
- `internal/application/resolver.go`: add workflow identifier resolver consolidating prior implementations
- `internal/application/resolver_test.go`: add resolver tests
- `internal/application/resolver_wire.go`: add resolver wiring helpers
- `internal/application/resolver_wire_test.go`: add resolver wire tests
- `internal/application/run_session.go`: add RunSession orchestrating facade-driven workflow execution
- `internal/application/run_session_test.go`: add run session tests
- `internal/application/session_registry.go`: add session registry tracking active facade sessions
- `internal/application/session_registry_test.go`: add session registry tests
- `internal/domain/errors/codes.go`: add facade-specific error codes
- `internal/domain/ports/facade.go`: define WorkflowFacade port interface
- `internal/domain/ports/facade_contract_test.go`: add contract tests for facade port
- `internal/domain/ports/facade_dto.go`: define facade input/output DTOs
- `internal/domain/ports/facade_event.go`: define facade event types
- `internal/infrastructure/transcript/fanout.go`: add mirror subscriber support for facade transcript
- `internal/interfaces/api/respond_handler.go`: add respond handler consuming facade via SSE
- `internal/interfaces/api/respond_handler_test.go`: add respond handler tests
- `internal/interfaces/api/server.go`: wire facade into API server
- `internal/interfaces/api/sse.go`: refactor SSE to consume facade events
- `internal/interfaces/api/sse_test.go`: update SSE tests for facade-driven flow
- `internal/interfaces/cli/config.go`: add facade configuration options
- `internal/interfaces/cli/resume_list.go`: add resume list command via facade
- `internal/interfaces/cli/resume_list_test.go`: add resume list tests
- `internal/interfaces/cli/root.go`: wire facade into CLI root command
- `internal/interfaces/cli/run.go`: delegate run command to facade
- `internal/interfaces/cli/run_test.go`: add run command facade tests
- `internal/interfaces/cli/status.go`: delegate status command to facade
- `internal/interfaces/cli/status_test.go`: update status tests for facade
- `internal/interfaces/cli/wiring_transcript.go`: update transcript wiring for facade
- `internal/interfaces/tui/bridge.go`: add TUI bridge wrapping facade for Bubble Tea integration
- `internal/interfaces/tui/bridge_test.go`: add TUI bridge tests
- `internal/interfaces/tui/command.go`: refactor TUI commands to use facade bridge
- `internal/interfaces/tui/command_test.go`: update TUI command tests
- `internal/interfaces/tui/input_reader.go`: remove superseded input reader
- `internal/interfaces/tui/messages.go`: add facade-driven TUI message types
- `internal/interfaces/tui/model.go`: integrate facade bridge into TUI model
- `internal/interfaces/tui/model_test.go`: add TUI model tests for facade integration
- `internal/interfaces/tui/tab_monitoring.go`: refactor monitoring tab to consume facade events
- `internal/interfaces/tui/tab_monitoring_test.go`: add monitoring tab tests
- `internal/testutil/facadetest/doc.go`: add facadetest package documentation
- `internal/testutil/facadetest/facadetest.go`: add scriptable WorkflowFacade fake for testing
- `internal/testutil/facadetest/facadetest_test.go`: add facadetest self-tests
- `tests/fixtures/facade/acp-session-update.golden`: add golden fixture for ACP session update
- `tests/fixtures/facade/cli-stdout.golden`: add golden fixture for CLI stdout output
- `tests/fixtures/facade/sse-frames.golden`: add golden fixture for SSE frames
- `tests/fixtures/facade/tui-tea-msg.golden`: add golden fixture for TUI Tea messages
- `tests/integration/features/agent_uniformity_test.go`: add agent uniformity integration test
- `tests/integration/features/facade_conformance_test.go`: add facade conformance integration test
- `tests/integration/features/facade_e2e_run_test.go`: add facade end-to-end run integration test
- `tests/integration/features/facade_resume_test.go`: add facade resume integration test

Closes #371
@pocky pocky force-pushed the feature/F107-single-core--interfaces-facade branch from f06f9e0 to 6c44a88 Compare June 9, 2026 16:23
@pocky pocky marked this pull request as ready for review June 9, 2026 16:36
@pocky pocky merged commit 100e737 into main Jun 9, 2026
5 checks passed
@pocky pocky deleted the feature/F107-single-core--interfaces-facade branch June 9, 2026 16:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

F107: Single core ↔ interfaces facade

1 participant