PR Format#
Pull requests in the MSX ecosystem double as release notes. The description is written for end users of the solution, not for reviewers or developers. Implementation details go in a clearly separated technical section at the bottom.
Title#
<Icon> [<Type>]: <User-facing outcome>
- The Icon matches the change type.
- The Type in brackets is one of:
Major,Feature(Minor),Patch,Fix,Docs,Maintenance. - The outcome describes what changed from the end user's perspective. Never internal function names, class names, refactoring verbs.
Good titles#
๐ [Major]: Legacy export command removed๐ [Feature]: Custom templates now supported๐ฉน [Patch]: Default timeout value corrected๐ชฒ [Fix]: Parameter validation no longer fails on null input๐ [Docs]: Installation guide updated with prerequisitesโ๏ธ [Maintenance]: Release workflow and dependencies updated
Bad titles#
Add support for custom templatesโ describes the action, not the outcome.Refactor parameter validation logicโ implementation language.Update stuffโ meaningless.
Change types#
| Type | Icon | Label | Description |
|---|---|---|---|
| Major | ๐ | Major |
Breaking changes that affect compatibility |
| Feature | ๐ | Minor |
New features or enhancements |
| Patch | ๐ฉน | Patch |
Small fixes or improvements |
| Fix | ๐ชฒ | Patch |
Bugfixes (Patch-level release impact) |
| Docs | ๐ | NoRelease |
Documentation changes only |
| Maintenance | โ๏ธ | NoRelease |
CI/CD, build configs, AI/agent files, internal upkeep |
Detecting the change type#
The change type is decided in this order:
- Explicit user input โ if the contributor / Shipper specified a type, use it.
- Pre-1.0.0 rule โ projects with no version tags or latest tag below
v1.0.0follow SemVer ยง4. Major is never auto-detected for pre-1.0.0 projects. Breaking changes there are classified as Minor (0.x.0). -
Artifact-based inference from the branch diff:
Artifact type How to recognize Important files (affect artifact) Non-important (framework / tooling) Library / Module src/with the library's source and a package manifestsrc/**, package manifest.github/**,*.md,tests/**,scripts/**,agents/**GitHub Action action.ymlat repo rootaction.yml,src/**.github/**,*.md,tests/**,agents/**Reusable Workflow .github/workflows/with callable workflows.github/workflows/***.md,tests/**,agents/**Infrastructure module *.tfwith input variables and outputs*.tf,*.tf.json.github/**,*.md,tests/**,examples/** -
Classification rules (apply in order):
- Docs โ all changes are documentation only.
- Maintenance โ all changes are non-important for the artifact (no shipped change).
- Patch โ important-file changes are small fixes or minor improvements.
- Minor โ important-file changes add features without breaking.
- Major โ important-file changes break backward compatibility (pre-1.0.0 โ downgrade to Minor).
If the branch contains both important and non-important changes, classify based on the important changes only.
Description structure#
Ordered, top to bottom.
1. Leading paragraph โ Summary#
A concise paragraph describing what changes for the user. Present tense, active voice. Never open with implementation language ("Refactored", "Updated class", "Added null checks").
2. User-facing changes โ sections with headers#
Organize by what the user experiences, not by what was changed internally.
## Breaking Changesโ what stopped working or changed incompatibly (Major only).## New: <capability>โ new things the user can do.## Changed: <behavior>โ existing behavior that now works differently.## Fixed: <problem>โ problems now resolved.
Under each header:
- What the user can now do, or what changed for them.
- What they need to do differently โ migration steps, new parameters, changed defaults.
- Examples or code snippets showing new usage.
Do not mention internal function names, class names, private APIs, or refactoring decisions here.
3. Technical details (optional)#
## Technical Details
For reviewers and maintainers. Not part of the release note. Include:
- Which internal functions, classes, or files were changed.
- Implementation approach and design decisions.
- Backward compatibility notes for developers.
- Implementation plan progress โ cross-reference Section 3 of the linked issue. Which tasks does this PR complete? Which remain?
Omit the section entirely if there's nothing noteworthy.
4. Related issues#
A collapsible <details> block at the very end of the description containing issue links. Always use fully qualified references (Owner/Repo#N) so links work across repositories.
<details>
<summary>Related issues</summary>
- Fixes Owner/Repo#123
- Owner/OtherRepo#124
</details>
One bullet per linked issue. Use a closing keyword (Fixes, Closes, Resolves) when the PR fully addresses the issue. Otherwise, list the reference without a keyword to indicate a relationship without auto-closing.
If no issue is linked: stop. PRs without issues break the workflow. Route back to the Ideator role or proceed only on explicit user confirmation. The Shipper enforces this.
Formatting#
- Paragraphs are written as a single unbroken line. GitHub renders mid-paragraph newlines as spaces.
- The PR description is the release note. Write it for users, not reviewers.
- If a linked issue exists, the PR title and description should align with the issue's user-facing framing and the Technical Decisions section (Section 2).
Example#
Repository objects now include custom properties directly โ no separate API call needed. Queries that encounter missing or inaccessible resources now return partial results with warnings instead of failing entirely.
## New: Custom properties on repository objects
The `repo get` command now returns custom properties inline on the repository object. Previously, retrieving custom properties required a separate `repo properties` call.
```text
repo get --owner MyOrg --name MyRepo --format table
```
The `repo properties` command remains available if only the properties are needed.
## Fixed: Queries no longer fail when a resource doesn't exist
Commands that query a specific repository, enterprise, or release by name now return nothing instead of throwing when the resource doesn't exist. This makes them safe to use in conditional logic without error handling.
## Technical Details
- The repository model's custom-properties field is now a typed collection rather than an untyped object.
- The GraphQL query layer splits error handling into partial-success (data + errors โ warnings) and full-failure (errors only โ terminating error) branches.
- Null guards added to the repository lookup helpers.
- Implementation plan progress: tasks 1โ3 in #218 completed; task 4 (integration tests) remains.
<details>
<summary>Related issues</summary>
- Fixes Owner/Repo#218
- Owner/Repo#219
</details>
Drafts and readiness#
- The Shipper always creates the PR as draft so CI attaches immediately.
- Marking ready for review is the contributor's decision โ never the agent's.
- Suggested gates before marking ready: tests pass locally, description finalized, no known issues.
Branches and commits#
- Branch naming:
<type>/<issue-number>-<short-slug>, e.g.fix/123-pagination-truncation. - Commit messages: plain, direct, descriptive. No conventional-commit prefixes (
fix:,feat:,docs:). See Commit Conventions. - Self-review the staged diff before each commit. Unintended files (debug output, editor temp, credentials) get caught before they reach the remote.
Labels and assignment#
- Apply the change-type label.
- Apply phase labels if the repo uses them (Planning, Implementation, etc.).
- Assign the current user.
- Request reviewers per
CODEOWNERS; if none, fall back to repo defaults or skip.