How do I create a PR?

Table of Contents

The body content should be assembled via How do I generate a PR summary? before running compass pr create here.

1. Question

How do I open a pull request from my current feature branch, with a correctly-formatted title and a structured body?

2. Answer

  1. Run the local check gate — mandatory, never skip. GitHub runs no check on a pull request, so compass check is the only gate between the branch and main. It classifies the branch diff against the decision tree in build/scripts/local_checks.py, runs the checks that class needs, and writes build/output/local_checks/report.md:

    ./compass.sh check
    

    A documentation-only change builds the changed pages and runs the doc corpus checks; a change to the compiled tree builds the preset and runs the suites. --plan prints the classes and the checks without running them. The result goes in the PR description (step 3), the only record that the gate ran. See CI workflows and local checks and the PR Raise skill.

  2. Close task/story bookkeeping now, if not already done — task DONE, * Result written, story/sprint rows synced (see compass-agile-close-task). This happens before raising the PR, so the bookkeeping commit is part of the very first push, not a follow-up after review.
  3. Create the PR with compass pr create. It validates the title convention, refuses the raise when a required Testing flag carries no text, and assembles one fixed body template: ## Summary, ## Changes, the ## Traceability table derived from the branch's task and story docs (with an Environment row alongside Story and Task), ## Testing, then the footer. The step-1 verification result goes in the Testing section, emitted as Plan., Evidence. and Limitations. paragraphs from --testing-plan, --testing-evidence and --testing-limitations, so it is visible in the description without asking. It then pushes the branch, opens the PR, records it on the task (#+pr: and the * PRs table), commits and pushes that record, and stamps the session journal:

    ./compass.sh pr create --title "[component] One-line description" \
      --summary "What changes, why." \
      --change "First change" --change "Second change" \
      --testing-plan "What will be tested, and how." \
      --testing-evidence "Local build clean (<preset>); ctest <N>/<N> passed" \
      --testing-limitations "What was left untested."
    

    Use --draft for a draft PR, --task <uuid-or-slug> when the branch carries more than one task, and --environment <name> to override the environment shown (default: the task's #+environment: frontmatter field, e.g. prime_origin; falls back to (none) if the task doesn't record one).

  4. Confirm the PR URL it prints. There is nothing else to do — the task-doc record is already committed and pushed.

3. Conventions

  • PR body is Markdown, not org-mode. GitHub renders the body as Markdown; use **bold**, `code`, [text](url) etc. — never [[id:...]] links, #+begin_src blocks, or other org syntax.
  • Body template is fixed. Every compass pr create body has the same four sections — Summary, Changes, Traceability, Testing — then the 🤖 Generated with Claude Code footer. Sections may be expanded (Notes, Decisions, Follow-ups) and the optional Captures section may be inserted before Traceability, but Testing is never omitted: the generator requires --testing-plan, --testing-evidence and --testing-limitations text and refuses the raise when any is missing.
  • Testing section carries three plain paragraphs — Plan., Evidence. and Limitations. — one per required flag, under a ## Testing heading after the Traceability table and before the footer. The Evidence paragraph holds the step-1 verification (change class, checks run, results); Limitations names what was not tested.
  • Title format is [COMPONENT] Description. Multi-component PRs use [a,b,c].
  • Captures section (optional): the captures you filed while working — a bug, limitation, or idea noticed in passing and recorded with compass capture (it lands in the product-backlog inbox, not as a story task). List one Markdown link per line to each capture's published page, so what you deferred is traceable from the PR. The same un-assigned captures also surface in the sprint's * Captures section. Place it just before Traceability. compass pr create does not yet generate this section — add it by hand (or via =–summary=/body editing) until it does.
  • Traceability section follows the Changes section and precedes the Testing section, always. It is a Markdown table with three columns — Artefact, Link, ID — and one row per tracked artefact (Story, Task), plus a final Environment row so it's visible at a glance alongside Story and Task rather than buried in prose. The Link cell contains a markdown hyperlink to the published HTML page; the ID cell contains the full UUID as read from the :ID: property of the .org file. Never abbreviate the UUID to just the first segment.
  • Story and task page URLs follow the pattern: https://orestudio.github.io/OreStudio/<path-without-extension>.html where <path> is the file path relative to the repo root:
    • Story: doc/agile/versions/v0/sprint_<NN>/<STORY_SLUG>/story
    • Task: doc/agile/versions/v0/sprint_<NN>/<STORY_SLUG>/task_<TASK_SLUG>
  • Traceability is forward-only: add it to new PRs; do not back-fill old ones.
  • Environment row is the last row of the Traceability table, always: | Environment | <name> | |. It records which ores_dev_* worktree environment the work was done in (read from the task's #+environment: field), so a reviewer or a later session can tell where to reproduce/continue the work at a glance, without opening the description body. (none) if the task doesn't record one.

4. Script

compass pr create (projects/ores.compass/src/compass_pr.py) wrapping gh pr create. The gh CLI must be authenticated (gh auth login) once per checkout.

5. Tested by

Manual. Reviewers verify the PR shape; compass pr checks reports CI.

6. See also

Emacs 29.3 (Org mode 9.6.15)