Skip to content

spacedock codex/claude front-door launch UX — honest auto-install message + pre-launch workflow banner#336

Merged
clkao merged 6 commits into
nextfrom
spacedock-ensign/frontdoor-launch-ux
Jun 8, 2026
Merged

spacedock codex/claude front-door launch UX — honest auto-install message + pre-launch workflow banner#336
clkao merged 6 commits into
nextfrom
spacedock-ensign/frontdoor-launch-ux

Conversation

@clkao

@clkao clkao commented Jun 8, 2026

Copy link
Copy Markdown
Collaborator

Make the spacedock codex/claude front door honest and useful: truthful auto-install messaging and a pre-launch banner that names the real workflow.

What changed

  • A: move the NoPluginFound message to the caller — Installing the {host} plugin… on auto-install, a host-correct remedy on --no-install (no hardcoded claude).
  • B: add a pre-launch banner that names the repo's real workflow from any launch dir, pruning agent/linked-worktree copies via .gitignore patterns + a nested-.git-checkout skip (shared with status --discover).
  • Delete the false requires-contract doctor note; add .safehouse + .claude/ to .gitignore.

Evidence

  • Real front-door live drive: banner names docs/dev from any dir and --discover agrees; honest install message; go test ./... 1209/1209 green.
  • Detached audit found one test-strength hole (the nested-checkout prune untested in isolation) → closed by TestDiscoverWorkflowsSkipsNestedCheckout (proven reds-on-neuter); re-validation confirmed.

yq

clkao and others added 6 commits June 8, 2026 15:59
…bootstrap prompts

A — move the NoPluginFound remedy ownership from gateHost to the caller. gateHost
stops printing for both NoPluginFound paths (empty + phantom manifest) and keeps
the always-fail-fast prints (resolve-error, mismatch). The caller now announces
`Installing the {host} plugin…` before ops.Install on the auto-install arm and a
host-correct noPluginRemedy(host) on the --no-install refuse arm — a codex run
never names `claude`.

B — launchBanner(host, dir, w) over status.DiscoverWorkflowDir: version line +
detected-workflow rel path (else "none detected (launching anyway)") + one
orientation line, emitted to stderr before the host launches in both launchers,
suppressed on --resume / codex resume.

D — neutral bootstrap prompts: drop the personal/relay flavor from both consts;
keep the load-bearing codex `Assume $spacedock:first-officer` clause. The two
test-file oracle copies are updated to the same new literals (independent source)
with added absence (no personal text) and FO-clause-presence assertions.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The launchBanner workflow line read the workflow dir relative to the launch dir
(cwd), but DiscoverWorkflowDir walks UP — so it only ever returns the cwd or an
ancestor, making the rel path always `.`/`..` and defeating the banner's purpose
(orient the operator to WHICH workflow). Render it relative to the enclosing git
repo root instead (workflowLabel over status.FindGitRoot), so a workflow at
<repo>/docs/dev reads `Workflow: docs/dev` from anywhere inside it. Fall back to
the workflow dir's base name when there is no enclosing `.git` (or it is the repo
root) — never `.`/`..`. The AC-B oracle is corrected to match: the fixture places
the commissioned workflow at a known repo-relative location under a temp `.git`
and asserts the banner names that path, plus a no-`.git` fallback case.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…o's real workflow

Captain-directed (two live-run findings):

1. Revert D — restore the original personal launch prompts. Both consts and their
   two test-file `want*BootstrapPrompt` oracle copies go back to the shipped text
   ("You totally got this. … I love you. … Engage."), the codex one keeping its
   `Assume $spacedock:first-officer` clause. The neutral-prompt absence assertions
   are dropped — a neutral default is no longer a deliverable.

2. Fix the banner's workflow detection. It walked UP (DiscoverWorkflowDir), so from
   the repo root it missed the `docs/dev` subdir and read "none detected"; and the
   downward `--discover` walk multiplied the one real workflow by the dozens of
   agent/linked-worktree copies (each a full checkout carrying a `docs/dev`). Now
   the banner scans the enclosing git repo downward (status.DiscoverWorkflows) and
   names the single real workflow relative to the repo root (`docs/dev`) from ANY
   launch dir; two or more report the count + a `spacedock status` pointer; outside
   a repo a bounded walk-up still names a workflow at/above the dir; never `.`/`..`.

   The discovery noise is pruned host-neutrally: discoverWorkflows now skips any
   descended dir carrying its own `.git` (a nested checkout / linked-or-agent
   worktree whose workflows are copies), so the FO's `status --discover` boot and
   the banner agree on the one real workflow — without hardcoding a host-specific
   `.claude` path (which the host-neutrality oracle forbids in internal/status).
   DiscoverWorkflows is exported for the cli banner to share the same walk.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…nested-checkout skip

Captain's preferred mechanism for the discovery-noise exclusion: gitignore, not a
hardcoded list. Add `.safehouse` and `.claude/` to the repo .gitignore (untracked
agent/sandbox dirs). discoverWorkflows already reads the root .gitignore's directory
patterns (readGitignoreDirBasenames), so `.claude/` now prunes the agent-worktree
`docs/dev` copies under .claude/ — the exclusion is data, not code. The nested git
checkout skip (a dir with its own `.git`) stays for `.worktrees/*` and any other
nested checkout. Together they resolve the single real top-level `docs/dev`.

The AC-B fixture and the status discovery test now plant their noise copies under a
gitignored path (the `.claude` copy, no `.git`) and a nested-checkout path (the
`.worktrees` copy, with a `.git` gitlink), so the tests prove the EXCLUSION MECHANISM
rather than a hardcoded skip; a new TestDiscoverWorkflowsHonorsGitignoreDirPattern
isolates mechanism (a) with an arbitrarily-named ignored dir.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude Code's runtime loads plugins silently and does NOT warn on unknown
plugin.json fields at load time — only `claude plugin validate` flags them
(non-blocking, dev-time). The Compatible-arm note excused a runtime warning that
does not exist, so it was pure noise on `spacedock doctor`. Delete it; the OK
verdict line stands alone. requires-contract stays in the manifests as the clean
single-source spot (the runtime is silent), not moved to a sidecar.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…name mask

The adversarial audit found a test-strength hole: every nested-checkout fixture
sites its copy under .worktrees/…, but discoverIgnoreDirs ALSO prunes .worktrees
by hardcoded basename — so the basename rule masks hasGitEntry. Neutering
hasGitEntry to `return false` left every test green, so a future refactor deleting
it would pass CI and silently regress the banner + `status --discover` back to
dozens of workflow copies.

Add TestDiscoverWorkflowsSkipsNestedCheckout: the noise copy lives under
submods/checkout-z (a dir name in NEITHER discoverIgnoreDirs NOR .gitignore) with a
.git gitlink, so ONLY hasGitEntry can prune it. Verified the test reds when
hasGitEntry returns false and greens when restored. No production change.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
clkao added a commit that referenced this pull request Jun 8, 2026
@clkao clkao merged commit 0b5dad5 into next Jun 8, 2026
4 of 7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant