mandrel-platform 0.19.2 → 0.20.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -13,7 +13,7 @@ hand-maintaining its own copies and drifting apart over time.
13
13
  | ------ | ---------------- |
14
14
  | **Reusable workflows** | `workflow_call` CI, deploy, secret-scan, release, and CodeQL pipelines, consumed by tag/SHA pin. |
15
15
  | **Composite action** | `setup-toolchain` — pnpm + Node + frozen install in one step. |
16
- | **Config bases (npm)** | `extends`-able baselines: TypeScript, Biome, Knip, Stryker, commitlint, dependency-cruiser, size-limit, Lighthouse. |
16
+ | **Config bases (npm)** | `extends`-able baselines: TypeScript, Biome, Knip, Stryker, commitlint, dependency-cruiser, secretlint, size-limit, Lighthouse. |
17
17
  | **Edge-security middleware (npm)** | Per-env closed-allowlist CORS, security headers, and app-layer rate limiting for Astro + Hono. |
18
18
  | **Guardrail scripts (npm)** | Dependency-free policy checks: CVE gate, action-pin ratchet, coverage floor, destructive-migration guard, workflow-portability, required-contexts, docs-staleness. |
19
19
  | **Renovate preset** | Shared dependency-update policy, including auto-bumping this repo's own `uses:` pins. |
@@ -143,10 +143,11 @@ upgrade to 2.x before adopting this base (refs #153).
143
143
 
144
144
  ### Code-quality tooling base configs
145
145
 
146
- The package also ships shared base configs for the five code-quality /
146
+ The package also ships shared base configs for the code-quality /
147
147
  hygiene tools every consumer runs — **Knip**, **Stryker**,
148
- **dependency-cruiser**, **size-limit**, and **Lighthouse**. Each is the
149
- best-of-breed union of the consumers' previously hand-maintained configs.
148
+ **dependency-cruiser**, **markdownlint**, **secretlint**, **size-limit**,
149
+ and **Lighthouse**. Each is the best-of-breed union of the consumers'
150
+ previously hand-maintained configs.
150
151
  Adoption is opt-in via `extends` (or a spread / deep-merge where the tool
151
152
  has no native `extends`), and every project-specific knob — entrypoints,
152
153
  mutate globs, bundle paths, score floors, and budgets — stays
@@ -238,6 +239,92 @@ resolve the package export and add repo-specific rules
238
239
  }
239
240
  ```
240
241
 
242
+ #### `markdownlint.base.jsonc`
243
+
244
+ Shared markdownlint **content** rule base — the union of the fleet's three
245
+ previously per-repo configs, which had diverged only by accretion (~90%
246
+ identical). Ships the common core (`default: true`) narrowed by `MD013: false`
247
+ (line-length — Prettier owns wrap), `MD024: { siblings_only: true }`
248
+ (duplicate headings allowed under different parents), `MD033: false` (inline
249
+ HTML), `MD041: false` (first-line-heading), and `MD060: false` (GFM table
250
+ style — Prettier owns table reflow).
251
+
252
+ **Canonical runner: `markdownlint-cli2`.** It is the maintained, recommended
253
+ runner and two of the three consumers already run it; new adopters standardize
254
+ on it (classic `markdownlint` consumes the same `MDxxx` rule IDs, so the base
255
+ is compatible either way). markdownlint-cli2 resolves `extends` to a package
256
+ path, so a consumer's local config reduces to the extend plus repo-specific
257
+ **ignore globs** — which stay local, since generated/vendored trees differ per
258
+ repo (`.markdownlint.jsonc`):
259
+
260
+ ```jsonc
261
+ // .markdownlint.jsonc — extend the shared content base
262
+ {
263
+ "extends": "mandrel-platform/markdownlint.base.jsonc"
264
+ // ...repo-specific rule overrides (rare)
265
+ }
266
+ ```
267
+
268
+ ```jsonc
269
+ // .markdownlint-cli2.jsonc — ignore globs stay consumer-local
270
+ {
271
+ "ignores": ["CHANGELOG.md"]
272
+ }
273
+ ```
274
+
275
+ The base carries **content rules only, never `ignores`**. Excluding the
276
+ release-please-generated `CHANGELOG.md` is a mandatory per-consumer ignore
277
+ documented in
278
+ [`docs/reusable-workflows.md`](docs/reusable-workflows.md). markdownlint gates
279
+ content rules Prettier does not — the two are **complementary**, not
280
+ substitutes: keep both.
281
+
282
+ #### `secretlint.base.json`
283
+
284
+ The single source of truth for the **local pre-commit secret-scan mirror**
285
+ of the CI gitleaks tiers — the shift-left dev-experience twin that catches
286
+ a secret at `git commit` time before it ever reaches the CI gitleaks gate.
287
+ The ruleset ships the recommended preset
288
+ (`@secretlint/secretlint-rule-preset-recommend`); single-sourcing it here
289
+ means a rule change lands fleet-wide in one place instead of drifting across
290
+ each consumer's hand-copied `.secretlintrc.json`.
291
+
292
+ secretlint's `.secretlintrc` has **no native file-level `extends`**, so
293
+ consumers adopt this base one of two ways. The **husky hook _wiring_ stays
294
+ consumer-local** either way — only the _ruleset_ is single-sourced.
295
+
296
+ **Reference the base directly from the husky hook (simplest — no local
297
+ config file).** Point the pre-commit hook's `--secretlintrc` at the package
298
+ export; there is no `.secretlintrc.json` to maintain:
299
+
300
+ ```sh
301
+ # .husky/pre-commit — scan staged files against the shared ruleset
302
+ npx secretlint --secretlintrc node_modules/mandrel-platform/config/secretlint.base.json --maskSecrets "$(git diff --cached --name-only)"
303
+ ```
304
+
305
+ **Or import + spread into a JS-module `.secretlintrc.mjs`** when the repo has
306
+ genuine, explicitly-listed local overrides (an extra rule, an
307
+ `allowMessageIds` suppression). Keep the local file to the base plus **only**
308
+ the deltas:
309
+
310
+ ```js
311
+ // .secretlintrc.mjs — spread the shared ruleset, layer repo-specific deltas only
312
+ import base from "mandrel-platform/secretlint.base.json" with { type: "json" };
313
+
314
+ export default {
315
+ ...base,
316
+ // repo-specific overrides ONLY — e.g. an additional rule, or an
317
+ // allowMessageIds suppression for a known-safe fixture. Leave empty
318
+ // to inherit the shared ruleset verbatim.
319
+ };
320
+ ```
321
+
322
+ > **Local mirror, not a CI replacement.** This base is the *local* shift-left
323
+ > scanner; the blocking secret-scan gate remains the shared CI gitleaks
324
+ > tiers (see [reusable-workflows.md](docs/reusable-workflows.md)). Swapping
325
+ > the local tool for a local↔CI gitleaks-parity scan is a deliberate separate
326
+ > question, out of scope for this base.
327
+
241
328
  #### `size-limit.base.json`
242
329
 
243
330
  size-limit's own config is a per-entry **array** whose paths and limits
@@ -722,6 +809,8 @@ repo is developed with — dev-time only, and not shipped in the npm package.
722
809
  | `mandrel-platform/stryker.base.json` | `config/stryker.base.json` |
723
810
  | `mandrel-platform/commitlint.base.mjs` | `config/commitlint.base.mjs` |
724
811
  | `mandrel-platform/dependency-cruiser.base.json` | `config/dependency-cruiser.base.json` |
812
+ | `mandrel-platform/markdownlint.base.jsonc` | `config/markdownlint.base.jsonc` |
813
+ | `mandrel-platform/secretlint.base.json` | `config/secretlint.base.json` |
725
814
  | `mandrel-platform/size-limit.base.json` | `config/size-limit.base.json` |
726
815
  | `mandrel-platform/lighthouse.base.json` | `config/lighthouse.base.json` |
727
816
  | `mandrel-platform/lighthouse-thresholds.base.json` | `config/lighthouse-thresholds.base.json` |
@@ -0,0 +1,58 @@
1
+ // markdownlint.base.jsonc — shared markdownlint rule base for
2
+ // mandrel-platform consumers.
3
+ //
4
+ // Single-sources the fleet's common-core markdownlint content rules so the
5
+ // three consumers stop hand-maintaining ~90%-identical rule sets that diverge
6
+ // only by accretion. This is the union of the previously per-repo configs
7
+ // (domio / athportal / swarm-os), keyed by the same underlying `markdownlint`
8
+ // MDxxx rule IDs both `markdownlint-cli2` and classic `markdownlint` consume.
9
+ //
10
+ // CANONICAL RUNNER: markdownlint-cli2. Two of the three consumers already run
11
+ // it; it is the maintained, recommended runner. New adopters standardize on it.
12
+ //
13
+ // ADOPTION (markdownlint-cli2): consumers reference this base via the
14
+ // `extends` property in their own `.markdownlint.jsonc` /
15
+ // `.markdownlint-cli2.jsonc` and keep only repo-local ignore globs there:
16
+ //
17
+ // // .markdownlint.jsonc
18
+ // {
19
+ // "extends": "mandrel-platform/markdownlint.base.jsonc"
20
+ // // ...repo-specific rule overrides (rare)
21
+ // }
22
+ //
23
+ // // .markdownlint-cli2.jsonc — ignores stay local (e.g. generated CHANGELOG.md)
24
+ // { "ignores": ["CHANGELOG.md"] }
25
+ //
26
+ // The base carries CONTENT rules only — it does NOT carry `ignores`. Ignore
27
+ // globs are inherently repo-specific (generated files, vendored trees) and
28
+ // stay consumer-tunable locally. Excluding the release-please `CHANGELOG.md`
29
+ // in particular is documented in docs/reusable-workflows.md.
30
+ //
31
+ // This base is complementary to Prettier's markdown FORMATTING (line wrap,
32
+ // list markers) — markdownlint gates CONTENT rules Prettier does not, and the
33
+ // two are not substitutes.
34
+ {
35
+ // Start from the full default rule set, then narrow.
36
+ "default": true,
37
+
38
+ // MD013 line-length: off. Prose reflow is Prettier's job; a hard line-length
39
+ // gate on hand-authored docs produces noise, not signal.
40
+ "MD013": false,
41
+
42
+ // MD024 no-duplicate-heading: allow same-text headings under DIFFERENT
43
+ // parents (siblings_only). Repeated "### Notes" under distinct sections is
44
+ // legitimate structure, not a mistake.
45
+ "MD024": { "siblings_only": true },
46
+
47
+ // MD033 no-inline-html: off. Docs legitimately embed <details>, <kbd>,
48
+ // <br>, and alignment attributes GitHub-flavored Markdown renders.
49
+ "MD033": false,
50
+
51
+ // MD041 first-line-heading: off. Files that open with front-matter, a
52
+ // badge row, or an admonition before the first heading are valid.
53
+ "MD041": false,
54
+
55
+ // MD060 (table column style / GFM table hygiene): off. Table formatting is
56
+ // owned by Prettier's GFM table reflow, not a markdownlint content gate.
57
+ "MD060": false
58
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "_comment": "Shared secretlint config for mandrel-platform consumers — the single source of truth for the LOCAL pre-commit secret-scan mirror of the CI gitleaks tiers (shift-left dev-experience). secretlintrc has NO native file-level `extends`, so consumers reference this base instead of hand-copying the ruleset: point the husky pre-commit hook at it directly (`secretlint --secretlintrc node_modules/mandrel-platform/config/secretlint.base.json`) or import + spread it into a JS-module `.secretlintrc.mjs` layering only genuine repo-specific overrides. See README § secretlint.base.json for the adoption pattern. The husky hook *wiring* stays consumer-local; the *ruleset* is single-sourced here so a rule change lands fleet-wide in one place.",
3
+ "rules": [
4
+ {
5
+ "id": "@secretlint/secretlint-rule-preset-recommend"
6
+ }
7
+ ]
8
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mandrel-platform",
3
- "version": "0.19.2",
3
+ "version": "0.20.1",
4
4
  "description": "Shared CI/deploy workflows, composite toolchain action, npm config package, Renovate preset, and operator runbook templates.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -23,6 +23,8 @@
23
23
  "./stryker.base.json": "./config/stryker.base.json",
24
24
  "./commitlint.base.mjs": "./config/commitlint.base.mjs",
25
25
  "./dependency-cruiser.base.json": "./config/dependency-cruiser.base.json",
26
+ "./markdownlint.base.jsonc": "./config/markdownlint.base.jsonc",
27
+ "./secretlint.base.json": "./config/secretlint.base.json",
26
28
  "./size-limit.base.json": "./config/size-limit.base.json",
27
29
  "./lighthouse.base.json": "./config/lighthouse.base.json",
28
30
  "./lighthouse-thresholds.base.json": "./config/lighthouse-thresholds.base.json",