Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,72 @@ session-scoped ID. The relay still observes normal network and HTTP tunnel
traffic. These statements are pinned to that v0.5.1 source commit and must not
be generalized to other releases.

#### Windows Temporary Layered Entry

For Windows amd64 attended sessions, a trusted Agent can verify the signed
`rdev-bootstrap.exe` release artifact and materialize a private layered handoff.
The bootstrap fetches an HTTPS `layered-assets.json`, verifies its Ed25519
release-root signature, selects only the Windows core `rdev-host` runtime, and
uses the shared resumable content-addressed downloader. The controller pins the
expected release version and `windows/amd64` in signed bootstrap metadata; the
bootstrap requires the downloaded manifest to match that version before it
requests the runtime. Ticket and gateway values remain in the separately
signed join manifest.

The first run downloads and SHA-256 verifies the core runtime. A warm run
revalidates and reuses the digest cache without fetching the runtime again.
The user-scoped cache is rooted below
`%LOCALAPPDATA%\RemoteDevSkillkit\cache`; managed directories and files use
private `0700`/`0600` permissions. On Windows, the primary visible launcher is
`Start-ConnectionEntry.ps1`. The visible `Start-ConnectionEntry.cmd` broker
tries that launcher under the current policy, retries with a process-scoped
`-ExecutionPolicy Bypass`, and then uses its native CMD path. The retry changes
no registry or machine policy. All paths share one private attempt directory;
once its state reaches `core_started`, no launcher starts another core. Both
launchers restrict handoff, attempt, and cache ACLs to the current user,
SYSTEM, and Administrators; reject reparse or UNC paths; recheck bootstrap size
and SHA-256; and keep the verified bootstrap in the foreground.

Temporary mode runs the selected host in the foreground. It does not install a
service, create a scheduled task or registry persistence, or start a background
updater. If layered prerequisites were not published, Connection Entry retains
the visible `Start-ConnectionEntry.ps1` archive-compatible fallback. Signature,
digest, origin, path, or verification failures never execute the downloaded
asset or automatically downgrade. The launcher prints the separately verified
self-contained archive fallback as an explicit recovery command instead.

The layered run report contains `from_cache`, `resumed`, `bytes`, and ordered
stage durations for manifest fetch, signature verification, runtime resolution,
and launch preparation. `bytes` is the verified runtime size, not measured
network transfer volume. No performance target is claimed until real Windows
cold and warm acceptance evidence is collected.

For acceptance, save the first standalone JSON report emitted by each run as
`cold-layered-run.json` and `warm-layered-run.json`; do not include subsequent
foreground host output in either file. Package both reports with the other real
Windows evidence:

```bash
rdev acceptance package-windows-temporary \
--plan windows-plan/windows-temporary-plan.json \
--out windows-evidence \
--transcript transcript.txt \
--release-verification rdev-verify.json \
--audit audit.jsonl \
--no-persistence-dir no-persistence \
--denial-probes-dir denial-probes \
--cold-layered-run cold-layered-run.json \
--warm-layered-run warm-layered-run.json
```

The packager requires a cache miss in the cold report, a cache hit in the warm
report, the complete ordered verification stages, and nonnegative durations.
Reports containing ticket, gateway, token, redaction-marker, or private-path
content are rejected before copying. Synthetic fixture reports are
non-production and do not satisfy the formal release gate or replace a real
Windows run. Keep the complete session-bound Windows evidence package private;
review any report separately before publication.

### 2. Run Scoped Work

The agent creates signed tasks for specific capabilities: shell, PowerShell,
Expand Down
29 changes: 15 additions & 14 deletions TASKS.md

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion cmd/rdev-bootstrap/main.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//go:build !windows

package main

import (
Expand All @@ -9,7 +11,7 @@ import (
)

func main() {
app := bootstrapcmd.App{Stdout: os.Stdout, Stderr: os.Stderr}
app := bootstrapcmd.App{Stdin: os.Stdin, Stdout: os.Stdout, Stderr: os.Stderr}
if err := app.Run(context.Background(), os.Args[1:]); err != nil {
_, _ = fmt.Fprintln(os.Stderr, err)
os.Exit(1)
Expand Down
3 changes: 3 additions & 0 deletions cmd/rdev-bootstrap/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,7 @@ func TestRdevBootstrapEntrypointAvoidsFullRuntimeImports(t *testing.T) {
if !strings.Contains(source, "internal/bootstrapcmd") {
t.Fatalf("rdev-bootstrap entrypoint should delegate to internal/bootstrapcmd:\n%s", source)
}
if !strings.Contains(source, "Stdin: os.Stdin") {
t.Fatalf("rdev-bootstrap entrypoint should pass inherited stdin to foreground commands:\n%s", source)
}
}
23 changes: 23 additions & 0 deletions cmd/rdev-bootstrap/main_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//go:build windows

package main

import (
"context"
"errors"
"os"
"syscall"

"github.com/EitanWong/remote-dev-skillkit/internal/bootstrapcmd/windowsentry"
)

func main() {
app := windowsentry.App{Stdin: os.Stdin, Stdout: os.Stdout, Stderr: os.Stderr}
if err := app.Run(context.Background(), os.Args[1:]); err != nil {
_, _ = os.Stderr.WriteString("rdev-bootstrap layered-run failed\n")
if errors.Is(err, syscall.ERROR_ALREADY_EXISTS) {
os.Exit(2)
}
os.Exit(1)
}
}
74 changes: 34 additions & 40 deletions docs/operations/ACCEPTANCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ one-message flow:
11. report `connected=true` through `connected_next_steps.user_report`;
12. fetch a local join page, Windows `bootstrap.ps1`, macOS/Linux
`bootstrap.sh`, and `/assets/*.sha256` endpoints from a `httptest` gateway
to prove clean targets can download and SHA-256 verify helper binaries
to prove clean targets can download and SHA-256 verify bootstrap binaries
instead of being told to install `rdev` manually;
13. configure `RDEV_RELAY_GATEWAY_URL` during the local gate and prove the
high-level handoff auto-selects that stable gateway, the target command uses
Expand All @@ -217,17 +217,17 @@ one-message flow:
asking the Agent to write relay/mesh/VPN/SSH glue;
14. include signed runtime gateway candidates in the generated target bootstrap
URL, so the fetched join manifest can carry ordered gateway candidates to
`rdev host serve` and the target host can select a reachable signed
candidate before registration;
`rdev-bootstrap`; the verified core can select a reachable signed candidate
before registration and later switch routes without registering again;
15. avoid custom PowerShell, shell, relay, authorization-polling, ticket, root,
gateway, transport, or bootstrap glue;
16. include `rdev.support-session-target-handoff-envelope.v1` on created,
connected, and started payloads, so Agents no longer need to reconstruct the
human-facing text from separate fields;
17. include `agent_connection_runbook.fresh_agent_failure_prevention`, a
machine-readable regression guard for real fresh-Agent failures such as
manual gateway/invite/bootstrap assembly, missing helper assets that produce
`rdev is required`, background gateway workarounds, custom authorization polling,
manual gateway/invite/bootstrap assembly, missing bootstrap assets or signed
layered metadata, background gateway workarounds, custom authorization polling,
and Agent-written PowerShell/shell setup.

The command writes `report.json` with schema
Expand Down Expand Up @@ -266,10 +266,10 @@ rdev acceptance package-relay-adapter \
The package archives the shareable standard evidence files and does not require
Agents to pass six individual file flags. The result uses schema
`rdev.connection-entry.runner-result.v1` and records the selected path, gateway
override, helper-start status, transport, host-serve argv, probe results, and
override, helper-start status, transport, bootstrap argv, probe results, and
manual-action requirements. The helper transcript, status files, and audit JSONL
are standard evidence generated by the runner from dependency install,
helper-start, gateway-probe, host-serve, and cleanup events, so Agents should
helper-start, gateway-probe, bootstrap, and cleanup events, so Agents should
not hand-write them.

If a helper is missing, the runner accepts dependency repair only through
Expand Down Expand Up @@ -436,35 +436,28 @@ host plan:
```bash
rdev acceptance windows-temporary \
--out .rdev/acceptance/windows-temporary \
--gateway https://api.example.com/v1 \
--ticket-code ABCD-1234 \
--download-url https://agent.example.com/rdev-host.exe \
--expected-sha256 <rdev-host-sha256> \
--release-bundle-url https://agent.example.com/release-bundle.json \
--release-root-public-key release-root:... \
--verifier-download-url https://agent.example.com/rdev-verify.exe \
--verifier-sha256 <rdev-verify-sha256>
--handoff-archive ./Windows-ConnectionEntry.zip
```

The command writes `windows-temporary-plan.json` with schema
`rdev.acceptance.windows-temporary-plan.v1` and `run-windows-temporary.ps1`. It
`rdev.acceptance.windows-temporary-plan.v1` and a private copy of the measured
handoff ZIP. It
validates:

- local or URL bootstrap script availability;
- bootstrap script SHA-256 availability;
- gateway URL, ticket code, host download URL, and host SHA-256;
- signed release manifest or signed release bundle, release root, verifier
download URL, verifier SHA-256, and bundle required artifacts when bundle mode
is used;
- the closed ZIP SHA-256, hard size limit of 1,048,576 bytes, and bounded full
entry reads (including compressed-entry integrity) before any evidence is written;
- the exact PowerShell, process-scoped PowerShell retry, and native CMD order;
- required `rdev-bootstrap`, signed manifest, checksum, verification, and
explicit recovery-profile entries;
- bootstrap-only launcher content with no direct full-helper startup;
- host-denial probes for package install, elevation, service management, GUI
control, and credential changes;
- no-persistence inspection commands for services, scheduled tasks, Run keys,
startup folders, and firewall rules.

This command does not execute PowerShell. It produces the operator-reviewed plan
for a real Windows VM or support-host acceptance run. The generated launcher is
intentionally visible and foreground-only; it does not install a service or
autorun entry.
This command does not execute PowerShell. It produces a non-sensitive summary
plan for a real Windows VM or support-host run; the private ZIP remains outside
the public evidence package.

Verify the generated plan before sending or running the launcher:

Expand All @@ -477,14 +470,10 @@ The verifier emits `rdev.acceptance-verification.windows-temporary-plan.v1` JSON
and exits nonzero if any preflight check fails. It validates:

- plan schema and generated plan checks;
- launcher existence, private file mode, and parameter agreement with the plan;
- launcher absence of forbidden persistence or policy-weakening operations such
as `Set-ExecutionPolicy`, service creation, scheduled-task registration,
Run-key mutation, firewall-rule creation, or elevation through `runas`;
- local bootstrap script SHA-256 when the script path is available, or a pinned
bootstrap SHA-256 when the launcher downloads the script by URL;
- signed release manifest or signed release bundle, release root, verifier URL,
host SHA-256, verifier SHA-256, and bundle required-artifact inputs;
- private handoff ZIP existence, protected private file ACL, SHA-256, size, bounded
full-entry integrity, and required entries;
- PowerShell-first selection, fallback order, bootstrap-only command, and
non-automatic recovery;
- foreground run command, transcript commands, no-persistence checks,
host-denial probes, and required evidence checklist.

Expand All @@ -498,25 +487,30 @@ rdev acceptance package-windows-temporary \
--release-verification rdev-verify.json \
--audit audit.jsonl \
--no-persistence-dir no-persistence \
--denial-probes-dir denial-probes
--denial-probes-dir denial-probes \
--cold-layered-run cold-layered-run.json \
--warm-layered-run warm-layered-run.json \
--layered-entry-evidence layered-entry-evidence.json
```

The package command emits `rdev.acceptance-package.windows-temporary.v1` JSON,
writes `package.json` and `checksums.txt`, copies the plan and launcher, redacts
writes `package.json` and `checksums.txt`, copies the non-sensitive plan, redacts
transcripts and verifier output, and fails closed until all required release
evidence is present:

- PowerShell transcript from bootstrap and foreground host startup;
- PowerShell/CMD attempt transcript and exactly one core-start transition;
- standalone `rdev-verify` output with `"ok": true`;
- session join, endpoint trust, task, host-denial probe, revoke, and cancellation
- session registration, route reselection, task, revoke, and cancellation
audit evidence;
- cold Range-resume and warm-cache layered run reports;
- one no-persistence evidence file for services, scheduled tasks, HKCU/HKLM Run
keys, startup folders, and firewall rules;
- one host-denial probe evidence file for package install, elevation, service
management, GUI control, and credential change.

Use the packaged directory as the release-candidate artifact. Do not publish a
Windows temporary acceptance claim from screenshots or raw transcripts alone.
The private handoff ZIP is deliberately excluded from this public evidence
directory. Do not publish a Windows temporary acceptance claim from screenshots
or raw transcripts alone.

## Linux Managed Service

Expand Down
27 changes: 13 additions & 14 deletions docs/operations/AGENT_BOOTSTRAP_PROMPT.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ Steps:
missing `rdev`, what not to ask humans for, and which custom PowerShell,
shell, tunnel, interrupt, or polling scripts are forbidden. If you are about
to improvise setup code, stop and follow that contract instead. If local
`rdev`, gateway state, or target helper assets are unclear, call
`rdev`, gateway state, or target bootstrap assets are unclear, call
the CLI-only `rdev support-session prepare` command or run
`rdev support-session prepare --build-assets` from the checkout. Follow its
`connection_readiness`, `asset_report`, `missing_inputs`, and
Expand Down Expand Up @@ -187,17 +187,16 @@ Steps:
Connection Entry URLs on the target machine with the returned
`connection_attempt_policy` timeout/retry behavior; do not write your own
PowerShell, shell, relay, or interrupt-polling fallback. Ordinary attended
`/join/.../bootstrap.*` handoffs use `rdev host serve --transport
long-poll` for stable HTTPS-only connectivity. Use `--transport auto` only
for managed or explicit advanced runner paths where WSS fallback has been
validated. Read
`/join/.../bootstrap.*` handoffs verify and invoke `rdev-bootstrap
layered-run`. The single verified core uses `--transport auto` and may
switch among signed routes without another registration. Read
`agent_connection_runbook` first; it is the machine-readable order of
operations for connecting, waiting, reporting, and recovering without
custom scripts. Read
`agent_connection_runbook.fresh_agent_failure_prevention` before writing
any setup code: it captures known bad fresh-Agent failure patterns such as
manual `gateway serve` plus `invite create`, missing helper assets that make
Windows say `rdev is required`, background gateway glue, custom interrupt
manual `gateway serve` plus `invite create`, missing bootstrap assets or
signed layered metadata, background gateway glue, custom interrupt
polling, and Agent-written PowerShell/shell bootstraps. If you are about to
write one of those workarounds, stop and use the returned
`cli_start_now_command`, `ready_file.path`, `status_file.path`,
Expand Down Expand Up @@ -226,14 +225,14 @@ Steps:
extract the join URL into a separate first message. Also read
`target_bootstrap_requirements` and, for CLI
create calls, `target_bootstrap_readiness`. If an existing gateway cannot
serve the verified helper assets for the selected platform, use the
serve the verified bootstrap assets for the selected platform, use the
standard `rdev support-session connect --start` or
`rdev support-session prepare --build-assets` recovery path instead of
asking the target-side human to install `rdev` manually or writing a custom
downloader. If no suitable
asking the target-side human to install a runtime manually or writing a
custom downloader. If no suitable
gateway is running yet, run `rdev support-session connect --start` in a visible
foreground terminal. It
prepares verified Windows/macOS/Linux helper assets when a checkout and Go
prepares verified Windows/macOS/Linux bootstrap assets when a checkout and Go
are available, starts the local gateway, and prints
`rdev.support-session-started.v1` with top-level
`target_handoff_envelope`, `user_handoff`,
Expand Down Expand Up @@ -284,11 +283,11 @@ Steps:
code when the plan can provide it. Do not manually combine
`rdev gateway serve` plus `rdev invite create` for a normal support session;
use `rdev support-session connect --start` so ready/status files,
auto-authorization, and helper assets are created together. If a low-level dev
auto-authorization, and bootstrap assets are created together. If a low-level dev
gateway is explicitly required, keep the default
`--auto-build-rdev-assets` behavior enabled from a valid checkout with Go,
or configure helper assets with `--rdev-assets-dir` / platform-specific
asset flags before generating human-facing target commands. For lower-level package materialization
or configure bootstrap assets and signed layered release inputs with
`--rdev-assets-dir` before generating human-facing target commands. For lower-level package materialization
or when `rdev.sessions.create` is not sufficient, use
`CLI-only: rdev invite create` or `rdev invite create` so the Agent receives
`connection_entry`, `connection_entry.package_catalog`,
Expand Down
Loading
Loading