Skip to main content

First Contribution

Green Goods is open-source infrastructure, and contributions of any size are welcome. A fixed typo teaches you the PR flow just as well as a feature does. This page walks the whole path: finding something to work on, making the change, proving it, and getting it merged.

This page is the full contributor guide. The repository's CONTRIBUTING.md is its one-screen summary, kept next to the code.

Find something to work on​

Green Goods tracks its work in Linear, not GitHub issues; GitHub is for pull requests and code review. That means the best first step is a conversation: say hello on Discord, tell us what interests you, and a maintainer will point you at a scoped task that fits.

Two honest ground rules: confirm scope with a maintainer before investing serious time, and don't treat unlabeled roadmap items as funded work. Green Goods doesn't run open-ended bounties; paid implementation is grant-dependent and always scoped in writing first.

Set up​

If you haven't run the project yet, Getting Started takes 15 to 30 minutes and ends with the app running on your machine. Come back here once you've seen it work.

Bring an agent​

Building with AI agents is a core part of how Green Goods gets made, not a side channel. The maintainers develop with Claude Code and Codex daily, and the repository is instrumented for it: an AGENTS.md contract at the root and in most packages, a catalog of packaged skills for common workflows, and a validation selector that keeps agent-made changes honest.

The fastest start is below: copy the repository's ONBOARDING.md into your agent. It's written to be read by one: your agent becomes an onboarding buddy that checks your setup, picks the right path, and finishes with a short report of what it verified, what's still missing, and which package owns your first task.

ONBOARDING.md, ready to copy
ONBOARDING.md
# Onboarding to Green Goods

Use this procedure with a coding agent or follow it yourself. The [README](README.md)
explains the product; [AGENTS.md](AGENTS.md) owns repository rules. Run commands from
the repository root unless a command specifies `--cwd`.

## Before setup

1. Read `AGENTS.md`, inspect the current branch and working-tree changes, and preserve
work belonging to other sessions. Do not switch branches during shared-checkout work.
2. Check Node, Bun, Git, and existing dependencies. Use the versions in
[.mise.toml](.mise.toml); Node must be version 22. Use WSL2 on Windows.
3. Inspect existing services with `bun run dev -- status`. Reuse compatible services;
only the owning session may stop them. Missing dependencies may prevent status from running.
4. Choose the public-contributor path without shared credentials, or the team path
with 1Password access and Docker. Do not print environment values or credentials.

Setup may install dependencies and missing tools. Agents must honor the installation
permissions in `AGENTS.md`; if installation is not authorized, report that dependency
before proceeding. An existing root `.env` is preserved on setup reruns.

## Public contributor path

The isolated profile works on a local machine as well as in a worktree or container.
It avoids host-tool installation and writes non-secret defaults only when `.env` is absent.

```bash
npm run setup -- --profile isolated
bun run dev:health -- prod
bun run dev -- prod
```

When Bun is already available, `bun run setup -- --profile isolated` uses the same setup.
The hosted mode starts local client, admin, docs, and Storybook, using production APIs.
It needs neither team secrets nor a local indexer for public browsing. Missing credentials
for passkeys, wallets, or uploads remain capability limits, not proof of a broken public setup.

Open the printed client URL and browse public gardens. The admin sign-in/access gate is
expected without steward credentials. Do not claim privileged workflows are verified.
**Hosted mode permits real wallet-confirmed Arbitrum transactions; browsing verification
must not submit transactions.**

## Team path

Start OrbStack or Docker Desktop before launching local indexer services.

Existing `.env` files are kept. Review readiness before explicitly replacing local credentials.
**Confirmed transactions affect live Arbitrum.**

```bash
npm run setup -- --profile host
test -f .env || bun run env:sync
bun run env:check
bun run dev:health
bun run dev
```

Host setup reports how to configure the environment; it does not fetch shared secrets.
The sync resolves the 1Password references in `env.schema`, the one checked-in environment file,
and writes the root `.env`. The [environment guide](https://docs.greengoods.app/builders/getting-started#environment)
explains 1Password access and personal credentials. Never create package-level env files.

The default stack starts local client, admin, agent, and Docker indexer against **live
Arbitrum One**. Confirmed wallet and passkey transactions are production transactions.
`ENVIO_API_TOKEN` supports reliable indexer replay; service health alone does not prove
that replay has caught up. Uploads and messaging require their own service credentials.

## Development modes

Use `bun run dev -- <mode>`, with the same mode for health and smoke:

| Mode | Local services | Chain and data |
|---|---|---|
| `local` | admin, client, agent, indexer | Default; live Arbitrum and local APIs |
| `full` | docs, admin, client, agent, indexer, storybook, browser | Live Arbitrum and local APIs |
| `fork` | anvil-arbitrum, admin, client, agent, indexer | Local Arbitrum fork; indexer still reads live networks |
| `web` | docs, admin, client, storybook, browser | Live chain; local APIs must already be available |
| `prod` | docs, admin, client, storybook, browser | Live chain and hosted APIs |
| `prod-mirror` | docs, admin, client, indexer, storybook, browser | Live chain, hosted agent, local live-data indexer |

Service names select a narrower launch: `bun run dev -- client admin` does not start
its agent or indexer dependencies. Stop the owning launcher before changing modes.

For fork testing, use a dedicated browser profile and a disposable Anvil-funded wallet.
Local account details are in `packages/contracts/.generated/runtime/arbitrum-fork.json`.
Configure RPC `http://127.0.0.1:3009`, chain `42161`. The file redacts the upstream fork
endpoint. Restarting Anvil resets local chain state; the indexer does not ingest these
local writes. Passkeys are blocked in fork mode. Mock authentication does not sign transactions.

## Verify and hand off

Run `bun run dev:smoke -- <mode>` after startup. Automatic smoke checks reachability and,
for connected modes, chain/indexer readiness. It submits no transactions. If replay is
behind, leave the owning launcher running and rerun smoke after catch-up.

For local agent browser verification, follow `AGENTS.md § Browser Evidence`: label the engine and
session behind every rendered proof, and use the authenticated Brave extension path only for the
authenticated surface class. If it cannot be reached, record that proof as pending; never report
an isolated profile as authenticated proof or an HTTP check as rendered proof.

Keep the launcher in the foreground; Ctrl-C stops only its services. A detached stop uses
`GREEN_GOODS_DEV_OWNER=<same-owner> bun run dev -- stop`. Never stop an unknown listener.

Finish onboarding by reporting:

- The setup path, selected mode, and URLs that were actually verified.
- Missing credentials, services, or browser access and the workflows they block.
- The package that owns the contributor's first task and its nearest `AGENTS.md`.
- The next targeted check selected with `bun run check --plan -- --intent qa`.

Use [CONTRIBUTING.md](CONTRIBUTING.md) for the contribution process and
[the command reference](scripts/README.md) for specialist tooling. Agent-specific harness
notes belong in [CLAUDE.md](CLAUDE.md), not in this procedure.

Agents get no shortcuts. Their changes pass the same review, the same CI Gate, and the same repo rules as anyone else's, and that's exactly why the practice works.

Make the change​

  1. Branch from develop, named <type>/<short-work-description>. For example fix/garden-join-toast or feature/assessment-export. PRs target develop, the staging branch; maintainers promote to main in monthly releases.
  2. Read the nearest AGENTS.md before editing a package. The root one maps the monorepo, and most packages carry their own with the rules that actually bite.
  3. Keep the change inside the smallest package boundary that solves the problem, and add or update tests when behavior changes.

A few repo-wide rules worth knowing before your first diff: React hooks live in @green-goods/shared, Ethereum addresses use the shared Address type, logging goes through the shared logger (never console.log), user-facing strings ship in en, es, and pt together, and the environment lives in one root .env (Getting Started explains it). The full list lives in CONTRIBUTING.md § Repo Rules.

Prove it​

Prove a change in four steps, smallest first. CI covers broad regression across the repository, so you never need to run everything locally.

  1. Ask what your change needs. The selector reads the files you changed and lists the smallest honest set of checks. Nothing runs yet:

    bun run check --plan -- --intent qa
  2. Run the one test closest to your change. Start with the test that proves the behavior you touched, through its package's own command. For a client test, that looks like this:

    bun run --cwd packages/client test src/__tests__/bootFallback.test.tsx

    The Testing Guide has the command for every package. Always bun run test, never bun test.

  3. Run what the plan selected. The same command without --plan runs those checks and prints an Outcome line that says whether they passed:

    bun run check -- --intent qa
  4. Format, then push. Run bun run format. When you push, the pre-push hook runs the ready-for-CI gate for you and stops the push if a check fails. The Testing Guide shows how to run that gate by hand and which Playwright project matches your surface.

If your change is visible, add rendered proof to the pull request and say where it came from: mock auth on localhost, Storybook, CI Playwright, or a real signed-in browser.

Open the pull request​

Open the PR into develop and say three things: what changed, why, and how you validated it. Then expect some robot company:

  • CI Gate is the required check. It aggregates every workflow your change triggered, and the PR merges only when it's green.
  • CodeRabbit and Codex review every push. Respond to what's right, explain what isn't, and they re-review each time you push.
  • Merging to develop deploys to staging. Your change reaches production with the next monthly release.

Stay in touch​

  • Discord, where the conversation happens and where a maintainer will point you at a first task.
  • The Code of Conduct applies everywhere. Report security issues through the Security Policy, never a public issue.

Next steps​