From 657f203fe1fd3cb83fc1f6c5e611299692c5c017 Mon Sep 17 00:00:00 2001 From: Vadim Zolotokrylin <1125014+zolotokrylin@users.noreply.github.com> Date: Mon, 29 Jun 2026 13:12:45 +0800 Subject: [PATCH 1/2] docs(rules): add authoring guide for creating and managing rules --- README.md | 6 +++ docs/RULES.md | 129 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 135 insertions(+) create mode 100644 docs/RULES.md diff --git a/README.md b/README.md index a287318..1faecfd 100644 --- a/README.md +++ b/README.md @@ -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. + ## For Developers _Developers_ are everyone creating value—business developers, designers, diff --git a/docs/RULES.md b/docs/RULES.md new file mode 100644 index 0000000..0ed9a7b --- /dev/null +++ b/docs/RULES.md @@ -0,0 +1,129 @@ +# 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" +enforcement: "manual" +severity: "error" +problem: "One-line statement of the situation this rule addresses" # optional +--- +``` + +Followed by the rule body: + +```markdown +## [Rule title repeated as heading] + +### Problem + +What goes wrong when this rule is not followed. Be concrete — name the +failure mode, not an abstract risk. + +### 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. + +#### Acceptance Criteria + +- [ ] Checkable item that confirms the rule was applied +- [ ] Another checkable item +``` + +`Acceptance Criteria` is optional but strongly recommended for rules that +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 + 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`) + +## 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. From 38dcdc81dedd4638370e05e5ea841599ef8d4572 Mon Sep 17 00:00:00 2001 From: Vadim Zolotokrylin <1125014+zolotokrylin@users.noreply.github.com> Date: Mon, 29 Jun 2026 13:32:52 +0800 Subject: [PATCH 2/2] docs(rules): add depends_on sequencing and CI validation guidance --- docs/RULES.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/docs/RULES.md b/docs/RULES.md index 0ed9a7b..d8be811 100644 --- a/docs/RULES.md +++ b/docs/RULES.md @@ -23,6 +23,7 @@ Every rule is a standalone markdown file in `docs/rules/` with YAML frontmatter: 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 @@ -78,6 +79,29 @@ any existing references. - 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