Agent skill
gtmos-onboarding
Guide a user through the per-organization GTM OS setup wizard over MCP (gtm_describe / gtm_query / gtm_act) -- Welcome, Connect your data, Your definitions, Rules and who approves what, The build, First motion and 90 days -- citing the evidence behind every draft, never inventing a value, and stopping for the human-only steps and the four-eyes approvals.
Filed under Onboarding, retention and expansion.
From ay-automate/gtmos-skills · 107 skill entries · 0 · pushed 2026-11-02
What it does when it runs
Guide a user through the per-organization GTM OS setup wizard over MCP (gtm_describe / gtm_query / gtm_act) -- Welcome, Connect your data, Your definitions, Rules and who approves what, The build, First motion and 90 days -- citing the evidence behind every draft, never inventing a value, and stopping for the human-only steps and the four-eyes approvals. Use when the user wants to set up (or finish setting up) an organization in a running GTM OS instance; run gtmos-setup first if no instance is connected.
Automated analysis of the skill and the 0 files bundled beside it. A skill’s own description is written to be selected by an agent, so it describes the job and not the dependencies.
- Keys and connectors you must supply
- None found.
- Hosts it reaches
- No third-party host appears in the skill or its bundled files.
- Tool permissions it declares
- No
allowed-toolsin the frontmatter. It only issues instructions, so there is nothing to bound. - Actions present in the files
- None. Instructions only.
Ask about gtmos-onboarding
Opens your assistant with this page's recorded context. Check the linked sources before relying on it.
Install it
View source on GitHub ↗git clone --depth 1 --filter=blob:none --sparse https://github.com/ay-automate/gtmos-skills.git /tmp/gtmos-skills git -C /tmp/gtmos-skills sparse-checkout set "skills/gtmos-onboarding" mkdir -p ~/.claude/skills/gtmos-onboarding cp -R "/tmp/gtmos-skills/skills/gtmos-onboarding/." ~/.claude/skills/gtmos-onboarding/
Picked up without a restart. A project skill of the same name is shadowed by your personal one. For one repository only, swap ~/.claude/skills for .claude/skills. Claude Code docs ↗
Or take the whole library
This repo ships a .claude-plugin manifest, so Claude Code can install all 107 skills at once. Plugin skills are invoked as /<plugin>:<skill>, so they never collide with your own.
/plugin marketplace add ay-automate/gtmos-skills /plugin
The folder is the same in every client that implements the format — 46 of them — so if yours is not above, only the destination changes.
The skill
Source on GitHub ↗Reproduced in full from ay-automate/gtmos-skills/blob/86780d2f545cdc0a1de971917aa04b41bb0b3ccd/skills/gtmos-onboarding/SKILL.md, which is licensed MIT (repository). 7,620 words, 13 headings.
GTM OS per-org setup runbook (the agent executes this)
The console's setup wizard and this runbook drive the SAME operations: whatever you save here, the
user sees in the console (Setup), and the other way round. Before this skill, the workspace must be
connected to an instance (.claude/gtmos-instance.json has an apiUrl, /mcp shows the gtmos
server). If not, run the gtmos-setup skill first.
Step 0 -- probe the instance first
Before the first screen, and again at the start of a new session:
- Call
harness.statuswithgtm_query {"name":"harness.status"}. CompareoperationsHashwithreferenceOpsHashin.claude/gtmos-instance.json, andexpectedSkillsTagwith the skills tag you were installed from. A difference means the instance changed sincegtm init: tell the user and suggestgtm init --refresh. - Call
gtm_describewith no argument for the catalog of this instance, and again with anamefor every operation a screen needs, just before you use it. - If the instance does not know an operation, skip that part of the screen and say why in the same reply ("this instance has no
<operation>"). Add an Open item. Never call a different operation in its place and never invent one. - If
harness.statusitself is unknown, the instance is older than GTM OS 0.2.6: carry on with the catalog fromgtm_describealone.
Rules (all of them, every time)
- Read the schema before every call.
gtm_describe {"name":"<operation>"}returns the exact input schema;docs/gtmos/reference/operations.mdhas the same entries. Never guess a field or a value of an enum. Reads go throughgtm_query {"name":"<op>","input":{...}}, writes throughgtm_act {"name":"<op>","input":{...}}. - Never invent a value. A value you save comes from one of: the user's own words in this
conversation, an
evidenceentry of a drafted card, areasons[].factofonboarding.suggest, the crawled site (research.workspace_profile.get), an uploaded setup document, or a connected source's real counts. If none of these has it, leave the field empty and open a numbered ask (asks.create, oronboarding.request_access/onboarding.request_docs) with an owner. "I don't know yet" is a valid answer; a plausible guess is not. - Cite the evidence. When you show a draft, show where each value comes from: quote the card's
evidenceitem (or the suggestion's{ fact, source }) next to the value, e.g. "ICP country DE, weight 30 -- evidence: 14 of 22 closed-won accounts are in DE (closed-won deals)". A value with no evidence is shown as "no evidence -- please confirm or leave empty". - The model drafts, the human owns. Present drafts; save a value only after the user confirms
it (
onboarding.card.edit/onboarding.update). Never approve a card the user has not seen. - Human-only operations. Agent keys are refused on some operations (the tables say human
only; the full list and what you do instead is in "Human-only: what you do instead" below). The
refusal reads
FORBIDDEN: Operation "<name>" can only be performed by a human. Over MCP every call counts as an agent call, even when the MCP bearer is a human's own session token:roles.assign,onboarding.launchand the rest are refused there too, so the human does them in the console. Never retry, never route around it (another key, the user's session, a raw API call): propose what you can, prepare the draft, then ask the human to finish it in the console and tell them where to click. - The ARR band is private.
profile.arrBandis set and read by human owners / admins only; agents get FORBIDDEN ("the ARR band is private: only a human owner or admin can set it") and see it redacted. Never ask the user to paste it to you: tell them to set it themselves in Setup > Welcome (or leave it empty, which keeps it private). Never write it to a file or the memory. - Four-eyes. An operation that proposes (
blueprint.apply,env.promote,stage_map.set, the ICP / pilot / customer-type / suppression ChangeSets, the journeys, what a build step proposes) is approved by a DIFFERENT human: not the proposer and not the person you act for. You never approve, never ask for the approver's password, and never use their session. Report the approval id and<console>/org/<org id>/approvals, then continue. - Optimistic concurrency. Every write takes
expectedVersionfrom the lastonboarding.get. A CONFLICT means someone else (often the user in the console) changed the session: re-read, show what changed, and ask before you redo the write. - Never silent. A refusal (FORBIDDEN, NOT_CONFIGURED, VALIDATION_FAILED, CONFLICT) or a
proposal is told to the user in the same reply: the operation, the error, the fix and who owns it.
Record it as an Open item in
.claude/memory/setup-status.md. - Only what exists. Use the operations listed below; if
gtm_describedoes not know one, see "On an older instance". - Say why. A
gtm_actthat proposes an effect takes an optionaljustification(the MCP argument ofgtm_act; over REST thex-gtmos-justificationheader): why now, in your own words, for the person who approves. In GTM OS 0.2.6 it is optional. An agent proposal at tier T2 or above without one is still recorded, and the approver sees "No reason given by the agent". From GTM OS 0.2.7 (GTMOS_JUSTIFICATION_ENFORCEon by default) it is required for agent proposals at T2 or above: at least 10 characters that are not spaces, or the call is refused with VALIDATION_FAILED and nothing is written. Always send one now. A good reason names the evidence and the effect: "14 of 22 closed-won accounts are in DE, so this saves the ICP card with country DE". A bad one repeats the operation name or says "as requested". It is a statement, not a proof: never write a reason you cannot back with a number or a source. A person may leave it out. At tier T3 and above a named person other than you approves, whatever the reason says.
The six screens
- Welcome (screen
welcome; stepscompany,motion) - Connect your data (screen
connect; stepsconnections) - Your definitions (screen
definitions; stepsdefinitions) - Rules and who approves what (screen
rules; stepsrules,team) - The build (screen
build; stepsbuild) - First motion and 90 days (screen
first_motion; stepsplan,launch)
Start every session with gtm_query {"name":"onboarding.get"}: it starts the session on first read
and returns session.currentStep, completedSteps, version, the cards and the progress. Resume
at currentStep; never redo a completed step unless the user asks (onboarding.update with
reopenStep). After each screen, mark its steps done with onboarding.update
{"completeStep":"<step>","expectedVersion":<v>} (one step per call, in order).
Operations for every screen:
| Operation | Access | Use |
|---|---|---|
onboarding.get | read (gtm_query) | The session (status, currentStep, completedSteps, profile, version), cards with evidence, runbook, docs checklist, seats, plan, progress. Read it first and after every write. |
onboarding.update | you may call it (gtm_act) | Save answers the USER gave (profile, pains, engines, sources, team, stakeholders) and step progress (completeStep / reopenStep / currentStep). Always pass expectedVersion. |
asks.list | read (gtm_query) | The org's open asks (access requests, document requests, questions) with their numbers and owners. |
asks.get | read (gtm_query) | One open ask. |
asks.create | you may call it (gtm_act) | Turn a value nobody gave you into a numbered open ask with an owner, instead of guessing it. |
asks.answer | you may call it (gtm_act) | Record an answer -- an agent answers only asks it owns; for any other ask, relay the answer to its owner (they answer it, or a member relays it in the console). |
runtime.list_approvals | read (gtm_query) | What is waiting for a human approver (your proposals included). |
harness.status | read (gtm_query) | Step 0 probe: the operation count and hash of this instance, the skills tag it expects and the first-win path. Compare operationsHash with referenceOpsHash in .claude/gtmos-instance.json; a difference means the instance changed since gtm init (run gtm init --refresh). No secret, no org data. |
Screen 1 -- Welcome (company, motion)
- Ask the user, in one grouped question: company name, website, industry, team size, markets, deal
sizes, sales cycles, motions, maturity, the tools in their stack, up to 3 pains, who runs it and
the hours a week they give it, and the five free answers (what you sell, who buys, a great next
quarter, what has not worked, what the OS must never do). Use the enum values of
onboarding.update(gtm_describe); map the user's words to them and show the mapping. Unanswered = left empty. The stack decides which sources are selected by default and which access asks open; the hours size the 90-day plan. - With a website, run
research.workspace_profile.refresh, then readresearch.workspace_profile.get: offer facts from it (with the page it came from) for the user to confirm; never copy them in unconfirmed. - Save the confirmed answers with
onboarding.update(profile,pains,team,stakeholders). The ARR band: rule 6. - Read
onboarding.suggest. Show the engines and blueprints with theirreasons(andagainst). The user picks the engines (onboarding.update{"engines":[...]}, ornull= take the suggestion) and, optionally, a blueprint (blueprint.getshows what it installs). Save the pick withonboarding.update{"blueprint":"<id>"}: the build (Screen 5) applies it adapted to the approved cards. Apply it now (blueprint.apply, it proposes: rule 7) only when the user asks, and then save{"seed":{"changeSetId":"...","approvalId":"..."}}too. Applying the same input again while its proposal still waits (and its base versions are current) returns that proposal withreused: true, not a duplicate. completeStepcompany, thenmotion.
| Operation | Access | Use |
|---|---|---|
research.workspace_profile.refresh | you may call it (gtm_act) | Crawl the company website so drafts can cite it. An agent key needs engine.configure (the build scope), else FORBIDDEN: ask an owner / admin to run it. |
research.workspace_profile.get | read (gtm_query) | The crawled site profile (evidence for the company answers). |
onboarding.suggest | read (gtm_query) | Suggested engines, blueprints and sources, each with reasons [{ fact, source }]. |
blueprint.list | read (gtm_query) | The blueprint catalog. |
blueprint.get | read (gtm_query) | One blueprint: what it installs. |
blueprint.apply | proposes (gtm_act); a different human approves | Seed the picked motion; returns a ChangeSet + approval a different human approves. Usually left to the build (Screen 5), which applies it adapted to the approved cards. |
Screen 2 -- Connect your data (connections)
- Read
onboarding.signal_coverage: per category, what is connected, real record counts, the most accounts one source covers (never a sum),stackMissing, andcatalog(each connector: how it connects, where its data lands, the operations that pull it, what it still needs). Report only these numbers; no percentage or score that the operation did not return. - Read
onboarding.getrunbook: per source, what to ask for, who grants it, lead time, and whether it is EARLY. Connecting a source follows thegtmos-setupskill (Step 6: Connections): provider keys as connections, Composio apps throughcomposio.sync_connections; a new OAuth sign-in is clicked by a human in the console. - A connected source the catalog says still needs a setting (a project id, an event map): ask the
user for the value and save it with
connections.set_provider_setting. Never guess an id. - Pull now, once a source is connected, so the next screens draft from real data:
product_analytics.sync(PostHog, Mixpanel, Amplitude),transcripts.sync(Fireflies, Gong, Zoom, Fathom),outbound_rails.sync_replies(Smartlead, Instantly, lemlist). NOT_CONFIGURED means that tool is not connected: say so.outbound_rails.listshows which rail senders / campaigns a lane can bind; every send through a rail still goes through the approval-gatedoutreach.send_message. - For the grants the user cannot give now, run
onboarding.request_access(optionallygrantors= the emails the user names) and hand the user the numbered list it returns to forward. completeStepconnections(missing sources stay as numbered open asks; that is fine).
Imports (GTM OS 0.2.6): a file import goes through a review gate. import.review.list shows the batches and
each row's gate result; rows the gate blocked are held back from the CRM. You may fix or skip a row with
import.review.decide and show the user the reasons. You never override the gate: that needs a reason of
10 or more characters from the person, and a legal block (suppression, consent, do-not-contact) cannot be
overridden at all.
| Operation | Access | Use |
|---|---|---|
onboarding.signal_coverage | read (gtm_query) | Real coverage per category (CRM, analytics, ads, calls, warehouse, outbound), the stack tools not connected yet, and per category the catalog: every connector we read, how it connects, where its data lands, the operations that pull it, what it still needs. |
sources.coverage | read (gtm_query) | The per-source counts behind the coverage. |
instance.readiness | read (gtm_query) | Which live seams are configured on this instance (Composio seams included). |
connections.list | read (gtm_query) | The org's connections and their state (configured_unverified, live, ...). |
composio.status | read (gtm_query) | Each app connected through Composio and whether it is ACTIVE. |
composio.sync_connections | you may call it (gtm_act) | Record every app already connected in the org's Composio account (needs the connection.manage scope). Connecting a NEW app (composio.connect, OAuth) is human-only: gtmos-setup Step 6. |
connections.set_provider_setting | you may call it (gtm_act) | A per-org connector setting the catalog says is missing (posthog / mixpanel project_id, tiktok_ads advertiser_id, an event_map, gsc site_url, ...). Only values the user gave you. |
product_analytics.sync | you may call it (gtm_act) | Pull now: PostHog, Mixpanel and Amplitude events of the last 7 days become contact signals (and the 6-hourly pull stays scheduled). Owner / admin, or an agent key they scoped. |
transcripts.sync | you may call it (gtm_act) | Pull now: call transcripts from Fireflies, Gong, Zoom and Fathom into conversation memory. Owner / admin, or an agent key they scoped. |
outbound_rails.list | read (gtm_query) | The Smartlead senders and Instantly / lemlist campaigns a sending lane can bind, and why a campaign cannot carry an approved message (owner / admin). |
outbound_rails.sync_replies | you may call it (gtm_act) | Pull now: replies from Smartlead, Instantly and lemlist into conversation memory (they stop the sequence). Owner / admin, or an agent key they scoped. |
onboarding.request_access | you may call it (gtm_act) | One numbered open ask per missing grant (what, who grants it, lead time); returns the list to forward. |
import.review.list | read (gtm_query) | The import batches with staged rows, or one batch's rows with each row's gate result and reasons. Rows the gate blocked are held back from the CRM until someone decides. |
import.review.decide | you may call it (gtm_act) | Fix or skip one staged import row. Do not override the gate yourself: an override needs a reason of 10 or more characters from the person, and legal blocks (suppression, consent denied or withdrawn, do-not-contact) cannot be overridden at all. |
Screen 3 -- Your definitions
- Documents first.
onboarding.getdocsis the checklist (ICP notes, stage definitions, pricing, brand voice, suppression lists, DPA). A document the user hands you (a file in this workspace):onboarding.docs.uploadwith itsdocKey(it answers that document's open ask);onboarding.docs.listshows what was extracted. A document they mention but have not shared:onboarding.request_docswith an owner each. Never upload a file the user did not point you at. onboarding.draft_cardsdrafts every card from the org's own data, answers and documents. With a model configured (modeauto), each value cites evidence ids; an uncited value is dropped and opens a numbered question ask; without a model the card says so (evidence.model). Edited, approved, pending and skipped cards are kept (passforceonly when the user asks to redraft one).- For each card of this step (
onboarding.getcards), show the draft WITH its evidence (rule 3). The user confirms, changes or skips it:onboarding.card.edit(shape per card in the reference) /onboarding.card.skip. - Approve with
onboarding.card.approveonly what the card table lets you; for the rest, tell the user to approve it in Setup > Your definitions (rule 5). The answer'scard.statusisapproved,pending_approval(a different human approves: rule 7) orfailed(say why; the card stays editable). A card whose draft is not complete yet is refused with VALIDATION_FAILED and itsissues(e.g. anicpcard with no rules on an org without closed-won deals): fill it with the user's own criteria (onboarding.card.edit), or skip it. Seen live: with no revenue source connected, themoneycard opens the numbered ask "Connect a CRM with deals or Stripe" and fails until one is connected;brand_voiceneeds at least one tone word in the user's words. - The cards of this screen:
crm_stages:stage_map.unmappedlists the CRM's REAL stage values;stage_map.suggest/stage_map.ai_suggestpropose a mapping; the user confirms it on the card (or you save it withstage_map.set, which an agent proposes for the approver).customer_types: compare withcustomer_type.list(andcustomer_type.classifyfor a sample record the user names); approving proposes a ChangeSet.brand_voice: compare withbrand.get; brand voice is human-only (brand.set).suppression: built from their suppression documents and words; approving proposes a ChangeSet a different human approves. Suppression lists are RESTRICTED documents: an agent cannot read them, so your draft has the competitors and existing-customer rules but NOT the do-not-contact list. Say so, and ask an owner / admin to redraft that card (onboarding.draft_cards{"force":["suppression"]}, or Redraft in the console) and approve it. Never ask for the addresses in the chat.
onboarding.blueprint_adaptationsshows what the picked blueprint will take from the approved cards when the build applies it: show it before the build.- Definitions you publish land in
dev; prod needs signing + promotion (Screen 6). completeStepdefinitions.
Newer definitions (GTM OS 0.2.6), only when the user asks for them and Step 0 showed the instance has them:
a data-quality policy (identity_dq.dq_policy.get, then identity_dq.dq_policy.propose), a funnel
(funnel.list, funnel.evaluate), a revenue target (board.target.get, board.target.propose) and
the recommendation rules (recommendation.rules.get, recommendation.rules.propose). Each is a
definition a person signs. Read before you propose. Quote the coverage block with every funnel rate and
say "unavailable" where board.evaluate does. A data steward bundle (identity_dq.steward_plan, then
identity_dq.steward_bundle) is shown as a plan first; a different person approves it.
The cards of this screen and who can approve them:
| Card | Publishes through | Approve |
|---|---|---|
stages (Lifecycle stages) | journey.propose, journey.apply | you may approve it: it becomes pending_approval and a different human approves the ChangeSet / journey / mapping in Approvals |
icp (ICP and the weights sheet) | config.propose_changeset, config.validate_changeset, config.apply | you may approve it: it becomes pending_approval and a different human approves the ChangeSet / journey / mapping in Approvals |
money (Revenue truth and currency) | money.settings.set, crm.settings.set | a human approves it in the console (its target is human-only): you prepare the draft, they click Approve |
deal_words (Your words for deals) | deal_type.set | a human approves it in the console (its target is human-only): you prepare the draft, they click Approve |
owners (Who owns what) | territory.upsert | a human approves it in the console (its target is human-only): you prepare the draft, they click Approve |
pilot (Pilot scope) | config.propose_changeset, config.validate_changeset, config.apply | you may approve it: it becomes pending_approval and a different human approves the ChangeSet / journey / mapping in Approvals |
customer_types (Customer types and their journeys) | config.propose_changeset, config.validate_changeset, config.apply | you may approve it: it becomes pending_approval and a different human approves the ChangeSet / journey / mapping in Approvals |
crm_stages (Your CRM stage values) | stage_map.set | you may approve it: it becomes pending_approval and a different human approves the ChangeSet / journey / mapping in Approvals |
brand_voice (Brand voice and forbidden claims) | brand.set | a human approves it in the console (its target is human-only): you prepare the draft, they click Approve |
suppression (Who the engines never contact) | config.propose_changeset, config.validate_changeset, config.apply | you may approve it: it becomes pending_approval and a different human approves the ChangeSet / journey / mapping in Approvals |
| Operation | Access | Use |
|---|---|---|
onboarding.docs.upload | you may call it (gtm_act) | Upload a setup document the user GAVE you (<= 10 MB: PDF with text, .docx, .xlsx, CSV, TSV, JSON, Markdown, text) so the drafts can cite it; with docKey it answers that document's open ask. Images and scans are refused with the reason. |
onboarding.docs.list | read (gtm_query) | The uploaded setup documents and what was extracted (restricted ones -- suppression lists, the DPA, contact data -- show their text to owners / admins only). |
onboarding.docs.remove | you may call it (gtm_act) | Remove a setup document (its uploader or an admin). Drafted cards keep their values. |
onboarding.request_docs | you may call it (gtm_act) | Ask for the setup documents (ICP notes, stage definitions, pricing, brand voice, suppression lists, DPA) as numbered open asks. |
onboarding.draft_cards | you may call it (gtm_act) | Needs engine.configure (the build scope). Draft the definition cards from the org's own data, answers and documents (mode auto: the org's model drafts with cited evidence, else the deterministic drafter with the reason). Each draft carries its evidence. |
onboarding.card.edit | you may call it (gtm_act) | Needs engine.configure (the build scope). Change a card's draft to a value the user confirmed. |
onboarding.card.skip | you may call it (gtm_act) | Needs engine.configure (the build scope). Skip a card for now, or reopen it. |
onboarding.card.approve | you may call it (gtm_act) | Needs engine.configure (the build scope). Publish a card through the operation that owns it, as the caller. Only for the cards the card table lets you finish: a human-only target refuses you and marks the card failed. |
stage_map.unmapped | read (gtm_query) | CRM stage values not mapped to a canonical stage yet (real values from the CRM): the crm_stages card. |
stage_map.suggest | read (gtm_query) | Deterministic stage mapping suggestions. |
stage_map.ai_suggest | you may call it (gtm_act) | Model-assisted stage mapping suggestions (review them with the user). An agent key needs engine.configure. |
stage_map.set | proposes (gtm_act); a different human approves | Save a stage mapping the user confirmed. An agent key needs engine.configure, and an agent's call becomes an approval proposal: the approver signs it. |
journey.list | read (gtm_query) | The org's journeys (the stages card's current state). |
customer_type.list | read (gtm_query) | The org's customer types, the journeys they route to and how many companies each holds (the customer_types card's current state). |
customer_type.classify | read (gtm_query) | Which customer type a company, person or deal is, and which types it matches. |
brand.get | read (gtm_query) | The brand voice and kit in force (the brand_voice card's current state). |
brand.set | human only: agent keys are refused | Brand voice and kit: a human approves the brand_voice card (or sets it) in the console. |
proof.list | read (gtm_query) | The proof library: sources (case studies, metrics, testimonials, logos) with permission (public / anonymized / internal_only), expiry, state and claims. Only active proof backs a claim in outreach. |
proof.extract_from_document | you may call it (gtm_act) | Turn a case study the user hands you (file or pasted text) into a DRAFT proof source; the org's model proposes claims, each quoted word for word (no model = the text is saved and you add claims with proof.update). Ask the user the permission and expiry; never guess them. |
proof.update | you may call it (gtm_act) | Add / fix / remove a draft's claims (each excerpt copied exactly from the text, holding every number of the claim). |
proof.propose_activation | human only: agent keys are refused | Activating proof: a person proposes it in Settings > Proof library and a different person approves it. |
voice.customer_language.mine | you may call it (gtm_act) | Find the customers' own words (pains, outcomes, objections, triggers) in transcripts, classified replies and won-deal notes; each phrase keeps its source. They wait for a human to approve. |
voice.customer_language.approve | human only: agent keys are refused | Approving customer phrases: a person reviews them in Settings > Proof library > Customer language. |
onboarding.blueprint_adaptations | read (gtm_query) | What the chosen blueprint takes from the approved cards (ICP, pilot, stages, customer types, suppression, trust caps) before it is applied. |
identity_dq.dq_policy.get | read (gtm_query) | The data-quality policy in force (definition.data_quality_policy): required fields, validity rules, the staleness window. The import gate reads it. |
identity_dq.dq_policy.propose | you may call it (gtm_act) | Propose a new data-quality policy version from what the user confirmed. A person signs it; nothing is live until then. |
identity_dq.steward_plan | read (gtm_query) | Plan one data steward bundle (duplicate merges and value fixes) with the evidence and the count, before anyone is asked to approve. |
identity_dq.steward_bundle | proposes (gtm_act); a different human approves | Propose that bundle for a person to approve. Show the plan first; the approval says what runs. |
funnel.list | read (gtm_query) | The org's funnels (definition.funnel) with their stages and status. |
funnel.evaluate | read (gtm_query) | The cohort funnel: per stage entered, converted, rate, sample and median days, with an honest coverage block. Quote the coverage block with every rate. |
board.target.get | read (gtm_query) | The revenue target that applies (the signed definition.revenue_target in prod), the dev draft and the spec an editor starts from. |
board.target.propose | you may call it (gtm_act) | Propose a revenue target version from the closed-won figures the user gave. A person signs it. Never invent a period or an amount. |
board.evaluate | read (gtm_query) | The board: weighted pipeline, conversion, win rate, coverage against the target, slip rate. A number that cannot be computed honestly says unavailable; repeat that, never fill it in. |
recommendation.rules.get | read (gtm_query) | The interpretation rules the recommendation loop applies (the signed ones, else the shipped ones) and the vocabulary a rule may use. |
recommendation.rules.propose | you may call it (gtm_act) | Propose a new definition.recommendation_rules version: thresholds, minimum samples and one allowed action per rule. A person signs it. |
Screen 4 -- Rules and who approves what (rules, team)
- The cards of this step (below): show the draft and its evidence; the user approves them in the
console (their targets are human-only). For
autonomy, say plainly that outreach never acts within caps unless the org baseline already grants it, and that engines go live only at Launch. - Show the current policy as read (
policy.get_dry_mode,policy.guardrails.get,policy.engine_modes.get,policy.get_autonomy_scopes) next to the draft, so the user sees the change. - Seats:
roles.listshows the profiles and the members. Save the seats the user names (member user ids fromroles.listmembers) withonboarding.seats.set. Itsroles.errorsfor an agent is expected: the binding to a role profile (roles.assign) is human-only -- the user saves the seats again in the console, or assigns the profiles in Settings > Members. Warn before a seat is bound: a profile caps its holder at its base role and removes its denied operations (Operator = member; Exec = admin without config / journey / send operations; Ops lead = admin; Engineer = builder).roles.listreturnskeepsSetupAuthorityper profile andsetupStewards(the owners / admins who can still run the build, approve the cards and launch). Never put the sole owner in the Operator or Exec seat: seat them as Ops lead (or leave them unseated). The kernel refuses a change that would narrow, demote or remove the last setup steward with CONFLICTdetails.reasonLAST_OWNER_NARROWING: the fix is another un-narrowed owner or admin first. - Custom role profiles (
roles.upsert) are human-only: describe what the user wants (base role, denied operations, KPIs, actions) and let them create it in the console. A profile only narrows. completeSteprules, thenteam.
| Card | Publishes through | Approve |
|---|---|---|
buying_roles (Buying roles) | buying_roles.set | a human approves it in the console (its target is human-only): you prepare the draft, they click Approve |
consent (Consent and GDPR) | privacy.settings.set | a human approves it in the console (its target is human-only): you prepare the draft, they click Approve |
trust (Dry mode and guardrails) | policy.set_dry_mode, policy.guardrails.set | a human approves it in the console (its target is human-only): you prepare the draft, they click Approve |
autonomy (Autonomy per engine) | policy.engine_modes.set, policy.set_autonomy_scope | a human approves it in the console (its target is human-only): you prepare the draft, they click Approve |
Before the user decides who approves what, owners and admins can read risk.tier_readiness: it lists the
operations that would start needing a named approver when the stricter risk tiers turn on (default on from
GTM OS 0.2.7).
| Operation | Access | Use |
|---|---|---|
policy.get_dry_mode | read (gtm_query) | Whether the org is in dry mode. |
policy.guardrails.get | read (gtm_query) | The caps, quiet hours, timezone and channels in force. |
policy.engine_modes.get | read (gtm_query) | Each engine's dry / live mode. |
policy.get_autonomy_scopes | read (gtm_query) | The autonomy grants (org baseline and per engine). |
policy.set_dry_mode | human only: agent keys are refused | Dry mode: part of the trust card, a human approves it. |
policy.guardrails.set | human only: agent keys are refused | Caps, quiet hours, timezone, channels: part of the trust card, a human approves it. |
policy.engine_modes.set | human only: agent keys are refused | Engine live / dry: part of the autonomy card (and Launch), a human approves it. |
policy.set_autonomy_scope | human only: agent keys are refused | Autonomy grants: part of the autonomy card, a human approves it. |
roles.list | read (gtm_query) | Role profiles (Operator, Ops lead, Exec, Engineer + custom) with keepsSetupAuthority, who holds which, setupStewards, the KPI / action catalog. |
roles.my_dashboard | read (gtm_query) | The caller's seat dashboard (an agent sees its delegator's). |
roles.upsert | human only: agent keys are refused | Create or edit a role profile: owner / admin, human only. |
roles.assign | human only: agent keys are refused | Give a member a role profile: owner / admin, human only. |
onboarding.seats.set | you may call it (gtm_act) | Save the seats (operator, ops lead, exec, deputy); the role-profile binding it runs is human-only and comes back in roles.errors for an agent. |
risk.tier_readiness | read (gtm_query) | Owner or admin. Which operations would start needing approval when the stricter risk-tier flag turns on (default on from 0.2.7), and the org's T3 limits. Read it before the user decides who approves what. |
Screen 5 -- The build
onboarding.engine_readiness: per picked engine, each requirement met / missing / unknown, with the evidence and the remediation. An unknown is reported as unknown, never as met.- Tell the user what the build will do (the steps below), then
onboarding.build.start. It returns at once (run.statusqueued); one run at a time per org (a second start returns the running one withalreadyRunning: true). - Follow it with
onboarding.build.getevery few seconds untilrun.terminal: report each step's status and its real result (ChangeSet, approval, ask and adapter ids). A step you may not run isskippedwith the refusal; a failure carries its reason and the run continues. Stop it withonboarding.build.cancelonly when the user asks. needsHumanlists what waits for a person: the proposals of this run (a different human approves them in Approvals) and the asks raised. Nothing you do executes an approval. A finished run with failed, partial or cancelled steps: fix the cause with the user, thenonboarding.build.start{"retryRunId":"<run id>"}re-runs only the failed, partial, cancelled and unfinished steps. Askippedstep is NOT retried that way: once its cause is fixed (a CRM connected, a website given), start a new run, optionally only that step:onboarding.build.start{"steps":["<step key>"]}.- Walk the missing readiness requirements with the user: each one maps to an earlier screen, a connection, or an open ask. Do not mark the build done while a required requirement is missing without telling the user it is.
completeStepbuild.
The build steps, in run order:
| Step | What it does | Runs |
|---|---|---|
cards | Settle the definition cards waiting on an approval | onboarding.cards.resolve |
blueprint | Adapt the chosen blueprint to your approved cards and propose it | blueprint.apply, onboarding.update |
stages | Suggest a stage for each unmapped CRM value and ask you to decide | stage_map.unmapped, stage_map.ai_suggest, asks.create |
crm_adapters | Read each connected CRM's schema, audit it and propose the mapping | adapter.get, adapter.start, adapter.audit, adapter.propose |
completeness | Check how complete your synced data is | sync.completeness.run |
plays | Re-rank the plays catalog for your org | plays.rescore |
score | Rescore your accounts (no outbound action) | policy.engine_modes.get, score.rescan_organization |
site | Read your website again for the workspace profile | research.workspace_profile.refresh |
index | Reindex search and agent memory | search.reindex_now |
readiness | Snapshot what each engine still waits on | onboarding.engine_readiness |
brief | Regenerate the OS brief (readiness snapshot + your model's cited summary) | onboarding.brief.refresh |
| Operation | Access | Use |
|---|---|---|
onboarding.build.start | proposes (gtm_act); a different human approves | Start the build run (a worker job). Each step runs real operations AS YOU (your scopes, your delegator's role profile); what a step proposes waits for a different human in Approvals. One run at a time; retryRunId re-runs only a finished run's failed / partial / cancelled / unrun steps. Needs engine.configure (the build scope). |
onboarding.build.get | read (gtm_query) | The run's live log: each step's status, real results and linked ids (ChangeSets, approvals, asks #n, adapters, jobs), and needsHuman (your proposals still waiting, the asks you raised). |
onboarding.build.cancel | you may call it (gtm_act) | Needs engine.configure (the build scope). Stop a run between steps (its requester or an owner / admin). What a finished step proposed stays proposed. |
onboarding.cards.resolve | you may call it (gtm_act) | Needs engine.configure (the build scope). Settle the cards waiting on an approval: executed = approved, rejected / expired = failed (editable again). Never approves anything; the build's first step runs it. |
onboarding.engine_readiness | read (gtm_query) | Per picked engine: each requirement met / missing / unknown, with the evidence read and the next step. |
config.promotion_status | read (gtm_query) | Definitions still in dev (not live) and what must be signed. |
plays.rescore | you may call it (gtm_act) | Rescore the plays once the definitions changed (the build's plays step runs it too). |
Screen 6 -- First motion and 90 days (plan, launch)
- Read the plan in
onboarding.get(plan.phases,deferred,overCapacity, sized by the hours a week; each item says why it is there, who owns it and what it waits on). The user shapes it withonboarding.plan.set(keys fromplan.phases[].items[].key/plan.deferred[].key, play refs fromplays.catalog):add,remove,deferwith a reason,undefer,order,phase,hours. A play they want that the catalog does not have:request(it runsstudio.requestas you); a catalog play not installed yet:addwithinstall: true(it ships only after a different person approves it in Studio). onboarding.brief.refresh(readiness checked live + the model's cited summary), thenonboarding.brief: give the user the Markdown, or save it where they ask. A withheld section says why (role, scopes); a summary sentence without evidence is never shown.- Going live:
onboarding.launch.previewsays per definition what Launch would sign / promote and per engine what the approved autonomy card allows. Launch (onboarding.launch) is human-only: show the preview and ask the user to click Launch in Setup > First motion (signing is four-eyes: the signer is never the proposer; each promotion is approved by a teammate). Outside Launch you may proposeenv.promote(rule 7). completeStepplan, thenlaunch. Then summarise: what is live, what waits for whom (approval ids, ask numbers), and the Open items.
The motion and the recommendation loop (GTM OS 0.2.6, check Step 0 first). motion.assess ranks the
motions on real counts; motion.decide and motion.change are the person's, so show the ranking and let
them record it. After launch, recommendation.generate reads the funnel and proposes at most one
recommendation per finding; recommendation.accept, recommendation.dismiss and
recommendation.start_mission are the owner's (agent keys are refused). After an accept you may call
recommendation.act (a different person approves it) and, later, recommendation.measure.
motion.checkpoint (the +30, +60 and +90 day readings) is the person's too: bring the real numbers.
| Operation | Access | Use |
|---|---|---|
motion.assess | read (gtm_query) | Rank the GTM motions on the org's real counts and the seven intake answers: fit, blocking gaps, why not. Never answer an intake question for the user. |
motion.get | read (gtm_query) | The motion in force: the decision and its reason, the history and the +30, +60 and +90 day checkpoints. |
motion.decide | human only: agent keys are refused | Record the motion the person chose and why. A person's decision, append-only. |
motion.change | human only: agent keys are refused | Change the motion with a reason; the new blueprint is proposed and a different person approves it. |
motion.checkpoint | human only: agent keys are refused | Record a +30, +60 or +90 day checkpoint: what was expected against what was observed. A person records it; agent keys are refused. |
recommendation.list | read (gtm_query) | The recommendations from the funnel, newest first, with evidence, proposed action, tier, owner, state and outcome. |
recommendation.get | read (gtm_query) | One recommendation with its approval and measured outcome. |
recommendation.generate | you may call it (gtm_act) | Read the funnel, apply the rules and create at most one recommendation per finding. It only proposes; nothing runs. |
recommendation.accept | human only: agent keys are refused | The owner says yes to a recommendation. Nothing runs yet. Agent keys are refused. |
recommendation.dismiss | human only: agent keys are refused | Dismiss a recommendation with a reason. Agent keys are refused. |
recommendation.start_mission | human only: agent keys are refused | Start a bounded mission from an accepted low-risk recommendation. Agent keys are refused; nothing runs until a person approves the mission plan. |
recommendation.act | proposes (gtm_act); a different human approves | Act on an accepted recommendation: its operation is proposed at its own tier and a different person approves. |
recommendation.measure | you may call it (gtm_act) | Read the same funnel again over the same cohorts and write before and after into the recommendation's outcome. |
plays.catalog | read (gtm_query) | The plays the plan can use (refs catalog:<key>, org:<key>, request:<id>). |
onboarding.plan.set | you may call it (gtm_act) | Shape the 90-day plan: add plays from plays.catalog to a lane, remove, defer with a reason, bring back, reorder, pin a lane, set your own hours, ask Studio for a new play (request). Capacity comes from the Welcome hours; what does not fit is deferred with the reason. Publishes nothing. |
studio.request | you may call it (gtm_act) | Request a new play the catalog does not have (onboarding.plan.set request does the same and puts its review in the plan). |
onboarding.brief | read (gtm_query) | The smart OS brief for the caller (Markdown + sections): company, their words, engines + readiness, data, approved definitions, rules + seats, guessed-for-you drafts, numbered open asks, the 90-day plan, decisions (approval ids), the model's cited summary. |
onboarding.brief.refresh | you may call it (gtm_act) | Check engine readiness live (the plan reads it) and have the org's model write the cited summary (uncited sentences dropped; no model = said so). |
onboarding.launch.preview | read (gtm_query) | What Launch would sign, promote and turn live (nothing written): tell the person what launching needs. |
onboarding.launch | human only: agent keys are refused | Launch: sign + promote every setup definition, engines live only per the approved autonomy card. A human runs it in the console. |
definition.sign_many | human only: agent keys are refused | Sign the proposed definitions: a human, never the person who proposed them. |
env.promote | proposes (gtm_act); a different human approves | Needs engine.configure (the build scope). Propose promoting dev -> prod; a different human approves and executes it. |
Human-only: what you do instead
Every operation below refuses an agent key with FORBIDDEN: Operation "<name>" can only be performed by a human (the ARR band with its own
FORBIDDEN). That is expected, not an error to work around. For each one: do the part you may do
(prepare and edit the draft, propose, read the preview), then ask the human to finish it, naming the
screen and the button, and record it as an Open item.
| Refused for agents | What you do instead |
|---|---|
profile.arrBand | Never ask for it, never store it. Tell the user to set it in Setup > Welcome themselves (or leave it empty: it stays private). |
composio.connect | Connecting a new app is an OAuth sign-in: give the user the console link (Connections > Composio > Connect), then run composio.sync_connections when they say done. |
money.settings.set | Prepare the money card (edit it to what the user confirmed); the user approves it in Setup > Your definitions. |
deal_type.set | Prepare the deal_words card; the user approves it in Setup > Your definitions. |
territory.upsert | Prepare the owners card; the user approves it in Setup > Your definitions. |
brand.set | Prepare the brand_voice card from their words and their brand documents; the user approves it in Setup > Your definitions. |
buying_roles.set | Prepare the buying_roles card; the user approves it in Setup > Rules. |
privacy.settings.set | Prepare the consent card; the user approves it in Setup > Rules. |
policy.set_dry_mode | Prepare the trust card; the user approves it in Setup > Rules. |
policy.guardrails.set | Prepare the trust card (caps, quiet hours, timezone, channels); the user approves it in Setup > Rules. |
policy.engine_modes.set | Prepare the autonomy card; the user approves it in Setup > Rules. Engines go live only at Launch, per that approved card. |
policy.set_autonomy_scope | Prepare the autonomy card; the user approves it in Setup > Rules. |
roles.upsert | Describe the profile the user wants (base role, denied operations, KPIs, actions: it only narrows); an owner / admin creates it in Settings > Members. |
roles.assign | Save the seats with onboarding.seats.set (its roles.errors is expected); an owner / admin saves them again in Setup > Rules, or assigns the profile in Settings > Members (never the sole owner as Operator or Exec: LAST_OWNER_NARROWING). |
definition.sign_many | List what waits to be signed (config.promotion_status, onboarding.launch.preview); a human other than the proposer signs it. |
proof.propose_activation | Prepare the draft proof (proof.extract_from_document / proof.update) and tell the user to propose activation in Settings > Proof library; a different person approves it. |
voice.customer_language.approve | Mine the phrases (voice.customer_language.mine) and tell the user to review them in Settings > Proof library > Customer language. |
onboarding.launch | Read onboarding.launch.preview and tell the user exactly what Launch will sign, promote and turn live; they click Launch in Setup > First motion. |
motion.decide | Run motion.assess and show the ranking with its gaps; the person decides in the console and gives the reason. Never record a motion for them. |
motion.checkpoint | Read motion.get for the checkpoint dates and bring the real numbers (funnel.evaluate, board.evaluate); the person records what they expected against what they observed in the console. |
motion.change | Show motion.get and the checkpoints; the person changes the motion in the console with a reason. |
recommendation.accept | Show the recommendation with its evidence (recommendation.get); the owner accepts it in the console. |
recommendation.dismiss | Say what you would dismiss and why; the owner dismisses it in the console. |
recommendation.start_mission | Tell the owner the recommendation is eligible once accepted; they start the mission in the console and a different person approves its plan. |
Open asks
Every gap becomes a numbered ask with an owner, never a guess: asks.list shows them (number,
kind, owner, status). When the owner answers in the conversation, record it with asks.answer and
then save the value through the screen's own operation. You answer only the asks you own: for any other, give the answer to the ask's owner (or a member relays it in the console). Report the open asks in every summary.
On an older instance
The setup operations above ship with GTM OS 0.2.5. If gtm_describe does not know one, the instance
is older: say which part needs the update, carry on with what exists, and ask an operator to update
the instance (console Settings > Updates, or gtm upgrade). Never imitate a missing operation with
other writes.
Other skills for the same job
Different authors, same problem. Matched on the words in the skill name, across every library in the catalogue except this one.
- onboarding by coreyhaines31 · 57,918
- icp-onboarding by growthenginenowoslawski · 797
- onboarding-cro by OpenClaudia · 724
- onboarding-flow by shawnpang · 374
- customer-onboarding by louisblythe · 195
- paid-media-onboarding by langchain-ai · 116
- paid-media-org-onboarding by langchain-ai · 116
- user-onboarding by manojbajaj95 · 109
Need help setting it up?
This page tells you what gtmos-onboarding does and what it needs. Cheetah builds the agent setup it runs inside: data, CRM, sequencing and the guardrails.
Book a call →The directory stays free. There is nothing gated behind this.