/createpr — Standardized PR creation
SkillDocs & knowledgeOpen a high-quality pull request with a standardized description (Problems / Solutions / UX improvements / Documentation / Test plan / Breaking changes), the change_guardrails_rules.md pre-PR checklist enforced, and thorough functional-change documentation under docs/ surfaced via the docs server and docs site. Use this whenever a PR is about to be opened — directly via /create_pr or as a sub-step of /process_issues, /process_prs, /release, /fix_feature_bug.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the /createpr — Standardized PR creation skill
What this skill tells your AI
The instructions your AI receives, as published by markmhendrickson/neotoma in .claude/skills/create_pr/SKILL.md and read by ahel’s review.
When to invoke
- User says
/create_pror asks to open a PR. - Another skill (
/process_issues,/process_prs,/release,/fix_feature_bug) reaches the point of opening a PR. Call this skill rather than inlininggh pr create. - A worktree has a committed branch ready for review and no PR exists yet.
Do not invoke when amending an existing PR description — use gh pr edit directly with the same body conventions below.
Inputs
The caller (or the user) should provide, or this skill should infer:
- Branch — current branch (
git branch --show-current); if it equals the configured main branch, stop and ask. - Base branch — usually
main; for release work, the RC branch. - Linked issue(s) — GitHub issue number(s) the PR closes or refers to.
- Source plan / spec — Neotoma
planentity_id ordocs/path, if any. - Change classification — bug fix / feature / refactor / docs / release. Drives commit-style prefix in the title.
- Functional surface touched — CLI command/flag, MCP tool, HTTP endpoint, observable event, schema field, runtime knob, integration. Drives the docs-coverage check below.
Functional change documentation (mandatory for functional changes)
Every PR that changes user-observable behavior MUST ship thorough markdown documentation under docs/, and MUST surface it via the docs server (src/services/docs/) and the docs site (docs/site/pages/ via docs/site/site_doc_manifest.yaml). A PR that adds, removes, or changes any of the following counts as functional:
- A CLI command, subcommand, flag, env var, or output format
- An MCP tool name, parameter, or response shape
- An HTTP endpoint, request/response field, or error envelope field
- An entity_type schema field, relationship type, or canonical-name rule
- An observable event payload, metric name, or log structure
- A user-visible runtime config knob (timeout, header policy, allow-list)
- An integration/provider added or removed
What "thorough" means
The doc MUST cover:
- What the surface is and what it's for — one-paragraph orientation grounded in a use case.
- Inputs / parameters / fields — every parameter or field with type, default, allowed values, and constraints. Don't describe only the happy path.
- Outputs / responses / side effects — what the caller gets back, what state changes, what events fire.
- Examples — at least one complete request/response or invocation/output pair, in a fenced code block, that a reader can copy.
- Error modes — every documented
ERR_*code and structuredhintthe surface can return, with cause and remediation. - Cross-references — links to the canonical doc that owns the surface (per
change_guardrails_rules.md§ Canonical doc index) and to any plan/issue.
Where the doc lives
Pick the canonical location based on what changed; do not create a new top-level docs subdirectory without a reason. Common homes:
- CLI surfaces → extend
docs/developer/cli_reference.md(or a focused page underdocs/developer/). - MCP tools →
docs/developer/mcp/(and mirror behavioral rules intodocs/developer/mcp/instructions.mdper the canonical-first rule). - HTTP / API →
docs/api/plusopenapi.yaml. - Subsystems →
docs/subsystems/<subsystem>.md. - Architecture decisions →
docs/architecture/anddocs/architecture/architectural_decisions.mdregistry. - Observability surfaces (events, metrics, logs) →
docs/observability/. - Integrations →
docs/integrations/<provider>.md. - User-facing release notes → in-progress supplement under
docs/releases/in_progress/<TAG>/.
When extending an existing doc, place the new content under the most specific existing heading and update the table of contents / cross-references; do not append orphan paragraphs.
Surfacing via docs server and site
Both surfaces must list the doc, not just the filesystem:
- Docs server (
src/services/docs/) — verify the new or updated path is discoverable. Run the docs-service tests after editing:
If the doc is new and the discovery layer doesn't pick it up automatically, register it in the appropriate index module (thenpm test -- src/services/docsdocsservice owns this; do not hand-edit generated indexes — update the source). - Docs site (
docs/site/pages/rendered fromdocs/site/site_doc_manifest.yaml) — add the doc todocs/site/site_doc_manifest.yamlunder the right section, and add apages/entry if the manifest convention requires one. Run the manifest tests:npm test -- src/services/docs/manifest_loader
Abort criteria
If the PR makes a functional change and any of the following is true, stop and surface the gap before opening the PR:
- No new or modified file under
docs/covers the change. - The doc exists but is missing one of: parameters/fields, outputs, an example, or error modes.
- The doc is not reachable via the docs server (not in the discovery surface).
- The doc is not listed in
docs/site/site_doc_manifest.yaml.
Pre-PR checklist (run before opening)
From .claude/rules/change_guardrails_rules.md — surface these as a checklist in the PR body, and abort if a hard-required item fails:
- OpenAPI-first: if any handler, request field, or response field changed,
openapi.yamlwas edited first andnpm run openapi:generateoutput is committed. - Contract mappings:
src/shared/contract_mappings.tsupdated for any newoperationId, MCP tool, or CLI command. - Tests:
npm test -- tests/contract/passes; new top-level CLI commands appear intests/cli/cli_command_coverage_guard.test.ts. - Agent-instruction parity: MCP and CLI agent instructions mirrored (run
neotoma cli config --yesif instructions changed). - Runtime overrides: any new override follows
flag > env > default, with aNEOTOMA_-prefixed env var, listed incli_reference.md. - Errors: structured
hint/details/issuespopulated; no upgrade text concatenated intomessagestrings. - Tightening change: if previously-accepted input now rejects, a legacy-payload fixture under
tests/contract/legacy_payloads/is updated andCHANGES.mdhas the entry. - Breaking changes: release-visible breaking changes named in
docs/releases/in_progress/<TAG>/supplement under an explicitBreaking changessection. Use the literal lineNo breaking changes.when none. - Determinism / immutability / privacy: no
Math.random(), noDate.now()in ID derivation, no PII in logs, metric labels, event payloads, or error messages. - Security gates:
npm run security:classify-diffrecorded; ifsensitive=true,security:lint,security:manifest:check,test:security:auth-matrixall clean andsecurity_review.mdfilled. - User-facing surface coverage: any new CLI command / flag, destructive op, external-file parser, or HTTP runtime knob has an end-to-end test (not just a helper unit test).
- File naming: snake_case for new files;
foundation_config.yaml/.claude/rules/symlinks updated on rename. - Functional-change documentation: docs/ entry exists per the section above, covers parameters/outputs/examples/error modes, is discoverable via
src/services/docs/, and is listed indocs/site/site_doc_manifest.yaml. Required whenever any functional surface is touched. - Downstream docs: per
.claude/rules/downstream_doc_updates.mdanddocs/doc_dependencies.yaml, any upstream doc edit propagated to its downstream consumers in this PR.
If any item in 1–4, 7, 8, 10, 11, or 13 fails, stop and surface the gap to the user before opening the PR.
PR title conventions
- ≤70 characters.
- Conventional-commit prefix matching the repository's recent
git logstyle:feat(scope):,fix(scope):,refactor(scope):,docs(scope):,chore(scope):,test(scope):. - Title states the outcome, not the activity. "Add Problems/Solutions sections to /create_pr template" beats "Update create_pr skill."
PR body template
Use this exact structure. Omit a section only when it would genuinely be empty.
## Problems
- <Concrete pain point, failure mode, or gap this PR addresses.>
- <If there's a tracked issue, link it: "Fixes #123" — GitHub will auto-close on merge.>
## Solutions
- <Concrete change made, file-scoped where helpful: `src/foo.ts` now does X.>
- <Design choice with the alternative considered, when non-obvious.>
## UX improvements
- <User-visible behavior changes: CLI output, error messages, response shape, latency.>
- <If purely internal, write "No user-visible change." — don't omit the section silently.>
## Documentation
- <Path(s) under `docs/` added or updated, e.g. `docs/developer/cli_reference.md`, `docs/subsystems/foo.md`.>
- <Confirmation the doc covers parameters, outputs, an example, and error modes.>
- <`docs/site/site_doc_manifest.yaml` entry added/updated; docs service tests pass.>
- <If purely non-functional (refactor, internal rename, test-only) write "No functional change; no user-facing docs required.">
## Test plan
- [ ] `npm run type-check`
- [ ] `npm test`
- [ ] `npm test -- src/services/docs` (if docs changed)
- [ ] `npm run test:integration` (if backend/DB)
- [ ] `npm run test:e2e` (if UI)
- [ ] Manual verification: <steps>
## Breaking changes
<Literal line `No breaking changes.` OR a bulleted list of breaking changes, each linked to the release supplement entry under `docs/releases/in_progress/<TAG>/`.>
## Related
- Plan: <Neotoma plan entity_id or docs/ path>
- Issue(s): <#123, #456>
- Foundation rules touched: <list>
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Mechanics
-
Verify branch state
git statusclean; uncommitted changes → stop and ask.git rev-parse --abbrev-ref HEAD≠ main branch.git log <base>..HEAD --onelineto enumerate commits for the description.
-
Detect functional change and check docs
- Diff
git diff --name-only <base>..HEADagainst the functional-surface list above. - If functional, verify there is at least one
docs/**/*.mdchange in the diff, that it covers the required content elements, that the docs service surfaces it, and thatdocs/site/site_doc_manifest.yamllists it. - If any check fails → stop and surface the gap.
- Diff
-
Push if needed
git push -u origin HEADif no upstream is set.- On rejection, follow
git_remote_sync.md(pull --no-rebase, resolve, push).
-
Draft body via HEREDOC into a temp variable. Never inline multi-line strings into
gh pr create -b. -
Open the PR
gh pr create --base <base> --title "<title>" --body "$(cat <<'EOF' <body> EOF )" -
Return the PR URL to the caller.
-
Link to plan/issue in Neotoma — if a
planentity exists for this work, callstoreto setpr_urlon the plan, thencreate_relationship(REFERS_TO, plan, pr)if apull_requestentity is created downstream.
Invocation contract (for other skills)
Other skills should call /create_pr with a structured handoff:
/create_pr
base: main
branch: <current>
closes_issues: [123, 456]
plan_entity_id: ent_xxx (optional)
classification: fix|feat|refactor|docs|chore
functional_surface: cli|mcp|http|schema|event|integration|none
problems: <bullet list>
solutions: <bullet list>
ux_improvements: <bullet list or "No user-visible change.">
documentation:
paths: [docs/.../foo.md, ...]
site_manifest_updated: true|false
docs_service_verified: true|false
breaking_changes: <bullet list or "No breaking changes.">
test_plan: <bullet list>
/create_pr is responsible for: rendering the body, running the pre-PR checklist, running the functional-change documentation check, executing gh pr create, and returning { pr_url, pr_number }.
Callers are responsible for: ensuring the branch is committed, supplying accurate Problems/Solutions/UX/Documentation content, and following up on any checklist gaps surfaced by this skill.
Constraints
- MUST use the exact section order above.
- MUST NOT silently omit
Breaking changes— writeNo breaking changes.instead. - MUST NOT omit the
Documentationsection for functional changes. - MUST NOT open a PR for a functional change without a docs/ entry surfaced by both the docs server and
docs/site/site_doc_manifest.yaml. - MUST NOT use
--no-verifyor skip hooks. - MUST NOT force-push to the base branch.
- MUST run the pre-PR checklist (including the functional-change documentation gate) before opening.
- MUST pass the body via HEREDOC, not as a multi-line
-bargument.
Related rules / docs
.claude/rules/change_guardrails_rules.md— Pre-PR checklist source of truth..claude/rules/plan_sections_rules.mdandplan_format.md— Origin of Problems / Solutions structure..claude/rules/downstream_doc_updates.mdanddocs/doc_dependencies.yaml— Upstream→downstream doc propagation..claude/rules/readme_maintenance.md— README regeneration when materially affected..claude/rules/git_remote_sync.md— Push/pull recovery.docs/site/site_doc_manifest.yaml— Docs-site surface registration.src/services/docs/— Docs server discovery and rendering.docs/developer/github_release_process.md— Breaking changes section requirements.
Signals
- GitHub stars
- 32
- Forks
- 3
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
create-pr-markmhendrickson- Source
- github.com/markmhendrickson/neotoma