This document defines the issue, branch, commit, Pull Request, and merge workflow for FrilVault.
The expected Git remote layout is:
origin -> contributor fork
upstream -> canonical FrilVault repository
Default project values:
UPSTREAM_REPO="FrilLab/frilvault"
BASE_BRANCH="main"The fork repository may differ by contributor. Determine it from origin instead of assuming an account name.
git remote -v
git remote get-url origin
git remote get-url upstreamGitHub Issues and Pull Requests belong to the upstream repository.
Working branches are pushed to the contributor fork.
Use this lifecycle for issue work:
Issue
-> Scope
-> Branch
-> Implementation
-> Validation
-> Commit
-> Push
-> Pull Request
-> CI
-> Merge
-> Issue closure
Do not start several unrelated issues merely to reduce the open issue count. Prioritize changes that move the next release toward completion.
When creating a Pull Request:
- Read
.github/PULL_REQUEST_TEMPLATE.md - Preserve its structure.
- Fill every section.
- Do not remove sections.
- Add "Closes #xx" only when the issue is completely resolved.
Read the complete issue before changing code.
gh issue view <ISSUE_NUMBER> \
--repo "$UPSTREAM_REPO" \
--commentsConfirm:
- the issue is still open
- no existing Pull Request already solves it
- the latest comments have not changed the requirements
- required predecessor issues are complete
- the acceptance criteria are understandable
- the work belongs in the current release
Summarize the intended scope before implementation:
Issue:
Goal:
Included:
Excluded:
Affected modules:
Validation:
Do not expand the scope to nearby cleanup or architectural work unless it is required for the issue to function correctly.
Before switching branches:
git status --shortIf uncommitted changes exist:
- do not discard them
- do not automatically stash them
- do not reset the working tree
- report the conflict and preserve the changes
Use the canonical repository as the source of truth.
git fetch upstream
git switch "$BASE_BRANCH"
git pull --ff-only upstream "$BASE_BRANCH"Do not push directly to main.
Do not use git reset --hard as a normal synchronization step.
Branch format:
<type>/<issue-number>-<short-description>
Allowed types:
feat
fix
refactor
test
docs
ci
chore
release
Examples:
feat/62-tag-support
fix/39-remove-duplicate-notes
refactor/71-note-query
test/75-separate-test-helpers
ci/93-github-releases
Rules:
- use lowercase
- use hyphens between words
- include the issue number
- keep the description short and specific
- do not include a date or developer name
Prefer creating a branch linked to the issue:
gh issue develop <ISSUE_NUMBER> \
--repo "$UPSTREAM_REPO" \
--base "$BASE_BRANCH" \
--name "<BRANCH_NAME>" \
--checkoutWhen the linked branch must be created in a fork:
gh issue develop <ISSUE_NUMBER> \
--repo "$UPSTREAM_REPO" \
--branch-repo "<FORK_OWNER>/frilvault" \
--base "$BASE_BRANCH" \
--name "<BRANCH_NAME>" \
--checkoutIf gh issue develop cannot support the repository arrangement, create the branch with Git:
git switch -c "<BRANCH_NAME>" "upstream/$BASE_BRANCH"Report why the fallback was required.
During implementation:
- follow existing module boundaries and naming conventions
- put shared behavior in
frilvault-core - keep integration layers thin
- add a regression test before or with a bug fix
- add tests for new observable behavior
- preserve backward compatibility unless the issue explicitly changes it
- avoid speculative abstraction
- avoid unrelated formatting or file movement
- remove temporary logging and debugging code
- validate paths and file-system operations
- return useful errors instead of hiding failures
When an unrelated problem is discovered, record it as a follow-up issue candidate rather than adding it to the current branch.
Before staging:
git status --short
git diff --check
git diffCheck for:
- accidental files
- debug output
- generated artifacts
- credentials
- unrelated changes
- missing tests
- unexpected API changes
Stage intentionally:
git add <FILES>
git diff --cachedAvoid git add . when unrelated local files may be present.
Use Conventional Commits:
<type>: <imperative description>
Examples:
feat: add note search by source file
fix: remove notes with duplicate anchors
refactor: introduce note query abstraction
test: separate shared test helpers
ci: add GitHub release workflow
Optional issue reference:
feat: add tag support (#62)
Commit rules:
- use an imperative description
- do not end the subject with a period
- avoid vague subjects such as
update,changes, orfix stuff - keep unrelated changes in separate commits
- do not rewrite published history without approval
Push the working branch to the fork:
git push -u origin HEADNever push directly to main.
Do not force-push without explicit approval.
Create the Pull Request against the canonical repository:
gh pr create \
--repo "$UPSTREAM_REPO" \
--base "$BASE_BRANCH" \
--head "<FORK_OWNER>:<BRANCH_NAME>" \
--title "<TYPE>: <DESCRIPTION>" \
--body-file .github/PULL_REQUEST_TEMPLATE.mdFor the common fork workflow, prefer an explicit command like:
gh pr create \
--repo "FrilLab/frilvault" \
--base "main" \
--head "<FORK_OWNER>:<BRANCH_NAME>" \
--draft \
--fillUse --draft by default while the branch is still under review or while CI has not finished.
If the template must be filled manually, write the PR body to a temporary file with real newlines and then pass it to --body-file.
When generating the body directly, use this structure:
## Summary
- Describe the primary change.
- Describe the user-visible or architectural result.
- Mention important compatibility details.
## Motivation
Explain the problem addressed by the issue.
## Implementation
- Describe the important implementation decisions.
- Mention the main modules changed.
- Explain meaningful tradeoffs.
## Validation
- [x] Formatting
- [x] Linting
- [x] Unit and integration tests
- [ ] Manual validation, when required
## Scope
### Included
- Items completed by this Pull Request.
### Excluded
- Explicit follow-up work.
Closes #<ISSUE_NUMBER>Use an automatic closing keyword only when the Pull Request fully resolves the issue:
Closes #62
Fixes #39
Resolves #75
For partial work, use:
Related to #66
Part of #27
Inspect the created Pull Request:
gh pr view \
--repo "$UPSTREAM_REPO"Watch checks:
gh pr checks \
--repo "$UPSTREAM_REPO" \
--watchWhen CI fails:
gh run list \
--repo "$UPSTREAM_REPO" \
--branch "<BRANCH_NAME>"
gh run view <RUN_ID> \
--repo "$UPSTREAM_REPO" \
--log-failedIdentify whether the failure:
- was introduced by the branch
- already exists on the base branch
- is environmental or flaky
- represents a missing requirement
Do not disable checks merely to merge the Pull Request.
For each review cycle:
- inspect unresolved review threads
- separate required changes from questions
- apply only the relevant changes
- rerun affected validation
- commit and push
- summarize what changed
- resolve only completed threads
Do not perform a broad rewrite in response to a narrow review comment.
The default merge strategy is squash merge.
Merge only when:
- required checks pass
- required reviews are complete
- merge conflicts are resolved
- acceptance criteria are satisfied
- validation results are recorded
- the issue closing reference is correct
Command:
gh pr merge \
--repo "$UPSTREAM_REPO" \
--squash \
--delete-branchUse automatic merge only when explicitly authorized:
gh pr merge \
--repo "$UPSTREAM_REPO" \
--squash \
--delete-branch \
--autoIf the user requested only implementation or Pull Request creation, do not merge.
After merge:
git switch "$BASE_BRANCH"
git fetch upstream
git pull --ff-only upstream "$BASE_BRANCH"Confirm the issue state:
gh issue view <ISSUE_NUMBER> \
--repo "$UPSTREAM_REPO"Delete a local branch only after confirming it is merged:
git branch --merged "$BASE_BRANCH"
git branch -d "<BRANCH_NAME>"Never use git branch -D as routine cleanup.
Use git worktree when independent issues must be developed concurrently:
git fetch upstream
git worktree add \
"../frilvault-issue-<ISSUE_NUMBER>" \
-b "<BRANCH_NAME>" \
"upstream/$BASE_BRANCH"Rules:
- one issue per worktree
- one branch per worktree
- do not mix files between worktrees
- limit active worktrees to two or three
- do not parallelize strongly dependent issues
- do not force-remove a worktree with uncommitted changes
Clean up after merge:
git worktree remove "../frilvault-issue-<ISSUE_NUMBER>"
git worktree pruneProcess dependent issues sequentially unless a stacked Pull Request workflow was explicitly requested.
Example:
In-memory cache
-> Cache invalidation
-> File preloading
-> Index warm-up
-> Cache integration
Do not create all dependent branches from main at the same time.
At the end of an issue task, report:
Issue:
Branch:
Commit:
Pull Request:
Status:
Implemented:
- ...
Validation:
- PASS: ...
- FAIL: ...
- SKIPPED: ...
Remaining:
- ...
Risks:
- ...
Never report incomplete or failing work as complete.