fix(e2e-ui): multi-workspace identity scopes and dual HMR suite - #178
patrickleet wants to merge 53 commits into
Conversation
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Depends on hops-cli stacked PR: hops-ops/hops-cli#90 |
Implements [[tasks/contract-lifecycle-tooling-2]]
Implements [[tasks/contract-lifecycle-tooling-2]]
Implements [[tasks/contract-lifecycle-tooling-2]]
Implements [[tasks/contract-lifecycle-tooling-2]]
Implements [[tasks/contract-lifecycle-tooling-3]]
Implements [[tasks/contract-lifecycle-tooling-3]]
Implements [[tasks/contract-lifecycle-tooling-3]]
Implements [[tasks/contract-lifecycle-tooling-9]]
Close the next-major surface identity cutover for task 9: application surfaces carry distinct eligible_roles (who may open) and schema_roles (privilege intersection), end-to-end across Surface IR, client manifest, protocol authority, projection deltas, CLI selectors, and TS replica validation/clone. Also land remaining application composition fixtures (contract-only artifact bin, runtime/unlisted packages, renamed-dependency trybuild) and remove the dual manifest owner path. Implements [[tasks/contract-lifecycle-tooling-9]]
Add the pure deployment-plan compiler for task 10: composable MountSelector presets (Full/Writer/Projector/QueryApi), Atomic collocation validation, explained capability closure with single schema-lifecycle owner, topology intent inventory, and byte-deterministic plan identity linked to ApplicationManifest. Implements [[tasks/contract-lifecycle-tooling-10]]
Add contract lifecycle snapshot flattening, path-level semantic diffs, distinct manifest-wire vs protocol decision classification, and no-write predecessor chain diagnostics with owner/path/expected/observed facts. Implements [[tasks/contract-lifecycle-tooling-4]]
Rename the standalone binary from dctl to distributed, add top-level DistributedArgs with contracts check/accept, and implement exact-scope accept transactions with staging, atomic replace, and rollback. Update in-repo product docs, workflows, skills, and generated client banners to invoke distributed. Implements [[tasks/contract-lifecycle-tooling-5]]
Introduce the versioned command dispatch boundary used by API-only and writer processes: object-safe CommandDispatcher, LocalCommandDispatcher over Service, and the task-20 approved HTTPS mTLS remote profile with loopback parity tests that strip forwarded role claims. Implements [[tasks/contract-lifecycle-tooling-11]] and [[tasks/contract-lifecycle-tooling-20]]
Introduce the task-12 process host skeleton: bind one DeploymentPlan process against explicit capability providers and an optional CommandDispatcher, failing closed when required capabilities or dispatch are missing. Implements [[tasks/contract-lifecycle-tooling-12]]
Add an explicit application composition module for e2e-ui surface and module identities, re-export it from the service crate, migrate read models to ReadModelCatalog, and update GraphQL surface registration for eligible/schema role split. Partial [[tasks/contract-lifecycle-tooling-13]]
Expose graphql_router_with_dispatcher as the host-facing mutation path, keep graphql_router_with_service as the local adapter implementation, and update dispatcher-not-configured diagnostics. Implements [[tasks/contract-lifecycle-tooling-11]]
Add make contracts-check, e2e-ui Makefile routing, an opt-in pre-push template, and a PR contracts job that other broad jobs can depend on. Implements [[tasks/contract-lifecycle-tooling-6]]
Add deterministic ClientProgramDescriptor building, asset hashing, and three-way Current / asset-only / incompatible classification, with program:<id> accept scopes. Implements [[tasks/contract-lifecycle-tooling-7]]
Verify application → plan → optional program predecessor links and release program classification for CTL closeout outside K8s/Hops work. Implements [[tasks/contract-lifecycle-tooling-8]]
Move process wiring into e2e_service::run_e2e_host with LocalCommandDispatcher at the host boundary, shrink the runner binary to env selection + host call, and check in selectable deployment-plan inventories for full/api/writer/ projector/mixed/split cuts. Implements [[tasks/contract-lifecycle-tooling-13]]
Replace the ~900-line central service.rs wiring file with explicit todo/chat/blob modules, a compose root listing them into one Service, GraphQL/surface exports, and a thin compatibility façade. Runner remains one-screen host invocation. This is the DX outcome of the application-composition epic for e2e-ui: module inventory is review-visible; infrastructure stays in host. Implements [[tasks/contract-lifecycle-tooling-13]]
Re-export compose/graphql APIs from lib.rs and keep client-surface tests next to graphql module. No intermediate service.rs re-export layer. Implements [[tasks/contract-lifecycle-tooling-13]]
Add LocalProjectionMountsBuilder so apps declare program+model+epoch only, Routes::for_aggregate to hide QueuedRepository wiring, and shared outbox/ consumer worker helpers. Rewrite e2e projection mounts and host loops to use them — product code keeps command intent, not topology ceremony. Implements [[tasks/contract-lifecycle-tooling-13]]
Derive client projection previews from command input, defaults, and row-policy claims when .applies is omitted. Add command_transition and sourced domain_commands witnesses so emit sets come from domain methods. Migrate todo/chat/blob to that path, thin blob move to game_id+direction, delete client simulate_move, and fix distributed client --surface to read roles from the manifest for gen-client.
Drop simulate-move unit test, stop requiring fat blob preview fields, and assert eligible/schema application roles on generated clients.
…tests Workers require tokio spawn/sleep — compile them only when a feature enables the optional tokio dep so default-feature checks pass. Rename integration test env! paths from CARGO_BIN_EXE_dctl to CARGO_BIN_EXE_distributed after the binary rename.
Defer --surface kind/name mismatches to the client compiler so CLI stderr keeps client.manifest.surface_mismatch. Use Session::new() in the default- feature typed guard dispatch test so session_with_role is not required without the graphql feature.
Move session admission (has user / is admin) onto TypedRouteBuilder .guarded mounts so handlers only bind principal and call domain. Add CausalCommandContext::session, causal_has_user/causal_is_admin helpers, and keep input/domain checks in the handler body.
Extract pure simulate_move into blob-core (no distributed host), export it via blob-wasm, and replace the TypeScript board twin with a thin loader that registers the same pure id for auto-optimism. make wasm / ui-install builds pkg; CI installs wasm-pack + wasm32.
Collapse blob-core and blob-wasm into blob-domain: pure rules live in src/core/, WASM exports in src/wasm.rs behind --features wasm, aggregate host stays default --features domain. make wasm builds that one package.
Update blob walkthrough for known-row pure reduce + blob-domain WASM, session guards/principal in command mounts and handlers, and add a Service module tab on every demo (MODULE_ID, routes, compose).
Add createWasmJsonPure for load/JSON/fail-closed hosting. blobSimulateMove now takes record+args JSON and validates inside blob-domain wasm. App simulate-move.ts is a short pure registration only.
Declare CommandProjectionPureReduce::wasm(package, export); render_pures emits createWasmJsonPure hosts and ensurePureFunctionsReady. Blob move registers blob/pkg/blob_wasm; delete hand pure host. board.ts stays as UI presentation helpers (tiles/parse), not domain pure.
Expand every Service tab with compose, host.run_e2e_host, and e2e-runner main. Blob commands tab explains pure-reduce reasoning, benefits, gen-client WASM host, and fail-closed authority; domain tab covers core vs wasm faces.
Add Helm deploy charts for api/ui with cluster-dev vs package posture, local PSQLCluster for the API, and hops.local Application YAMLs under gitops/env/local. Document hops local up as Option A for dogfood. Implements [[tasks/lwb-e2e-ui-gitops-charts]] [[tasks/lwb-docs-happy-path]]
When sourceDelivery.mode=sync, wait for .hops-synced / package manifest before cargo/vite so tar/mutagen can populate emptyDir first.
api deliveryPath points at e2e-ui Cargo root; ui at ui/ with vite. cluster-dev waits indefinitely for .hops-synced/package/Cargo before start.
…ault Add gitops/cluster tree (packages, providers, AuthStack, PSQLStack, e2e-identity MRs) and SecretStack vault backend claim for local workbench. Wire app charts/env Applications for cluster-dev delivery. Keep secrets out of YAML; document kubectl bootstrap in SECRETS.md.
Move shared Zitadel Project/roles/humans to cluster scope, keep OIDC apps worktree-scoped for redirects and Login V2 baseUri. Restructure cluster gitops (configurations/, stacks/, DRCs) and ExternalSecrets hooks for OIDC + demo passwords.
Wire project id into local Application env so the API does not fall back to DevHeaders, and drop hand-rolled deliveryPath so delivery uses the git worktree root by default.
Manage Zitadel instance loginV2 via Features MR so authorize redirects to this worktree's custom /login. Derive baseUri and OIDC placement from hops --name / helm release namespace; drop hand-set residual docs.
Keep shared Project/roles/humans in default, scope OIDC to release namespace, seed local OIDC secrets for cluster-dev pods, and add a local dual-worktree suite that gitops alice+bob and proves UI beacon updates.
Single-file beacon sync and pause full-tree tar watchers so Vite client HMR updates without full navigation; fail the suite on extraNav>0.
Refs: [[incidents/inc-005-e2e-ui-optimism-stalls]]
7be8ed7 to
9e48f87
Compare
5164c2b to
f96887b
Compare
Squash the complete stacked change set through PR #178 after GitHub's stack merge operation landed only the bottom layer. Includes PRs #172, #173, #174, #177, and #178. BREAKING CHANGE: the standalone CLI binary is named distributed instead of dctl, and application surface roles use the eligible/schema split.
|
Stack merge recovery: GitHub’s stack operation partially landed the stack. The complete stack through #178 is now preserved on main as aggregate squash b97f96a, whose tree matches the original #178 head exactly. This PR is superseded by that commit; its source branch is being retained. The prior broken main is preserved at recovery/github-stack-broken-main-20260813-031051. |
Summary
projectIdRef.namespace→ shared Project; emptymrNamespacefor worktree OIDC appse2e-ui-oidcso cluster-dev pods schedule without Vault residual--dory-namevs workspace--name)Stack
Stacked on
feat/e2e-ui-local-workbench-identity(#177).Test plan
./tests/e2e-ui/scripts/helm-contract-test.shdory-nameunchanged