Skip to content

Commit 12b8265

Browse files
ioannischtzclaude
andauthored
docs: Claude Code skills and path-scoped rules (#67)
* docs: AGENTS.md / CLAUDE.md agent guidance Canonical AGENTS.md at the repo root (imported by CLAUDE.md via @AGENTS.md), plus per-subproject AGENTS.md / CLAUDE.md pairs for move, ts-sdks, relayer, walrus-discovery-indexer, chat-app, and publish. Covers canonical-vs-reference mental model, repo invariants, build/test/lint entry points, tooling baseline, and security considerations. Includes the pnpm v11 troubleshooting doc that AGENTS.md links to. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: Claude Code skills and path-scoped rules Add .claude/skills/ runbooks (fork-and-extend and SDK-consumer tasks) and .claude/rules/ path-scoped guards (no-edit-generated-codegen, wire-protocol-cross-impact). Update .gitignore to exclude Claude Code user-local state, graphify, and skill-eval artifacts. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: split extend-smart-contracts skill + localnet doc fixes Address review feedback on the skills. - Split the 415-line extend-smart-contracts SKILL.md into a lean router plus six reference/*.md files (package-layout, seal-policy, gated-membership, custom-permission, build-and-publish, wire-to-sdk). - spin-up-relayer: note the localnet gRPC port is the fullnode :9000, not the :9124 consistent store (404s on subscribe_checkpoints). - develop-walrus-indexer: note it can't target localnet (config rejects non-testnet/mainnet, hardcoded gRPC URL, BlobCertified only on testnet). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 0e3a2be commit 12b8265

20 files changed

Lines changed: 2108 additions & 1 deletion

File tree

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
---
2+
paths:
3+
- "ts-sdks/packages/sui-stack-messaging/src/contracts/sui_stack_messaging/**"
4+
---
5+
6+
# Do not hand-edit generated Move bindings
7+
8+
Every file under `ts-sdks/packages/sui-stack-messaging/src/contracts/sui_stack_messaging/` is auto-generated by the `pnpm codegen` pipeline (defined in `ts-sdks/packages/sui-stack-messaging/package.json`):
9+
10+
```
11+
codegen = codegen:summaries → codegen:patch → codegen:generate → lint:fix
12+
```
13+
14+
**Hand-edits are silently clobbered** the next time codegen runs — which is unavoidable any time the Move package's public API changes.
15+
16+
## What to do instead
17+
18+
- If the Move source changed and the bindings are stale: from `ts-sdks/packages/sui-stack-messaging/`, run `pnpm codegen`. Commit the regenerated tree along with the Move-side change in the same PR — reviewers need to see both halves.
19+
- If the binding *behavior* is wrong: fix it in the codegen pipeline (the patch script, the codegen config, or upstream `@mysten/codegen`) and regenerate. The pipeline's output is the source of truth; don't patch it locally.
20+
- If a generated file is missing an export that downstream code needs: that's almost always a sign the Move public API needs to be widened (e.g., a function needs to be `public`), not that the generated file should be edited.
21+
22+
## Why the pipeline has four stages (not one)
23+
24+
The repo's `sui-codegen.config.ts` sets `generateSummaries: false`, so `@mysten/codegen` does **not** run `sui move summary` itself. Instead the in-repo pipeline does it explicitly so a patch step can run between summary generation and TS emission:
25+
26+
1. **`codegen:summaries`**`sui move summary` against `move/packages/sui_stack_messaging/`, producing `package_summaries/` (including `address_mapping.json` for the package and each of its dependencies).
27+
2. **`codegen:patch`**`scripts/patch-address-mappings.js` rewrites `address_mapping.json` so dependency package addresses (e.g. `sui_groups`) become **MVR names** (e.g. `@local-pkg/sui-groups`) instead of the placeholder addresses `sui move summary` emits. This is the workaround for the cross-package dependency issue described below.
28+
3. **`codegen:generate`**`sui-ts-codegen generate` reads the (patched) summaries and emits the bindings under `src/contracts/`.
29+
4. **`lint:fix`** — formats the generated output.
30+
31+
If you need to evolve any of these stages, do it in the right file: the Move package (for summary content), `scripts/patch-address-mappings.js` (for MVR mappings — the `DEPENDENCY_MVR_MAPPINGS` constant), or `sui-codegen.config.ts` (for codegen-side config).
32+
33+
## Known quirks that still require workarounds in this repo
34+
35+
### 1. Cross-package dependency addresses ⇒ `patch-address-mappings.js`
36+
37+
`sui move summary` assigns placeholder addresses to **dependency** packages (here, `sui_groups`, which `sui_stack_messaging` depends on). If those placeholders fed straight into `sui-ts-codegen generate`, the generated bindings would carry hardcoded wrong addresses for everything sourced from `sui_groups`. The patch script rewrites them to MVR names so SuiClient's MVR override resolves the correct address at runtime.
38+
39+
**Implication for anyone extending the Move package with new dependencies:** add the new dependency's MVR mapping to `DEPENDENCY_MVR_MAPPINGS` in `scripts/patch-address-mappings.js`. Without it, the new dep's types in the generated bindings will reference the `sui move summary` placeholder and break at runtime.
40+
41+
### 2. `Move.toml` `r.mvr` key syntax ⇒ explicit `packageName` in config
42+
43+
`sui-codegen.config.ts` sets `packageName: 'sui_stack_messaging'` explicitly, with the comment "Explicit packageName avoids Move.toml parsing failures caused by the `r.mvr` key syntax (not supported by the toml@3 parser)." If you add new packages to the `packages` array, set `packageName` explicitly too — the auto-derivation path hits the toml parser bug.
44+
45+
## What is *no longer* a known quirk
46+
47+
The phantom-type-parameter issues that previously required hand-patching generated BCS functors are **largely fixed upstream**. `@mysten/codegen 0.8.0` shipped:
48+
49+
- a fix for phantom type parameter index mismatch in BCS types for structs with phantom params followed by non-phantom params,
50+
- inclusion of phantom type parameters in generated `MoveStruct` names (e.g. `Pair<T, phantom U>` instead of just `Pair<T>`),
51+
- a new `includePhantomTypeParameters` config option to emit phantom params as function arguments.
52+
53+
This repo pins `@mysten/codegen ^0.8.3` ([`ts-sdks/packages/sui-stack-messaging/package.json`](../../ts-sdks/packages/sui-stack-messaging/package.json)), so the phantom-type fixes are in. If you encounter a *new* phantom-related codegen issue, check the `@mysten/codegen` CHANGELOG on npm for a release that addresses it, bump the version, and regenerate — don't reintroduce hand-edits to the generated files.
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
---
2+
paths:
3+
- "ts-sdks/packages/sui-stack-messaging/src/relayer/**"
4+
- "ts-sdks/packages/sui-stack-messaging/src/verification.ts"
5+
- "ts-sdks/packages/sui-stack-messaging/src/recovery/**"
6+
- "relayer/src/handlers/**"
7+
- "relayer/src/models/**"
8+
- "relayer/src/services/walrus_sync.rs"
9+
- "walrus-discovery-indexer/src/event-parser.ts"
10+
- "walrus-discovery-indexer/src/blob-inspector.ts"
11+
- "walrus-discovery-indexer/src/discovery-store.ts"
12+
- "walrus-discovery-indexer/src/api.ts"
13+
- "walrus-discovery-indexer/src/types.ts"
14+
- "docs/sui-stack-messaging/Relayer.md"
15+
---
16+
17+
# Wire-protocol changes have cross-component impact — coordinate all three sides
18+
19+
The files matched by this rule define **wire contracts shared across three independently-deployed components**: the TypeScript SDK, the Rust relayer, and the TypeScript walrus-discovery-indexer. A change in any one place that breaks the contract silently breaks the other two — often in ways that don't surface until a real cross-component interaction (auth failure, decode error, missing field).
20+
21+
## The three load-bearing contracts
22+
23+
1. **HTTP request/response shape** between SDK ↔ relayer.
24+
- SDK side: `ts-sdks/packages/sui-stack-messaging/src/relayer/http-transport.ts`, `transport.ts`, `types.ts`.
25+
- Relayer side: `relayer/src/handlers/messages/*`, `relayer/src/models/*`.
26+
- Authoritative doc: `docs/sui-stack-messaging/Relayer.md`.
27+
28+
2. **Canonical-message format for signature verification** (security-critical).
29+
- SDK side: `ts-sdks/packages/sui-stack-messaging/src/verification.ts` (`buildCanonicalMessage` / `verifyMessageSender`).
30+
- Relayer side: the same canonical format is reconstructed and verified in `relayer/src/auth/` and in the message models in `relayer/src/models/`.
31+
- Authoritative doc: `docs/sui-stack-messaging/Security.md`.
32+
- **Drift here means signatures the SDK produces won't verify on the relayer (silent auth failures) or vice versa.** Other group members also re-verify with this same format — diverging means *every other client* in the same group stops being able to verify your messages.
33+
34+
3. **Walrus archive format** between relayer (writer) ↔ indexer (reader) ↔ SDK `RecoveryTransport` (consumer of the indexer's output).
35+
- Writer: `relayer/src/services/walrus_sync.rs`.
36+
- Reader: `walrus-discovery-indexer/src/event-parser.ts`, `blob-inspector.ts`.
37+
- Consumer: `ts-sdks/packages/sui-stack-messaging/src/recovery/` and the indexer's REST API in `walrus-discovery-indexer/src/api.ts`.
38+
- Existing archives stop being readable on schema flips — treat as a versioned contract: bump a format version and support both during transition.
39+
40+
## What to do when you must change a contract
41+
42+
- **Update all three sides in the same PR.** Coordinating across two PRs lands you in a window where the components are mutually broken.
43+
- **Update `docs/sui-stack-messaging/Relayer.md` in the same PR** — it's the protocol spec downstream forks rely on.
44+
- **Prefer additive over breaking:** a new endpoint, a new permission type, a new archive variant. Keep old shape supported for at least one release.
45+
- **Bump a format version field** and accept both old and new during the transition; remove the old branch in a later release.
46+
- **If the work is exploratory:** start with the smallest change to all three sides that round-trips a single test case end-to-end (SDK → relayer → Walrus → indexer → SDK recovery), then expand.
47+
48+
## Verification checklist before declaring done
49+
50+
- [ ] `cargo test` passes in `relayer/` (signature verification still works on round-trip).
51+
- [ ] `pnpm test:unit` passes in `ts-sdks/packages/sui-stack-messaging/` (verification.ts unit tests + http-transport.ts unit tests).
52+
- [ ] `pnpm test:integration` runs the localnet-docker stack end-to-end at least once with the new contract.
53+
- [ ] `pnpm test` passes in `walrus-discovery-indexer/`.
54+
- [ ] `docs/sui-stack-messaging/Relayer.md` reflects the new shape.

0 commit comments

Comments
 (0)