CtrlK
BlogDocsLog inGet started
Tessl Logo
SkillPublic

engram-branch-pr

PR creation workflow for Engram following the issue-first enforcement system. Trigger: When creating a pull request, opening a PR, or preparing changes for review.

Quality

79%

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide
SecuritybySnyk

Passed

No findings from the security scan

Fix and improve this skill with Tessl

tessl review fix ./skills/branch-pr/SKILL.md
SKILL.md
Quality
Evals
Security

When to Use

Use this skill when:

  • Creating a pull request for any change
  • Preparing a branch for submission
  • Helping a contributor open a PR

Critical Rules

The contribution policy transition is PRE-CUTOVER / NOT ACTIVE; the active rules below still apply.

  1. Every PR MUST link an approved issue — no exceptions
  2. Every PR MUST have exactly one type:* label
  3. All required automated checks must pass before merge is possible
  4. Blank PRs without issue linkage will be blocked by GitHub Actions
  5. The PR targets the canonical repository, the branch lives in your fork — origin is your fork, upstream is the canonical repository. A push straight to the canonical repository is refused, either by permissions or by the ruleset with GH013; do not retry it or switch destinations silently
  6. Applying the type:* label needs maintainer triage access on the canonical repository. When the API refuses, ask a maintainer instead of retrying

Workflow

1. Verify every linked issue has `status:approved`, a real assignee, and the proportional evidence defined in CONTRIBUTING.md; the PR author need not match the assignee
2. Create branch from the canonical `main` (`upstream/main`), with `origin` pointing at your fork: feat/*, fix/*, docs/*, refactor/*, chore/*
3. Implement changes
4. For behavior changes, run a focused regression test and affected package tests locally; record commands and outcomes. For docs-only changes, record N/A for Go tests and verify the documentation.
5. Check every changed path against the [Transient Artifact Policy](../../CONTRIBUTING.md#transient-artifact-policy)
6. Push the branch to your fork, then open the PR against the canonical repository using the template
7. Add exactly one type:* label — this needs a maintainer with triage access on the canonical repository, so ask for it rather than retrying
8. After pushing/opening the PR, wait for GitHub CI's full unit/E2E/lint and applicable platform checks; report results only after they run

Branch Naming (enforced by GitHub ruleset)

Branch names are validated by a GitHub ruleset. Pushes that don't match will be rejected.

Pattern: ^(feat|fix|chore|docs|style|refactor|perf|test|build|ci|revert)\/[a-z0-9._-]+$

TypeBranch patternExample
Featurefeat/<description>feat/json-export-command
Bug fixfix/<description>fix/duplicate-observation-insert
Chorechore/<description>chore/bump-bubbletea-v0.26
Docsdocs/<description>docs/api-reference-update
Stylestyle/<description>style/fix-tui-alignment
Refactorrefactor/<description>refactor/extract-query-sanitizer
Performanceperf/<description>perf/optimize-fts5-queries
Testtest/<description>test/add-sync-coverage
Buildbuild/<description>build/update-go-toolchain
CIci/<description>ci/split-e2e-job
Revertrevert/<description>revert/broken-migration

Rules:

  • Description MUST be lowercase
  • Only a-z, 0-9, ., _, - allowed in description
  • No uppercase, no spaces, no special characters

PR Body Format

Use the canonical PR template as the source for body shape; do not duplicate its structure here. Describe the problem and result, record honest verification, and include risks and mitigations only when applicable.

Every PR body MUST contain a closing reference to an approved, assigned issue:

Closes #<issue-number>

Valid keywords: Closes #N, Fixes #N, Resolves #N (case insensitive). Every linked issue MUST have status:approved and a real assignee. Approval means a maintainer accepted proportional evidence: scope/checks for trivial changes; current-remote-main SHA, reproduction, root cause, and regression tests for bugs; approved design, non-goals, and independent review for high-risk changes. Evidence can live in the issue; no separate design document is required by default.

Existing PRs must comply before merge, without waiting for backlog-wide migration. Re-run native validation after issue approval/assignment changes; do not rely on stale green checks.

Add exactly one canonical type:* PR label; no duplicate type checkbox is required in the body. All required automated checks must pass before merge; report other applicable checks honestly as described below.

Record actual verification commands/steps and observed outcomes, not assumed passes. For behavior changes, include focused regression and affected package tests. For docs-only changes, mark local Go tests N/A — documentation-only; no Go behavior changed and list the documentation checks actually run. Targeted coverage can help find missed branches; no total module coverage or per-PR numeric gate applies. Without a PR (or before pushing), and for high-risk changes, run additional applicable local checks. Identify checks not run and missing CI evidence; GitHub CI full unit/E2E/lint and applicable platform results remain pending until they run. Local success is not a hosted CI pass.

For high-risk changes, link the approved design, non-goals, and independent review evidence required by CONTRIBUTING. Omit the risk section for low-risk changes.


Automated Checks

The six required contexts are listed in CONTRIBUTING.md; all six must pass before merge. Lint, transient-artifact checks, Windows Setup Test, and Cloud Sync Wrapper Tests (Windows) run for PRs but not merge groups, and are not among the six required contexts. Report their actual outcomes without treating pending checks as passed.

CheckJob nameWhat it verifies
PR ValidationCheck Issue ReferenceBody contains Closes/Fixes/Resolves #N
PR ValidationCheck Issue Has status:approvedEvery linked issue is approved and assigned
PR Label PolicyCheck PR Has type:* LabelPR has exactly one type:* label
Transient Artifact CheckCheck PR Has No Transient ArtifactsPR files comply with the Transient Artifact Policy
CIUnit Testsgo test ./... passes
CIE2E Testsgo test -tags e2e ./internal/server/... passes
CIPlugin Testsnpm test passes in plugin/pi
CILintgolangci-lint reports no new findings in Go changes
CIWindows Setup TestWindows setup preserves absolute paths and MCP job-object parent-lifetime tests pass
CICloud Sync Wrapper Tests (Windows)Cloud sync wrapper and missing-PowerShell-Engram tests pass on Windows

Conventional Commits (enforced by GitHub ruleset)

Commit messages are validated by a GitHub ruleset. Commits that don't match will be rejected.

Pattern: ^(build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test)(\([a-z0-9\._-]+\))?!?: .+

Format:

<type>(<optional-scope>): <description>
<type>(<optional-scope>)!: <description>   ← breaking change

Allowed types

TypePurposePR label
featNew featuretype:feature
fixBug fixtype:bug
docsDocumentation onlytype:docs
refactorCode refactoringtype:refactor
choreMaintenance, depstype:chore
styleFormatting, whitespacetype:chore
perfPerformance improvementtype:refactor
testAdding/fixing teststype:chore
buildBuild system changestype:chore
ciCI/CD changestype:chore
revertRevert previous commit(match original type)
feat! / fix!Breaking changetype:breaking-change

Rules

  • Type MUST be one of the listed values
  • Scope is optional, lowercase, allows a-z, 0-9, ., _, -
  • ! before : marks a breaking change
  • Description MUST start after : (colon + space)

Examples

feat(cli): add --json flag to session list command
fix(store): prevent duplicate observation insert on retry
docs(contributing): update workflow documentation
refactor(internal): extract search query sanitizer
chore(deps): bump github.com/charmbracelet/bubbletea to v0.26
style(tui): fix alignment in session detail view
perf(store): optimize FTS5 query for large datasets
test(sync): add coverage for conflict resolution
ci(workflows): split e2e into separate job
fix!: change session ID format

Invalid examples (will be rejected)

Fix bug                          ← no type prefix
feat: Add login                  ← description should be lowercase
FEAT(cli): add flag              ← type must be lowercase
feat (cli): add flag             ← no space before scope
feat(CLI): add flag              ← scope must be lowercase
update docs                      ← no conventional commit format

Commands

# Identify the remotes before publishing. origin must be your fork and upstream
# the canonical repository; verify with git remote -v before pushing anything.
# A plain clone of your fork has only origin, and forking on the GitHub web
# interface changes nothing in a local clone. If upstream is absent, add it:
git remote add upstream <canonical-repository-url>
# Ensure origin points at your fork:
git remote set-url origin <your-fork-url>
git remote -v
git fetch upstream

# Branch from the canonical main, not from a local main that may be stale.
git checkout -b feat/my-feature upstream/main

# For behavior changes, run actual focused regression and affected package commands:
# go test ./internal/store -run '<actual regression test name>'
# go test ./internal/store
# Record actual commands and outcomes in the PR test plan.
# For docs-only changes, record N/A for Go tests and the documentation checks run.
# Without a PR or for high-risk changes, run additional applicable local checks.
# After pushing, GitHub CI runs broad unit/E2E/lint and applicable platform checks;
# do not claim their results until the checks actually pass.

# Push to your fork, never to the canonical repository. A direct push to the
# canonical repository is refused, by permissions or by its ruleset with GH013.
git push -u origin feat/my-feature

# Open the PR against the canonical repository, explicitly, so the destination is
# never inferred from the clone you are in.
gh pr create --repo <canonical-owner>/<canonical-repo> \
  --head <your-fork-owner>:feat/my-feature --base main \
  --title "feat(scope): description" --body-file pull_request_body.md

# The type:* label needs triage access to the canonical repository. A contributor
# without it gets "does not have the correct permissions to execute
# AddLabelsToLabelable": ask a maintainer to apply it, and do not retry.
#   Maintainer step (not a contributor step). Name the repository explicitly:
#   with both remotes present, GitHub CLI resolves a bare pull request number
#   against its configured default repository, which may be the fork.
#   gh pr edit <pr-number> --repo <canonical-owner>/<canonical-repo> \
#     --add-label "type:feature"

The --head <owner>:<branch> form supports user-owned forks only; GitHub CLI does not support an organization as <owner>. For an organization-owned fork, use GitHub's web pull-request flow and explicitly select the canonical base repository and branch, the fork, and the head branch before submitting.

Forks, Remotes, and Publication

A pull request targets the canonical repository. A fork is where the branch lives, not where the pull request opens.

RemotePoints atHolds
originyour forkyour branches
upstreamthe canonical repositorythe canonical main

After git fetch upstream, branching from upstream/main uses the current canonical main; this workflow does not require synchronizing your fork's main. Branching from a stale local or fork main instead may omit recent canonical changes, but does not necessarily produce an unclean diff.

Authorizations are separate

ActionWho performs it
Create or use a forkyou, once authorized to create or use that fork
Push commits to a branch in your forkyou, once separately authorized to push those commits there
Open or update a pull request in the canonical repositoryyou, once authorized to publish there
Apply the type:* label to a pull request in the canonical repositorya maintainer with triage access
Merge a pull requesta maintainer

Request the specific action you need. Authorization to create or use a fork does not authorize pushing commits to it. Being authorized to open a pull request is not authorization to label it or to merge it.

When a push to the canonical repository is rejected

Do not push branches to the canonical repository. It fails in one of two ways, depending on your access:

  • Without push access — the remote refuses the push: ERROR: Permission to <canonical-owner>/<canonical-repo>.git denied to <you>.
  • With push access — the repository's ruleset rejects the new branch: the push fails with GH013 and the required checks are reported as expected.

Both are the controls working as designed.

  • Do not retry the push, silently switch the destination, use an exempt branch namespace, fabricate checks, or change the ruleset.
  • Push the branch to your fork and open the pull request from there.
  • If neither the fork nor the label step is authorized for your account, stop and ask a maintainer for an authorized route, and record the rejection on the issue as evidence.

Dependent pull requests

A dependent pull request is a second pull request whose base branch is another contributor's branch. This repository has no validated procedure for delivering one from a fork, so treat it as requiring maintainer guidance rather than something to work around.

For a pull request targeting the canonical repository, the base branch must exist in the canonical repository. A fork-only branch can supply the head, not the base. Targeting a fork instead is a distinct, unvalidated workflow requiring maintainer guidance. The diff is computed against the selected base, but that alone does not require the parent pull request to merge first. Who may create the canonical base branch and how to sequence merges are maintainer workflow decisions that this skill does not make for you.

Ask before you start one. For a pull request targeting the canonical repository, do not use a base branch that does not exist in that repository. Pushing a branch to your fork does not make it a valid base for that pull request.

Repository

Gentleman-Programming/engram

Path

skills/branch-pr/SKILL.md

Last updated
First committed

Is this your skill?

If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.