Source commit: 20b59dc46b72103c2f8a516c692b5cc3d54fab19 Public tree identity: sha256:aaa5ac7b58b2a0d23c6b11e5f76324bf3839ca1f62653a83deb736932adcfbd9
421 lines
25 KiB
Markdown
421 lines
25 KiB
Markdown
# Disasmer
|
|
|
|
Disasmer is a distributed Wasm runtime for source-debuggable, local-first execution. The flagship workflow is a build written as Rust source code: one virtual process, many virtual threads/tasks, ordinary debugger controls, attached user nodes, and explicit artifact handling.
|
|
|
|
The MVP shape is:
|
|
|
|
```text
|
|
examples/launch-build-demo/envs/linux/Containerfile
|
|
examples/launch-build-demo/src/build.rs
|
|
```
|
|
|
|
```rust
|
|
use disasmer::env;
|
|
|
|
let linux = env!("linux");
|
|
```
|
|
|
|
`envs/<name>/Containerfile` or `envs/<name>/Dockerfile` defines an environment named `<name>`. Source code references that environment by logical name with `env!("name")`, not by runner label or machine name.
|
|
|
|
Bundle metadata is inspectable before launch:
|
|
|
|
```bash
|
|
disasmer bundle inspect --project examples/launch-build-demo
|
|
```
|
|
|
|
The inspection output includes discovered environments, selected input digests, default source-provider choices, and the bundle identity. Container images are not embedded by default.
|
|
|
|
The development example lives in `examples/launch-build-demo`. Its coordinator
|
|
main prepares a node-local source snapshot, compiles a real static executable
|
|
with `cc` in the declared rootless-Podman environment, flushes the output file,
|
|
and passes its artifact handle to a downstream deterministic packaging task.
|
|
|
|
Canonical public documentation covers the [architecture](docs/architecture.md),
|
|
[security model](docs/security.md), [task ABI](docs/task-abi.md),
|
|
[artifact semantics](docs/artifacts.md), [debugging](docs/debugging.md), and
|
|
[self-hosting](docs/self-hosting.md).
|
|
|
|
## Quickstart
|
|
|
|
Prerequisites for the local MVP path are a Rust toolchain, Node.js for smoke
|
|
scripts, rootless Podman for Linux environment materialization, and VS Code when
|
|
debugging through the extension.
|
|
|
|
Build the public workspace and install the local command binaries:
|
|
|
|
```bash
|
|
cargo build --workspace
|
|
cargo install --path crates/disasmer-cli --bin disasmer
|
|
cargo install --path crates/disasmer-node --bin disasmer-node
|
|
cargo install --path crates/disasmer-coordinator --bin disasmer-coordinator
|
|
cargo install --path crates/disasmer-dap --bin disasmer-debug-dap
|
|
```
|
|
|
|
Install or run the VS Code extension from this checkout:
|
|
|
|
```bash
|
|
code --extensionDevelopmentPath "$(pwd)/vscode-extension" examples/launch-build-demo
|
|
```
|
|
|
|
For a persistent local install, copy or symlink `vscode-extension` into the VS
|
|
Code user extension directory under a versioned folder such as
|
|
`disasmer.disasmer-vscode-0.1.0`, then restart VS Code.
|
|
|
|
Inspect and run the flagship project:
|
|
|
|
```bash
|
|
disasmer bundle inspect --project examples/launch-build-demo
|
|
disasmer run --local --project examples/launch-build-demo build
|
|
```
|
|
|
|
For explicit process-boundary inspection, run the local services yourself:
|
|
|
|
```bash
|
|
disasmer-coordinator --listen 127.0.0.1:7999 --allow-local-trusted-loopback
|
|
disasmer node attach --coordinator 127.0.0.1:7999
|
|
disasmer run --local --coordinator 127.0.0.1:7999 --project examples/launch-build-demo build
|
|
```
|
|
|
|
`disasmer run --local` starts a loopback coordinator and user-attached local
|
|
node for the run when no coordinator address is supplied. `disasmer run [entry]`
|
|
selects an entrypoint such as `build`; `--project` overrides the project
|
|
directory. When the CLI has a hosted login and no local override is selected,
|
|
`disasmer run` uses the hosted coordinator. Use `--local` or
|
|
`--coordinator <host:port>` to force local coordinator mode. The
|
|
`--allow-local-trusted-loopback` switch is an explicit single-machine development
|
|
compatibility mode: it is rejected on non-loopback listeners and must not be
|
|
used for a shared or remotely reachable coordinator.
|
|
|
|
The MVP keeps bundles inline in the existing 1 MiB control frame. The CLI
|
|
therefore supports raw Wasm modules up to approximately 696 KiB (712704 bytes)
|
|
after reserving space for the authenticated request and task metadata. It builds,
|
|
resolves, validates, and checks this boundary before creating the virtual
|
|
process. Larger bundles fail without leaving an active process; a larger-bundle
|
|
transport is explicitly post-MVP.
|
|
|
|
In VS Code, open `examples/launch-build-demo`, start the `Disasmer: Launch
|
|
Virtual Process` configuration or press F5, inspect the Disasmer nodes,
|
|
processes, logs, artifacts, and inspector views, and use the ordinary debugger
|
|
controls for breakpoints, continue, pause, and restart. Pause is
|
|
participant-acknowledged; source stepping still fails explicitly instead of
|
|
simulating success. Restarting a terminal task rebuilds the bundle: a compatible
|
|
edit launches only that task under a fresh instance ID while preserving its
|
|
validated arguments, handles, environment, and clean VFS boundary. An active
|
|
task cannot be silently replaced, and an ABI-incompatible edit clearly requires
|
|
a whole-process restart. Artifact download
|
|
behavior is exercised by `node scripts/artifact-download-smoke.js`; final export
|
|
is explicit and should go through an attached receiver node or user-provided
|
|
storage integration rather than hidden coordinator storage.
|
|
|
|
Cleanup for the local quickstart is ordinary process and artifact cleanup: stop
|
|
the coordinator process, stop attached node processes, remove any temporary
|
|
artifacts under `target/acceptance/`, and remove the local VS Code extension copy
|
|
or symlink if one was installed.
|
|
|
|
## First-Run Diagnostics
|
|
|
|
Use these messages as first checks before debugging infrastructure:
|
|
|
|
- Missing nodes: attach a node with `disasmer node attach --coordinator <host:port>` or check the Disasmer Nodes view.
|
|
- Missing environments: add `envs/<name>/Containerfile` or `envs/<name>/Dockerfile`; the VS Code extension highlights unknown `env!("name")` references.
|
|
- Quota limits: hosted/community denials are returned before dispatch with a specific community tier reason.
|
|
- Unavailable artifacts: downloads fail before showing a link when retention, size, authorization, quota, or connectivity makes streaming impossible.
|
|
- Auth failures: browser login uses the device/browser flow, while agents and nodes use public-key identity and scoped enrollment grants.
|
|
- Failed debug freezes: all-stop reports the participant that could not freeze instead of claiming success.
|
|
- Source-provider capability gaps: source preparation stays pending until a node reports `SourceGit` or `SourceFilesystem`.
|
|
|
|
## Repository Shape
|
|
|
|
The public workspace contains the open-source contract layer:
|
|
|
|
```text
|
|
crates/disasmer-core shared identities, policy traits, scheduling, VFS/artifacts
|
|
crates/disasmer-coordinator local coordinator state model
|
|
crates/disasmer-dap Debug Adapter Protocol adapter for VS Code/debug clients
|
|
crates/disasmer-macros #[disasmer::main] and #[disasmer::task]
|
|
crates/disasmer-node node backend interfaces and local node runtime
|
|
crates/disasmer-cli CLI command surface
|
|
crates/disasmer-sdk user-facing Rust SDK
|
|
scripts/verify-public-split.sh
|
|
```
|
|
|
|
Hosted-only policy code lives under `private/**`. The public split is verified by copying the repo without `private/**` and running the public workspace tests.
|
|
|
|
Deployment names and authority names describe different things. The
|
|
**standalone Core coordinator** is the open-source self-hosted server. The
|
|
**Hosted coordinator** is the managed deployment that adds hosted policy around
|
|
Core. Within either deployment, **Client**, **Node**, **Identity**, and
|
|
**Operator** name authority lanes. “Public” and “private” describe source or
|
|
release visibility; they do not grant authority.
|
|
|
|
## Hosted Coordinator
|
|
|
|
Public CLI binaries default to the hosted coordinator at
|
|
`https://disasmer.michelpaulissen.com` unless local/self-hosted mode is
|
|
selected. The CLI asks the hosted coordinator to create a state-, nonce-, and
|
|
PKCE-bound login transaction, opens the returned Authentik authorization URL,
|
|
and polls with an opaque transaction secret. Authentik returns to the hosted
|
|
`/auth/callback`; provider codes and identity claims never pass through the CLI.
|
|
The hosted website for the MVP is deliberately barebones HTML with no CSS;
|
|
layout and UX polish are later work.
|
|
|
|
The hosted coordinator combines private hosted policy code with the open-source
|
|
Core coordinator. Client traffic uses authenticated user sessions, Identity
|
|
traffic handles browser/OIDC login, Node traffic is signed by enrolled workers,
|
|
and privileged Operator actions require a separate private credential. It does
|
|
not give community users arbitrary hosted native commands or hosted containers.
|
|
Real work runs on attached nodes.
|
|
|
|
Self-hosted users do not need the hosted website. They can run the public
|
|
coordinator and public node runtime from this repository, attach their own
|
|
nodes, and use the CLI/API for normal project, process, log, artifact, debug,
|
|
quota, and admin operations.
|
|
|
|
The standalone Core coordinator uses strict Client authority by default. A
|
|
self-hosted operator supplies one scoped bootstrap session through protected
|
|
service configuration:
|
|
|
|
```bash
|
|
DISASMER_SELF_HOSTED_SESSION_SECRET="$SELF_HOSTED_SESSION_SECRET" \
|
|
DISASMER_SELF_HOSTED_TENANT=my-team \
|
|
DISASMER_SELF_HOSTED_PROJECT=my-project \
|
|
DISASMER_SELF_HOSTED_USER=me \
|
|
disasmer-coordinator --listen 127.0.0.1:7999
|
|
```
|
|
|
|
From the project directory, connect the CLI without placing the secret in a
|
|
process argument:
|
|
|
|
```bash
|
|
printf '%s\n' "$SELF_HOSTED_SESSION_SECRET" | \
|
|
disasmer auth connect-self-hosted \
|
|
--coordinator 127.0.0.1:7999 \
|
|
--tenant my-team --project-id my-project --user me \
|
|
--session-secret-stdin
|
|
```
|
|
|
|
The CLI verifies the scoped session before writing `.disasmer/session.json`; on
|
|
Unix the file is mode `0600`. Enrollment-grant creation and ordinary Client
|
|
operations then use this authenticated session. Signed Node and Agent requests
|
|
remain separate authority lanes.
|
|
|
|
The native Core transport is plaintext and therefore refuses non-loopback
|
|
listeners. For administration from another machine, create an authenticated SSH
|
|
tunnel to the coordinator loopback port and connect the CLI to the tunnel's
|
|
local `127.0.0.1` endpoint. Do not expose port 7999 directly.
|
|
|
|
Release dry-run mechanics, Forgejo publication, filtered repository preparation,
|
|
deployment evidence, and public-release e2e commands are source-side release
|
|
operations, not the product quickstart. They live in
|
|
`public_release_dryrun.md`.
|
|
|
|
## Coordinator State
|
|
|
|
The coordinator separates durable project and identity state from live runtime state. Tenants, users, projects, node identities, credentials, source-provider configuration, durable service policy records, and explicit project permissions can be stored in Postgres. Active virtual processes, live virtual threads, scheduler state, debug epochs, ephemeral VFS manifests, and transient artifact locations remain in coordinator memory for the MVP and are not represented in the Postgres schema.
|
|
|
|
Process lifecycle is independent of task count. `disasmer process list` and
|
|
`disasmer process status` read the live virtual-process registry directly.
|
|
`disasmer process cancel --yes` requests cooperative cancellation and leaves the
|
|
process visible as `cancelling` until its runtime exits. `disasmer process abort
|
|
--yes` is the explicit forced operation: it terminates the coordinator-side
|
|
process identity, signals active node work to stop, and immediately releases the
|
|
single-process slot. VS Code uses the same live registry for its sidebar and
|
|
offers Attach, Restart, Cancel, or Abort when F5 finds an existing process.
|
|
|
|
The local workspace and the hosted **Coordinator Project** are distinct. A
|
|
Coordinator Project is the identity, authorization, quota, and one-active-process
|
|
boundary; a local workspace is the source/bundle launch target. When another
|
|
workspace launch is occupying the same Coordinator Project, VS Code avoids
|
|
blindly attaching with the wrong source and offers different-project actions.
|
|
|
|
## Local-First Builds
|
|
|
|
Disasmer is designed so local source checkouts and large outputs stay node-local unless user code or policy explicitly moves bytes.
|
|
|
|
`flush()` publishes metadata and visibility information. It makes produced artifacts visible to downstream tasks without implying durable coordinator storage.
|
|
|
|
`sync()` is explicit. It may move bytes to another node or user-provided storage according to code or configured policy.
|
|
|
|
User-provided storage/export integrations are ordinary project code or external
|
|
commands, such as publishing through a CLI. Disasmer records metadata and
|
|
coordinates capability, scheduling, and transfer decisions; it does not provide
|
|
or manage an explicit artifact-store feature as part of the MVP.
|
|
|
|
Artifacts are best-effort retained on nodes by default. If unsynced node-local bytes are garbage collected or the retaining node is lost, the artifact becomes unavailable instead of silently recovering from coordinator storage.
|
|
|
|
Artifact downloads are created only when current retention, size, authorization, and community tier accounting allow it. Download links are scoped to the tenant, project, process, artifact, actor, and policy context, expire after a bounded TTL, can be revoked, and streaming usage is charged before and during transfer.
|
|
|
|
On Linux nodes, Containerfile and Dockerfile environments are materialized with rootless user Podman. The node runtime has a concrete runner path for `podman build` followed by `podman run`; tests use a recording runner, while real attached nodes can use the `std::process::Command` runner. A local build from an attached local checkout uses a node-local bind mount into the selected environment; the coordinator does not create a full-repo tarball or route compiler file reads. Command output is associated with the virtual thread that started it and can be staged into the VFS artifact namespace. `node scripts/wasmtime-node-smoke.js` builds the launch example for `wasm32-unknown-unknown`, runs its exported task through the node Wasmtime runtime, and verifies a Wasm task can invoke a native command through the versioned `disasmer.command_run_v1` host capability without moving command execution into the hosted coordinator.
|
|
|
|
## Nodes And Trust
|
|
|
|
Users attach their own nodes for real work. The hosted coordinator is a control plane for identity, rendezvous, scheduling metadata, debug sessions, logs, artifact metadata, and operator state. The community tier does not provide arbitrary hosted native commands or hosted containers.
|
|
|
|
Agent and worker automation should use enrolled public-key identity. User OAuth or browser session tokens are not task credentials and should not be passed to nodes.
|
|
|
|
```bash
|
|
disasmer login
|
|
disasmer login --browser
|
|
disasmer agent enroll --public-key <agent-public-key>
|
|
DISASMER_AGENT_PRIVATE_KEY=<agent-private-key> disasmer run --non-interactive build
|
|
disasmer run --local --non-interactive build
|
|
disasmer node attach --enrollment-grant <grant> --public-key <node-public-key>
|
|
disasmer-node --coordinator https://disasmer.michelpaulissen.com --tenant <tenant> --project-id <project> --node <node-id> --public-key <node-public-key> --enrollment-grant <grant> --worker --emit-ready
|
|
```
|
|
|
|
`disasmer login` uses a short-lived human device flow and does not ask users to paste long-lived secrets. `disasmer login --browser` opens the server-provided authorization URL, polls the hosted transaction, and stores only normalized CLI-session metadata in `.disasmer/session.json`; provider authorization codes, OAuth tokens, and identity claims are not accepted or persisted by the CLI. `disasmer login --browser --plan` is the diagnostic JSON login plan path. `--non-interactive` never opens a browser; `disasmer login --browser --non-interactive` and an unauthenticated implicit hosted `disasmer run --non-interactive` fail with an authentication-category report and next actions instead of prompting or guessing. Node attach exchanges a short-lived enrollment grant for a scoped long-lived node identity and then exits; a long-lived `disasmer-node --worker` process must be running for coordinator-side launches and DAP live-services debugging to place real command/container work on that node.
|
|
|
|
Hosted agent public keys are project-scoped records: a signed-in user can
|
|
register, list, rotate, and revoke an agent key without giving the agent browser
|
|
or OAuth credentials. An enrolled agent can run CLI commands non-interactively
|
|
with `DISASMER_AGENT_PRIVATE_KEY`; the CLI derives the registered public key,
|
|
signs workflow requests, and records the public-key fingerprint in its run plan
|
|
instead of starting a browser flow. `DISASMER_AGENT_PUBLIC_KEY` may identify or
|
|
cross-check the registered key, but cannot authenticate without the private key.
|
|
|
|
`disasmer node attach` auto-detects OS, architecture, command/container,
|
|
VFS/artifact, source-provider, and environment capabilities. `--cap <name>` is
|
|
available as an override for unusual local setups, not as required normal
|
|
configuration.
|
|
|
|
For local process-boundary testing, the public workspace includes a TCP JSON-line coordinator service and a node runtime binary:
|
|
|
|
```bash
|
|
cargo run -p disasmer-coordinator -- --listen 127.0.0.1:0
|
|
cargo run -p disasmer-node -- --coordinator <host:port> --worker \
|
|
--project-root examples/launch-build-demo
|
|
```
|
|
|
|
`scripts/real-flagship-harness.js` starts those as separate long-lived processes. The real `build` Wasm entrypoint spawns its named Wasm tasks through the coordinator; the Linux task selects `env!("linux")`, runs its command through rootless Podman against the node-local checkout, publishes content-addressed bytes, and reports task and artifact metadata. The download and export smokes reuse that workflow and then retrieve the retained bytes through an authorized reverse stream. `scripts/wasmtime-assignment-smoke.js` separately proves cooperative cancellation observed by task code and forced abort of uncooperative Wasm/native work.
|
|
|
|
For self-hosted local clouds, trusted teams, or VPN deployments, run the public
|
|
coordinator on the chosen listen address and attach team-owned nodes with their
|
|
public keys. This path uses the open-source coordinator, scheduler, node
|
|
heartbeat, task metadata, retained-node downloads, and direct node-to-node export
|
|
planning without private hosted OIDC or community tier policy modules.
|
|
`node scripts/self-hosted-coordinator-smoke.js` exercises that public path with
|
|
two trusted Linux nodes.
|
|
|
|
## Debugging
|
|
|
|
The VS Code extension contributes the normal `disasmer` debug type, refreshes bundle metadata before launch, and starts the DAP adapter. Bundle probe ownership comes from actual `#[disasmer::main]` and `#[disasmer::task]` declarations and their declared names, not function-name heuristics. In the verified local-services path, an executing Wasm probe reports a breakpoint hit, every active participant acknowledges the freeze, and only then does DAP emit an all-stop `stopped` event. Runtime child tasks appear as dynamic virtual threads. Continue requests a real coordinator resume. Stack, task-argument, live task-handle, native-command status, and output data come from node acknowledgements; values the runtime did not report are labeled unavailable instead of being inferred or fabricated. Each dispatched task captures a clean entry checkpoint containing its TaskSpec, bundle, ABI, arguments, environment digest, VFS epoch, and required-artifact manifest. After a terminal failure, `restartFrame` rebuilds the current source and relaunches only a boundary-compatible task with a fresh instance ID; an ABI-incompatible edit requires a whole virtual-process restart without mutating the existing process. Active-task restart and arbitrary source stepping fail explicitly. Disasmer-specific side views expose nodes, virtual processes, logs, artifacts, and inspector state alongside the normal debugger UI.
|
|
|
|
Live-services launch now uses the same bundle builder, Wasm entrypoint TaskSpec,
|
|
probe plan, worker placement, Debug Epoch observation, continuation, and restart
|
|
code as local-services; only ownership of the already-attached worker differs.
|
|
That path remains labeled integration-verified until the final revision-bound
|
|
hosted E2E is recorded. F5 and DAP acceptance therefore continue to exercise
|
|
local services as well as the strict hosted deployment rather than treating
|
|
deployment configuration alone as live proof.
|
|
|
|
The built-in operator panel preview is rendered by the coordinator from live
|
|
process, task, log, and artifact metadata. It uses typed widgets only, keeps
|
|
program UI events scoped and rate-limited, and keeps control-plane actions such
|
|
as debug, cancel, restart, and artifact download available when program UI events
|
|
are disabled.
|
|
|
|
## Windows
|
|
|
|
Windows node support uses the same node protocol and capability model as Linux. MVP Windows command execution is user-attached development execution, labeled `windows-command-dev`. Production-grade managed Windows sandboxing is behind an explicit backend stub until it is implemented and validated independently. When the acceptance report shows `windows_validation: "not-run"`, Windows support is best-effort and unvalidated for that release; the public smoke only verifies protocol, placement, metadata, and download behavior for a Windows-capable node identity.
|
|
|
|
Real Windows validation runs through the manual Forgejo workflow
|
|
`.forgejo/workflows/windows-validation.yml` when the intermittent Windows runner is
|
|
online. That workflow records `windows_validation: "forgejo-windows-runner"` in
|
|
the acceptance report, runs `disasmer node attach` against a coordinator, starts a
|
|
Windows node process, executes a simple `windows-command-dev` command, publishes
|
|
artifact metadata, checks Windows placement, and verifies the debugger can show a
|
|
Windows virtual thread.
|
|
|
|
## Source Providers
|
|
|
|
Git is an optional source-provider module included by default. The VFS core depends on source-provider manifests and snapshot handles, not on Git internals. Non-Git source providers can implement the public source-provider interface and run snapshot preparation as node work instead of requiring coordinator filesystem access.
|
|
|
|
Source preparation is scheduled as node work. The coordinator can return a
|
|
pending source-preparation status while waiting for any capable node, then assign
|
|
the work after a node reports `SourceGit` or `SourceFilesystem` capability; it
|
|
does not need checkout or provider access itself.
|
|
|
|
Source-provider manifests are validated as public input and must declare a
|
|
local-first transfer policy: local source bytes stay node-local, the coordinator
|
|
does not receive source bytes by default, and remote preparation uses required
|
|
content or explicit snapshot chunks rather than a full-repo tarball.
|
|
|
|
## Verification
|
|
|
|
Run the public workspace checks:
|
|
|
|
```bash
|
|
scripts/acceptance-public.sh
|
|
```
|
|
|
|
Run the CLI-first non-e2e gate before any final public-release e2e attempt:
|
|
|
|
```bash
|
|
scripts/acceptance-cli-first.sh
|
|
```
|
|
|
|
This gate composes the CLI/API, local-services, self-hosted, hosted-compat,
|
|
debugger, artifact, safety, and public dry-run contract checks without invoking
|
|
`public-release-dryrun-e2e.js` or the final evidence verifier. Leave
|
|
`DISASMER_PUBLIC_RELEASE_DRYRUN_E2E` and `DISASMER_PUBLIC_RELEASE_DRYRUN_FINAL`
|
|
unset until the CLI-first criteria are otherwise implemented to pass.
|
|
|
|
Or run the individual public checks:
|
|
|
|
```bash
|
|
cargo test --workspace
|
|
node scripts/acceptance-report-smoke.js
|
|
node scripts/public-private-boundary-smoke.js
|
|
node scripts/release-blocker-smoke.js
|
|
node scripts/docs-smoke.js
|
|
node scripts/public-release-dryrun-contract-smoke.js
|
|
node scripts/wasmtime-node-smoke.js
|
|
node scripts/podman-backend-smoke.js
|
|
node scripts/vscode-extension-smoke.js
|
|
node scripts/vscode-f5-smoke.js
|
|
node scripts/node-attach-smoke.js
|
|
node scripts/wasmtime-assignment-smoke.js
|
|
node scripts/cli-local-run-smoke.js
|
|
node scripts/artifact-download-smoke.js
|
|
node scripts/artifact-export-smoke.js
|
|
node scripts/operator-panel-smoke.js
|
|
node scripts/source-preparation-smoke.js
|
|
node scripts/scheduler-placement-smoke.js
|
|
node scripts/windows-best-effort-smoke.js
|
|
node scripts/quic-smoke.js
|
|
node scripts/flagship-demo-smoke.js
|
|
node scripts/dap-smoke.js
|
|
node scripts/prepare-public-release-dryrun.js
|
|
scripts/verify-public-split.sh
|
|
```
|
|
|
|
When the Forgejo Windows runner is online, run the manual `Windows validation`
|
|
workflow as the release Windows gate. The local equivalent on a Windows machine is:
|
|
|
|
```powershell
|
|
$env:DISASMER_WINDOWS_VALIDATION = "forgejo-windows-runner"
|
|
node scripts/acceptance-report.js windows
|
|
cargo fmt --all --check
|
|
cargo test -p disasmer-node windows_backend_is_labeled_user_attached_dev_execution
|
|
node scripts/windows-runner-smoke.js
|
|
```
|
|
|
|
Run private hosted policy checks separately:
|
|
|
|
```bash
|
|
scripts/acceptance-private.sh
|
|
```
|
|
|
|
The private hosted gate includes `hosted-client-compat-smoke.js`, which starts
|
|
the hosted dry-run service locally and verifies that the released Client CLI and
|
|
signed Node runtime can attach, launch work through coordinator task assignment,
|
|
and publish debug/log/artifact metadata through the hosted Client protocol
|
|
boundary.
|
|
|
|
Both acceptance scripts write an environment report under `target/acceptance/`
|
|
with the commit SHA, toolchain versions, OS/kernel, Podman/Postgres discovery,
|
|
browser/VS Code harness metadata, and Windows-validation status. The report
|
|
records Podman as `available` only when rootless Podman is discoverable; if it is
|
|
missing or not rootless, Linux Podman backend behavior is marked `incomplete`
|
|
with the reason and the Podman backend smoke blocks acceptance with the same
|
|
incomplete reason.
|