feat(compass-app): embedded-mode launch pipeline (mode-select, preflight, stack supervise, WhoAmI) (SEA-1685) - #209
Open
seal-agent wants to merge 2 commits into
Conversation
…ght, stack supervise, WhoAmI) (SEA-1685)
…timeout copy, resolver+identity tests) Additive review-fix commit on the T4.1 embedded-launch bookmark. - embeddedDatabaseDSN: doc comment now states it is a deliberate second copy of cmd/compass-stack's defaultDSN (the source of truth), guarded by a golden test; SoT consolidation tracked as SEA-1856. - runStackUp: a context-deadline failure now names the bring-up window and the likely cold GHCR image-pull cause instead of a bare deadline error. - whoAmIOverUDS: reject an empty account id from a successful WhoAmI rather than resolving an empty identity downstream. - Remove the dead --listen scaffolding (field, argv branch, test) with no caller. - Add table tests for resolveStackBin/resolveStateDir/resolveImage/resolveMode. - accountID doc comment corrected to match its real write site. Co-authored-by: Matt Wilkinson <matt@sealedsecurity.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR is part of a stack containing 2 PRs:
mainWhat
T4.1 — the embedded-mode launch pipeline for
compass-app, additive on the #191 shell scaffold. Wires embedded mode end-to-end before the window opens: mode-select → host preflight → spawn/supervise the private stack (via thecompass-stackCLI) → learn the caller account id (WhoAmI, DL-111) → hand the resolved socket + account id to the bridge/UI.main.go,embedded.go):appconfig.Load+ a--mode/$COMPASS_APP_MODEoverride; embedded runs the pipeline, client returns anot yet implemented (T5)sentinel (no fake stub).preflight_adapters.go): the 3 real adapters —podmanRootless(podman info),imagePresent(podman image exists),dbReachable(short-timeout pgx connect+ping, mirroringstack/adapters/dbprobe.go). Severity split at the T4 wiring boundary (classifyPreflight): host-capability checksupcannot create ({OS, uid, rootless podman}) are fatal; the checksupitself ensures ({image, database}) are advisory — see Open Question 2.embedded.go): shells out to thecompass-stackbinary (up --state-dir --image --socket), waits for its fire-and-return exit 0 (Ready), surfaces stderr on a non-zero exit. Does not importinternal/stack(design.md:482 — "consumes T2's compass-stack CLI"). The resolved socket is the single value passed to--socketand dialed for WhoAmI/bridge. Argv is built by a pure, unit-testedstackUpArgs;--databaseis omitted so the CLI recomputes the identical default DSN from--state-dir(no drifting second DSN definition).embedded.go):whoAmIOverUDSdials the stack socket over h2c-UDS (transport shape fromstack/adapters/health.go) and callsWhoAmIfor the server-derived account id (never guessed). Exposed to the JS/UI via a boundbridgeService.AccountID(ctx)IPC getter (the JSConnectionProviderconstruction is a separate compass-ui hand-off; noapps/ui/**edits here).preflight/uid.go): exportedpreflight.DefaultAgentUID = 1000, cited to compass-runner's unimportablepackage mainconst — see Open Question 1.Pipeline seams (
preflight,stackUp,whoAmI) are injectable function fields;launchByMode,stackUpArgs, andclassifyPreflightare pure. All the real effects are supplied only inrun().Tests
embedded_test.godrives the whole pipeline with injected effects (no real podman/postgres/stack/exec): mode embedded vs client; preflight short-circuit; happy-path argv + single-socket invariant + WhoAmI; stack-up non-zero exit; WhoAmI error; the preflight severity split (host-cap unmet → fatal; image/DB-only unmet with host-caps OK → nil, the load-bearing cold-start case; advisory never masks a host gap nor leaks into the fatal fold). ThewhoAmIOverUDStransport is proven against a real in-process compass.v1 WhoAmI server over h2c on a UDS.runStackUp's exec+stderr contract is driven with a real child process.Gate (all on the real tree, both tag sets):
gofmtclean;go vet+go vet -tags gtk3clean;go test -race ./cmd/compass-app/... ./internal/preflight/...+go test -tags gtk3 ./cmd/compass-app/...pass;go build(nogtk3) +go build -tags gtk3both link;golangci-lint run0 issues on both tag sets.Open Questions (parked for Matt — overnight mode)
Agent-uid single source of truth.
preflight.DefaultAgentUIDhere duplicates compass-runner'sdefaultAgentUID(cmd/compass-runner/main.go), which lives inpackage mainand is unimportable. This PR takes the tonight-move (duplicate + cite, tracked as deliberate). The fork: lift to one shared exported const and refactor compass-runner to consume it — that refactor is in compass-runner's lane (its owner has acknowledged and will drive it once you rule). No drift ships; the two consts are pinned to the same value with a cross-reference.Preflight severity placement. The severity split (host-cap fatal / image+DB advisory) is applied at the T4 wiring boundary (
classifyPreflight), not inpreflight.Run/Err. This is required for cold start:upstarts postgres (design.md:176) and pulls the image (stack/adapters/image.go), so on a fresh state dir image+DB necessarily fail pre-up; gating on them would make the app unable to cold-start, andup-Ready (GetServerInfo answering, design.md:189-191) transitively verifies both, so no post-upre-check is needed. The fork: keep the split at the boundary (as here —preflight.Run/Errstays a pure "report every unmet precondition" surface for its operator-facing use) vs. lift the advisory/fatal distinction into the core'sErr()(one SoT for cold-start severity). Cold-start behavior is correct either way; this is about where the knowledge lives.Review round 1 (sole
reviewagent) — dispositioned0 high, 3 medium, 3 low; zero-high earned (per-axis ground trace). All findings fixed or deferred with a filed issue:
embeddedDatabaseDSN's comment now states it is a deliberate copy of compass-stack'sdefaultDSN(the SoT), guarded by a golden drift test. Deferred: the SoT consolidation (one importable helper) → SEA-1856.resolveStackBin/resolveStateDir/resolveImage/resolveMode) had no coverage → added table tests (incl. the load-bearing relative-XDG_STATE_HOME-falls-through determinism guard).--listenscaffolding (no caller; T4.3 re-adds it when the headless variant needs it).accountIDdoc comment corrected to match its real write site.Refs SEA-1685