From 24fd7f3ba218452bae95b8378f8570d5cf360c8f Mon Sep 17 00:00:00 2001 From: CL Kao Date: Sat, 13 Jun 2026 10:46:14 -0700 Subject: [PATCH 1/3] docs: slim README to front door + drop banned prose-grep test [yw] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Wave 1 structural cleanup for the site-is-canonical doc architecture: - Remove internal/release/install_doc_test.go — a banned prose-grep that os.ReadFile'd docs/site/get-started/install.md and asserted author substrings. readInstallJourney was file-local; executableShellCommands stays (defined in workflow_exec_guard_test.go, 9 other call sites). - Slim README.md to the front-door skeleton: keep title + Why hook, What's different, Install, License, Contributing. Drop Quick start, How it works, Usage (now on the canonical site). - Install now links the published site https://spacedock.md/docs/ (site_url in mkdocs.yml), keeping the in-repo install.md as secondary. go test ./... green; install-journey grep-clean over live docs/code. Co-Authored-By: Claude Opus 4.8 (1M context) --- README.md | 73 ++++------------------------ internal/release/install_doc_test.go | 72 --------------------------- 2 files changed, 9 insertions(+), 136 deletions(-) delete mode 100644 internal/release/install_doc_test.go diff --git a/README.md b/README.md index df009dc0..254220e8 100644 --- a/README.md +++ b/README.md @@ -74,71 +74,16 @@ spacedock claude "/spacedock:survey" Using Codex or Pi instead? Swap the subcommand: `spacedock codex "/spacedock:survey"` or `spacedock pi "/spacedock:survey"`. -See [`docs/site/get-started/install.md`](docs/site/get-started/install.md) for the full first-run -walkthrough, the Codex and Pi paths, and a from-source build for development. - -## Quick start - -Commission a workflow by describing what you want: - -```bash -spacedock claude "/spacedock:commission Dev task workflow: design -> plan -> -implement -> review, with the design and implementation plan inlined in each work -item, implementation on isolated worktrees with strict TDD, design and review -gated for approval." -``` - -The first officer commissions the workflow and opens a worktree for the -implementation stage. It pauses at the design and review gates for your call. - -The same shape drives non-dev work. This example triages a Gmail inbox. It -requires a Gmail integration set up before you run it: - -```bash -spacedock claude "/spacedock:commission Email triage: fetch, categorize, and act -on my Gmail inbox. Entity: a batch of up to 50 emails. Stages: intake (triage -in:inbox, categorize, propose an action per email as a table) -> approval -(Captain reviews the proposal) -> execute (carry out approved actions). Walk me -through Gmail setup if needed." -``` - -## How it works - -A workflow is a directory of plain-text work item files plus a README that -defines the stages, the schema, and the gates. Everything about a work item lives -in the file itself: the problem, the design notes, the bar for done, the stage -reports. State survives a session; the next one picks up where you left off. -Three roles: - -| Role | Who | -|------|-----| -| **Captain** | You. You define the mission and make the calls at approval gates unless delegated. | -| **First Officer** | The orchestrator agent that runs the workflow and reports to you at gates. | -| **Ensign** | The worker agent that moves one item forward through one stage. | - -The first officer reads the workflow README, checks which items are ready to -advance, and dispatches ensigns. Stages that need isolation run in their own git -worktree; lightweight stages run inline. At a gate, the first officer pauses and -presents the stage report for a decision: approve, redo with feedback, or -reject. Some gates wait on you; others resolve through a delegated agent review. -Rejected work bounces back to an earlier stage for revision. A hard cap prevents -loops. - -When you end a session, `/spacedock:debrief` captures what happened: commits, -state changes, decisions, open issues, all in a record the next session picks up. -When a new Spacedock release is out, `/spacedock:refit` upgrades your workflow -scaffolding while keeping local modifications. - -## Usage - -```bash -spacedock claude "task" [--safehouse…] [-- host-flags…] # launch the first officer in Claude Code -spacedock codex "task" [--safehouse…] [-- host-flags…] # launch the first officer in Codex -spacedock pi "task" [--safehouse…] [-- host-flags…] # launch the first officer in Pi -spacedock doctor # plugin compatibility check -spacedock --version # print the installed version -``` +Full docs — the install walkthrough, the Codex and Pi paths, concepts, and the +command reference — live at **[spacedock.md/docs](https://spacedock.md/docs/)**. +Browsing the repo on GitHub? The same install guide is at +[`docs/site/get-started/install.md`](docs/site/get-started/install.md). ## License Spacedock is released under the [Apache License 2.0](LICENSE). + +## Contributing + +Spacedock is early; we welcome proposals as [GitHub issues](https://github.com/spacedock-dev/spacedock/issues). +See [CONTRIBUTING.md](CONTRIBUTING.md). diff --git a/internal/release/install_doc_test.go b/internal/release/install_doc_test.go deleted file mode 100644 index b1b6652d..00000000 --- a/internal/release/install_doc_test.go +++ /dev/null @@ -1,72 +0,0 @@ -package release - -import ( - "os" - "path/filepath" - "strings" - "testing" -) - -// TestInstallJourneyDocumentsLinuxPath locks AC-4's positive half: the install -// guide carries a runnable `curl … install.sh | sh` invocation so a Linux user -// has a concrete install path (the cask is darwin-only). The check requires the -// raw.githubusercontent install.sh URL piped to a shell — the exact line a user -// copy-pastes — not merely a mention of "install.sh". -func TestInstallJourneyDocumentsLinuxPath(t *testing.T) { - doc := readInstallJourney(t) - commands := executableShellCommands(doc) - - found := false - for _, c := range commands { - if strings.Contains(c, "install.sh") && - strings.Contains(c, "curl ") && - strings.Contains(c, "raw.githubusercontent.com/spacedock-dev/spacedock") && - (strings.Contains(c, "| sh") || strings.HasSuffix(c, "sh")) { - found = true - break - } - } - if !found { - t.Errorf("docs/site/get-started/install.md has no runnable `curl … install.sh | sh` Linux install line") - } -} - -// TestInstallJourneyDoesNotOverclaimLinuxSandbox locks AC-4's honesty half: -// spacedock ships no sandbox — internal/safehouse only detects a profile, checks -// for a `safehouse` binary on PATH, and wraps argv. So the doc must NOT assert an -// unqualified "sandboxed on Linux" claim. We scan for sandbox-claim phrasings -// near "Linux" and reject any that promise sandboxing without the -// requires-a-safehouse-binary qualifier. -func TestInstallJourneyDoesNotOverclaimLinuxSandbox(t *testing.T) { - // Strip markdown code backticks so `safehouse` binary reads as the plain - // phrase the qualifier check looks for. - doc := strings.ToLower(strings.ReplaceAll(readInstallJourney(t), "`", "")) - - // Phrasings that would over-claim a Linux sandbox if stated unqualified. - for _, claim := range []string{ - "sandboxed on linux", - "runs sandboxed on linux", - "sandboxing on linux works", - } { - if strings.Contains(doc, claim) { - t.Errorf("install-journey over-claims a Linux sandbox with %q; spacedock ships no sandbox — sandboxing requires a Linux-capable safehouse binary", claim) - } - } - - // If the doc discusses safehouse on Linux at all, it must name the binary - // dependency so the claim is qualified, not an unconditional promise. - if strings.Contains(doc, "safehouse") && strings.Contains(doc, "linux") { - if !strings.Contains(doc, "safehouse binary") { - t.Errorf("install-journey mentions safehouse + Linux but never names the required `safehouse binary` — the qualifier that keeps the claim honest") - } - } -} - -func readInstallJourney(t *testing.T) string { - t.Helper() - data, err := os.ReadFile(filepath.Join("..", "..", "docs", "site", "get-started", "install.md")) - if err != nil { - t.Fatal(err) - } - return string(data) -} From 18f5c913bfbbb360546c793010f2db293f01f748 Mon Sep 17 00:00:00 2001 From: CL Kao Date: Sat, 13 Jun 2026 10:50:02 -0700 Subject: [PATCH 2/3] docs: land the five 0.20.1 behaviors on canonical site pages [yw] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Wave 2 behavior-doc pass — yw is the sole doc-owner; the five members shipped zero .md. Each behavior documented on its reverified anchor: - gj (#350): new `## --version` section in command-reference.md showing the version+contract line, the Sandbox: posture, and the per-runtime install/enablement block (wording exercised from `spacedock --version`). - te (#351): command-reference `## Setup` names the contract-compatible- but-behind opt-in upgrade hint (doctor + front-door print it; never blocks). - zrc (#349): command-reference `## Launch` names the unsandboxed posture — claude `--permission-mode auto`, codex `--ask-for-approval on-request`, vs the sandboxed skip/bypass. Scoped to claude/codex; pi injects none. - gp (#352): releasing.md made decouple-accurate — marketplace manifest moved to the standalone spacedock-dev/marketplace repo, no plugin-branch manifest, marketplace.json dropped from the release steps; build-from- source.md adds a spacedock-edge edge-channel user pointer. - 8p (#347): install.md Homebrew tab notes brew also installs agentsview; safehouse is installed separately. Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/releasing.md | 18 ++++++++++++------ docs/site/contributing/build-from-source.md | 6 ++++-- docs/site/get-started/install.md | 4 ++++ docs/site/reference/command-reference.md | 18 +++++++++++++++++- 4 files changed, 37 insertions(+), 9 deletions(-) diff --git a/docs/releasing.md b/docs/releasing.md index 7c1f5824..ac2945ff 100644 --- a/docs/releasing.md +++ b/docs/releasing.md @@ -14,8 +14,13 @@ marketplace source. - publishes the GitHub Release with those assets; - bumps BOTH `spacedock-dev/homebrew-tap` casks (`spacedock` stable + `spacedock@next` edge) via `HOMEBREW_TAP_TOKEN`; -- stamps the plugin manifests' `version` on `main`; -- keeps the marketplace entry serving the stable plugin from `main`. +- stamps the plugin manifests' `version` on `main`. + +The marketplace manifest no longer lives in the plugin branch. It is the +standalone `spacedock-dev/marketplace` repo, whose entries pin each channel by +ref — `spacedock` (stable, repointed to the released tag) and `spacedock-edge` +(edge, tracking `next`). Repointing the stable entry is a commit in that repo, +not a manifest stamp on `main`. The tag triggers the release, but goreleaser publishes only after the `e2e-gate` job confirms the tagged commit has a green Runtime Live E2E run (or a recorded @@ -34,15 +39,16 @@ a reviewable annotated-tag changelog and manifest diff before the tag is pushed. ``` 3. Bump the version stamps with the release tool, then commit. `stamp-version` - writes the release `X.Y.Z` into the plugin manifests; `bump-calendar` advances - the marketplace entry's separate `0.0.YYYYMMDDNN` calendar key: + writes the release `X.Y.Z` into the plugin manifests: ```bash go run ./cmd/spacedock-release stamp-version X.Y.Z .claude-plugin/plugin.json .codex-plugin/plugin.json - go run ./cmd/spacedock-release bump-calendar .claude-plugin/marketplace.json - git commit -m "release: bump version to spacedock@X.Y.Z" -- .claude-plugin/plugin.json .codex-plugin/plugin.json .claude-plugin/marketplace.json + git commit -m "release: bump version to spacedock@X.Y.Z" -- .claude-plugin/plugin.json .codex-plugin/plugin.json ``` + The marketplace entry is no longer stamped here — repoint the `spacedock` + stable entry's ref in the standalone `spacedock-dev/marketplace` repo. + 4. Write a changelog. Summarize the commits since the last tag into plain text: ```bash diff --git a/docs/site/contributing/build-from-source.md b/docs/site/contributing/build-from-source.md index 2d23bbc5..fbcd3df2 100644 --- a/docs/site/contributing/build-from-source.md +++ b/docs/site/contributing/build-from-source.md @@ -30,5 +30,7 @@ effect immediately. For a normal install, see [Install Spacedock](../get-started first-officer and ensign agents from your checkout instead of the installed plugin. Edits to the repo are live. -The `next` branch is the development channel. It has no Homebrew release; use the -[Homebrew install](../get-started/install.md) for a stable build. +The `next` branch is the development channel. If you want the bleeding edge +without building from source, install the **edge channel** (`spacedock-edge`) +instead — it tracks `next` and ships through the same install path as stable. +For a stable build, use the [Homebrew install](../get-started/install.md). diff --git a/docs/site/get-started/install.md b/docs/site/get-started/install.md index e1257241..9bee4ee8 100644 --- a/docs/site/get-started/install.md +++ b/docs/site/get-started/install.md @@ -10,6 +10,10 @@ Pi. Install one of those first. brew install spacedock ``` + `brew install` also pulls in `agentsview` (it powers `/spacedock:survey`). + The optional sandbox, safehouse, is installed separately — see + [Sandboxing](../reference/sandbox.md). + === "Binary (macOS / Linux)" ```bash diff --git a/docs/site/reference/command-reference.md b/docs/site/reference/command-reference.md index dc917c84..235939de 100644 --- a/docs/site/reference/command-reference.md +++ b/docs/site/reference/command-reference.md @@ -2,6 +2,20 @@ The `spacedock` binary groups its subcommands into Launch, Setup, and Workflow, plus a top-level `spacedock --version` (the binary version and contract level). For the exact flags of any command, run `spacedock --help`, the always-current source of truth; `spacedock` with no arguments prints the grouped help. +## --version + +`spacedock --version` prints the version and contract level, the sandbox posture, then a per-runtime install/enablement line: + +``` +spacedock 0.20.0 (contract 1) +Sandbox: available, not enabled (no .safehouse profile) +claude: installed, spacedock enabled +codex: installed +pi: not installed +``` + +The `Sandbox:` line is one of `enabled (safehouse)`, `available, not enabled (no .safehouse profile)`, or `unavailable (safehouse not on PATH)`. Each runtime line reports whether the host binary resolves and, when it does, whether the spacedock plugin is enabled (`spacedock enabled`, bare `installed`, or `enablement unknown` when the enablement read is denied). + ## Launch `spacedock claude`, `spacedock codex`, and `spacedock pi` start a host with the first officer loaded. Claude Code is the primary surface; Codex and Pi are experimental. The grammar is the same for all three: @@ -12,6 +26,8 @@ spacedock claude [task] [spacedock-flags] [-- host-flags] The task comes first and becomes the launch prompt. Anything after `--` forwards verbatim to the host (`--model`, `--resume`, and the like). When no plugin is installed, the launcher auto-installs it and launches, so the single command yields a working session; a contract mismatch fails fast. The sandbox flags (`--safehouse` and its knobs) and the contract-gate flags are listed by `spacedock claude --help`. +An unsandboxed launch carries no safehouse isolation, so per-action permission prompting is friction without a matching safety gain: `spacedock claude` starts in `--permission-mode auto` and `spacedock codex` in `--ask-for-approval on-request`. A sandboxed launch instead skips/bypasses approvals (`--dangerously-skip-permissions` for claude, `--dangerously-bypass-approvals-and-sandbox` for codex) since the sandbox is the gate. Either posture is suppressed when you pass your own mode or a resume. + ## Setup | Command | What it does | @@ -19,7 +35,7 @@ The task comes first and becomes the launch prompt. Anything after `--` forwards | `spacedock install` | Install the per-host plugin, then run the compatibility check | | `spacedock doctor` | Run the compatibility check alone | -Both take `--host claude|codex|pi` (default `claude`). When `doctor` reports the plugin is out of date, refresh it with `spacedock install`. See [Install Spacedock](../get-started/install.md) for the full setup path. +Both take `--host claude|codex|pi` (default `claude`). When `doctor` reports the plugin is out of date, refresh it with `spacedock install`. When the plugin is still contract-compatible but a newer one is available, `doctor` and the front-door launch print an opt-in upgrade hint (`run spacedock install --host to refresh`); the hint never blocks the launch. See [Install Spacedock](../get-started/install.md) for the full setup path. ## Workflow From 26419af0e044eb8b833bc5b6082d333c0cc297cd Mon Sep 17 00:00:00 2001 From: CL Kao Date: Sat, 13 Jun 2026 12:15:09 -0700 Subject: [PATCH 3/3] docs: rewrite --version section to match version-forward output (#354) [yw] #354 (da) replaced the enablement-jargon per-runtime block with a version-forward one. Rewrite the `## --version` section to match: - `: spacedock ` when a plugin is installed - ` (disabled)` appended only when the host reports it disabled - `pi: spacedock ready` (pi launches from skills, no versioned plugin) - `: spacedock not installed` when host present but no plugin - `: not installed` when the host binary is absent Drops the obsolete "installed, spacedock enabled" / "enablement unknown" phrasing. Wording read from runtimeLine in internal/cli/host_runtime.go; example output built and exercised via `go build && ./spacedock --version`. Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/site/reference/command-reference.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/site/reference/command-reference.md b/docs/site/reference/command-reference.md index 235939de..4945de69 100644 --- a/docs/site/reference/command-reference.md +++ b/docs/site/reference/command-reference.md @@ -4,17 +4,17 @@ The `spacedock` binary groups its subcommands into Launch, Setup, and Workflow, ## --version -`spacedock --version` prints the version and contract level, the sandbox posture, then a per-runtime install/enablement line: +`spacedock --version` prints the version and contract level, the sandbox posture, then a per-runtime line reporting the installed spacedock plugin version: ``` -spacedock 0.20.0 (contract 1) +spacedock 0.20.1 (contract 1) Sandbox: available, not enabled (no .safehouse profile) -claude: installed, spacedock enabled -codex: installed -pi: not installed +claude: spacedock 0.20.1 +codex: spacedock 0.20.0 (disabled) +pi: spacedock ready ``` -The `Sandbox:` line is one of `enabled (safehouse)`, `available, not enabled (no .safehouse profile)`, or `unavailable (safehouse not on PATH)`. Each runtime line reports whether the host binary resolves and, when it does, whether the spacedock plugin is enabled (`spacedock enabled`, bare `installed`, or `enablement unknown` when the enablement read is denied). +The `Sandbox:` line is one of `enabled (safehouse)`, `available, not enabled (no .safehouse profile)`, or `unavailable (safehouse not on PATH)`. Each runtime line reads the plugin installed for that host: `spacedock ` when a plugin is installed (with ` (disabled)` appended only when the host reports it disabled), `spacedock ready` for pi (which launches from skills, not a versioned plugin), `spacedock not installed` when the host is present but carries no plugin, and `not installed` when the host binary itself is absent. ## Launch