Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@
Welcome to our Developer Guidelines! Your journey to shape the future of DeFi
starts here.

## For Contributors

If you are adding or updating documentation in this or any other Holdex repo,
read [How to Create and Manage Rules](./docs/RULES.md) to understand the
difference between rules, specs, and end-user docs, and how to author each.
Comment on lines +6 to +10

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Contributors are developers.
This needs to be factored into contributing.md


## For Developers

_Developers_ are everyone creating value—business developers, designers,
Expand Down
153 changes: 153 additions & 0 deletions docs/RULES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
# How to Create and Manage Rules

Rules are enforceable operational guidelines — one concern per file,
structured so they can be referenced, audited, and kept up to date independently.
They are distinct from two other document types used across Holdex repos:

| Type | Purpose | Audience |
| --- | --- | --- |
| **Rule** | Defines what must or must not be done and why | Team members executing the work |
| **Spec** | Describes what to build and how it fits together | Builders planning implementation |
| **End-user doc** | Explains how to use something that already exists | External users or end consumers |

If a document enforces a behaviour, it is a rule.
If it describes a system or design, it is a spec.
If it helps someone use a product, it is end-user documentation.

## File format

Every rule is a standalone markdown file in `docs/rules/` with YAML frontmatter:

```yaml
---
id: XXX-NNN
title: "Short description of the rule"
status: "active"
depends_on: "XXX-NNN" # optional — ID of the rule that must be applied first
enforcement: "manual"
severity: "error"
problem: "One-line statement of the situation this rule addresses" # optional

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: must be under 60 chars

---
```

Followed by the rule body:

```markdown
## [Rule title repeated as heading]

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why this is H2 and not H1?


### Problem

What goes wrong when this rule is not followed. Be concrete — name the
failure mode, not an abstract risk.
Comment on lines +40 to +41

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

must be 360 chars max


### Solution

What to do. Use numbered steps for sequential actions, bullets for
independent items. Be specific enough that a new team member can apply
it without asking for clarification.
Comment on lines +45 to +47

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

must be 360 chars max


#### Acceptance Criteria

- [ ] Checkable item that confirms the rule was applied
- [ ] Another checkable item
```

`Acceptance Criteria` is optional but strongly recommended for rules that

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

each step must be atomic

require a sequence of steps to verify.

## File naming

Name rule files by ID only — no descriptive slug:

```
docs/rules/SAL-190.md ✓
docs/rules/SAL-190-hourly-rate-expression.md ✗
```

The title lives in the `title:` frontmatter field and in the README index.
The file name must stay stable even when the rule content changes. A
descriptive slug would need renaming whenever the rule evolves, breaking
any existing references.

## ID numbering

- Each repo has its own prefix (e.g. `SAL-` for `holdex/partners`,
`HR-` for `holdex/hr-internal`, `DEV-` for `holdex/developers`)
- IDs increment by 10 (`DEV-010`, `DEV-020`) to leave room for insertion

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

by 100, not 10

without renumbering the existing set
- IDs are permanent — never change or reuse a retired ID
- When inserting between existing IDs, use the midpoint
(e.g. `DEV-015` between `DEV-010` and `DEV-020`)

## Sequencing with depends_on

When one rule must be applied before another, declare the prerequisite with
`depends_on`. Only one dependency per rule — chains resolve transitively:

```yaml
depends_on: "SAL-260"
```

If rule C depends on B and B depends on A, only B needs to declare A —
C picks up the full chain automatically.

A CI script validates the dependency graph on every PR that touches
`docs/rules/` or the README:

1. **No cycles** — the graph must be a DAG. A → B → A is an authoring
error and fails the check.
2. **README order** — within each README section, no rule may be listed
before its dependency. Out-of-order entries fail the check.

When adding `depends_on` to a rule, also verify the README index lists
the dependency above it in the same section.

## Status lifecycle

Every rule must have a `status` field. Change it as the rule evolves — never
delete a rule file, because its ID may be referenced elsewhere.

| Status | When to use |
| --- | --- |
| `active` | Current and enforced |
| `deprecated` | No longer relevant; kept so existing references resolve |
| `superseded` | Replaced by a newer rule |

When a rule is superseded, add `superseded_by: XXX-NNN` to its frontmatter
pointing to the replacement:

```yaml
---
id: DEV-010
title: "Old rule title"
status: "superseded"
superseded_by: "DEV-050"
enforcement: "manual"
severity: "error"
---
```

## README index

Every `docs/rules/` directory must have a corresponding README section that
indexes all active rules. Format each entry as a list item with the rule ID
linked to the file and a one-line description:

```markdown
## Section name

1. [DEV-010](./docs/rules/DEV-010.md): one-line description of what it enforces
1. [DEV-020](./docs/rules/DEV-020.md): one-line description of what it enforces
```

Deprecated and superseded rules are omitted from the index but their files
remain in `docs/rules/`.

## When not to write a rule

- **Advice without enforcement** — if there is no clear wrong behaviour, it
is guidance, not a rule. Write it in the relevant README or doc instead.
- **Implementation detail** — how a system works internally belongs in a spec
or inline code comment, not a rule.
- **One-time decisions** — things that were decided once and will not recur
belong in an ADR or commit message, not a rule.