Skip to content

Clean-machine install and offline run

SM-RDEP-001 E3-S3-WP3. Its acceptance test: "Every plugin installs from the marketplace and runs offline." This runbook installs the four plugins into an empty Claude Code configuration, cuts a scratch engagement repository, makes Rosetta unreachable, and runs one short check per plugin. Allow about an hour and a half; the archaeology phases take most of it.

Each run is recorded in results/ (step 8). The first is results/install-offline-2026-10-16/install-offline.md. The manifest asks for a second person to run it, on their own machine and login.

What "offline" means here

  • No MCP server in any session.
  • No route to Rosetta. api.rosetta-design.com and the other Rosetta hosts do not answer.
  • No ROSETTA_* environment variable is set.

The plugins still need the Claude API, and the install needs git access to this repository or its mirror. Neither is Rosetta.

Before you start

You need Notes
Claude Code Note your version (claude --version). The first run used 2.1.289
git access to the library For GitHub, run gh auth login and then gh auth setup-git, once. For the GitSoma mirror, its clone URL and your credentials
A ref that has all four plugins A release tag after v0.1.0. v0.1.0 carries only rosetta-knowledge and rosetta-d360-builder. Until the next tag, use main; the archaeology run then names the release in rosetta.yaml (v0.1.0), because that line moves only at a release
Admin rights on the machine To block the Rosetta hosts (step 1)

Use one shell for the whole test. Set these first; every command below runs in that shell:

export REF=main                       # or the release tag under test
export T="$HOME/rdep-install-test"    # a new folder; step 7 deletes it

1. Make Rosetta unreachable

  1. Block the Rosetta hosts. Add this line to /etc/hosts (it needs sudo):
0.0.0.0 api.rosetta-design.com rosetta-design.com docs.rosetta-design.com

On macOS, also flush the DNS cache: sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder.

  1. Check it.
curl -sS -m 10 https://api.rosetta-design.com/ ; echo "exit $?"

A non-zero exit, with no HTTP response, passes. Any HTTP response fails: fix the block before going on.

  1. Unset every Rosetta variable. List them:
env | cut -d= -f1 | grep -i rosetta

unset each name it prints, then list again. It must print nothing.

2. Install into an empty Claude Code configuration

mkdir -p "$T/claude-config" "$T/empty"
export CLAUDE_CONFIG_DIR="$T/claude-config"

CLAUDE_CONFIG_DIR points this shell's Claude Code at a new, empty folder: no settings, plugins, MCP servers or login. Your normal configuration is not touched.

claude plugin marketplace add "vernonkeenan/rosetta-deploy@$REF"
claude plugin install rosetta-knowledge@rosetta-deploy
claude plugin install rosetta-d360-builder@rosetta-deploy
claude plugin install rosetta-archaeology-deploy@rosetta-deploy
claude plugin install engagement-codex-deploy@rosetta-deploy
claude plugin list

From the GitSoma mirror, the first line is claude plugin marketplace add "<mirror clone URL>#$REF". "SSH not configured, cloning via HTTPS" is normal.

Pass when every command succeeds and claude plugin list shows all four plugins, each ✔ enabled, at the versions that .claude-plugin/marketplace.json gives at $REF. Then check the installed copies:

C="$CLAUDE_CONFIG_DIR/plugins/cache/rosetta-deploy"
ls "$C"                                          # the four plugin folders
find "$C" -type l | wc -l                        # 0: the library was copied, not linked
grep gitCommitSha "$CLAUDE_CONFIG_DIR/plugins/installed_plugins.json"   # the commit under test

Each plugin's own files are in $C/<plugin>/<version>/. You need those folders in step 5.

3. Cut the engagement repository

The engagement plugins run inside an engagement repository: a clone of this library cut from a release, with the engagement in customer/<customer>/ (see customer/_template/README.md). For the test, a local clone that is never pushed is enough. The engagement is fictional: Larkspur Cycles, whose one-page dossier is evals/install-smoke/discovery-notes.md.

git clone --branch "$REF" https://github.com/vernonkeenan/rosetta-deploy.git "$T/engagement"
cd "$T/engagement"
git switch -c engagement
git remote rename origin upstream
git remote set-url --push upstream DISABLED-test-clone-never-pushes
cp -R customer/_template customer/larkspur
cp evals/install-smoke/discovery-notes.md customer/larkspur/project-docs/
printf '# Larkspur Cycles\n\nFictional, for an install test. Never pushed.\n' > customer/larkspur/README.md
git add customer/larkspur
git commit -m "test: Larkspur Cycles baseline (fictional)"

A real engagement follows customer/_template/README.md instead: a private repository on GitSoma, with this library as upstream.

4. Start Claude Code with no MCP servers

Start every session in this test the same way:

claude --strict-mcp-config

--strict-mcp-config with no server list means no MCP server at all, including claude.ai connectors. The first start in the new configuration asks you to log in: do. Then run /mcp; it must show no servers.

End each session with /exit before you change folders.

5. Check each plugin

Write down, for each check, every permission prompt Claude Code shows: what it asked, and what you chose. Deny any prompt to run a shell command or fetch a URL; a plugin that asks for one fails this test. The one exception is printenv ROSETTA_DEPLOY_ROOT, from rosetta-knowledge. Press ctrl+o to see each tool call.

5.1 rosetta-knowledge: one question

In $T/empty (cd "$T/empty", then start Claude Code):

/rosetta-knowledge:ask When should Data 360 federate a Snowflake table instead of ingesting it?

Pass when the answer cites a library file and id for each claim, as in ADR/ADR-G-003.md (ADR-G-003), ends with a Status: line, and reads only files under $C/rosetta-knowledge/<version>/. The skill's allowed-tools cover its reads, so a headless run needed no approval; note whether you saw a prompt.

5.2 rosetta-d360-builder: it loads and stops

The builder's skills run on a Data 360 MCP server's d360_* tools, against a sandbox org. With no MCP server, a skill must load and then stop at its tooling gate. Still in $T/empty:

/rosetta-d360-builder:customer-360-foundation Walk me through the Customer 360 foundation build in my sandbox org. Gates P-1 to P-4 are settled: the home org is decided, this source is a CRM ingest, the data space exists, and the consumption budget has an owner.

Pass when it stops at Gate P-5 because the d360_* tools are not connected, and calls no tool. Skipped: the build itself. It needs a Data 360 MCP server and a sandbox org, and a skill's sandbox smoke is recorded in Rosetta's verification ledger, not here (MAINTAINING.md, E3-S2-WP1).

5.3 rosetta-archaeology-deploy: Phases 1 to 3

In the engagement repository (cd "$T/engagement", then start Claude Code):

/rosetta-archaeology-deploy:survey larkspur-01 ENGAGEMENT_DIR=customer/larkspur --autonomous

Allow it to read its own folder. Early in Phase 1, Claude Code asks to read a file under $C/rosetta-archaeology-deploy/<version>/skills/digital-twin-archaeology/. Allow it, for the whole folder if that is offered. Or add the folder first, with /add-dir and the folder's full path. Refused, the run stops before Phase 1 and writes nothing, as designed.

--autonomous drafts the authored fields without stopping to ask you; for a real engagement, leave it off.

An interactive session also loads the repository's root CLAUDE.md. Its customer-data rule now says that an engagement repository's customer work goes under customer/<customer>/. In the first run, before it said so, Phase 1 named the rule, took the clone for the engagement's own repository, and wrote the name. Note what yours does: whether it asks, refuses or carries on.

Pass when its last message reports the Phase 1 gate passed and customer/larkspur/archaeology/MANIFEST.md records it. Then, in the same session:

/rosetta-archaeology-deploy:excavate larkspur-01 ENGAGEMENT_DIR=customer/larkspur --autonomous
/rosetta-archaeology-deploy:classify larkspur-01 ENGAGEMENT_DIR=customer/larkspur --autonomous

Pass when each reports its gate passed. Phase 3 writes archaeology/twin.json and the drafts in customer/larkspur/CP/ and customer/larkspur/ADR/. Phase 4 (preserve) is not needed here.

5.4 engagement-codex-deploy: the audit render

In the same session, or a new one in $T/engagement:

/engagement-codex-deploy:solution-thesis-render ENGAGEMENT_DIR=customer/larkspur TONE=audit

Allow the read of its own folder, $C/engagement-codex-deploy/<version>/, as in 5.3. Pass when it writes customer/larkspur/deliverables/solution-thesis.audit.md and a row in deliverables/RENDER-LOG.md, and cites each library file by path and id.

5.5 After the checks

cd "$T/engagement"
git status --porcelain -- . ':!customer/larkspur'    # must print nothing
curl -sS -m 10 https://api.rosetta-design.com/ ; echo "exit $?"

Pass when nothing outside customer/larkspur/ changed and Rosetta is still unreachable.

6. Headless runs (maintainers)

A claude -p run cannot answer the folder-read prompt, so it needs --add-dir with the plugin's own folder (found 2026-10-16). Each check in the first run was:

claude -p "<the command from step 5>" \
  --plugin-dir "$C/<plugin>/<version>" --add-dir "$C/<plugin>/<version>" \
  --setting-sources "" --strict-mcp-config --no-session-persistence \
  --permission-mode acceptEdits --tools "Read,Write,Edit,Glob,Grep,Skill"
  • rosetta-knowledge adds Bash to --tools for its printenv and needs no --add-dir; rosetta-d360-builder needs only Read,Glob,Grep,Skill.
  • --plugin-dir loads the installed copy, byte for byte, under the machine's own login: the new configuration has none, and copying a login into it risks the original's refresh token (as in E3-S1-WP1's install-read.md).
  • --setting-sources "" also skips the repository's CLAUDE.md, which an interactive session loads. Load it with --setting-sources project.
  • The first run also routed every connection through a logging proxy that refused the Rosetta hosts, and traced every connect(); its record says how.

7. Clean up

  • Remove the /etc/hosts line (on macOS, flush the DNS cache again).
  • rm -rf "$T", then close the shell, or unset CLAUDE_CONFIG_DIR REF T C.

8. Record the run

Add results/install-offline-<YYYY-MM-DD>-<your handle>/install-offline.md in a pull request, with:

  • your Claude Code version and OS, $REF and the gitCommitSha from step 2;
  • each step's result, pass, fail or skip, with a line of evidence;
  • every permission prompt, in its own words, and your answer;
  • anything that surprised you.

Leave the engagement's files out: the record holds the evidence, not the twin. Keep the dossier's names as they are, all fictional, and add no real customer or person anywhere (C-5).

This page as Markdown — for pasting into Claude or another assistant · llms.txt