Port a custom assistant (a Gemini Gem, a custom GPT, a Claude Project, or a long custom-instructions setup) into a portable SKILL.md skill that still works. Use when migrating, exporting, or rescuing an assistant off its platform, when a platform migration lands it as an inactive draft, or when you need an inventory, a tool-gap map, rewrite rules, and a parity test set with a gap log instead of a silent copy-paste.
name: "assistant_skill_porting" description: "Port a custom assistant (a Gemini Gem, a custom GPT, a Claude Project, or a long custom-instructions setup) into a portable SKILL.md skill that still works. Use when migrating, exporting, or rescuing an assistant off its platform, when a platform migration lands it as an inactive draft, or when you need an inventory, a tool-gap map, rewrite rules, and a parity test set with a gap log instead of a silent copy-paste."
Assistant Skill Porting
Purpose
Move a custom assistant off the platform that hosts it and into a portable skill folder, without losing the jobs it actually does. A platform copy is not a port. Instructions copy cleanly, knowledge files move with work, and tools often do not move at all. This skill forces the difference into the open: inventory first, map every dependency, rewrite into plain portable steps, then prove parity with a test set and log every gap that remains.
Use it for a Gemini Gem, a custom GPT, a Claude Project, or a single long custom-instructions blob that has grown into several jobs. Do not use it to build a brand new skill from scratch with no source assistant. There is nothing to port in that case.
Workflow
1. Freeze the source before you touch it
- Copy the source exactly as it runs today, not as you remember it. For a custom GPT, open the Configure view and copy name, description, instructions, conversation starters, the knowledge file list, the capabilities toggles, the recommended model, and every action. For a Gem, open Edit and copy name, the full instructions text, and the Knowledge file list. For a Claude Project, copy the project instructions and the knowledge list. For custom instructions, copy both fields in full.
- Save the original files themselves, not just their names. In a custom GPT the knowledge limit is 20 files at up to 512 MB each, and the platform holds the only copy for many builders. Download or locate the original of each file before any migration step. A file name in a list is not a backup.
- Publish or save any pending draft first if you plan to use a platform migration as a starting point. OpenAI migration uses the latest published version of a GPT only. Drafts and unpublished edits do not transfer, and the original becomes read only after migration.
- Record the source state on the inventory sheet in
assets/inventory-sheet.md. One sheet per assistant. Do not start rewriting until the sheet is complete.
2. Inventory what the assistant actually does
- List jobs, not features. Read the instructions and write down each distinct job in plain verbs: triage a support ticket, draft a reply in house style, look up an order, score a lead. A job counts if a real user asks for it on a normal week.
- For each job, note the inputs it needs, the output it must produce, and one real example prompt that triggers it. Pull examples from conversation starters and from real chats where you have them. Invented examples hide the hard cases.
- Separate the source into four piles and keep them separate on the sheet: behaviour (persona, tone, rules, workflow steps), reference material (knowledge files and pasted reference text), tools (built in capabilities, apps, actions, code execution), and presentation (conversation starters, output formats, file outputs).
- Apply the source platform test to every paragraph of instructions: behaviour belongs in instructions, reference material belongs in files. OpenAI and Google both state this split for GPTs and Gems, and ports fail most often when rules are buried inside a knowledge file or facts are hard coded into instructions.
- Flag hidden behaviour. Long instruction blocks often contain a second assistant: a formatting rule that only fires on one job, a refusal rule, a lookup table pasted inline. Give each one its own line on the sheet so the rewrite step can place it on purpose.
3. Map every tool and file to the target runtime
- Build the tool-gap mapping table before writing any skill text. One row per dependency. Use the table in
references/source-platform-fields.md as the starting map and adjust it to the target runtime in front of you.
- Classify each row with one of four verdicts. Direct: the target has the same capability under any name. Substitute: a different target tool does the same job with a changed step. Degraded: the job still completes but slower, with less data, or with a human step in the middle. Blocked: no target path exists today.
- Treat custom GPT actions as blocked by default until proven otherwise. An action is defined by an OpenAPI schema in JSON or YAML plus authentication of none, API key, or OAuth. OpenAI platform migration does not transfer custom actions at all, and rebuilding one may require a custom MCP server and technical setup. A skill folder alone does not recreate an API call. Write the replacement as a named connector, MCP server, or script step, or log it as a gap.
- Treat built in capabilities the same way. Web search, image generation, canvas or artifact editing, and code interpreter style data analysis are toggles on the source. None of them travel inside instruction text. Each one needs a target tool row.
- Map each knowledge file to one of three homes. Small and always needed: summarise the load bearing facts into the skill body and keep the file in
references/. Large or sometimes needed: place the file in references/ and name the exact step that reads it. Output shaping material such as templates, letterheads, and example outputs: place it in assets/.
- Never carry a secret across. API keys, OAuth client secrets, and tokens from an action config stay out of the skill folder, out of scripts, and out of the gap log. Record only the auth type and the service name. The replacement gets its credential through the target runtime normal credential flow.
4. Rewrite platform instructions into portable steps
- Write the target folder to the Agent Skills specification. The folder name matches the frontmatter
name: 1 to 64 characters, lowercase letters, numbers, and hyphens only, no leading, trailing, or double hyphens. The description is 1 to 1024 characters and states what the skill does and when to use it, with the trigger words a user would actually say.
- Keep
SKILL.md under 500 lines and under about 5,000 tokens of body text. Move long reference material into references/ and keep file references one level deep from SKILL.md. The target loads name and description first, the body on activation, and resource files only when a step calls for them, so a bloated body taxes every run.
- Convert persona prose into job steps. A Gem instruction built on Persona, Task, Context, and Format, or a GPT instruction block written as one long paragraph, becomes numbered workflow steps in the port. Keep the persona in two or three lines at the top. Turn the rest into verbs: gather this input, check this rule, produce this section, stop and ask when this is missing.
- Rewrite platform names out. Replace phrases like use your knowledge files, use browsing, or use the action with the concrete target step: read the price list file stored in the references folder, search the web and cite the source page, or run the named script with these arguments. If a sentence only makes sense on the source platform, it is not ported yet.
- Preserve prohibitions as testable rules. Rewrite a vague do not be verbose into a checkable limit, for example keep the summary to five bullets or fewer and put detail in an appendix file. Keep the source positive phrasing habit: state what to do, and keep bans short and specific.
- Split a multi job assistant into one skill per job when the jobs trigger on different requests. A single global custom-instructions set applies to every chat, which is why it misfires. One skill per job, each with its own description, is the gain from porting. Keep a shared
references/ file only when two skills genuinely read the same source file, and note the sharing on both inventory sheets.
- Turn conversation starters into parity prompts, not decoration. They are the most honest record of what users were told the assistant does, so they seed the test set in the next step.
5. Run the parity test set against the original
- Build the test set before you declare the port done. Minimum 12 cases: every conversation starter, one normal case per job, one case that needs a knowledge file, one case that needed a tool on the source, one refusal or out of scope case, and one hard case the source sometimes gets wrong.
- Run each case on the original assistant first while it still runs, and save its output verbatim. Then run the same prompt, word for word, against the port in the target runtime. Never grade from memory of what the original usually says.
- Score each case with the rubric in
assets/parity-test-set.csv: pass means same job done, same required sections, same facts from the same reference material, format within the stated limits. Partial means the job completed with a named loss. Fail means the job did not complete, a required fact was missing or invented, or the format broke the contract.
- Score it with the bundled script instead of by eye:
python3 scripts/parity_score.py assets/parity-test-set.csv
The script reports pass, partial, and fail counts, lists every non pass with its gap note, and exits non zero if any case fails or if any partial has no gap note. Ship gate: zero fails, and every partial has a gap log entry the owner has accepted.
- Validate the folder itself before testing behaviour:
python3 scripts/check_skill.py .
It checks the frontmatter rules from the specification, the folder name match, the line count, and that every file referenced from the body exists one level deep.
- Fix instruction problems in the instructions, not by adding tools. OpenAI makes the same point for GPT editing: tighten instructions and add examples before adding more tools. In porting terms, a parity fail caused by a missing example gets a worked example in the body or in
references/, not a new dependency row.
6. Log gaps and hand over as a draft
- Write the gap log as you go, using
assets/gap-log.md. One entry per degraded or blocked row and per parity partial or fail: what the source did, what the port does instead, who is affected, and the fix path or the accepted loss. A gap with no entry counts as a dropped feature, even if the drop was reasonable.
- Land the port as an inactive draft first. Install or publish it in a state where the owner can enable it after reading the gap log, not as a live replacement. Platform migration lands the same way: a migrated plugin starts private and does not install itself or give the old audience access. Match that caution on any target.
- Hand over four files: the inventory sheet, the mapping table, the parity results, and the gap log, alongside the skill folder. The owner signs off on the gap log, not on a claim that the port is identical. No honest port of a tool using assistant is identical.
Output Contract
A finished port delivers all of the following:
- A skill folder that passes
scripts/check_skill.py with no errors: SKILL.md plus any scripts/, references/, and assets/ the jobs need, and no secrets anywhere in the folder.
- A completed inventory sheet listing every job, input, output, example prompt, knowledge file, capability, app, and action found on the source, including the ones that did not port.
- A tool-gap mapping table with a verdict of direct, substitute, degraded, or blocked for every dependency row, and a named replacement or a gap entry for every row that is not direct.
- A parity test set of at least 12 cases with the original output saved, the port output saved, a score per case, and the scorer output showing zero fails.
- A gap log covering every degraded or blocked dependency and every partial or failed case, each with an owner accepted outcome: fix planned, substitute accepted, or loss accepted.
Operating Rules
- Never edit the source assistant to make the port look better. Freeze it, test against it as it is, and note source flaws on the inventory sheet. Improving the assistant is a separate job after the port lands.
- Never claim a tool carried over because the instruction text mentions it. A capability exists in the port only when a target tool, connector, MCP server, or script step is named and tested.
- Never grade parity on tone alone. A port that sounds right but drops a knowledge file fact or a required output section has failed the case.
- Keep facts from knowledge files traceable. When the port summarises a large file into the body, keep the original file in
references/ and name it in the step, so a later editor can check the summary against the source.
- Respect the retirement clock when one exists. Custom GPTs retire on December 11, 2026 on the standard schedule, and on February 11, 2027 for FedRAMP workspaces and Enterprise workspaces with an approved deferral. Run the original side tests before the source stops running. After that date there is nothing left to test against.
- One assistant, one port at a time. Finish the inventory, mapping, tests, and gap log for one source before starting the next, so test outputs and files never mix across assistants.
Worked Example: Support Triage Gem to Skill
Source: a Gemini Gem named Support Triage Helper. Instructions use Persona, Task, Context, and Format. Knowledge holds two files: a refund policy PDF and a macro library spreadsheet. No external tools.
Inventory found three jobs: classify a ticket by topic and urgency, draft a reply from the macro library in house style, and state whether a refund is allowed under the policy with the policy section cited.
Mapping verdicts: classification is direct, it is pure instruction logic. Macro drafting is a substitute, the spreadsheet moves to a macros file in the references folder, converted to plain text sections, because a spreadsheet grid reads poorly as a step by step reference. Refund policy lookup is a substitute, the PDF moves to a refund policy file in the references folder with section numbers preserved, and the workflow step requires citing the section, matching the source behaviour of showing knowledge citations.
Rewrite: the Gem Format block asking for an overview, then categories, then a draft becomes four numbered steps. The persona shrinks to two lines. The ported folder is support-triage, holding its own SKILL.md plus the macros and refund policy files in its references folder.
Parity results from a 12 case set: 10 pass, 2 partial, 0 fail. Partial one: a multi topic ticket classified under one topic where the original listed two. Fixed by adding a worked example for multi topic tickets, then retested to pass. Partial two: a refund edge case at a policy time limit boundary, where the port cited the right section but hedged on the verdict. Accepted as a gap with a note, because the original also hedged on the same case in two of three runs. Final scorer output after the fix: 11 pass, 1 partial with an accepted gap note, 0 fail. The port shipped as a draft for the owner to enable.
No ratings yet — be the first to rate it.