From 6fcd28dbec271eb68010b4ed8f81c42d3af460b0 Mon Sep 17 00:00:00 2001 From: grunch Date: Thu, 13 Aug 2026 10:18:29 -0300 Subject: [PATCH 1/2] ci: enforce MD040 on markdown with markdownlint-cli2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit AGENTS.md requires a language specifier on every fenced code block, but nothing enforced it, so violations only surfaced in review — the payment circuit breaker spec reached review with two bare fences. Add a Markdown workflow running markdownlint-cli2, pinned to the version the review tooling reports so a finding reproduces locally with the same command. The ruleset starts from default:false and enables only MD040: markdownlint's full defaults report ~1560 findings across 38 files (768 of them MD013 line-length), which is a reformatting project rather than a lint gate. Rules can be promoted one at a time, each with its fixes. Label the 17 pre-existing bare fences as text so the gate is green from the first run. --- .github/workflows/markdown.yml | 24 ++++++++++++++++++++++++ .markdownlint-cli2.jsonc | 21 +++++++++++++++++++++ README.md | 2 +- docs/BRANCH_PROTECTION.md | 2 +- docs/DEV_FEE.md | 20 ++++++++++---------- docs/RPC.md | 4 ++-- docs/SOURCE_TAG_PUBKEY.md | 6 +++--- 7 files changed, 62 insertions(+), 17 deletions(-) create mode 100644 .github/workflows/markdown.yml create mode 100644 .markdownlint-cli2.jsonc diff --git a/.github/workflows/markdown.yml b/.github/workflows/markdown.yml new file mode 100644 index 00000000..8c0cad23 --- /dev/null +++ b/.github/workflows/markdown.yml @@ -0,0 +1,24 @@ +name: Markdown + +on: + push: + paths: + - "**/*.md" + - ".markdownlint-cli2.jsonc" + - ".github/workflows/markdown.yml" + pull_request: + paths: + - "**/*.md" + - ".markdownlint-cli2.jsonc" + - ".github/workflows/markdown.yml" + +jobs: + markdownlint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + # Pinned to the version the review tooling reports, so a finding raised in + # review reproduces locally with the same command and the same result. + # Globs and ignores come from .markdownlint-cli2.jsonc. + - name: markdownlint-cli2 + run: npx --yes markdownlint-cli2@0.23.2 diff --git a/.markdownlint-cli2.jsonc b/.markdownlint-cli2.jsonc new file mode 100644 index 00000000..62b38f64 --- /dev/null +++ b/.markdownlint-cli2.jsonc @@ -0,0 +1,21 @@ +{ + // Markdown lint configuration for the repository's documentation. + // + // The ruleset is deliberately narrow: it starts from `default: false` and + // enables only what AGENTS.md § Documentation Guidelines actually mandates, + // so the job fails on policy violations and stays silent about style the + // repository has never agreed on. + // + // Turning on markdownlint's full default set today would report ~1560 + // findings across 38 files (768 of them MD013 line-length alone), which is a + // reformatting project, not a lint gate. Rules can be promoted here one at a + // time as the tree is cleaned up — each promotion should land together with + // the fixes that make it green. + "config": { + "default": false, + // AGENTS.md: "Add a language specifier to every fenced code block." + "MD040": true + }, + "globs": ["**/*.md"], + "ignores": ["target/**", "node_modules/**", ".git/**"] +} diff --git a/README.md b/README.md index 3590a7d4..b4e4e110 100644 --- a/README.md +++ b/README.md @@ -958,7 +958,7 @@ cargo clippy --all-targets --all-features -- -D warnings ### Project Structure -``` +```text mostro/ ├── src/ │ ├── main.rs # Entry point, initialization diff --git a/docs/BRANCH_PROTECTION.md b/docs/BRANCH_PROTECTION.md index 71eb339c..ed392207 100644 --- a/docs/BRANCH_PROTECTION.md +++ b/docs/BRANCH_PROTECTION.md @@ -163,7 +163,7 @@ Yes, but it **requires at least 1 approval from another person** before merge. ### What happens if I accidentally push to main? GitHub rejects it: -``` +```text ! [remote rejected] main -> main (protected branch hook declined) ``` diff --git a/docs/DEV_FEE.md b/docs/DEV_FEE.md index 0a594b99..bbe2a425 100644 --- a/docs/DEV_FEE.md +++ b/docs/DEV_FEE.md @@ -106,7 +106,7 @@ The development fee mechanism provides sustainable funding for Mostro developmen ### Fee Flow Diagram -``` +```text Order Creation → Fee Calculation → Hold Invoice → Seller Release → Buyer Payment → Dev Payment ↓ ↓ ↓ ↓ ↓ ↓ amount mostro_fee seller pays settle hold buyer paid mostrod pays @@ -202,7 +202,7 @@ pub fn get_dev_fee(total_mostro_fee: i64) -> i64 { - Production code uses Settings seamlessly **Formula Specification:** -``` +```text total_dev_fee = round(total_mostro_fee × dev_fee_percentage) ``` @@ -259,7 +259,7 @@ When a user takes a market price order, the following sequence occurs: **Example Scenario:** -``` +```text Initial Order: 100,000 sats at $50,000/BTC (market price) - Mostro fee: 1,000 sats - Dev fee (30%): 300 sats @@ -353,7 +353,7 @@ if order.has_no_amount() { **Example Scenarios:** **Fixed Price Order:** -``` +```text Order Created: - amount: 100,000 sats (known at creation) - fee: 1,000 sats (calculated at creation) @@ -372,7 +372,7 @@ Order Completes: ``` **Market Price Order:** -``` +```text Order Created: - Fiat: $100 USD - amount: 0 (unknown until taken) @@ -417,7 +417,7 @@ Order Completes: - Leaving stale `dev_fee` value causes incorrect charges on re-take **Example Flow:** -``` +```text Order Created (market price): - amount: 0, fee: 0, dev_fee: 0, status: pending @@ -768,7 +768,7 @@ let payment_hash = rx.recv().await?; // ← THIS is what goes into dev_fee_paym Complete timeline showing database field states at each stage: -``` +```text Order Creation (t=0): └─> dev_fee = 0 (always zero at creation) └─> dev_fee_paid = 0 @@ -1315,13 +1315,13 @@ RUST_LOG="dev_fee=error" mostrod **Log Examples:** Success: -``` +```text [INFO dev_fee] order_id=550e8400-e29b-41d4-a716-446655440000 amount_sats=300 destination= Initiating development fee payment [INFO dev_fee] order_id=550e8400-e29b-41d4-a716-446655440000 payment_hash=abcd1234... Development fee payment succeeded ``` Failure: -``` +```text [ERROR dev_fee] order_id=550e8400-e29b-41d4-a716-446655440000 error=LnAddressParseError stage=address_resolution Failed to resolve development Lightning Address [ERROR dev_fee] order_id=550e8400-e29b-41d4-a716-446655440000 dev_fee=300 Development fee payment failed - order completing anyway ``` @@ -1331,7 +1331,7 @@ Failure: ### Common Issues **1. Daemon Won't Start - Invalid Configuration** -``` +```text Error: Configuration error: dev_fee_percentage (0.05) is below minimum (0.10) ``` **Solution:** Set `dev_fee_percentage` to at least 0.10 in settings.toml diff --git a/docs/RPC.md b/docs/RPC.md index a9aaf855..d18ce530 100644 --- a/docs/RPC.md +++ b/docs/RPC.md @@ -168,14 +168,14 @@ async fn main() -> Result<(), Box> { When RPC is enabled, you'll see log messages like: -``` +```text INFO mostro::rpc::server: Starting RPC server on 127.0.0.1:50051 INFO mostro::rpc::server: RPC server started successfully ``` Admin operations will be logged: -``` +```text INFO mostro::rpc::service: Received cancel order request for order: 550e8400-e29b-41d4-a716-446655440000 ``` diff --git a/docs/SOURCE_TAG_PUBKEY.md b/docs/SOURCE_TAG_PUBKEY.md index 129a5bc9..236afa79 100644 --- a/docs/SOURCE_TAG_PUBKEY.md +++ b/docs/SOURCE_TAG_PUBKEY.md @@ -9,19 +9,19 @@ allowing clients to identify which Mostro instance published the order. ### Before -``` +```text mostro:{order_id}?relays={relay1},{relay2} ``` ### After -``` +```text mostro:{order_id}?relays={relay1},{relay2}&mostro={pubkey} ``` ### Example -``` +```text mostro:e215c07e-b1f9-45b0-9640-0295067ee99a?relays=wss://relay.mostro.network,wss://nos.lol&mostro=82fa8cb978b43c79b2156585bac2c011176a21d2aead6d9f7c575c005be88390 ``` From fd668059ca712c74d75214da8616ce9c6e141408 Mon Sep 17 00:00:00 2001 From: grunch Date: Thu, 13 Aug 2026 10:38:55 -0300 Subject: [PATCH 2/2] ci: harden markdown workflow token and pin checkout MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Narrow the job's GITHUB_TOKEN to contents: read — linting docs needs nothing more, and four other workflows already declare their scope. Pin actions/checkout to the immutable commit behind v6.1.0, verified against the upstream tag rather than taken on trust. --- .github/workflows/markdown.yml | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/.github/workflows/markdown.yml b/.github/workflows/markdown.yml index 8c0cad23..e89a8949 100644 --- a/.github/workflows/markdown.yml +++ b/.github/workflows/markdown.yml @@ -12,13 +12,20 @@ on: - ".markdownlint-cli2.jsonc" - ".github/workflows/markdown.yml" +# Linting documentation needs nothing but the checkout, so the job's +# GITHUB_TOKEN is narrowed to read-only rather than inheriting whatever the +# repository default grants. +permissions: + contents: read + jobs: markdownlint: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 - # Pinned to the version the review tooling reports, so a finding raised in - # review reproduces locally with the same command and the same result. - # Globs and ignores come from .markdownlint-cli2.jsonc. + - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0 + # markdownlint-cli2 is pinned to the version the review tooling reports, + # so a finding raised in review reproduces locally with the same command + # and the same result. Globs and ignores come from + # .markdownlint-cli2.jsonc, so this bare invocation matches CI exactly. - name: markdownlint-cli2 run: npx --yes markdownlint-cli2@0.23.2