Thank you for contributing to GuildPass Core.
GuildPass Core V2 is being rebuilt as a modular, Stellar-first backend and domain layer for programmable communities. Contributions should therefore favour clear boundaries, deterministic behaviour, focused scope, strong typing, and tests.
This guide explains how to contribute safely and consistently.
Please read:
README.mdCODE_OF_CONDUCT.mdSECURITY.md
If you are working from a campaign issue, read the full issue carefully before writing code.
Issues are intended to define:
- the problem;
- the expected outcome;
- implementation boundaries;
- acceptance criteria;
- likely affected files or directories.
Treat the issue as the primary source of truth for the contribution.
GuildPass Core V2 is a clean rebuild of the previous implementation.
The current direction is:
- TypeScript-first backend development;
- Stellar-first blockchain support;
- Soroban smart contracts for on-chain functionality;
- PostgreSQL for relational persistence;
- Redis for caching and infrastructure concerns;
- deterministic domain logic;
- independently testable modules.
Do not restore old V1 architecture unless an issue explicitly asks for it.
In particular, avoid reintroducing legacy complexity such as:
- EVM-specific assumptions;
- generic multichain abstractions;
- old migration history;
- deprecated services;
- duplicated access-control logic;
- tightly coupled route and domain logic.
A pull request should solve one issue.
Avoid combining unrelated:
- features;
- refactors;
- dependency upgrades;
- formatting changes;
- documentation rewrites;
- infrastructure changes.
Small, focused PRs are easier to review and safer to merge.
2. Do Not Create Hidden Dependencies Between Issues
Campaign issues are generally designed to be worked on concurrently.
Do not make your implementation depend on another open issue unless the issue explicitly says so.
If your task requires a missing helper, implement the minimum self-contained functionality needed for your issue instead of waiting for another contributor.
Given the same valid inputs, domain logic should produce the same result.
Avoid behaviour that depends unnecessarily on:
- object insertion order;
- global mutable state;
- implicit current time;
- random values without injection;
- network state;
- local environment assumptions.
Where time or randomness is required, make it testable.
Domain logic should not be hidden inside:
- Fastify routes;
- Prisma queries;
- Redis calls;
- Docker configuration;
- blockchain transport code.
Prefer a structure where business rules can be tested without starting external services.
New behaviour should include tests.
Bug fixes should preferably include a regression test that demonstrates the previous failure.
Tests should cover:
- normal behaviour;
- invalid input;
- boundary conditions;
- failure modes;
- deterministic ordering;
- concurrency where relevant;
- security-sensitive edge cases.
Install:
- Git
- Node.js 24 or newer
- pnpm 11.x
- Docker
- Docker Compose
If you are working on Soroban contracts, also install the required Rust and Stellar tooling.
Check versions:
node --version
pnpm --versionThe repository currently uses:
pnpm 11.16.0
Fork:
Adamantine-guild/guildpass-core
Then clone your fork:
git clone https://github.com/<YOUR_USERNAME>/guildpass-core.git
cd guildpass-coreAdd the upstream repository:
git remote add upstream https://github.com/Adamantine-guild/guildpass-core.gitVerify:
git remote -vYou should have:
origin your fork
upstream Adamantine-guild/guildpass-core
Before creating a new branch:
git checkout main
git fetch upstream
git pull upstream main
git push origin mainAlways start new work from the latest main.
Do not work directly on main.
Recommended branch prefixes:
feat/
fix/
test/
docs/
refactor/
chore/
ci/
Examples:
git checkout -b feat/stellar-address-validatorgit checkout -b fix/access-decision-orderinggit checkout -b test/quorum-boundariesRun:
pnpm installFor reproducible verification:
pnpm install --frozen-lockfileIf pnpm requests approval for expected dependency build scripts:
pnpm approve-buildsOnly approve dependencies you recognise and that are required by the project.
Create a local environment file:
cp .env.example .envThe default local values are:
NODE_ENV=development
PORT=3000
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/guildpass
DIRECT_URL=postgresql://postgres:postgres@localhost:5432/guildpass
REDIS_URL=redis://localhost:6379Do not commit .env.
Start PostgreSQL and Redis:
docker compose up -dCheck status:
docker compose psStop services:
docker compose downRemove volumes only when you intentionally want to reset local persisted data:
docker compose down -vStart the development server:
pnpm devor:
pnpm --filter @guildpass/api devDefault URL:
http://localhost:3000
Health check:
curl http://localhost:3000/healthBefore opening a pull request, run:
pnpm install --frozen-lockfile
pnpm typecheck
pnpm build
pnpm testAll applicable checks must pass.
Do not open a PR with known failing tests unless the issue explicitly concerns the failing test infrastructure.
GuildPass Core uses strict TypeScript.
Prefer:
- explicit domain types;
- discriminated unions;
- narrow public APIs;
- readonly values where appropriate;
unknownoveranyat trust boundaries;- runtime validation for external input.
Avoid:
- unnecessary
any; - unsafe type assertions;
- broad casts used to silence compiler errors;
- duplicating types already defined in shared packages.
Errors should be:
- structured;
- predictable;
- safe to expose;
- useful to tests and callers.
Do not rely only on free-form strings when a machine-readable code is more appropriate.
Avoid leaking:
- secrets;
- tokens;
- database credentials;
- private keys;
- raw authentication headers.
When modifying Prisma or PostgreSQL-related functionality:
- keep schema changes scoped;
- create reproducible migrations;
- test against a fresh database;
- avoid assuming local database history;
- preserve referential integrity;
- document important constraints.
A migration that only works on one developer's existing database is not acceptable.
Redis should be treated as infrastructure, not the authoritative source of domain state.
Use Redis for concerns such as:
- caching;
- temporary coordination;
- performance optimisation.
Do not make critical GuildPass state exist only in Redis unless explicitly designed and approved.
GuildPass Core V2 is Stellar-first.
When working on Stellar-related functionality:
- validate Stellar formats correctly;
- avoid prefix-only validation;
- keep network logic separated from pure domain logic;
- do not introduce EVM dependencies unless explicitly requested;
- keep Soroban-specific code isolated from unrelated backend functionality.
When working on Soroban contracts:
- include appropriate Rust tests;
- document storage and authorization assumptions;
- avoid unnecessary contract complexity;
- treat public contract interfaces as stable API surfaces.
Changes to public APIs should be intentional.
If your contribution changes:
- request shapes;
- response shapes;
- exported types;
- public function signatures;
- contract interfaces;
document the change clearly in the PR.
Do not introduce breaking changes casually.
Dependencies affect:
- security;
- install size;
- maintenance;
- build reproducibility.
Before adding one, consider whether the functionality can be implemented safely with:
- Node.js built-ins;
- existing project dependencies;
- a small self-contained implementation.
If a new dependency is necessary, explain why in the PR.
Follow the existing codebase conventions.
Prefer:
- clear names;
- small focused functions;
- explicit control flow;
- limited side effects;
- readable tests;
- meaningful comments only where behaviour is non-obvious.
Avoid comments that merely restate the code.
Use clear scoped commit messages.
Recommended format:
type(scope): description
Examples:
feat(policy): add deterministic rule evaluator
feat(stellar): validate Stellar account IDs
fix(api): reject malformed request metadata
test(governance): cover quorum boundary cases
docs(core): update contributor setup
A good pull request should include:
- a clear title;
- a reference to the issue;
- a concise explanation of the implementation;
- tests;
- any important design decisions;
- no unrelated changes.
Reference the issue using:
Closes #123
Your PR description should explain:
Describe the implementation.
Explain the problem being solved.
List the commands and tests you ran.
Example:
pnpm typecheck
pnpm build
pnpm test
Document:
- trade-offs;
- assumptions;
- unusual edge cases;
- intentionally excluded functionality.
GuildPass Core uses GitHub Actions.
The required validation job is:
Build and Test
The central Adamantine Guild PR automation checks:
- CI status;
- pending checks;
- failed checks;
- merge conflicts;
- merge eligibility.
A PR with failing required checks will not be auto-merged.
If checks are still running, the automation waits.
If checks pass and the PR is clean, the PR may be merged automatically.
Changes under:
.github/workflows/
receive additional scrutiny.
Do not modify GitHub Actions workflows as part of an unrelated feature.
Workflow changes may require manual maintainer review before automation is allowed to execute them.
Changes involving any of the following require extra care:
- authentication;
- authorization;
- wallet ownership;
- access control;
- secrets;
- governance;
- smart contracts;
- workflow permissions;
- cryptographic operations.
Security-sensitive code should include targeted tests and avoid undocumented assumptions.
Contributor issues include explicit acceptance criteria.
Your implementation should satisfy those criteria without expanding the task unnecessarily.
If you discover a separate problem while working:
- do not silently fold it into the same PR;
- open or suggest a separate issue;
- keep the current PR focused.
Campaign issues are designed so multiple contributors can work concurrently.
If an issue includes an Independence Requirement, it must be respected.
This means:
- do not wait for another open issue;
- do not import code that only exists in another contributor's unmerged branch;
- do not create hidden cross-issue dependencies;
- keep your solution independently mergeable.
Update documentation when your contribution changes:
- setup instructions;
- architecture;
- public APIs;
- data models;
- CI behaviour;
- Stellar integration;
- contract interfaces.
Documentation belongs under:
docs/
or the relevant public Markdown file.
Do not report vulnerabilities through public issues.
Follow:
SECURITY.md
for responsible disclosure instructions.
All contributors must follow:
CODE_OF_CONDUCT.md
If an issue is unclear, ask a focused question on the issue before implementing a significantly different interpretation.
Avoid opening large speculative PRs without alignment.
Thank you for contributing to GuildPass Core.