Contributing
For an end-to-end developer onramp, follow the quick-start series:
- 6. Local development — workstation setup,
pnpm dev - 7. Add a command flow — schema → handler → GraphQL → tests
- 8. Add a cloud adapter — implement a new provider behind the port spine
This page is a reference for conventions and the “everything I have to know” details that the quickstart guides do not cover.
Prerequisites
- Node 22, pnpm 10 (
corepack enable) - Pulumi + Wrangler (for infra preview and local Workers state)
- Clone with submodules:
git clone --recurse-submodules ...
Local Setup
pnpm installcp .env.example .env # ensure DEV_AUTH_BYPASS / DEV_AUTH_TENANT_ID (see quickstart 6)Local Stack
# D1 migrations + dev tenant seed (local wrangler state)pnpm dev:bootstrap
# Package watchers + gateway (wrangler dev) + agent (tsx watch).# The launcher waits for package watchers to settle before starting# gateway and agent. Run the console separately: apps/console, :3200.pnpm dev
# Optional: watch command and job handler packagespnpm dev:handlersQueue topic names, dev tenant ID, and dev kernel UUIDs all come from CoreManifest (packages/bootstrap/src/core-manifest.ts). Editing the manifest ripples through the bootstrap script, the gateway, and the Fleet UI automatically.
Type Checking
pnpm -r type-check # all packagespnpm --filter @mnemose/cloud-adapters type-checkTests
pnpm -r test # all unit + component testspnpm -r test -- --coveragepnpm --filter @mnemose/domain testpnpm test --filter @mnemose/tests # cross-cutting flow testsAdding a Command Flow
Follow Quick-Start 7. Summary:
- Domain schema — add
XxxCommand+XxxEventZod schemas topackages/domain/src/commands/andpackages/domain/src/events/. Add both toAnyCommandSchema/AnyDomainEventSchema, then re-export contracts (pnpm --filter @mnemose/domain contracts:export). - DB schema — add a job/state table to
packages/db/src/schema/if the command is long-running. Export frompackages/db/src/schema/index.ts. Add the SQL migration underpackages/db/src/migrations/(applied viawrangler d1 migrations). - Command handler — create
services/commands/xxx/src/index.tswithhandleXxx(rawPayload, deps). Pattern: validate → write job record →mintToken→ call IaaS → write domain event → publish. - GraphQL — add the mutation to
services/gateway/src/schema/. Mutations publish tomnemose.commandsviactx.platform.eventBus.publish. - Tests — Zod roundtrip tests in
tests/xxx-flow.test.ts; handler tests colocated with the handler package. - Infra — handlers ship inside the Worker bundle (Workers-edge dispatch); no container/infra entry needed.
- Docs — update
docs/api.mdif the mutation is part of the public API.
Adding a Cloud Adapter
Follow Quick-Start 8. Each port interface lives in packages/cloud-adapters/src/ports/. Implementations go in packages/cloud-adapters/src/<provider>/.
The implementation must:
- Implement the port interface completely (TypeScript will enforce this)
- Accept credentials via
IaaSContext.credential(forIaaS*) or constructor args (for platform-level adapters) - Narrow the
BoundCredentialdiscriminated union and throw for the wrong provider
Export the new class from the provider’s index.ts and wire it into the factory function.
Commit and PR Rules
Mnemose follows the straylight monorepo conventions (CLAUDE.md):
- Atomic, self-contained commits — no implicit context, no “see previous commit”
- Every behavioural change must include the tests that validate it in the same commit
- Every behavioural change must include the documentation update that explains it in the same commit
- No
Co-Authored-Bytrailers in commit messages - Commit messages follow conventional commits (
feat:,fix:,chore:,docs:, etc.) - Push to
apps/mnemosemain directly (no branch protection during bootstrap phase) - Bump the straylight submodule SHA after each mnemose push
Infra Changes
Infrastructure changes go in infra/ (Pulumi, Cloudflare provider). Preview locally:
cd infraPULUMI_CONFIG_PASSPHRASE=*** \pulumi stack select mnemose-dev --createpulumi previewFor end-to-end deploy, see Quick-Start 2.
Documentation Discipline
Per CLAUDE.md:
- Do not allow agent documentation to drift out of sync with the code
- Do update all relevant docs in every commit
That means:
| Change | Documentation that must move with it |
|---|---|
| New command / event | docs/api.md, PROJECT.md workspace layout |
| New service or handler package | PROJECT.md, docs/architecture.md service decomposition |
Schema change to CoreManifest | docs/architecture.md, docs/quickstart/04-provision-core.md |
| New infra resource | docs/architecture.md topology table, PROJECT.md cloud deployment section |
| New cloud adapter | docs/architecture.md port table, docs/integration.md, docs/quickstart/08-add-cloud-adapter.md |
| Any docs/*.md change | pnpm --filter @mnemose/docs compile (regenerate committed site content) |
If you find documentation that is stale or contradicts the code, fix it in the same commit as your change. Stale docs are bugs.