Skip to content

Commit a77a3fb

Browse files
committed
feat(store): harden pilot workspace operator flow
1 parent 10ef4fd commit a77a3fb

35 files changed

+1463
-76
lines changed

CHANGELOG.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,22 @@ This changelog tracks published releases and the major implementation milestones
66

77
## [Unreleased]
88

9+
## [1.7.0] - 2026-04-11
10+
11+
### Workspace Reliability And Operator Hardening
12+
- added stricter validation for pilot workspace create, update, job, and report-export requests so invalid operator input fails early with field-level API errors
13+
- added read-only workspace access for viewer principals while keeping workspace mutation and job execution operator-scoped
14+
- added workspace deletion, restart recovery for queued or running workspace jobs, configurable workspace job timeouts, and richer exported report handoff detail
15+
16+
### Dashboard And Operator Experience
17+
- switched runtime dashboard auth to session-scoped storage by default with an explicit remember option for trusted browsers
18+
- added workspace creation toggles, persisted job history, retry actions, and clearer correlation-aware job states in the workspace-first flow
19+
20+
### Release Engineering, Docs, And Contract
21+
- hardened the Windows release-gate helpers so race, coverage, and CLI smoke validation remain reproducible on Application Control-constrained operator workstations
22+
- documented `VIADUCT_ALLOWED_ORIGINS` and `VIADUCT_WORKSPACE_JOB_TIMEOUT`
23+
- updated the pilot workspace guide, quickstarts, installation guides, and OpenAPI contract to match the hardened workspace and auth behavior
24+
925
## [1.6.0] - 2026-04-11
1026

1127
### Workspace-First Operator Flow

INSTALL.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,4 +63,6 @@ The cleanest evaluation path is still the local lab in [examples/lab](examples/l
6363
For packaged or persistent evaluation environments:
6464
- use PostgreSQL instead of the in-memory store
6565
- prefer service-account keys for normal operator access
66+
- set `VIADUCT_ALLOWED_ORIGINS` if the dashboard is served from anything other than the default local Vite origins
67+
- tune `VIADUCT_WORKSPACE_JOB_TIMEOUT` if discovery or planning jobs need a different server-side timeout budget
6668
- keep the Vite dev server out of any shared or internet-facing environment

QUICKSTART.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ $env:VIADUCT_ADMIN_KEY = "lab-admin"
4545
.\bin\viaduct.exe serve-api --port 8080
4646
```
4747

48+
The API accepts browser requests from the default local dashboard origins (`http://localhost:5173`, `http://127.0.0.1:5173`, `http://localhost:4173`, `http://127.0.0.1:4173`). If you serve the dashboard from a different origin, set `VIADUCT_ALLOWED_ORIGINS` before starting the API.
49+
4850
## 4. Seed The Lab Tenant And Service Account
4951

5052
```bash
@@ -81,6 +83,8 @@ Authenticate with:
8183
- preferred: `lab-operator-key`
8284
- bootstrap only: `lab-tenant-key`
8385

86+
The dashboard stores the runtime key in session storage by default. Use the remember option only when you intentionally want the browser to keep a local copy across restarts.
87+
8488
## 6. Run The Workspace-First Flow
8589

8690
In the dashboard:

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,10 @@ curl -X POST \
8080

8181
Then start the dashboard in `web/`, sign in with `lab-operator-key`, and run the workspace-first flow.
8282

83+
The runtime bootstrap stores keys in the browser session by default. Use the optional remember toggle only on a trusted workstation.
84+
85+
If you serve the dashboard from a non-default origin, configure `VIADUCT_ALLOWED_ORIGINS` on the API so the browser can reach tenant-protected routes.
86+
8387
Use these entrypoints next:
8488
- Quickstart: [QUICKSTART.md](QUICKSTART.md)
8589
- Detailed quickstart: [docs/getting-started/quickstart.md](docs/getting-started/quickstart.md)

docs/getting-started/installation.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ npm run build
3131
Generate a self-contained local bundle:
3232

3333
```bash
34-
make package-release
34+
make package-release-matrix
3535
```
3636

3737
This creates:
@@ -92,3 +92,8 @@ viaduct --help
9292
```
9393

9494
If you installed only the CLI and not the dashboard assets, the API and migration/lifecycle backends still work; only the packaged static web assets are absent.
95+
96+
For browser access in packaged environments:
97+
- set `VIADUCT_ALLOWED_ORIGINS` if the dashboard is served from a non-default origin
98+
- prefer service-account keys for normal operator access
99+
- use `VIADUCT_WORKSPACE_JOB_TIMEOUT` if workspace jobs need a different server-side timeout budget

docs/getting-started/quickstart.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ export VIADUCT_ADMIN_KEY=lab-admin
3939
./bin/viaduct serve-api --port 8080
4040
```
4141

42+
The API accepts browser requests from the default local dashboard origins (`http://localhost:5173`, `http://127.0.0.1:5173`, `http://localhost:4173`, `http://127.0.0.1:4173`). For any other dashboard origin, set `VIADUCT_ALLOWED_ORIGINS` before starting the API.
43+
4244
In another terminal, create the lab tenant and operator service account:
4345

4446
```bash
@@ -69,6 +71,8 @@ Authenticate through the runtime bootstrap screen:
6971
- preferred service-account key: `lab-operator-key`
7072
- bootstrap-only tenant key: `lab-tenant-key`
7173

74+
The runtime key is kept in session storage by default. Use the remember option only when you intentionally want the browser to keep a local copy across restarts.
75+
7276
For packaged or persistent environments, prefer `VITE_VIADUCT_SERVICE_ACCOUNT_KEY` over `VITE_VIADUCT_API_KEY` so operator activity is attributable to a named service account instead of the tenant-wide admin credential.
7377

7478
## 5. Run The Workspace-First Operator Flow

docs/operations/pilot-workspace-flow.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,12 +84,16 @@ Authenticate in one of two ways:
8484
- Preferred: choose `Service account` and paste `lab-operator-key`
8585
- Bootstrap only: choose `Tenant key` and paste `lab-tenant-key`
8686

87+
The dashboard stores the runtime key in session storage by default. Use the optional remember toggle only on a trusted browser that should keep the key across restarts.
88+
8789
You can still pre-seed development credentials with:
8890
- `VITE_VIADUCT_SERVICE_ACCOUNT_KEY`
8991
- `VITE_VIADUCT_API_KEY`
9092

9193
The runtime bootstrap flow is the canonical operator path because it works for packaged environments and does not require a rebuild to rotate credentials.
9294

95+
The API accepts browser requests from the default local dashboard origins. If you serve the dashboard from another host or port, set `VIADUCT_ALLOWED_ORIGINS` before starting the API.
96+
9397
## 5. Run The Workspace-First Operator Flow
9498

9599
Inside the dashboard:
@@ -103,6 +107,8 @@ Inside the dashboard:
103107

104108
The workspace keeps the discovery baseline, readiness result, saved plan, notes, approvals, and report history attached to the same object.
105109

110+
Read-only operators can inspect workspace state and export reports with viewer access, but only operator-level principals can mutate workspace state or start jobs.
111+
106112
## API Equivalents
107113

108114
If you want to exercise the same flow through the REST API, the seeded request body below matches the default dashboard intake:
@@ -158,6 +164,10 @@ The workspace flow is correlation-aware:
158164

159165
If a step fails, capture the request ID and workspace/job identifier together. That is the intended operator handoff bundle for troubleshooting.
160166

167+
Queued or running workspace jobs are recovered when the API starts again, and each job is subject to the server-side timeout configured by `VIADUCT_WORKSPACE_JOB_TIMEOUT`.
168+
169+
If you want to discard a completed evaluation workspace, delete it through the dashboard or `DELETE /api/v1/workspaces/{workspaceID}`. That removes the workspace record and its job history, but it does not purge persisted snapshots or migration records outside the workspace document.
170+
161171
## Smoke Coverage
162172

163173
The deterministic end-to-end lab smoke now lives in:

docs/reference/configuration.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,14 +55,16 @@ Fields:
5555
- `VIADUCT_PASSWORD`: overrides config file password for CLI connector auth
5656
- `VIADUCT_ADMIN_KEY`: admin API key used by the REST server for tenant administration
5757
- `VIADUCT_PLUGIN_ADDR`: plugin listener address used by community connector plugins
58+
- `VIADUCT_ALLOWED_ORIGINS`: comma-separated browser origins allowed to call the API from another origin; defaults to the local Vite origins on ports `5173` and `4173`
59+
- `VIADUCT_WORKSPACE_JOB_TIMEOUT`: per-job server-side timeout for pilot workspace discovery, graph, simulation, and plan generation; defaults to `2m`
5860

5961
## Dashboard Environment Variables
6062
- `VITE_VIADUCT_API_KEY`: tenant API key injected into dashboard requests
6163
- `VITE_VIADUCT_SERVICE_ACCOUNT_KEY`: scoped service-account key injected into dashboard requests; when set, the dashboard prefers this header over `VITE_VIADUCT_API_KEY`
6264

6365
The dashboard reads this through Vite. See [`../../web/.env.example`](../../web/.env.example).
6466

65-
The dashboard now also supports runtime authentication bootstrap. When neither variable is set, the app starts on a bootstrap screen and accepts either a service-account key or tenant key at runtime. The selected credential is stored locally by the browser and reused for subsequent requests until the operator signs out or rotates the key.
67+
The dashboard now also supports runtime authentication bootstrap. When neither variable is set, the app starts on a bootstrap screen and accepts either a service-account key or tenant key at runtime. The selected credential is stored in browser session storage by default and is cleared when the browser session ends. Operators can explicitly choose to remember the key in local storage on trusted workstations.
6668

6769
For early-product and pilot use, prefer `VITE_VIADUCT_SERVICE_ACCOUNT_KEY` for normal dashboard access. Reserve `VITE_VIADUCT_API_KEY` for tenant bootstrap, short-lived admin work, or break-glass access.
6870

docs/reference/openapi.yaml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,28 @@ paths:
476476
$ref: "#/components/responses/ErrorResponse"
477477
"500":
478478
$ref: "#/components/responses/ErrorResponse"
479+
delete:
480+
summary: Delete a pilot workspace
481+
security:
482+
- TenantAPIKey: []
483+
- ServiceAccountKey: []
484+
parameters:
485+
- in: path
486+
name: workspaceID
487+
required: true
488+
schema:
489+
type: string
490+
responses:
491+
"204":
492+
description: Pilot workspace deleted
493+
"401":
494+
$ref: "#/components/responses/ErrorResponse"
495+
"403":
496+
$ref: "#/components/responses/ErrorResponse"
497+
"404":
498+
$ref: "#/components/responses/ErrorResponse"
499+
"500":
500+
$ref: "#/components/responses/ErrorResponse"
479501
patch:
480502
summary: Update pilot workspace state
481503
security:

docs/reference/troubleshooting.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,36 @@ Fix:
4848
- prefer `VITE_VIADUCT_SERVICE_ACCOUNT_KEY` for normal dashboard use
4949
- confirm API health at `/api/v1/health`
5050

51+
## Browser Reports `origin not allowed`
52+
53+
Cause:
54+
- the dashboard is running from an origin that the API CORS allowlist does not trust
55+
56+
Fix:
57+
- set `VIADUCT_ALLOWED_ORIGINS` to a comma-separated list of trusted dashboard origins
58+
- restart `viaduct serve-api`
59+
- keep the value narrow instead of using a wildcard
60+
61+
## Workspace Job Fails With `context deadline exceeded`
62+
63+
Cause:
64+
- the server-side workspace job timeout elapsed before discovery, graph generation, simulation, or planning completed
65+
66+
Fix:
67+
- increase `VIADUCT_WORKSPACE_JOB_TIMEOUT`
68+
- retry the job from the workspace job history after adjusting the timeout
69+
- use PostgreSQL for persistent evaluation environments so retry and recovery state survive restarts
70+
71+
## Dashboard Sign-In Disappears After Closing The Browser
72+
73+
Cause:
74+
- the runtime bootstrap stores keys in session storage by default
75+
76+
Fix:
77+
- sign in again
78+
- use the bootstrap screen's remember option if you intentionally want the browser to keep a local copy of the key
79+
- prefer service-account keys over tenant keys for saved browser credentials
80+
5181
## KVM Fixture Discovery Returns No VMs
5282

5383
Cause:

0 commit comments

Comments
 (0)