Use before writing anything that lands in this repository or on GitHub — PR titles/bodies, comments and review replies, commit messages and trailers, changesets, branch and file names, code comments and string literals, fixtures/specs/tests, docs, screenshots. Public text must describe the change on its own terms and never carry customer-derived identifiers, private paths, internal references, or workflow provenance.
This repository is public and generates SDKs, CLIs, MCP servers, and Terraform
providers for many organisations. Anything written here — or on a GitHub PR,
issue, review, or comment — is readable by everyone, indexed, mirrored, and
outlives the conversation that produced it. It therefore has to stand
alone: a maintainer with zero context should understand what changed and why,
and no reader should learn who our customers are or how our internal work is
organised.
The rule
Never publish customer or customer-derived identifiers. Not the company,
product, API, spec, or generated CLI/SDK/package name; not their operation
ids, command names, schema/property/enum names, hostnames, header names,
model ids, or verbatim error strings/payloads that only that API produces;
not "the customer" (or "a user", "a partner") plus details that narrow it
to one; not links to their material even when it is public. Public
discoverability does not make a customer name safe here. Never publish
credentials, customer documents, or unredacted private logs, even when
they carry no customer identifier.
Never expose internal context. No private repository URLs or names, no
real local filesystem paths (/Users/..., ~/...) or workspace/worktree
names copied from an environment (repository-relative paths are fine), no
private-tracker ids or links, no session/thread ids, no internal document
or spec titles, no internal reviewers or tools named as process actors.
No workflow provenance. Do not describe how the work was organised —
which agent, model, reviewer round, session, sibling branch, or orchestrator
produced a finding or decision. State the finding as a fact about the code.
Describe the change, not the story. Say what the code does now, what it
did before, and why the new behaviour is correct. If motivation matters,
describe the API shape that motivates it (see below), never its owner.
Applies to humans and AI agents equally, and to every public artifact and its
metadata: PR title/body, PR/issue/review comments and replies, labels, commit
messages and trailers (Co-authored-by included — commits become public on
push and survive rebases and squashes), branch and tag names, .changesets/,
CHANGELOG, code comments, string literals and templated error text, file/
fixture/spec/schema/test names, sample values, generated review SDK output,
docs, screenshots and attachments.
Rewrites
Don't
Do
"The FooCorp CLI needs --dry-run on every command"
"CLIs generated for APIs with keyless preview endpoints need --dry-run on every command"
"FooCorp's spec returns 400 with API_KEY_INVALID"
"An API that reports invalid credentials as HTTP 400 with a reason code in the body"
"Tested against the foocorp-cli-poc reference" / "the FooCorp fixture"
"Tested against a hand-written CLI with the target UX" / "the review fixture"
"Fixed in /Users/me/Code/my-worktree"
omit entirely
"codex round B found the retry loop double-counts"
"The retry loop double-counted attempts when Retry-After was present"
"the exit-codes agent's PR" / "sibling PR from the async worker"
"PR #70" / "the PR that adds --async"
"per orchestrator decision / per 's session"
"Decision: …" or just state the behaviour
"see TICKET-1234 / internal doc ' rev 1.0' item A8"
describe the requirement inline, or link a public issue
fixture foocorp-models.yaml with api.foocorp.com, foocorp-pro-2
route-dispatch.yaml with api.example.com, model-a; schemas Widget, Pet, AcmeOrder
PR example copied from a customer overlay (<their-command>, <TheirOp>#<TheirVariant>)
the same example expressed with the repository fixture's names
Allowed: the repository's own project, targets, features and public
repositories; public open-source dependencies, standards and tools (cobra,
zod, httpbin, RFC 9110, OpenAPI 3.1, google.rpc.ErrorInfo as a
convention, GitHub Actions); public GitHub PR/issue numbers and SHAs;
@-mentioning reviewers by their public GitHub handle. A customer's product,
repository, docs link, or SDK is not covered by this carve-out even when it
is public.
When context genuinely matters
Sometimes a change only makes sense because of a real API's behaviour. State
the minimum abstract shape needed to review and test it, normalise every
non-essential identifier and literal, and broaden or split rare combinations
that would fingerprint one API:
"an API whose list endpoints return a nextPageToken but no total count"
"an operation whose 200 response is a stream when Accept: text/event-stream"
"an auth scheme that accepts either an API key header or OAuth2 bearer"
That is enough for a reviewer to judge the change and for tests to cover it.
The owner of the API is never load-bearing. If the behaviour cannot be
explained without a source-specific name, value, or link, do not publish it —
ask privately for a safe abstraction.
Pre-publish checklist
Run this over the exact artifact you are about to post or commit (body,
comments, commit messages, branch/file names, the full staged diff); inspect
screenshots and attachments by eye — text search does not cover them:
Enumerate the customer/product/spec names, model ids, hostnames, command
and operation names from the private inputs used for this task (from the
source material — do not rely on memory); grep -Fi each literally: zero
hits, except values independently present in repository fixtures or
public standards.
grep -E '/Users/|~/|/home/' plus your actual workspace/worktree names:
zero real-path hits.
grep -Ei 'agent|codex|orchestrator|worktree|round [a-z0-9]|session|sibling|thread'
— review each remaining hit semantically; keep only technical meanings
(the documented "agent mode" feature, an HTTP session, a sibling schema
node, a public review thread) and remove anything that attributes work or
reveals private coordination.
No private tracker ids, private links, or real request/trace/session
ids. Clearly synthetic UUIDs in fixtures and public PR/issue numbers are fine.
Read the summary as a stranger: is it clear what changed and why without
any conversation context? Are findings and decisions stated directly —
no attribution or process narration, even where no keyword matched?
Fixtures, specs, sample values, and test names use neutral names
(acme, petstore, widgets; reserved domains example.com, .test,
.invalid).
The PR template's public-safety checklist is honestly ticked.
If a check fails, rewrite before publishing. If text was already published,
edit it in place (PR body, comment) or reword the commit before it merges —
and remember edits do not erase notifications, forks, or caches; rotate any
credential that leaked.
Related: CONTRIBUTING.md (repository-wide rules this skill turns into a
writing procedure) and .github/pull_request_template.md (per-PR checklist).
1---2name: public-repo-communication3description: Use before writing anything that lands in this repository or on GitHub — PR titles/bodies, comments and review replies, commit messages and trailers, changesets, branch and file names, code comments and string literals, fixtures/specs/tests, docs, screenshots. Public text must describe the change on its own terms and never carry customer-derived identifiers, private paths, internal references, or workflow provenance.4---56# Public-repo communication78This repository is public and generates SDKs, CLIs, MCP servers, and Terraform9providers for many organisations. Anything written here — or on a GitHub PR,10issue, review, or comment — is readable by everyone, indexed, mirrored, and11outlives the conversation that produced it. It therefore has to **stand12alone**: a maintainer with zero context should understand what changed and why,13and no reader should learn who our customers are or how our internal work is14organised.1516## The rule17181. **Never publish customer or customer-derived identifiers.** Not the company,19 product, API, spec, or generated CLI/SDK/package name; not their operation20 ids, command names, schema/property/enum names, hostnames, header names,21 model ids, or verbatim error strings/payloads that only that API produces;22 not "the customer" (or "a user", "a partner") plus details that narrow it23 to one; not links to their material even when it is public. Public24 discoverability does not make a customer name safe here. Never publish25 credentials, customer documents, or unredacted private logs, even when26 they carry no customer identifier.272. **Never expose internal context.** No private repository URLs or names, no28 real local filesystem paths (`/Users/...`, `~/...`) or workspace/worktree29 names copied from an environment (repository-relative paths are fine), no30 private-tracker ids or links, no session/thread ids, no internal document31 or spec titles, no internal reviewers or tools named as process actors.323. **No workflow provenance.** Do not describe how the work was organised —33 which agent, model, reviewer round, session, sibling branch, or orchestrator34 produced a finding or decision. State the finding as a fact about the code.354. **Describe the change, not the story.** Say what the code does now, what it36 did before, and why the new behaviour is correct. If motivation matters,37 describe the *API shape* that motivates it (see below), never its owner.3839Applies to humans and AI agents equally, and to every public artifact and its40metadata: PR title/body, PR/issue/review comments and replies, labels, commit41messages and trailers (`Co-authored-by` included — commits become public on42push and survive rebases and squashes), branch and tag names, `.changesets/`,43CHANGELOG, code comments, string literals and templated error text, file/44fixture/spec/schema/test names, sample values, generated review SDK output,45docs, screenshots and attachments.4647## Rewrites4849| Don't | Do |50| --- | --- |51| "The FooCorp CLI needs `--dry-run` on every command" | "CLIs generated for APIs with keyless preview endpoints need `--dry-run` on every command" |52| "FooCorp's spec returns 400 with `API_KEY_INVALID`" | "An API that reports invalid credentials as HTTP 400 with a reason code in the body" |53| "Tested against the foocorp-cli-poc reference" / "the FooCorp fixture" | "Tested against a hand-written CLI with the target UX" / "the review fixture" |54| "Fixed in `/Users/me/Code/my-worktree`" | omit entirely |55| "codex round B found the retry loop double-counts" | "The retry loop double-counted attempts when `Retry-After` was present" |56| "the exit-codes agent's PR" / "sibling PR from the async worker" | "PR #70" / "the PR that adds `--async`" |57| "per orchestrator decision / per <teammate>'s session" | "Decision: …" or just state the behaviour |58| "see TICKET-1234 / internal doc '<Spec title> rev 1.0' item A8" | describe the requirement inline, or link a public issue |59| fixture `foocorp-models.yaml` with `api.foocorp.com`, `foocorp-pro-2` | `route-dispatch.yaml` with `api.example.com`, `model-a`; schemas `Widget`, `Pet`, `AcmeOrder` |60| PR example copied from a customer overlay (`<their-command>`, `<TheirOp>#<TheirVariant>`) | the same example expressed with the repository fixture's names |6162Allowed: the repository's own project, targets, features and public63repositories; public open-source dependencies, standards and tools (`cobra`,64`zod`, `httpbin`, RFC 9110, OpenAPI 3.1, `google.rpc.ErrorInfo` as a65convention, GitHub Actions); public GitHub PR/issue numbers and SHAs;66@-mentioning reviewers by their public GitHub handle. A customer's product,67repository, docs link, or SDK is *not* covered by this carve-out even when it68is public.6970## When context genuinely matters7172Sometimes a change only makes sense because of a real API's behaviour. State73the minimum abstract shape needed to review and test it, normalise every74non-essential identifier and literal, and broaden or split rare combinations75that would fingerprint one API:7677- "an API whose list endpoints return a `nextPageToken` but no total count"78- "an operation whose 200 response is a stream when `Accept: text/event-stream`"79- "an auth scheme that accepts either an API key header or OAuth2 bearer"8081That is enough for a reviewer to judge the change and for tests to cover it.82The owner of the API is never load-bearing. If the behaviour cannot be83explained without a source-specific name, value, or link, do not publish it —84ask privately for a safe abstraction.8586## Pre-publish checklist8788Run this over the exact artifact you are about to post or commit (body,89comments, commit messages, branch/file names, the full staged diff); inspect90screenshots and attachments by eye — text search does not cover them:9192- [ ] Enumerate the customer/product/spec names, model ids, hostnames, command93 and operation names from the private inputs used for this task (from the94 source material — do not rely on memory); `grep -Fi` each literally: zero95 hits, except values independently present in repository fixtures or96 public standards.97- [ ] `grep -E '/Users/|~/|/home/'` plus your actual workspace/worktree names:98 zero real-path hits.99- [ ] `grep -Ei 'agent|codex|orchestrator|worktree|round [a-z0-9]|session|sibling|thread'`100 — review each remaining hit semantically; keep only technical meanings101 (the documented "agent mode" feature, an HTTP session, a sibling schema102 node, a public review thread) and remove anything that attributes work or103 reveals private coordination.104- [ ] No private tracker ids, private links, or real request/trace/session105 ids. Clearly synthetic UUIDs in fixtures and public PR/issue numbers are fine.106- [ ] Read the summary as a stranger: is it clear what changed and why without107 any conversation context? Are findings and decisions stated directly —108 no attribution or process narration, even where no keyword matched?109- [ ] Fixtures, specs, sample values, and test names use neutral names110 (`acme`, `petstore`, `widgets`; reserved domains `example.com`, `.test`,111 `.invalid`).112- [ ] The PR template's public-safety checklist is honestly ticked.113114If a check fails, rewrite before publishing. If text was already published,115edit it in place (PR body, comment) or reword the commit before it merges —116and remember edits do not erase notifications, forks, or caches; rotate any117credential that leaked.118119Related: `CONTRIBUTING.md` (repository-wide rules this skill turns into a120writing procedure) and `.github/pull_request_template.md` (per-PR checklist).
Run npx skillmds@latest add speakeasy-api/public-repo-communication in your terminal (requires Node.js), paste this page's agent-chat prompt into Claude, Cursor, or any MCP-connected agent, or download the SKILL.md file and copy it into your agent's skills directory.
Use before writing anything that lands in this repository or on GitHub — PR titles/bodies, comments and review replies, commit messages and trailers, changesets, branch and file names, code comments and string literals, fixtures/specs/tests, docs, screenshots. Public text must describe the change on its own terms and never carry customer-derived identifiers, private paths, internal references, or workflow provenance. It is listed under Productivity on SkillMD.
This skill has not completed SkillMD's automated safety review yet. SkillMD never runs a skill's scripts for you; review the SKILL.md before installing.
This skill is tagged as working with Claude Code, Claude.ai, OpenAI Codex. SKILL.md is an open format, so most agents that read a skills directory can load it too.
Yes. Installing skills from SkillMD is free, and the skill stays under its author's original license.
speakeasy-api (@speakeasy-api) published this skill. Their other Agent Skills are listed on their SkillMD profile.