# AGENTS.md

Authoring custody: this repository owns Ferry's complete source, selected
components, integration, requirements and releases. First-party maintainers,
owner forks and community publishers use the same `edition.json` and
`scripts/edition-authoring/cli.mjs` workflow. Edit the actual source here;
Sales no longer generates or publishes Ferry. `sources.lock.json` records the
effective bytes and retained comparison sources. `composition.lock.json` is
historical provenance only, retained for existing composition checks.

The shared product is a cohesive starting point. Owners and community authors
may change core behavior, schema, UI, infrastructure and any other source.
Configuration and hooks are useful conveniences, not limits. Agents choose the
integration method and handle complex merges; verify recorded requirements and
affected data transitions. Useful discoveries can be contributed with tests to
shared source, then deliberately adopted and verified by other editions.

> Read `HANDOVER.md`, `seed.json`, and `package.json` for implemented behavior, verified commands, and remaining contract acceptance.

You are working on a **seed**: a complete, self-hostable product the owner of this repository has installed and now owns. Launch it, make it exactly what the owner needs, keep it working, keep it updatable. Never make the product worse to avoid touching core code.

Read first:

1. `CONTRACT.md` — what the product does, as numbered clauses. `BASELINE.md` holds the security and data guarantees every seed makes.
2. Existing owner requirement records, including `DIVERGENCE.md`, relevant contract clauses and `.seed/intent.md` if present. Preserve binding requirements; no particular file or format is required.
3. `seed.json` — capabilities, non-goals, externals, env, limits, extension points.
4. `src/ext/` — customisations already made.

## About this product

Ferry is an intervention-first sales pipeline for one business. TanStack Start owns React documents and generated RPC; the custom Cloudflare Worker owns dispatch and scheduled events, while Hono owns the declared API and native-auth paths. Preserve native session validation in both documents and private generated functions.

## Launch

Locally:

```
pnpm install
FERRY_OWNER_EMAIL=you@your-business.example FERRY_OWNER_NAME="Your name" pnpm dev
```

This initializes an empty local D1 workspace with the explicit owner and pipeline stages. Use the local sign-in control. Sample records are confined to the test runtime `pnpm dev:test`.

To Cloudflare, set the owner, business, provider credentials and resource configuration listed in `README.md`, then run:

```sh
pnpm run setup
pnpm run deploy
```

These are package scripts; use `pnpm run` to avoid pnpm's built-in setup/deploy commands. Setup reuses the named resources; deploy applies migrations, bootstraps the owner, configures secrets and checks health. GitHub deployment and pull-request previews require owner-configured automation; they are not supplied by these commands.

Live check: `GET <url>/health` returns 200. Public surfaces are at `deploy.publicPaths` in `seed.json`.

If anything is missing the tooling names it. Do not substitute services or invent config.

## Ownership

```
src/core/  migrations/core/  tests/e2e/      shared starting source, freely editable.
src/ext/  .seed/  migrations/ext/  tests/local/   optional organisation conventions; customisations may live anywhere.
```

`src/ext/config.ts` and every file under `src/ext/local/` have a header comment with a worked example.

## Modify

Choose the coherent change that best serves the product and its future upkeep.
The mechanisms below are conveniences where implemented, not a required order
or a restriction on direct source changes.

| Owner wants to | Do this |
|---|---|
| Rename things, toggle features, change copy, branding | `src/ext/config.ts`; tokens in `src/core/app/theme` |
| Add a field to a record | Custom fields if the entity has them (`seed.json`). Otherwise change the schema with a new migration through the implemented migration command; do not assume an extension directory is applied automatically. |
| Add a page, route, nav entry, settings section, job, cron, queue consumer | `src/ext/local/<name>/`, registered from `index.server.ts` / `index.client.tsx` |
| Add UI to an existing screen | Contribute to a slot. IDs in `seed.json`. |
| Change a product decision (assignment, permissions, AI instructions) | Override the policy if one exists; otherwise edit the feature's `service.ts` |
| React to something that happened (Slack, webhook, sync) | Subscribe to the event in `server.ts`. Events cannot alter the operation that emitted them. |
| Run something async the owner triggers (export, report) | Dispatch a job |
| Swap email, AI, calendar, storage provider | Override the adapter |
| Inbound webhook | Route in `server.ts` under `/api/ext/`. Idempotent. |
| Redesign a core screen beyond what slots allow | Edit `src/core/features/<name>/ui/` |

- DB access only through a `repository.ts`. Never from a route or component.
- Prefer existing API boundaries where they fit; change them coherently when the product needs it.
- New API operation: zod input, typed output, standard error format, test.
- Preserve identities and contents of already-applied migrations; add migrations for schema changes, including new core migrations. Verify transitions from prior data and recovery for destructive changes. Never commit infrastructure IDs or secrets.

## Editing core

Allowed. Understand the whole feature, make the coherent change, add applicable
verification in the existing test suite, and record *why* alongside the edition’s
existing requirements. `tests/local/` and `.seed/intent.md` are optional conventions.
For example:

```
## Conversations
AI may draft replies but must never send one automatically.
```

Intent, not implementation. Never remove an intent unless the owner changes that requirement.

If the owner wants behaviour that contradicts a clause in `CONTRACT.md`, record the affected clause, the owner's reason and the replacement behavior alongside the edition's existing requirements, and add tests for that requirement. Preserve the upstream requirement and test history so the difference remains reviewable. Deliberate changes to baseline security requirements must reflect and record the owner’s authority; ordinary fixes that meet existing requirements need no additional confirmation. Automated contract-override and clause reporting are not implemented; `pnpm verify` does not certify them. An upstream failure without an intentional owner requirement is a regression to fix.

## Verify

```
pnpm verify
```

Before saying anything is done. It runs types, lint, manifest validation, bootstrap and shared component checks, Workers tests and build. Full clause reporting and the shared baseline acceptance remain open; do not infer complete contract satisfaction from a passing command. For user-facing changes, also exercise the journey on `pnpm dev` or a preview.

## Update

Use ordinary Git against the edition's upstream repository. Inspect its new commits and release evidence, then choose an integration method that preserves this fork's changes. An isolated branch or worktree can make the candidate easy to review; no marketplace `rer` update CLI or automatic verified-tag, migration, rebase or conflict-clause reporting is provided.

Read existing owner requirement records, the applicable contract clauses and upstream changes together. Resolve conflicts by preserving the owner's requirements and understanding the upstream fix; do not select whole sides blindly. Review migrations before applying them, run `pnpm verify` plus applicable owner tests, and exercise the affected workflow and guarantees. A clean merge or passing upstream suite alone does not establish that owner intent survived. Record the result in `HANDOVER.md`, then use `pnpm run setup` and `pnpm run deploy` for an authorized deployment.

## Leave

The edition repository is self-contained and remains in the owner's control. Portable database/storage export and restore remain acceptance work; there are no implemented `pnpm export` or `pnpm import` package scripts. Consult `HANDOVER.md` and the current provider tools when planning a verified backup or move. License terms are in `LICENSE`.

## Do not

- Remove upstream tests merely to hide a regression; preserve and test intentional owner requirements explicitly.
- Edit released migrations.
- Add a hosted dependency where the seed already provides the capability. New externals go in `seed.json` behind an adapter.
- Hide failures behind fallbacks.
- Build plugin systems, event buses, or runtime code loading.
- Stop at scaffolding, or claim completion because it compiles.
