Skip to content

docs: restructure quickstart with sbx cli as primary path - #42

Merged
wz-gsa merged 3 commits into
mainfrom
docs/improve-user-journey
May 27, 2026
Merged

wz-gsa merged 3 commits into
mainfrom
docs/improve-user-journey

Conversation

@wz-gsa

@wz-gsa wz-gsa commented May 27, 2026

Copy link
Copy Markdown
Contributor

Overview

Restructures the quickstart documentation to improve the user journey by:

  1. Making sbx CLI the recommended primary path (better for federal compliance, automation, audit trails)
  2. Creating dedicated guides instead of interleaving two approaches
  3. Adding comprehensive secret management documentation

Closes #41

Changes

Lean README.md (177 lines, down from 366)

  • Added 5-minute quickstart with sbx secret commands as primary copy-paste path
  • Linked to detailed guides instead of inline content
  • Removed interleaved Docker Desktop instructions
  • Focused on USAi endpoint configuration

New: docs/QUICKSTART_SBX.md (~350 lines)

Primary recommended path for federal users

  • Complete sbx CLI setup walkthrough
  • Full sbx secret tutorial with comparison tables
  • Why sbx secret is better than shell export (keychain, persistence, audit)
  • Supported services table (anthropic, github, openai, etc.)
  • Common commands reference
  • CI/CD automation section
  • Troubleshooting guide

New: docs/QUICKSTART_DOCKER_DESKTOP.md (~200 lines)

Alternative for GUI preference

  • Clear header recommending sbx CLI instead
  • Comparison table showing sbx CLI advantages
  • Notes that some features still require CLI
  • Guide for switching to sbx CLI method

Updated: docs/SBX_QUICKSTART.md

  • Added redirect header to focused guides
  • Kept comprehensive content as reference
  • Now clearly positioned as detailed reference (not quickstart)

Why sbx CLI as Primary?

Feature sbx CLI Docker Desktop UI
Secure secret storage (keychain) ✅ ❌
Full policy control ✅ Partial
CI/CD automation ✅ ❌
Audit trail ✅ Limited
Federal compliance ✅ Better ⚠️ Limited

Metrics

Metric Before After
README.md lines 366 177 (52% reduction)
Time to first working sandbox 10-15 min (reading) <5 min (copy-paste)
Secret management docs Minimal Comprehensive
Method confusion points 10 identified 0 (separated)

Testing

  • All internal links verified
  • Commands tested against sbx CLI v0.30.0
  • Markdown renders correctly
  • Pre-commit hooks pass

Related Issues

Closes #41

wz-gsa and others added 2 commits May 27, 2026 12:59
- Make sbx CLI the recommended primary path
- Add sbx secret commands to quickstart
- Link to detailed guides instead of inline content
- Remove Docker Desktop interleaved instructions
- Focus on USAi endpoint configuration
- Reduce from 366 to ~150 lines

Part of #41
- Create QUICKSTART_SBX.md as primary recommended path (~350 lines)
  - Full sbx secret tutorial with comparison tables
  - Comprehensive command reference
  - CI/CD automation section
  - Troubleshooting guide

- Create QUICKSTART_DOCKER_DESKTOP.md as GUI alternative (~200 lines)
  - Clear recommendation to use sbx CLI instead
  - Comparison showing sbx CLI advantages
  - Guide for switching to sbx CLI

- Update SBX_QUICKSTART.md with redirect header
  - Links to focused guides for faster start
  - Keeps comprehensive content as reference

Part of #41

Co-authored-by: OpenCode Agent <[email protected]>
@wz-gsa
wz-gsa requested a review from a team as a code owner May 27, 2026 17:04
@wz-gsa wz-gsa added documentation Improvements or additions to documentation enhancement New feature or request labels May 27, 2026
@wz-gsa wz-gsa changed the title docs: restructure quickstart with sbx CLI as primary path docs: restructure quickstart with sbx cli as primary path May 27, 2026
@mogul

mogul commented May 27, 2026

Copy link
Copy Markdown
Contributor

Thanks for tackling this... I was uncomfortable with how much text was involved and how much repetition there was on the critical path, but I wasn't prepared to tackle that yet. (There's still lots more work to do to reduce the latter point, but this is a big improvement!)

wz-gsa added a commit that referenced this pull request May 27, 2026
The subject-case rule was blocking valid commit messages containing
acronyms like CLI, API, SQL. The Conventional Commits specification
only mandates lowercase for the type field, not the subject.

- Disable subject-case enforcement (set to level 0)
- Document rationale in config comments
- Unblocks PR #42 which uses 'sbx CLI' in the title

Closes #43

Co-authored-by: OpenCode Agent <[email protected]>
@wz-gsa
wz-gsa merged commit 506fbb5 into main May 27, 2026
1 check passed
@wz-gsa
wz-gsa deleted the docs/improve-user-journey branch May 27, 2026 19:11
mogul added a commit that referenced this pull request Oct 2, 2026
…#526)

* fix(msb): pick a free host port per sandbox instead of defaulting to guest

The neutral publishedPorts parser defaulted an omitted `host:` to the guest
port, so every sandbox created from one kit requested the SAME host port. msb
accepts the duplicate mapping silently, so a second parallel sandbox started
clean and was simply unreachable — the first one owned the port and served all
host traffic for it.

The host column is now emitted VERBATIM (empty when the kit did not declare
`host:`) by both the neutral and the deprecated sbx-only parser: "asked for a
specific host port" and "left the host port to the backend" are different
intents and only the consumer can act on the difference. The msb adapter then
picks a FREE loopback port per sandbox for an empty column, and FAILS the create
when an explicitly requested host port is already taken rather than silently
substituting another one. Contention is probed against the real host listener
(bash /dev/tcp on the literal IPv4 loopback), not against msb's declared
mapping; an unprobeable shell warns once and publishes anyway.

Published-port records now accumulate across kits and are emitted once after the
kit loop, deduped by guest port (last wins) — mirroring the volumes union, and
giving a later CLI override one place to compose.

sbx is unaffected: its translator never re-emitted the host column, so an empty
column is the neutral spelling of the behavior sbx already had.

Refs: #334

* feat(acq): add --publish HOST:GUEST to choose a sandbox's host port

A kit's publishedPorts entry declares a guest port; acq picks the host side.
There was no way to say which host port at launch time, so parallel sandboxes
from one kit could not be given predictable, distinct addresses without editing
the kit spec (which would pin every sandbox to the same port).

`acq run/create --publish HOST:GUEST` (repeatable) now does that. The flag is
acq-owned and is stripped before dispatch — `msb create` has its own `-p`, which
the adapter synthesizes from kit records, and sbx has none — and, like the other
acq-owned flags, is honored only BEFORE the `--` separator, so an identical flag
meant for the inner agent passes through verbatim.

The override joins the published-port records after every kit's, so the guest-
keyed last-wins union makes it beat both a kit's pinned host port and the free
port acq would have chosen. A host port already in use fails the create; there is
no fallback to the post-hoc `msb ssh serve` + `ssh -L` tunnel, which reaches
guest loopback rather than the guest IP the create-time publish targets.

Both sides of HOST:GUEST are required: a bare port is ambiguous, and the guest
port belongs to the kit rather than to the launcher. Values are range-checked
before they reach a backend argv.

Two explicit refusals rather than silence:
  * on sbx, which assigns the host port itself and exposes no knob, the flag is
    an error naming `acq ports NAME --publish` as the post-hoc alternative;
  * on a re-attach, where the mapping is already fixed in the create argv, it
    prints the same "ignored when re-attaching" note as --image and --clone.

Refs: #334

* docs(ports): record host-port selection and --publish in ADR-0034

ADR-0034 captures both halves of the change and the reasoning that is not
obvious from the code: why an absent host column must stay absent, why a
contended port fails instead of moving, why the probe measures the real host
listener rather than the backend's declared mapping, why "cannot tell" publishes
with a notice rather than guessing either way, and why --publish is refused on
sbx and on a re-attach.

CONCEPTS gains a user-facing "Published Ports" section (read the mapping with
`acq ports`, pin it with `--publish`, the two limits). BACKEND_GUIDE notes the
per-sandbox host port under its msb ports limitation. KNOWN_FAILURE_MODES #42
documents the symptom as a user would hit it — two sandboxes, one reachable —
with the recreate-to-fix step, since the mapping is baked into the create args.
The acq how-to's command table was missing `acq ports` entirely.

Refs: #334

* fix(msb): report an unprobeable host for an explicitly requested port too

Review finding: the explicit-host branch treated only a `busy` verdict as
exceptional, so when the availability probe could not run at all, a kit's pinned
`host:` or a `--publish` override was emitted with rc 0 and no notice — the one
case where the caller NAMED the address, and therefore the case where a wrong
answer is most visible to them, was the silent one. It also contradicted the
visibility driver recorded in ADR-0034: a chosen port, a refused port, or an
"I could not tell".

The status is now captured once (no double probe) in a `case`, and `unknown`
reuses the same once-per-provision notice as the chosen-port branch, extracted
into _acq_msb_probe_unknown_notice so both branches share one implementation and
_acq_msb_port_flags_from_records stays within the 50-line limit. It still
proceeds rather than failing: the fail-loud rule is about measured contention,
not about a host acq cannot measure.

Flag position: the acq-owned run/create flags are recognized only AFTER the
subcommand. Placed before it they fall into the generic unknown-subcommand
passthrough and reach the backend CLI — pre-existing behavior shared by --clone
and --no-update-check, so this documents the restriction in the usage text and
ADR-0034 rather than making one flag inconsistent with its siblings. A
family-wide fix is tracked separately.

Docs corrections from the same review: ADR-0014's "when host is omitted it
defaults to guest" now carries a supersession note (its decision text is left
intact, per the repo's append-an-Update convention); ADR-0034 no longer promises
that msb fails loudly on a post-probe race, which the evidence in
KNOWN_FAILURE_MODES contradicts; and the tracker references that had landed in a
code comment and in ADR body prose are rewritten to state the fact and cite the
ADR, leaving the issue links only in the ADR's Links section.

Refs: #334

* docs(adr): cite the tracked follow-up issues in ADR-0034 Links

The flag-position entry carried a "to be filled in when filed" placeholder while
the issue did not exist yet; it now cites the filed issue, and the scaffolding
about who could post it is dropped — that was process chatter, not durable
content. The explanation of what the trap is and why it is tracked separately
from this change is unchanged.

Also records the lint-coverage gap found while writing this ADR: the markdownlint
glob is `docs/*.md`, so `docs/adr/` — this file included — is never checked, which
is why the ADRs in this change were linted by hand.

Refs: #334
Refs: #524
Refs: #525

* fix(msb): keep --publish pins out of the key check and refuse reused host ports

- The throwaway key-check sandbox now publishes no ports, so it no longer
  contends with the real sandbox for a --publish pin or a kit's pinned host:
  port (which failed its create and silently skipped the key check).
- A host port requested for more than one guest port in one create now fails
  loudly instead of handing msb two -p flags for it; a chosen free port also
  skips any host port the create already maps.
- `acq run NAME --publish ...` on an existing sandbox now says the flag is
  ignored, like the AGENT PATH re-attach path already did.

Refs: #526

* fix(msb): split the explicit-host check out of the port mapper

The reused-host-port check pushed _acq_msb_port_flags_from_records past the
50-line function limit. Move the explicit-host checks (already mapped in this
create, busy on the host, unprobeable) into _acq_msb_explicit_host_ok; behavior
is unchanged.

Also mark the two array assignments in the key-check test as consumed by the
sourced provision (SC2034), matching the file's existing pattern.

Refs: #526

---------

Co-authored-by: Bret Mogilefsky <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

docs: restructure quickstart user journey with sbx CLI as primary path

2 participants