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.comand 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¶
- Block the Rosetta hosts. Add this line to
/etc/hosts(it needssudo):
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.
- 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.
- 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-knowledgeaddsBashto--toolsfor itsprintenvand needs no--add-dir;rosetta-d360-builderneeds onlyRead,Glob,Grep,Skill.--plugin-dirloads 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 inE3-S1-WP1'sinstall-read.md).--setting-sources ""also skips the repository'sCLAUDE.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/hostsline (on macOS, flush the DNS cache again). rm -rf "$T", then close the shell, orunset 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,
$REFand thegitCommitShafrom 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