Phase 1: Walking skeleton and quality pipeline
Implemented
- Added the Go control-plane module, Cobra composition root, daemon bootstrap, graceful shutdown, single-daemon PID lock, stale-lock recovery, and loopback-only address validation.
- Added private SQLite creation, embedded Goose migrations, sqlc queries, and a durable system-health schema version.
- Defined the versioned OpenAPI contract, generated Go server/client types and
a TypeScript fetch client, and implemented
/api/v1/systemplus a typed WebSocket connection event. - Added structured
slogrequest logging and correlation IDs across the HTTP boundary. - Built the Vue/Vite walking skeleton with live daemon, version, database, and event-stream state using TanStack Query.
- Added
switchyard version,daemon,ui, anddoctorcommands and embedded the production Vue build in the Go binary. - Added pinned toolchains, Make targets, generated-code checks, dependency automation, GitHub Actions jobs, linting, vulnerability scanning, unit/race, migration, browser, and visual-regression tests.
- Added an architecture analyzer plus a deliberate forbidden-import test and depguard policy.
Files and modules added
cmd/switchyardandinternal/bootstrapprocess composition.internal/foundation,internal/system, and transport adapters underinternal/transport.internal/platform/sqlite,migrations,queries, and generated sqlc code.api/openapi.yaml, Go contract generation, and generated TypeScript client.web/srcwalking-skeleton UI, Vitest coverage, Playwright E2E, and visual baseline.tools/archcheck, root toolchain configuration, Makefile, and CI workflows.
Architecture decisions applied
- ADR-0001 dependency direction is enforced by
archcheckand depguard. - ADR-0002 keeps application and orchestration logic in Go.
- ADR-0003 provides one
switchyardbinary with daemon and client subcommands. - ADR-0004 makes OpenAPI and the WebSocket envelope explicit contracts.
- ADR-0005 uses private local SQLite, sqlc, and forward-only embedded migrations.
- ADR-0013 restricts the Phase 1 browser server to loopback; authenticated local IPC, browser bootstrap sessions, and CSRF enforcement arrive in Phase 2.
Tests added
- Go unit tests for build identity, correlation IDs, SQLite migration and file mode, system queries, CLI behavior, HTTP contracts, WebSocket envelopes, daemon addresses, lock exclusion, stale-lock recovery, and architecture rules.
- Go race suite and Windows cross-compilation of process-lock support.
- Vue component test with V8 coverage.
- Playwright end-to-end test against a real daemon, SQLite database, Vite proxy, and WebSocket stream.
- Full-page visual-regression baseline with a bounded cross-platform pixel tolerance.
Commands run and results
Browser E2E and visual tests use a dedicated, overridable daemon address so the quality gate can run while a normal Switchyard daemon is active on port 19616.
make generate: passed; OpenAPI, sqlc, and TypeScript outputs reproducedmake lint: passed; golangci-lint reported 0 issues, archcheck and ESLint passedmake typecheck: passedmake test: passed; Go packages and Vitest passedmake test-race: passedmake migrate-check: passed from an empty temporary directorymake vuln: passed; no vulnerabilities foundmake test-e2e: passed; 1 browser testmake test-visual: passed; 1 visual testmake build: passed; production Vue assets embedded in bin/switchyardGOOS=windows GOARCH=amd64 go test -c ./internal/bootstrap: passedpackaged smoke test: /api/v1/system, embedded UI, and switchyard doctor passedpermission smoke test: data directory 0700, lock and database 0600shutdown smoke test: SIGINT and Playwright SIGTERM both removed daemon.lockAcceptance criteria status
-
switchyard daemonserves an embedded page showing real daemon status. - Local quality commands and matching CI jobs cover generation, formatting, lint, architecture, type, unit, race, migration, vulnerability, browser, visual, and release-build gates.
- A deliberate forbidden domain-to-adapter import fails the architecture analyzer test.
- SQLite creation and migration succeed from an empty data directory.
- Graceful daemon and test-harness shutdown leave no lock-file corruption; valid stale PID locks also recover after abrupt termination.
Known limitations
- Loopback HTTP is the Phase 1 browser transport, but privileged local IPC, browser bootstrap authentication, session cookies, and CSRF checks are Phase 2 work.
- The event stream contains only the walking-skeleton connection event; durable operation replay begins in Phase 2.
switchyard uiprints the local URL. Desktop-aware browser launching begins in Phase 8.
Deferred work
- Phase 2 operation lifecycle, event journal, cancellation, recovery, local IPC, browser authentication, and CLI attach/start behavior.
Manual verification
- Run
make build. - Run
./bin/switchyard daemon --data-dir .switchyard-data/manual. - Open
http://127.0.0.1:19616and confirm daemon, event stream, build, and database schema state are live. - Run
./bin/switchyard doctorin another terminal. - Stop the daemon with Ctrl-C and confirm
daemon.lockis absent.
2026-07-17 CI stabilization evidence
- pnpm 11’s build-script allowlist now explicitly approves the pinned
esbuildandvue-demipackages, so frozen installs no longer stop before the Node, browser, and desktop jobs begin. pnpm install --frozen-lockfile, generated-code drift checks, repository policy, Go vet, GolangCI, architecture checks, and Vue lint/typechecking pass from the release checkout.
Use this pageLast verified Jul 17, 2026
Copy-ready MarkdownOpen sourceReport a docs issue