Skip to content

Commit 2c80f19

Browse files
committed
(docs) add AGENTS.md
1 parent d895c3a commit 2c80f19

1 file changed

Lines changed: 171 additions & 0 deletions

File tree

AGENTS.md

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
# AGENTS.md
2+
3+
Guidance for AI coding agents working in this repository. See
4+
<https://agents.md/> for the file convention.
5+
6+
## Project Overview
7+
8+
- Project name: write it as `fcf` in prose and commands.
9+
- Purpose: CLI tooling and EVM smart contracts for the
10+
`@freecodexyz` funding layer.
11+
- Repository shape: small monorepo with a TypeScript CLI in `cli/` and a
12+
Foundry Solidity project in `contracts/`.
13+
- CLI stack: Node 24 in CI, ESM TypeScript, `pnpm@10.24.0`, Commander, Viem,
14+
tsup, tsx, TypeScript, and Vitest.
15+
- Contract stack: Foundry, Solidity `^0.8.24`, OpenZeppelin Contracts, and
16+
`forge-std` as git submodules under `contracts/lib/`.
17+
- Core contract: `RIK`, an ERC-721 "Repository Identity Key" that registers a
18+
GitHub repository identity from a GitHub Actions OIDC JWT.
19+
20+
## Environment Setup
21+
22+
- Use Node 24 for CLI work to match GitHub Actions.
23+
- Use Corepack and pnpm in `cli/`; there is no root `package.json`.
24+
- Initialize submodules before contract work:
25+
`git submodule update --init --recursive`.
26+
- Install Foundry for contract build/test commands: `forge`, `cast`, and
27+
`anvil` are expected for local contract workflows.
28+
- `contracts/foundry.toml` has `ffi = true` because the Foundry tests call a
29+
Node fixture generator via `vm.ffi`.
30+
31+
## Commands
32+
33+
| Purpose | Command |
34+
| --- | --- |
35+
| Install CLI dependencies | `cd cli && corepack enable && pnpm install --frozen-lockfile` |
36+
| Run CLI from source | `cd cli && pnpm dev -- --help` |
37+
| CLI typecheck | `cd cli && pnpm typecheck` |
38+
| CLI tests | `cd cli && pnpm test` |
39+
| CLI build | `cd cli && pnpm build` |
40+
| Regenerate committed ABI | `cd cli && pnpm abi` |
41+
| Contract format check | `cd contracts && forge fmt --check` |
42+
| Contract build with sizes | `cd contracts && forge build --sizes` |
43+
| Contract tests | `cd contracts && forge test -vvv` |
44+
| Local Anvil deploy helper | `./local-rpc.sh src/RIK.sol:RIK` |
45+
| Sepolia deploy script | `cd contracts && PRIVATE_KEY=... ./deploy-sepolia.sh` |
46+
| Finds agents TODOs when asked | `rg -F 'TODO (AGENT)'` |
47+
48+
Do not run release/versioning commands such as `cd cli && pnpm version:minor`
49+
or `cd cli && pnpm prepublishOnly` unless the user explicitly asks for a
50+
release path. They mutate `cli/package.json`.
51+
52+
## Repository Structure
53+
54+
- `.github/workflows/test-cli.yml`: CLI CI; installs with pnpm and runs
55+
`pnpm test` under `cli/`.
56+
- `.github/workflows/test-contracts.yml`: contract CI; runs `forge fmt --check`,
57+
`forge build --sizes`, and `forge test -vvv` under `contracts/`.
58+
- `.github/workflows/fcf-register.yml`: checked-in registration workflow emitted
59+
by the CLI `init` command.
60+
- `local-rpc.sh`: root helper that starts Anvil, deploys a contract, prints the
61+
RPC URL/private key/owner/contract address, and waits until interrupted.
62+
- `cli/src/index.ts`: Commander CLI entrypoint and workflow template.
63+
- `cli/src/oidc.ts`: JWT base64url helpers, parsing, and GitHub `kid` hashing.
64+
- `cli/src/importAbi.ts`: loads the committed static ABI by default.
65+
- `cli/src/abi/RIK.json`: committed generated ABI used by the published CLI.
66+
- `cli/scripts/generate-abi.mjs`: copies the ABI from the Foundry artifact into
67+
`cli/src/abi/RIK.json`.
68+
- `contracts/src/RIK.sol`: repository identity ERC-721 and JWT verification.
69+
- `contracts/src/JsonClaim.sol`: minimal byte-search JSON claim helper.
70+
- `contracts/test/RIK.t.sol`: Foundry regression tests for registration,
71+
ownership, JWT claims, keys, and expiry.
72+
- `contracts/test/fixtures/load-fixture.mjs`: Node helper used by `vm.ffi` to
73+
generate deterministic RSA/JWT fixtures for Solidity tests.
74+
- `contracts/script/Deploy.s.sol`: Foundry deploy script.
75+
- `contracts/deploy-sepolia.sh`: Sepolia deploy wrapper using `PRIVATE_KEY` and
76+
optional `SEPOLIA_RPC_URL` / `VERIFY`.
77+
- `contracts/lib/`: git submodules and vendor code. Do not edit directly.
78+
79+
## Architecture Boundaries
80+
81+
- `RIK.tokenIdOf(githubRepoId)` is intentionally identity mapping; the token ID
82+
is the GitHub repository ID.
83+
- `RIK.register()` must validate the JWT before minting: active `kid`, RSA
84+
signature, `aud`, `repository_id`, `repository_owner_id`, issuer, `exp`,
85+
`nbf`, and duplicate registration.
86+
- Preserve the issuer string exactly:
87+
`https://token.actions.githubusercontent.com`.
88+
- The CLI requests GitHub OIDC tokens with the lowercase signer address as the
89+
audience; the contract compares `aud` against `Strings.toHexString` of
90+
`msg.sender`.
91+
- GitHub JWKS `kid` values are stored on-chain as `keccak256(Buffer.from(kid))`;
92+
keep `jwtKid()` and contract key lookups aligned.
93+
- `keys sync` is the path that imports active GitHub RSA keys into the contract.
94+
Do not weaken key filtering or signature validation.
95+
- `JsonClaim` is deliberately small and byte-oriented. If claim parsing changes,
96+
add regression tests for missing claims, mismatched claims, and valid compact
97+
JWT payloads.
98+
- `cli/src/importAbi.ts` defaults to the committed static ABI. `SKIP_STATIC_ABI`
99+
switches to the Foundry artifact path for local development.
100+
- Keep `cli/src/index.ts`'s `REGISTER_WORKFLOW` template and
101+
`.github/workflows/fcf-register.yml` behavior in sync when registration
102+
workflow semantics change.
103+
- Contract ABI changes must be followed by `cd cli && pnpm abi` so the packaged
104+
CLI ABI stays current.
105+
106+
## Code Style
107+
108+
- Prefer small, direct changes. Avoid broad refactors unless the user asks.
109+
- Match nearby formatting in each file. There is no configured TypeScript
110+
formatter in the CLI package.
111+
- TypeScript is strict ESM with `module: nodenext`, `verbatimModuleSyntax`,
112+
`exactOptionalPropertyTypes`, and `noUncheckedIndexedAccess`.
113+
- Use `node:` built-in imports in new TypeScript files.
114+
- Use type-only imports when importing TypeScript types, e.g. `import type`.
115+
- Keep CLI command behavior explicit through Commander options and `die()`
116+
messages rather than silent fallbacks.
117+
- Solidity code should pass `forge fmt`; use custom errors for contract-specific
118+
failures when practical.
119+
- Use `// forge-lint: disable-next-line(...)` only next to the exact line that
120+
needs it, and keep a short reason nearby when the reason is not obvious.
121+
- Comments should explain constraints or non-obvious behavior, not restate names.
122+
123+
## Testing
124+
125+
- For CLI-only changes, run `cd cli && pnpm typecheck` and `cd cli && pnpm test`.
126+
- For contract-only changes, run `cd contracts && forge fmt --check`,
127+
`cd contracts && forge build --sizes`, and `cd contracts && forge test -vvv`.
128+
- For ABI-affecting contract changes, also run `cd cli && pnpm abi`,
129+
`cd cli && pnpm typecheck`, and `cd cli && pnpm build`.
130+
- Keep Foundry tests deterministic and local. Do not hit GitHub, Sepolia, or
131+
other live RPC endpoints from unit tests.
132+
- Contract tests may use `vm.ffi` with `contracts/test/fixtures/load-fixture.mjs`;
133+
avoid adding more external process dependencies unless necessary.
134+
- Add CLI tests as Vitest tests under `cli/src/` or a future `cli/test/`
135+
directory. Mock `fetch`, Viem clients, and filesystem writes rather than using
136+
live network calls.
137+
138+
## Git/PR Workflow
139+
140+
- Recent human commit format: `(type) imperative summary`.
141+
- Examples from this repo: `(feat) add deployment script for RIK contract`,
142+
`(fix) add shebang to index.ts for execution in github actions`,
143+
`(chore) bump cli version`.
144+
- AI-created commit format when the user asks for a commit:
145+
`(type) (openai/gpt-5.5, reviewed T|F, tested T|F) imperative summary`.
146+
- Before creating an AI commit, ask the user whether a human reviewed the
147+
changes so `reviewed T|F` is accurate.
148+
- Mark `tested T` only after the relevant checks have run successfully.
149+
Otherwise use `tested F`.
150+
- Before committing, inspect `git status --short`, `git diff`, and
151+
`git log --oneline -10`; stage only intended files.
152+
- Run `git diff --check` before commit/PR handoff.
153+
154+
## Boundaries
155+
156+
- Never edit, print, copy, infer, or commit real secrets: `.env`, `.env.*`,
157+
`PRIVATE_KEY`, GitHub tokens, RPC credentials, wallet data, or provider keys.
158+
- Do not commit `contracts/.dev-wallet-data` or values printed by
159+
`local-rpc.sh`. Anvil keys are disposable but still should not enter commits.
160+
- Do not deploy, broadcast transactions, sync production keys, or call live RPCs
161+
unless the user explicitly asks.
162+
- Do not change production/provider configuration without explicit approval:
163+
environment variable names, default RPC behavior, GitHub OIDC issuer,
164+
workflow permissions, contract addresses, or default package tags.
165+
- Do not edit generated or dependency directories directly: `cli/node_modules/`,
166+
`cli/dist/`, `contracts/cache/`, `contracts/out/`, `contracts/broadcast/`,
167+
or `contracts/lib/`.
168+
- The committed static ABI at `cli/src/abi/RIK.json` is generated but tracked;
169+
update it only through `cd cli && pnpm abi` when the contract ABI changes.
170+
- Never replace pnpm with npm/yarn or Foundry with another contract toolchain
171+
without explicit user approval.

0 commit comments

Comments
 (0)