These are the project rules, not a welcome page. If you follow them, your pull request can be reviewed and merged. If you do not, it will be sent back regardless of the quality of the code.
PARTHA is a Repository Intelligence Platform. One architectural rule sits above all others:
Repository Intelligence is the shared repository-understanding layer. Architecture, dependencies, reviews, documentation, exports, and optional AI features consume it. AI must remain a downstream consumer, never an independent interpreter of the repository.
Throughout this document, must and must not are requirements, should is a strong expectation, and may is permission.
PARTHA's direction is maintainer-directed and tracked in the open: accepted
RFCs under docs/architecture/ and the issue tracker
are the source of truth for what is in scope, not an unpublished document.
A pull request is in scope only if it advances a tracked GitHub issue or an accepted RFC, with accepted evidence. A "quick useful surface" or breadth addition that does not trace to either is out of scope and should not be proposed or merged. The encouraged default is to deepen the existing moat (versioned evidence, history and drift, governed team memory, workflow outcomes); new surfaces or languages are the discouraged direction and need explicit owner justification before you start.
You must fill the Scope section of the pull request template on every pull request — naming the issue or RFC it advances and the accepted evidence. A pull request that cannot fill it is, by definition, out of scope and will be sent back. If you are unsure whether a change is in scope, ask on the issue before you start work.
Setting product direction is reserved to the maintainer; propose changes to it through an issue, not by editing an accepted RFC's conclusions.
| Tool | Version | Needed for |
|---|---|---|
| Python | 3.12 or 3.13 | Backend |
| Node.js | 22 | Frontend |
| Git | any recent | Everything |
cd apps/backend
python3.13 -m venv .venv
source .venv/bin/activate
pip install -e .
cd ../..
npm run dev:backendThe backend defaults to SQLite and local filesystem storage, so it starts with no PostgreSQL and no Redis. No .env file is required for local development — every setting has a working default. Copy apps/backend/.env.example only to change one.
npm ci --prefix apps/frontend
npm run dev:frontendRegister an account through the UI, then sign in.
For a fuller walkthrough — confirming the backend is actually up, running every test/lint/build command, and fixing the local database or API-contract failures you're most likely to hit — see docs/DEVELOPMENT.md.
| Path | Contents |
|---|---|
apps/backend/app/intelligence/ |
Repository Intelligence engine and models. The system's core boundary. |
apps/backend/app/api/ |
Routes and dependency wiring |
apps/backend/app/services/ |
Application services |
apps/backend/app/analysis/, graph/, review/, ai/, reports/ |
Consumers of Repository Intelligence |
apps/backend/app/auth/, core/, models/, storage/ |
Auth, config, ORM models, local storage |
apps/backend/alembic/, apps/backend/tests/ |
Migrations, backend tests |
apps/frontend/src/ |
app/ shell and routes, features/, shared/ |
docs/ |
Public documentation |
PARTHA uses a fork-first contribution model. You do not get push access to the official repository.
Contributors do not push directly to dev. They push a dedicated working branch to their own fork and open a pull request targeting dev.
All normal development pull requests target dev. The main branch is reserved for maintainer-controlled releases or promotion from dev.
- Fork
Second-Origin/PARTHAon GitHub. - Clone your fork and add the official repository as
upstream:
git clone https://github.com/<your-username>/PARTHA.git
cd PARTHA
git remote add upstream https://github.com/Second-Origin/PARTHA.git
git remote -vgit fetch upstream
git checkout -b feature/123-short-description upstream/dev
# ...commit your work...
git push -u origin feature/123-short-descriptionThen open a pull request from your fork's branch to Second-Origin/PARTHA:dev.
- push directly to
dev - push directly to
main - develop directly on your fork's
devbranch - open ordinary feature or fix pull requests against
main - combine unrelated issues in one branch
- reuse a merged branch for new work
- self-merge your pull request
- rewrite or force-push another contributor's branch
Substantial work must be claimed first. Unclaimed work may be closed unmerged even if it is correct, because it may duplicate or conflict with work already in progress.
Before starting, you must:
- Read the complete issue.
- Read its comments, linked issues, dependencies, and acceptance criteria.
- Confirm it is open and not already assigned to someone else.
- Comment on the issue stating why you want to work on it and requesting to be assigned.
- Start working — you do not need to wait for a maintainer to acknowledge before you begin. The comment itself is the claim; the maintainer will assign you on GitHub when able.
- Ask for clarification if the acceptance criteria are not testable, before you implement anything.
If you cannot assign yourself because of GitHub permissions, your comment is the claim mechanism — post it, then begin.
You must not begin substantial work on an issue that is already assigned to someone else. If one is, pick a different issue.
You must not begin substantial work on:
- an obsolete issue
- an issue whose scope is disputed
- an issue blocked by unmerged prerequisite work
- an issue without testable acceptance criteria
If no suitable issue exists, propose one using an existing issue template before implementing. Do not open a duplicate issue — search first, and comment on the existing one instead.
The repository provides three issue templates in .github/ISSUE_TEMPLATE/:
| Template | Use it for |
|---|---|
| Bug Report | Broken or incorrect behaviour. Give exact reproduction steps (route, endpoint, input repository, commands), the expected behaviour, the actual behaviour, evidence such as logs or payloads, and your environment. |
| Feature Request | A new capability or user workflow. State the problem first, then the proposed behaviour, the affected pages/endpoints/services, testable acceptance criteria, and any risks or dependencies. |
| Engineering Task | Technical debt, refactors, tests, infrastructure. State the task, why it matters now, the likely files and constraints, and acceptance criteria. |
In every template: write acceptance criteria that someone other than you can verify, name the affected components, and disclose dependencies and blocking work.
For documentation changes, open a Feature Request or Engineering Task describing what is inaccurate and what it should say.
Security vulnerabilities must never be filed as public issues. Report them privately through SECURITY.md. Do not include a vulnerability, an exploit, or a proof of concept in an issue, a pull request, or a comment.
Every issue gets a dedicated branch created from the latest upstream/dev.
<type>/<issue-number>-<short-description>
feature/123-python-symbol-extraction
fix/145-owner-scope-analysis
docs/152-contribution-workflow
test/167-archive-regression
refactor/181-parser-boundary
security/193-provider-configuration
chore/204-ci-cache
Allowed types: feature, fix, docs, test, refactor, chore, security.
One branch normally addresses one issue. If an issue is too large for a single reviewable pull request, split the issue, or use explicitly linked dependent pull requests (§9).
You must rebase onto the latest upstream/dev before opening a pull request, and again before final review.
git fetch upstream
git rebase upstream/dev
git push --force-with-lease origin <branch-name>Rules:
- Resolve conflicts locally, and rerun the relevant validation afterwards. A rebase can silently break code that previously passed.
- Use
--force-with-lease. Never use unrestricted--force. - Do not merge
devinto your working branch merely to avoid rebasing, unless a maintainer explicitly asks you to. - Never rebase or force-push a branch owned by someone else.
When the issue is complete:
- Push your dedicated branch to your fork.
- Open a pull request targeting
Second-Origin/PARTHA:dev. - Use the existing pull request template — do not delete its sections.
- Summarise what you implemented.
- Link the issue.
- Explain how you tested it, with the commands you ran.
- Include screenshots or a recording for any visible UI change.
- Identify configuration, migration, dependency, security, data, and compatibility implications.
- Disclose dependencies and blocked work.
- Request one reviewer:
@parthrohit22. - Wait for approval and maintainer merge.
If GitHub permissions prevent you from assigning a reviewer, request review in the pull request description or a comment. CODEOWNERS may also request review automatically.
You must not self-merge.
When a pull request fully completes an issue, its description must contain:
Closes #123
The closing statement must be in the pull request description — not only in a commit message, and not only in a later comment.
Use Closes, Fixes, or Resolves only when every acceptance criterion is complete.
If the pull request is partial, use one of:
Related to #123
Part of #123
Follow-up to #123
Do not use closing syntax when:
- any acceptance criterion remains incomplete
- tests required by the issue are missing
- documentation required by the issue is missing
- another pull request is still required
- the implementation deliberately changed scope
- any part of the work was deferred
- you cannot verify that the issue is actually solved
If implementation reveals that the issue is inaccurate, unsafe, obsolete, blocked, or no longer achievable as written, you must not silently change scope.
You must:
- Explain the discovery on the issue.
- Update the pull request description.
- State which acceptance criteria you completed.
- State what remains incomplete.
- Link any follow-up issues or dependent pull requests.
- Ask whether the issue should be rewritten, split, superseded, or closed.
A pull request that does not fully solve its issue must not use closing syntax. Important scope changes belong in the pull request description — do not leave essential information only in review comments.
After opening a pull request you must:
- wait for the automated checks
- respond to reviewer questions
- address requested changes
- keep the pull request focused on its issue
- update the description if scope changes
- keep the branch current with
dev - rerun tests after any rebase or conflict resolution
- wait for maintainer approval and merge
A reviewer approval does not override failing required checks.
Resolve a conversation only once the concern has actually been addressed, or a maintainer has made a decision. Do not resolve a reviewer's comment merely to clear the thread.
Merged branches may be deleted automatically. Assume your working branch disappears after merge.
Therefore you must:
- not leave unfinished work only on a branch that is being merged
- move unfinished work to a separate branch before merge
- not reuse a merged or deleted branch for unrelated work
- create follow-up branches from the latest
dev - preserve unmerged work in a dedicated dependent branch
Dependent branches are allowed only when the work genuinely cannot be reviewed independently. Do not use stacked pull requests to avoid properly splitting an oversized issue.
-
Create the first branch from
upstream/dev. -
Create the dependent branch from the prerequisite branch.
-
Open the prerequisite pull request first.
-
State the dependency in the dependent pull request:
Depends on #<pr-number> -
While the prerequisite is open, the dependent pull request may target the prerequisite branch, to keep its review diff clean.
-
Do not merge the dependent pull request before its prerequisite.
-
After the prerequisite merges:
git fetch upstream- rebase the dependent branch onto
upstream/dev - resolve conflicts
- rerun the relevant tests
- push with
--force-with-lease - retarget the dependent pull request to
dev - verify the final diff contains only the dependent work
Every dependent pull request must link its issue, its prerequisite pull request, any follow-up pull request, and the required merge order.
Run the checks relevant to your change. These are what CI runs.
| Command | Runs | CI job |
|---|---|---|
npm run test:backend |
Backend tests (pytest) | Backend |
ruff check app · ruff format --check app · mypy app |
Backend static analysis. Needs requirements-dev.txt — see the backend README |
Backend |
python scripts/check-capabilities.py |
Capability registry and its generated docs/CAPABILITIES.md block are current and deterministic. --write regenerates the block |
Backend |
npm --prefix apps/frontend run test |
Frontend tests (vitest) | Frontend |
npm run lint:frontend |
ESLint | Frontend |
npm run build:frontend |
tsc -b && vite build — type errors surface here, not in lint |
Frontend |
node scripts/dependency-audit.mjs · node --test scripts/dependency-audit.test.mjs |
Dependency audit policy and its own tests | Frontend |
npm --prefix apps/frontend run generate:api-contract -- --check |
Generated frontend DTOs have not drifted from the FastAPI schema | API Contract Drift |
npm run test:e2e |
Disposable fixtures plus the Playwright browser journeys | Prototype Browser Acceptance |
npm run test:accessibility |
The WCAG 2.2 AA baseline journeys only, on the same stack | Prototype Browser Acceptance |
npm run build runs the frontend build plus the backend tests. It does not run frontend lint or frontend tests — run those separately.
The CI job is still named "Prototype Browser Acceptance" even though the local command is npm run test:e2e — that job name is a required status check in branch protection, so renaming it needs a matching change to the branch ruleset, not just this file.
The table is the full CI gate list, so a change can pass test:backend and
build:frontend and still fail on contract drift, the capability registry, the
dependency audit, or a browser journey. If you touched a backend schema, run the
contract check; if you touched navigation or a page's structure, run
test:accessibility.
| If you changed… | You must run |
|---|---|
| Backend logic, services, intelligence, parsers | npm run test:backend |
| API request/response shape | npm run test:backend, update the frontend client and types, npm run build:frontend |
| Database models | Add an Alembic migration, then npm run test:backend (migration up/down is covered) |
| Frontend code | npm run lint:frontend, npm --prefix apps/frontend run test, npm run build:frontend |
| Local startup, CI, config, health | Smoke-check the affected backend/frontend start command and run the relevant tests above |
| Anything user-visible | Update the documentation in the same pull request |
Four backend tests are gated on real services and skip locally: two need PARTHA_TEST_PG_URL (the PostgreSQL analysis-job and refresh-token concurrency cases) and two need PARTHA_TEST_REDIS_URL (the Redis rate-limit backend cases). CI provides both services, so a locally green run showing four skips is expected rather than a problem.
If you cannot run a check locally, say so in the pull request and explain why. Do not claim a check you did not run.
Every CI run publishes JUnit test results and coverage reports as downloadable artifacts on the workflow run page (GitHub Actions run → Summary → Artifacts): frontend-test-results (junit.xml plus the vitest HTML/lcov coverage report) from the Frontend job, and backend-test-results (junit.xml plus the pytest-cov XML/HTML coverage report) from the Backend job. Artifacts are kept for 14 days and still upload on a failing run, so a failure's exact JUnit output is inspectable without reproducing it locally.
- Every schema change ships an Alembic migration, and it must downgrade cleanly — the migration test enforces this.
- Never edit a migration that has already merged. Add a new one.
- Backfills belong in the migration, not in application startup.
- A breaking API change requires the design to be agreed on the issue first, and the frontend client and documentation updated in the same pull request.
- Repository Intelligence is the shared repository-understanding boundary. If a feature needs a repository fact, add reusable extraction to
app/intelligence/and consume it from there. - Consumers must not create separate repository parsers. No walking the tree, no re-reading dependency manifests, no duplicating language or framework detection inside architecture, dependencies, review, documentation, export, or AI code.
- AI must remain an optional downstream consumer. It must not read repository files or reinterpret the repository independently.
- Heuristic results must not be presented as guaranteed facts. Most of what the engine infers — roles, modules, layers, symbols, frameworks — is inferred from paths and filenames. Label it accordingly in the API and the UI. See Repository Intelligence.
- Evidence must be represented only as precisely as the implementation supports. Supported extractors produce validated one-based inclusive line spans. Column-level evidence is not provided. Do not emit invented line numbers, placeholder citations, or fabricated success states to make output look grounded.
- Planned capabilities must not be documented as implemented. An API field, a model, or a class name is not evidence that a capability exists.
- Backend resources must be owner-scoped wherever authentication applies. Use the owner-scoped accessors, not the unscoped ones.
- Never expose secrets, credentials, or repository contents in logs.
- Security-sensitive changes require explicit tests and reviewer attention. Say so plainly in the pull request.
- Avoid unrelated refactors inside a scoped issue. Drive-by cleanup makes a diff unreviewable. Open a separate issue.
Current behaviour belongs in documentation. Future work belongs in GitHub issues.
Backend. Keep routes thin and logic in services. Use schemas at the boundary. Preserve the standard error response shape. Avoid broad except: — catch what you can handle.
Frontend. Keep shell, features, and shared code separate. Reuse the shared API client and types. No new any — use unknown and narrow it. Preserve loading, empty, error, and success states.
General. Remove dead code. Avoid speculative abstractions. Never commit secrets, .env files, local databases, build outputs, or caches.
An issue is ready to be claimed and started only when:
- its objective is clear
- its acceptance criteria are testable
- the affected component is identifiable
- dependencies and blockers are recorded
- security and data implications are identified
- it is not already assigned
- a maintainer has acknowledged the claim
An issue failing any of these is not "almost ready" — it needs design, not an assignee.
Work is complete only when:
- every claimed acceptance criterion is complete
- the implementation matches the agreed scope
- relevant tests are added or updated
- relevant tests pass
- documentation reflects the implemented behaviour
- security and data implications have been considered
- no credentials or sensitive information are committed
- the branch is rebased onto the latest
dev - the pull request contains no unrelated changes
- dependencies and follow-up work are linked
- the pull request description reflects the final outcome
- closing syntax is used only when the issue is fully resolved
- review feedback is addressed
- required checks pass
- the maintainer approves and merges the pull request
Code written does not mean issue completed.
Releases are cut by maintainers. Contributors do not tag, and no contributor pull request should change a version string — the release commit does that.
The two long-lived branches.
| Branch | Role |
|---|---|
dev |
Active development, and the target of every pull request. It moves constantly and is never itself a release. |
main |
The latest tagged release. Updated only by promoting dev at a release point. |
Both are protected by repository rulesets: a pull request with one approving review and code-owner review, passing required status checks, and no deletion or force-push.
Cutting a release.
- Bump the version in
package.json,apps/frontend/package.json,apps/marketing/package.json,apps/backend/pyproject.toml, and the FastAPIversion=inapps/backend/app/main.py, together with any documentation that is genuinely out of date. Merge that todevlike any other change. - Open a
dev→mainpull request and merge it once checks are green. - Tag the release commit
vMAJOR.MINOR.PATCHand push the tag. - Once the GitHub Release exists and its notes are curated (below), add a row for
the version to
CHANGELOG.md— a one-line summary and a link to the release notes — so the in-repo index stays current.
Pushing a v* tag runs .github/workflows/release.yml:
a validate job re-runs the release-relevant frontend and backend checks against real
PostgreSQL and Redis, and only if that passes does a github-release job create the
GitHub Release with gh release create --generate-notes — an automatically generated
list of merged pull requests and new contributors.
Those generated notes are a baseline, not the final notes. After the workflow runs,
a maintainer edits the release (gh release edit <tag> --notes-file …, or the Releases
UI) to replace or lead them with hand-written notes: grouped by area, stating what
changed and — for a truth-focused project — what is still not built. The generated
pull-request list may be kept underneath as a changelog. A release is not considered
done until that curation has happened.
main is only ever a pull-request target. Never open a pull request whose source
branch is main: merged head branches are deleted automatically, which would delete
main itself.
PARTHA is pre-1.0. Minor versions may change behaviour; the release notes say so when they do.
All participation is governed by the Code of Conduct.
PARTHA is licensed under the Apache License 2.0. By contributing, you agree your contribution is provided under that same license. Contribute only work you have the right to submit, and do not copy third-party code, images, fonts, datasets, or text into the project unless the license is compatible and the attribution is documented. There is currently no CLA or DCO requirement; if that changes, it will be documented here before being enforced.
Questions about scope, an issue, or a pull request are welcome on Discord before you invest time in something that might be out of scope.