init-4818bf — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited init-4818bf (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Entry point for a migration. Runs ONCE per run. This skill is pure bootstrap plus the two init-owned user gates (G-INPUT, G-OUTPUT). It scaffolds the run directory via bin/state.sh init, copies the shipped connector/selectors/config/instruction templates into the run dir, records the two answers into state.decisions/state.input/state.output, then hands control to the run controller via the Skill tool. It never advances the pipeline past init itself - run owns every step transition.
Before any work:
ultra skill is available in this session. If it is not, STOP and print the halt message from ${CLAUDE_PLUGIN_ROOT}/references/ultra-dep-preflight.md verbatim. Do NOT create files or edit state - set nothing, advance nothing. On Claude Code v2.1.110+ the dependency auto-installs via plugin.json dependencies, so this is normally a no-op; it is a safety net for older Claude Code and --plugin-dir dev loads.${CLAUDE_PLUGIN_ROOT}/references/node-playwright-preflight.md verbatim and STOP without scaffolding.Both halts are belt-and-suspenders: it is far cheaper to halt here than after the user has invested time editing config and connectors.
/claude-migrate:init [<run-name>]
Where <run-name> is a slug matching ^[A-Za-z0-9_-]+$ (e.g. old-to-new-2026). If omitted, derive a default slug from the date (e.g. migration-2026-06-02) and confirm it with the user before scaffolding.
$ARGUMENTS as the run-name.migration-YYYY-MM-DD).^[A-Za-z0-9_-]+$. If it does not, print usage and exit - state.sh enforces the same allowlist and would reject it anyway (path-traversal defense).Create the full run-dir tree and the §3.2 state.json schema in one call:
bash ${CLAUDE_PLUGIN_ROOT}/bin/state.sh init <run-name>This writes .planning/claude-migrate/<run-name>/ with state.json (status=pending, current_step=init, default profile tier large, all counters zeroed), the work-queue tree (units/{pending,in-progress,done,failed,dropped}/, value/, briefs/, project/, seed/{pending,in-progress,done,failed}/, apply/, out/payloads/, validation/, checkpoints/, state/requeue-archive/), and the run-dir .gitignore (§3.8). If state.sh exits code 2 (run already exists), STOP with: "Run <run-name> already exists - pick a different name or delete the existing run dir, then resume with /claude-migrate:resume <run-name>."
Capture the printed run path:
RUN_PATH=".planning/claude-migrate/<run-name>"Copy the static templates the pipeline reads. These are copied (never symlinked) so a /plugin update cannot wipe a user's in-run edits:
cp ${CLAUDE_PLUGIN_ROOT}/templates/config.yaml.template "$RUN_PATH/config.yaml"
cp ${CLAUDE_PLUGIN_ROOT}/templates/selectors.json.template "$RUN_PATH/selectors.json"Substitute {{RUN_NAME}} with the run name in both copies (Read the file, replace, Write back). Do NOT copy a connector yet - that depends on G-INPUT / G-OUTPUT below.
Ask exactly one question. Header: "Where is your source?"
input.mode = "export".input.mode = "live".Persist the choice:
bash ${CLAUDE_PLUGIN_ROOT}/bin/state.sh set "$RUN_PATH" .input.mode <export|live>If the user chose export, ask for the absolute path to the unzipped export folder and store it:
bash ${CLAUDE_PLUGIN_ROOT}/bin/state.sh set "$RUN_PATH" .input.export_path "<abs-path>"Then stage the source landing dir WITHOUT copying users.json (PII - see ${CLAUDE_PLUGIN_ROOT}/references/pii-policy.md): copy conversations.json, projects/, and memories.json (if present) into $RUN_PATH/source/. users.json is read for an account-hash sanity check ONLY by the parser and is never copied, written, or logged.
Now copy the matching SOURCE connector template (copy-first; the user may edit it):
# export mode:
cp ${CLAUDE_PLUGIN_ROOT}/templates/sources/export-file.md "$RUN_PATH/source-connector.md"
# live mode:
cp ${CLAUDE_PLUGIN_ROOT}/templates/sources/browser.md "$RUN_PATH/source-connector.md"Ask exactly one question with exactly two options (no both value - UX H-2). Header: "How should I apply the migration to the NEW account?"
output.mode = "auto".output.mode = "copy-page".Persist the mode AND the active-choice flag (UX H-3 - user_chose_auto=true ONLY when AUTO was ACTIVELY selected, never on Enter-on-default):
bash ${CLAUDE_PLUGIN_ROOT}/bin/state.sh set "$RUN_PATH" .output.mode <auto|copy-page>
# only if the user actively selected AUTO (not Enter-on-default):
bash ${CLAUDE_PLUGIN_ROOT}/bin/state.sh set "$RUN_PATH" .output.user_chose_auto trueCopy the matching SINK connector template (the copy-page sink is ALWAYS the reliable floor and is referenced in both modes):
cp ${CLAUDE_PLUGIN_ROOT}/templates/sinks/copy-page.md "$RUN_PATH/sink-connector.md" # copy-page mode
cp ${CLAUDE_PLUGIN_ROOT}/templates/sinks/browser.md "$RUN_PATH/sink-connector.md" # auto modeAlso copy the two project-instruction templates the synthesize step will consume:
cp ${CLAUDE_PLUGIN_ROOT}/templates/instructions/project-instructions-migration.md "$RUN_PATH/.tmpl-instructions-migration.md"
cp ${CLAUDE_PLUGIN_ROOT}/templates/instructions/project-instructions-steady.md "$RUN_PATH/.tmpl-instructions-steady.md"bash ${CLAUDE_PLUGIN_ROOT}/bin/state.sh checkpoint "$RUN_PATH"G-INPUT and G-OUTPUT are the only user gates init owns. Every later gate is owned by confirm, and every step transition is owned by run. Invoke the run controller via the Skill tool (it carries user-invocable: false; the Skill tool may invoke it - ultra precedent), passing the run name verbatim:
Invoke skillclaude-migrate:runwith argument<run-name>.
run will drive pre-split-gate (/ultra GATE 1), split, and preflight, then BLOCK at filter-gate and print "run /claude-migrate:confirm <run-name>". Print a concise summary to the user before handing off:
Initialized run: <run-name>
Location: .planning/claude-migrate/<run-name>/
Source: <export | live>
Output: <AUTO browser + copy page | copy page only>
Handing off to the controller; you will be asked to confirm what migrates shortly.users.json into the run dir, write it, or log its contents - read it for the account-hash sanity check only (PII; references/pii-policy.md).init; run owns all step transitions. init only scaffolds, asks G-INPUT/G-OUTPUT, and hands off.state.sh init exit 2 means STOP and tell the user to pick another name or resume.state.json outside bin/state.sh.output.user_chose_auto = true ONLY when AUTO was actively chosen, never on Enter-on-default (the demote rules at G-OUTPUT depend on this distinction).config.yaml, not hardcoded.~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.