Skip to content
Back to skills

Create Gtm Skill

ASecurity

Author a GTM skill in getcargohq/gtm-skills (one-off CLI job or deployed pipeline). Use when creating, adding, scaffolding, or reviewing a new skill, SKILL.md, cookbook, or pipeline folder in gtm-skills.

  • 3 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 19, 2026
ai-agentsgosqlnodeexpressgit

Works with

  • claude code
  • cursor
  • cli

Security analysis

A100/100

Scanned October 4, 2026

npx -y skills add getcargohq/gtm-skills --skill create-gtm-skill --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Create Gtm Skill?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Create Gtm Skill
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/getcargohq-create-gtm-skill/badge)](https://www.skillsdirectory.com/skills/getcargohq-create-gtm-skill)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: create-gtm-skill
description: >-
  Author a GTM skill in getcargohq/gtm-skills (one-off CLI job or deployed
  pipeline). Use when creating, adding, scaffolding, or reviewing a new
  skill, SKILL.md, cookbook, or pipeline folder in gtm-skills.
---

# Create a GTM skill

This is an authoring skill for people writing this repo. It is not a
customer skill and does not install with `npx skills add`. The canonical
copy lives in `.agents/skills` so Codex, Claude Code, and Cursor all load
the same file (the last two via symlink).

Read `CONTRIBUTING.md` first. That file is the contract the validators
enforce; this file is the procedure.

One folder at the repo root is one customer skill. Install path:
`npx skills add getcargohq/gtm-skills/<name>`.

## 1. Pick the kind

| Kind     | Frontmatter                 | Job                                                                        |
| -------- | --------------------------- | -------------------------------------------------------------------------- |
| one-off  | `metadata.source: one-off`  | Runs once in a turn: exact `cargo-ai` command and a price                  |
| pipeline | `metadata.source: cookbook` | Deploys a standing play. Customer copy says **pipeline**, never "cookbook" |

`metadata.source` must be exactly one of those two strings. The validator
uses `cookbook` as the internal discriminator. Do not put that word in
README, plugin listings, skill body, or examples. Customers learn: some
skills run once; some deploy a pipeline that keeps running.

If the same job exists both ways, they compete for prompts. Pin the seam in
`evals/routing.jsonl`: one case that must hit the pipeline, one that must
hit the one-off sibling.

Name the folder after the job, not the vendor. `name` in frontmatter equals
the folder name. The slug is what an agent matches before it opens the file,
so the kind has to be readable from the name:

| Kind      | Shape                 | Examples                                               |
| --------- | --------------------- | ------------------------------------------------------ |
| one-off   | verb + object         | `enrich-company-data`, `score-leads`, `build-tam-list` |
| pipeline  | the standing practice | `tam-building`, `account-scoring`, `crm-enrichment`    |
| migration | `x-to-cargo`          | `clay-to-cargo`                                        |

A verb says "do this once." A standing noun says "keep this running." That
is how `build-tam-list` and `tam-building` stay apart, and why
`score-leads` pairs with `account-scoring` rather than `score-accounts`.
Do not give both kinds the same stem.

`enrich-crm` would read as a one-off next to `enrich-company-data`. A
pipeline that keeps CRM records filled is `crm-enrichment`. Contacts later
stay in that same slug. Accounts that are not in a CRM, if they land, are
`account-enrichment`. Planned pipelines stay nouns (`contact-sourcing`,
`signal-based-tam`, `rep-cockpit`). Do not rename existing skills to force
`-ing` vs `-ment`; the kind matters more than the suffix.

Inside a cookbook, resource slugs are snake_case: plays, workflows, tools,
agents, segments and folders (`score_accounts`, `enrich_crm_contact`,
`account_enrichment`, `tam_tier_analyst`, `tam_tier_a`,
`crm_enrichment_plays`), the same as the connectors and models the CDK
already requires it of. Workers and apps are the exception: the CDK requires
kebab-case for them. File names stay kebab-case (`score-accounts.ts`). A slug
is the resource's identity in `cargo.state.json`, so renaming one after a
deploy creates a new resource and orphans the old one: get it right before
the first deploy.

A model that extracts a system you hold (a CRM, a warehouse) pulls all the
data. Never filter or pick columns in its `config`: extract every record and
every column, and narrow in the SQL or the play filter that reads it. A
filter in the config is a second place the question is asked, invisible to
anyone reading the queries, and changing it means a redeploy and a
re-extraction instead of an edited query. A paid search source is the
exception, because there the search is the data source rather than a filter
on it: `aiArk.fetchCompanies` or a Sales Navigator search bills per returned
record, so its query in `config` is what decides what you buy.

**Native models first.** A worked example runs on Cargo native models, not a CRM connector, so it
deploys on a bare workspace. When the outcome needs accounts, contacts, opportunities or activity,
declare the shared `gtm_*` models exactly as `references/native-models.md` defines them;
`scripts/check-native-models.mjs` fails on drift. The CRM is the `crm-backed` variation.

## 2. Description (the only text before load)

Four parts, in order:

1. The job in one sentence
2. `Triggers:` literal quoted phrases a user would type
3. Proper nouns (connectors, CRM, CDK)
4. `Skip when:` the sibling skill that should win instead

Quote any YAML value that contains colon-space. Unquoted, the installer
skips the file with a warning nobody reads.

## 3. Write the kind

### One-off

Copy the structure of `enrich-company-data/SKILL.md`:

- Setup (CLI install, login, session stamp)
- Do the job (exact `cargo-ai orchestration action execute` / `execute-batch`)
- Example (see below)
- What it costs (table of `integration.action` → credits)
- Worth knowing / Going further / star ask

Slugs and prices are not yours to invent. `validate.ts` asserts every
`integrationSlug`/`actionSlug` and every credit number against
`getcargohq/cargo-skills` playbooks. Copy from a sibling, then run
`node scripts/validate.ts`.

Register: `skills.sh.json`, `hooks/skill-loads.sh`, root `README.md` table.

### Pipeline

Copy the section order from `tam-building/SKILL.md`. The validator requires
these headings:

1. Honest banner: `**State: to-be-approved.**`
2. `## The outcome`
3. `## Example` (see below)
4. `## Put it in your project` (copy the procedure from `tam-building`; each
   skill carries its own)
5. `## What you will be asked` — derive before ask; more than ~4 asked rows
   means you skipped lookups
6. `## What you can change` — offer unprompted; every variation has a cost
7. `## What should not change` — name the concrete symptom if violated
8. `## Done when`
9. `## What it costs`
10. `## Composes into`

Folder:

```
<name>/
  SKILL.md
  README.md
  infra/           # or models/, plays/, agents/ — whatever the outcome needs
  references/      # supporting agent docs; never a nested SKILL.md
  evals/acceptance.md
```

Isolation: every model and connector the resources import lives in this
folder. No relative import may leave it. Two pipeline skills may both
carry an `accounts` model; the placing agent rewires to the project's
existing one.

Resources must earn their deploy:

- Do not wrap a single connector action in a tool. That is a one-off.
- Do not declare a segment that restates the play's own filter.
- Do not add `examples/example.md` until a live install has sanitized
  audit findings, mappings, a plan summary, and lookup-backed credits.
- A folder of CDK with no `SKILL.md` does not belong at the root. Older
  examples live in history: `git checkout 305cd88 -- <name>`, then write
  the skill.

**Credits.** Pipeline markdown must not contain a numeric credit amount.
Fetch live prices at run time (`cargo-ai connection integration get <slug>`).
One-offs quote playbook numbers; pipelines do not.

**Write the system you write back to.** If the outcome updates a CRM
record, the play runs on that CRM extract and matches the CRM record id.
Do not sit a native `unifyAccounts` / `ids` map between the play and the
write — the run looks successful and nothing lands.

**One shape in the file.** A new pipeline's checked example runs on the
shared `gtm_*` native models (`references/native-models.md`); its
`crm-backed` variation names the HubSpot swap, and Salesforce and Attio adapt
that (connector, extractor, record-id, write action, fill-blank guard). A
pipeline whose whole job is a CRM (crm-enrichment, crm-deduplication) keeps
HubSpot as its checked example. No parallel branches.

CDK workflow bodies must compile. These fail `cargo-cdk check` / `plan`:
`undefined`/`void`, comma / SequenceExpression, `Date#getTime()`.

Register: `skills.sh.json` (its stage, at its place in the order: the order is
what an agent suggests next), `hooks/skill-loads.sh`,
root README pipeline table, `.github/data/approvals.json` with
`state: to-be-approved` and empty evidence.

### Both kinds: personas and the example

`validate.ts` requires these of every skill; the site renders them before
anyone installs.

- `metadata.personas`, right after `metadata.source`: 1–3 of
  `sales-development`, `account-executive`, `revops`, `sales-leadership`,
  `marketing`, `gtm-engineering`, primary first.
- `## Example`, in exactly this shape:

  ```
  ## Example

  > Find work emails for the 40 people in webinar-attendees.csv.

  Illustrative output, fictional records:

  <table or fenced block, about 20 lines at most>

  <one closing line with the result in numbers>
  ```

  Fictional companies on the `.example` TLD. A one-off's credits must add up
  from its own cost table; a pipeline quotes none and shows what the deployed
  play writes. Never a command in it, and never a table row that opens on a
  backticked `integration.action` cell — the validator reads that as a price.

## 4. Finish

```sh
node scripts/build-catalog.mjs
node scripts/generate-llms-txt.ts
npm run typecheck
npm run validate
npm run format:check
```

`catalog.json` and `llms.txt` are generated. Edit SKILL.md, then regenerate.

Do not claim an outcome for a pipeline skill until it is approved (demo
workspace + two implementations in `approvals.json`). The banner in
`SKILL.md` must match that file exactly.

## Anti-patterns

- A new root skill that is the same job as an existing slug with extra
  words (`crm-account-enrichment` vs `crm-enrichment`)
- A pipeline named like a one-off (`enrich-crm`, `score-accounts`,
  `build-tam`) or a one-off named like a pipeline (`tam-building` for a
  list today)
- Customer-facing "cookbook"
- Hardcoded credits in a pipeline
- Stub walkthroughs that restate `SKILL.md`
- `PLACEHOLDER` values that survive into a "done" template when the
  checked example can use real HubSpot (or whatever) property names
- Asking the operator for anything a connector or live schema can answer

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.