Automation and CI

Treat validation, plan creation, build, publication, approval, activation, and verification as separate gates. Build one candidate from an exact source-attestation digest and publish that unchanged candidate only from an approved branch or environment. Git is a useful source of change evidence, not LeapView's source of truth: correctness, rollback, and target activation depend on content digests, retained candidates, plans, and deployment evidence.

Choose output and interaction explicitly

Commands with selectable results use --format text|json. The Boolean --json flag has been removed. Artifact exports retain their encoding formats; fixed JSON and raw-response commands are identified in the generated reference. There is no global format flag.

Results go to stdout; progress, prompts, and diagnostics go to stderr. Finite JSON results are one complete document. Development watch emits newline-delimited events; dev --once returns a finite result. Device login emits challenge and completion events and still needs a person to authorize it.

Pass --no-input in automation. JSON output also disables terminal prompts and automatic browser opening. A guided deployment that needs confirmation reports its exact next action and operation handle; preserve both rather than supplying an arbitrary answer.

Exit code Meaning
0 The requested operation completed successfully
1 Execution, validation, authentication, or a required diagnostic check failed
2 Invalid invocation, flags, arguments, or command selection
3 Guided deployment awaits confirmation or server approval
4 Guided deployment outcome is indeterminate; inspect/resume the retained operation
130 / 143 Client interrupted by SIGINT / SIGTERM

The server command serve returns 0 after successfully draining and shutting down on SIGINT or SIGTERM. A shutdown error still fails the command.

When a command already emitted a structured domain failure, the error boundary preserves it without appending a second result. Other failures use stderr, with a JSON error object when JSON output was selected. Deploy success means confirmed activation; build or publish success means that operation completed and does not prove activation.

Provide bounded credentials

Use LEAPVIEW_WORKLOAD_CLIENT_ID, LEAPVIEW_WORKLOAD_CLIENT_SECRET, and LEAPVIEW_WORKLOAD_PROJECT for production CI. Inject the service-principal secret from the CI secret manager and prevent pull requests from untrusted forks from reading it. The CLI exchanges it on demand for a short-lived target credential. The validation job does not need target credentials. LEAPVIEW_API_TOKEN remains a compatibility option for smaller teams.

The automation principal needs RESOURCE_USE, RESOURCE_READ, RESOURCE_EDIT, and RESOURCE_PUBLISH for its exact project. It must not receive human login, approval, activation, secret-provider administration, connection-secret, or source-data credentials. Target-owned connection resolution and row-level policy evaluation still run under the automation principal. Use a deliberately restricted automation role; do not impersonate an end user to make a candidate pass.

These names are the current short-lived authoring/workload compatibility profile. They are not permission choices for newly issued personal API tokens, which use explicit typed action-target pairs and currently fail closed for delivery operations that have not yet migrated to typed enforcement.

Keep the target and project identity in reviewable pipeline configuration:

export LEAPVIEW_TARGET=https://dash.example.com
export LEAPVIEW_WORKLOAD_PROJECT=analytics

Validate without network access

Compile the complete project first and retain structured diagnostics as a job artifact:

leapview validate --source-root dashboards --format json

Stop the pipeline on any non-zero exit status. Do not allow a later deployment job to replace or edit the project after validation.

Create and build the immutable delivery plan

Create a durable plan from the exact source snapshot, then build only that plan:

PLAN_JSON=$(leapview plan --source-root dashboards --target "$LEAPVIEW_TARGET" --format json)
PLAN_ID=$(printf '%s' "$PLAN_JSON" | jq -r .planId)
BUILD_JSON=$(leapview build "$PLAN_ID" --format json)
CANDIDATE_ID=$(printf '%s' "$BUILD_JSON" | jq -r .candidateId)

The target retains the portable bytes and source-attestation digest before physical work. build resolves target policy, leases, and credentials, and returns a candidate only after its catalog is sealed. dev remains an optional private watch/preview loop; it is not a second CI deployment path. For a local candidate preview, use leapview dev --once --source-root dashboards.

The compiler's source bundle stays unbound. Planning binds its exact digest to the target's existing Project UID and environment, target identity, current active generation and revision, and resolved target inputs. Bootstrap must already have claimed the target; an ordinary plan or build cannot create or replace that claim. A different Project or target is a conflict, not a context switch. A new build requires the plan's target revision and active generation to remain current at candidate admission; if either changes, create a new plan.

For promotion, plan the same portable bundle independently on each development, staging, and production target. Bootstrap those targets with the same issuer-owned Project UID, but keep their environments and credentials separate. Do not transfer another target's plan, approval, resource UIDs, revision, or active pointer. Branch and commit values are provenance, not environment or active-generation selectors.

Publish an immutable deployment request

Run publication from a protected job using the same source root and target used by dev:

leapview publish "$CANDIDATE_ID"

publish does not read, compile, or upload the project again. It submits the exact sealed candidate and plan provenance returned by build. An environment configured for immediate publication activates it; a protected environment returns the immutable publication and approval request without activating it.

Approve the exact persisted plan with a different principal holding PROJECT_ADMIN, then request cutover with a principal holding PROJECT_ADMIN. Immediately before cutover, LeapView rechecks the release, plan digest, approval revision, expiry, reviewer credential and grant, and activator credential and grant. Revocation or expiry closes the workflow safely.

Reconcile change lifecycle

Map source-control events onto the candidate lifecycle rather than inventing a CI deployment model:

Source event LeapView action
Open or reopen Validate locally, then create a target-owned plan in a trusted job
Update or synchronize Create a new plan for the new exact source snapshot
Retry or missed webhook Repeat the same operation and idempotency key
Superseded commit Synchronize the new revision; never publish the older checkpoint
Merge to a protected branch Build the reviewed plan, then run publish CANDIDATE_ID
Close or abandon Let the target expire the private candidate; reconcile its status before retrying

There is no candidate-cancellation operation in the canonical Delivery API.

Candidates expire on the target, so a missed close event does not leave an active runtime indefinitely. Scheduled reconciliation should inspect the candidate or publication status and must never publish a superseded candidate.

Preserve evidence and verify

The plan, build, and publish output records the exact source-attestation digest, plan, artifact, target, candidate, principal, and result. Retain those logs with the source-control run. The Delivery APIs expose the same immutable evidence after the runner disappears.

After activation, verify readiness and exercise a representative project query or dashboard with a separate verifier identity. A transport retry must reuse the same durable plan or candidate ID and its plan/seal digests; never rebuild from a moving branch between attempts.

The maintained GitHub Actions reference is /.github/examples/leapview-authoring.yml. It keeps fork validation credential-free, gates trusted candidate creation, uses protected publication, and relies on target expiry for abandoned candidates. Adapt only the source-control event syntax; keep the LeapView commands and target policy unchanged.

See Targets and environments for environment safeguards and the generated validate, dev, and publish references for all flags.