Skip to content
12 changes: 12 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,18 @@ same rules:
- Do not add dependencies or change the package split without explicit sign-off
- the package boundary is an audit boundary (see
[`ARCHITECTURE.md`](./ARCHITECTURE.md)).
- When you add a new package (a new `Move.toml` directory under `contracts/` or
`math/`), register it in the CI package matrix in the same PR - add its path to
the `PACKAGES` array in
[`.github/workflows/test.yml`](./.github/workflows/test.yml). The matrix is the
only thing that builds, lints, and tests a package in CI; a package missing from
it is silently never checked, so its tests do not gate merges.
- When you add a new public-facing component (a new package, or a new public
capability of an existing one), ship a runnable example in the same PR - add a
minimal program under the package's `examples/` that exercises it end to end.
Examples are the integration-facing source of truth for AI agents and
downstream integrators, the same way doc-comments are the source of truth for
the generated API reference.

## A typical workflow

Expand Down
24 changes: 20 additions & 4 deletions STYLEGUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,12 @@ Examples of required rewrites:
silently.
- Prefer pinning exact values: `assert_eq!(result, exact)` over bound-only
assertions (`assert!(r >= lo && r <= hi)`). For genuine property tests, use
Sui's `#[random_test]` attribute.
Sui's `#[random_test]` attribute. **Exception:** an approximation test that
checks an on-chain result against an off-chain mathematical reference within a
tolerance (e.g. `assert!(diff < epsilon)`) is *intentionally* bound-based - the
tolerance is the point. Do not convert these to `assert_eq!`; pinning the exact
on-chain output would only assert "the implementation returns what it returns"
and lose the closeness-to-truth check.
- Prefer `assert!(cond)` over `assert!(cond, 0)` - Move 2024 auto-assigns abort
codes when omitted; a literal `0` is meaningless boilerplate.
- No cleanup in expected-failure tests - just `abort` at the failure boundary.
Expand All @@ -233,15 +238,25 @@ Examples of required rewrites:

## Documentation

Doc-comments are the source of truth for the generated API reference
(`sui move build --doc`) and for downstream AI-integrator tooling - treat them as
part of the public API, not decoration. Keep them complete and accurate.

Comment thread
bidzyyys marked this conversation as resolved.
- `///` for doc comments (renders in IDEs), `//` for inline technical notes
- No JavaDoc-style `/** */`
- Use regular dashes (`-`) instead of em dashes (`—`) in all prose, comments,
and documentation
- Document struct fields, complex params, and return values
- Use section headings `#### Parameters`, `#### Returns`, and `#### Aborts` when
relevant; use `-` for list items (not `*`)
- Document public functions with at least `Parameters` and `Returns`; include an
`Aborts` section whenever a function can abort
- Document public functions: include `#### Parameters` and `#### Returns` where
they add detail beyond the one-line summary - a trivial getter whose summary
already states what it returns needs neither. Always include an `#### Aborts`
section whenever a function can abort, listing **every** cause it can raise -
including native aborts (e.g. arithmetic overflow, division by zero) and
errors propagated from internal calls
- State caller preconditions explicitly and map each to the error it fails with,
one bullet per cause (e.g. "`EUnauthorized` if the caller lacks the role")
- Keep terminology consistent with the implementation (e.g. avoid documenting
impossible paths)

Expand All @@ -256,5 +271,6 @@ Examples of required rewrites:
/// - Rounded output value.
///
/// #### Aborts
/// - Aborts if `value` is zero.
/// - `EZeroValue` if `value` is zero.
/// - Arithmetic overflow if the scaled result exceeds the type's range.
```
7 changes: 6 additions & 1 deletion contracts/access/sources/ownership_transfer/delayed.move
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,12 @@ public struct PendingTransfer has drop, store {

/// Hot potato to ensure a wrapped object was returned after being taken using
/// the `borrow_val` call.
public struct Borrow { wrapper_id: ID, object_id: ID }
public struct Borrow {
/// ID of the `DelayedTransferWrapper` the object was taken from.
wrapper_id: ID,
/// ID of the borrowed object that must be returned.
object_id: ID,
}

// === Events ===

Expand Down
12 changes: 10 additions & 2 deletions contracts/access/sources/ownership_transfer/two_step.move
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,18 @@ public struct PendingOwnershipTransfer<phantom T: key + store> has key {
}

/// Hot potato used to ensure a wrapped object was returned after being taken using `borrow_val`.
public struct Borrow { wrapper_id: ID, object_id: ID }
public struct Borrow {
/// ID of the `TwoStepTransferWrapper` the object was taken from.
wrapper_id: ID,
/// ID of the borrowed object that must be returned.
object_id: ID,
}

/// Hot potato used to ensure a wrapper was returned to its request after `request_borrow_val`.
public struct RequestBorrow { wrapper_id: ID }
public struct RequestBorrow {
/// ID of the `TwoStepTransferWrapper` that must be returned to its request.
wrapper_id: ID,
}

// === Events ===

Expand Down
Loading
Loading