mandrel 2.50.0 → 2.51.0

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.
@@ -12,6 +12,7 @@ Self-check your change against this lens's concerns before you ship:
12
12
 
13
13
  - [ ] `audit-accessibility` (this lens)
14
14
  - [ ] `audit-ux-ui`
15
+ - [ ] `audit-mobile`
15
16
  - [ ] Renderable surface
16
17
  - [ ] Static a11y tooling already in the repo
17
18
  - [ ] Design tokens
@@ -0,0 +1,35 @@
1
+ <!-- GENERATED FILE — do not edit by hand.
2
+ Source of truth: .agents/workflows/audit-mobile.md
3
+ Regenerate: node .agents/scripts/generate-lens-checklists.js
4
+ Drift is gated by: npm run docs:check
5
+ -->
6
+
7
+ # Mobile & Tablet UX Audit — authoring checklist
8
+
9
+ > Audit mobile and tablet UX — layout and viewport correctness, touch ergonomics, responsive assets, and whether anything actually verifies them at a small viewport (static-first, with an optional runtime viewport pass)
10
+
11
+ Self-check your change against this lens's concerns before you ship:
12
+
13
+ - [ ] Breakpoint scale
14
+ - [ ] Viewport contract
15
+ - [ ] Declared device matrix
16
+ - [ ] Runtime target (optional)
17
+ - [ ] Viewport meta
18
+ - [ ] Fixed dimensions
19
+ - [ ] Viewport-height units
20
+ - [ ] Horizontal overflow
21
+ - [ ] Safe-area insets
22
+ - [ ] Hover-only interaction
23
+ - [ ] Control size and spacing
24
+ - [ ] Input ergonomics
25
+ - [ ] Gesture conflicts
26
+ - [ ] Images
27
+ - [ ] Media and embeds
28
+ - [ ] Typography and spacing
29
+ - [ ] Coverage — is anything exercised at a non-desktop viewport?
30
+ - [ ] Effectiveness — does that exercise assert anything mobile-specific?
31
+ - [ ] Resolve the target from config — never a hardcoded URL.
32
+ - [ ] Sample routes from the navigability SSOT.
33
+ - [ ] Drive two form factors per route.
34
+ - [ ] Median-of-3 or provisional.
35
+ - [ ] Leave the viewport as you found it.
@@ -21,5 +21,4 @@ Self-check your change against this lens's concerns before you ship:
21
21
  - [ ] Information Hierarchy
22
22
  - [ ] Error States
23
23
  - [ ] Loading States
24
- - [ ] Responsiveness
25
24
  - [ ] Accessibility (UX-focused)
@@ -32,7 +32,7 @@ by `node .agents/scripts/generate-workflows-doc.js`; `npm run docs:check`
32
32
  fails when it drifts from the on-disk workflow set. To change a command’s
33
33
  description, edit the workflow file’s front-matter and regenerate.
34
34
 
35
- ## Commands (28)
35
+ ## Commands (29)
36
36
 
37
37
  | Command | Description |
38
38
  | --- | --- |
@@ -45,6 +45,7 @@ description, edit the workflow file’s front-matter and regenerate.
45
45
  | `/audit-dependencies` | Audit `package.json` for unused, outdated, and major-version-stale dependencies; surface Node-engine drift and propose upgrade batches. |
46
46
  | `/audit-devops` | Audit CI/CD workflows, container images, infrastructure-as-code, and deployment pipelines; surface failure modes and hardening gaps. |
47
47
  | `/audit-documentation` | Audit the repository's main documentation for staleness, semantic drift, and completeness; emit a structured High/Medium/Low findings report. |
48
+ | `/audit-mobile` | Audit mobile and tablet UX — layout and viewport correctness, touch ergonomics, responsive assets, and whether anything actually verifies them at a small viewport (static-first, with an optional runtime viewport pass) |
48
49
  | `/audit-navigability` | Audit the whole route tree against the consumer's nav-registry SSOT — every route has a persona nav door and no nav href is dead. A deliberately-global lens exempt from the cross-epic-leak guard and routed onto route-adding change sets. |
49
50
  | `/audit-performance` | Audit performance by measuring first — profile hot paths, I/O, memory, and payload against the repo's own numbers — and audit interleaving/partial-failure correctness (TOCTOU, unawaited promises, non-atomic writes) as a first-class dimension. |
50
51
  | `/audit-privacy` | Audit logs, telemetry, and persistence paths for PII leakage and retention violations; surface secrets exposure and consent gaps. |
@@ -299,6 +299,36 @@
299
299
  "scope": "local",
300
300
  "substitutionKeys": []
301
301
  },
302
+ "audit-mobile": {
303
+ "triggers": {
304
+ "gates": ["gate2", "gate3"],
305
+ "keywords": [
306
+ "mobile",
307
+ "tablet",
308
+ "responsive",
309
+ "breakpoint",
310
+ "viewport",
311
+ "touch"
312
+ ],
313
+ "filePatterns": [
314
+ "**/*.html",
315
+ "**/*.astro",
316
+ "**/*.css",
317
+ "**/*.{scss,sass,less}",
318
+ "**/styles/**",
319
+ "**/components/**/*.{js,jsx,ts,tsx,vue,svelte}",
320
+ "**/app/**/{page,layout,route,head,default,template,loading,error,not-found}.{js,jsx,ts,tsx}",
321
+ "**/pages/**/*.{js,jsx,ts,tsx,vue}",
322
+ "**/routes/**/*.{jsx,tsx,vue,svelte}",
323
+ "**/tailwind.config.{js,ts,cjs,mjs}",
324
+ "**/playwright.config.{js,ts,cjs,mjs}",
325
+ "**/cypress.config.{js,ts,cjs,mjs}"
326
+ ]
327
+ },
328
+ "target": "web",
329
+ "scope": "local",
330
+ "substitutionKeys": []
331
+ },
302
332
  "audit-navigability": {
303
333
  "triggers": {
304
334
  "gates": ["gate2", "gate3"],
@@ -33,6 +33,7 @@ export const AUDIT_LENSES = Object.freeze([
33
33
  'dependencies',
34
34
  'devops',
35
35
  'documentation',
36
+ 'mobile',
36
37
  'navigability',
37
38
  'performance',
38
39
  'privacy',
@@ -31,9 +31,9 @@ on a project with no rendered frontend, since there are no components, templates
31
31
  or routes to hold to WCAG. See the `target` key's schema description for how
32
32
  applicability is probed from the consumer's checkout.
33
33
 
34
- ## Boundary with `audit-ux-ui`
34
+ ## Boundaries with the neighbouring web lenses
35
35
 
36
- These two web lenses share a border and must not double-report:
36
+ These lenses share a border with this one and must not double-report:
37
37
 
38
38
  - **`audit-accessibility` (this lens)** owns **WCAG conformance** — the
39
39
  standards question: does an assistive-technology user perceive, operate, and
@@ -41,11 +41,17 @@ These two web lenses share a border and must not double-report:
41
41
  controls, text alternatives, and contrast against the WCAG ratio thresholds.
42
42
  - **`audit-ux-ui`** owns **design-system adherence** — the consistency
43
43
  question: do components and tokens match the project's own design system?
44
-
45
- Contrast is the one axis both can touch: **accessibility owns the WCAG ratio
46
- verdict** (4.5:1 body / 3:1 large text / 3:1 non-text), while ux-ui owns whether
47
- the colour came from a sanctioned token. When a contrast defect is in scope for
48
- both, report the WCAG failure here and leave the token-adherence note to ux-ui.
44
+ - **`audit-mobile`** owns **small-screen and touch behaviour** — layout at a
45
+ phone or tablet viewport, touch ergonomics, responsive assets, and mobile
46
+ test coverage. It may measure a control's rendered size as ergonomic
47
+ evidence, but the `2.5.8 Target Size (Minimum)` verdict on an undersized
48
+ target is reported here.
49
+
50
+ Contrast is the one axis accessibility and ux-ui both touch: **accessibility
51
+ owns the WCAG ratio verdict** (4.5:1 body / 3:1 large text / 3:1 non-text),
52
+ while ux-ui owns whether the colour came from a sanctioned token. When a
53
+ contrast defect is in scope for both, report the WCAG failure here and leave
54
+ the token-adherence note to ux-ui.
49
55
 
50
56
  ## Scope
51
57
 
@@ -0,0 +1,242 @@
1
+ ---
2
+ description: Audit mobile and tablet UX — layout and viewport correctness, touch ergonomics, responsive assets, and whether anything actually verifies them at a small viewport (static-first, with an optional runtime viewport pass)
3
+ ---
4
+
5
+ # Mobile & Tablet UX Audit
6
+
7
+ You are a Senior Mobile Web Engineer holding the frontend to its **small-screen
8
+ and touch contract**: does every surface lay out, scroll, and answer a finger on
9
+ a phone and a tablet — and does anything in the suite actually verify that it
10
+ does? Default to **static** detection over source; escalate to a **runtime**
11
+ viewport pass only when a live target is configured. The shared lens machinery —
12
+ read-only constraint, scope interpretation, report envelope + finding-block
13
+ skeleton, severity scale, self-cross-check, and execution strategy — lives in
14
+ [`helpers/audit-lens-core.md`](helpers/audit-lens-core.md). Write the report to
15
+ `{{auditOutputDir}}/audit-mobile-results.md`. Dimension values:
16
+ `Layout & Viewport | Touch Ergonomics | Responsive Assets | Mobile Verification`.
17
+ Extra finding field: **Evidence:** (`measured | static` + the observable;
18
+ single-run runtime numbers are tagged `provisional`).
19
+ The report adds a **Runtime Viewport Pass** section.
20
+
21
+ > **An emulated viewport is not a device.** Viewport emulation resizes and
22
+ > re-flows the page; it does not reproduce a real device's browser engine,
23
+ > input latency, font rendering, or OS chrome. Report what the emulator
24
+ > observed, never "verified on iPhone".
25
+
26
+ ## Applicability
27
+
28
+ **Web targets only.** Registered with `target: "web"` in
29
+ [`audit-rules.json`](../schemas/audit-rules.json): the selector skips this lens
30
+ on a project with no rendered frontend, since there is no layout to re-flow and
31
+ no control to touch. See the `target` key's schema description for how
32
+ applicability is probed from the consumer's checkout.
33
+
34
+ ## Boundaries with the neighbouring lenses
35
+
36
+ Four lenses border this one. Report a finding **here** only when it is a
37
+ small-screen or touch defect; defer the rest so the suite never double-reports:
38
+
39
+ - [`/audit-accessibility`](audit-accessibility.md) owns every **WCAG
40
+ success-criterion verdict**, including `2.5.8 Target Size (Minimum)`. This
41
+ lens may **measure** a control's rendered size as ergonomic evidence, but the
42
+ conformance verdict on an undersized target belongs there.
43
+ - [`/audit-ux-ui`](audit-ux-ui.md) owns **design-system adherence** — whether a
44
+ value came from a sanctioned token and whether a raw element should have
45
+ deferred to a design-system component. This lens asks only whether the result
46
+ works at a small viewport, whatever its provenance.
47
+ - [`/audit-performance`](audit-performance.md) owns **Core Web Vitals, bundle
48
+ weight, and network cost**, mobile ones included. An oversized hero image is
49
+ reported here only as a missing `srcset`/`sizes` **contract**, never as a
50
+ payload-weight verdict.
51
+ - [`/audit-quality`](audit-quality.md) owns the **generic** test verdicts —
52
+ pyramid balance, flake, and coverage gaps. This lens owns exactly one test
53
+ question: is any of it exercised at a non-desktop viewport, and does that
54
+ exercise assert something mobile-specific (Step 2).
55
+
56
+ ## Scope
57
+
58
+ Interpret this lens's change-set fence per the core's Scope interpretation:
59
+
60
+ ```text
61
+ {{changedFiles}}
62
+ ```
63
+
64
+ ## Execution strategy
65
+
66
+ Run this lens as a single `subagent_type: auditor` dispatch returning the report
67
+ path + Executive Summary; sequential inline execution is the fallback (see the
68
+ core's Execution strategy).
69
+
70
+ ## Step 0: Discover the responsive baseline (run first)
71
+
72
+ **You cannot audit responsiveness against a generic ideal — a 640px fixed width
73
+ is a defect only relative to the breakpoints the project actually claims to
74
+ support.** Before any detection, locate this lens's own sources of truth (they
75
+ are *not* ux-ui's design system, though they often live beside it) and record
76
+ what they declare:
77
+
78
+ - **Breakpoint scale:** the `screens` map in `tailwind.config.{js,ts}`, CSS
79
+ custom media / container queries, a `breakpoints` token file, or a
80
+ CSS-in-JS theme's media helpers. Census the `@media` / `container` queries
81
+ actually used in the stylesheets and note the narrowest one — that is the
82
+ smallest width the project has any evidence of supporting.
83
+ - **Viewport contract:** the `<meta name="viewport">` tag (or the framework
84
+ `viewport` export) and whether it sets `width=device-width` and leaves user
85
+ scaling enabled.
86
+ - **Declared device matrix:** any non-desktop viewport already configured in the
87
+ consumer's test tooling — Playwright `projects[]` using `devices[...]` or an
88
+ explicit `viewport`, a Cypress `viewportWidth`/`viewportHeight`, a
89
+ visual-regression viewport list. This is the project's own statement of which
90
+ form factors it holds itself to.
91
+ - **Runtime target (optional):** the `qa.environments` map (see
92
+ [*Runtime viewport pass*](#step-3-runtime-viewport-pass-optional-corroboration))
93
+ and the navigability route SSOT.
94
+
95
+ Record the breakpoints, the viewport contract, and the device matrix. Every
96
+ finding downstream is measured against *this discovered baseline*. If the
97
+ project declares **no** breakpoint scale and no device matrix, say so and
98
+ downgrade findings to "no responsive baseline declared — recommend establishing
99
+ a breakpoint scale and a phone/tablet test viewport first" rather than scoring
100
+ the tree against an invented one.
101
+
102
+ ## Step 1: Static detection, then triage
103
+
104
+ Run the **mechanical detectors first** (cheap, deterministic greps over the
105
+ in-scope styles and components), then apply **LLM triage** to each candidate
106
+ against the Step 0 baseline — a mechanical hit is a *candidate*, not
107
+ automatically a finding.
108
+
109
+ ### Layout & Viewport
110
+
111
+ - **Viewport meta:** absent `<meta name="viewport">`, a missing
112
+ `width=device-width`, or `user-scalable=no` / `maximum-scale=1` pinning the
113
+ page against pinch-zoom.
114
+ - **Fixed dimensions:** `width`/`min-width`/`height` px literals wider than the
115
+ narrowest declared breakpoint, outside token and container-query files — the
116
+ classic source of a page that cannot shrink.
117
+ - **Viewport-height units:** `100vh` (or `vh` arithmetic) with no `dvh`/`svh`
118
+ fallback, which cuts content off under a mobile browser's collapsing toolbar.
119
+ - **Horizontal overflow:** unconstrained wide content — tables, `<pre>` blocks,
120
+ code fences, flex rows with no `min-width: 0`, absolutely-positioned elements
121
+ extending past the viewport — and any `overflow-x: visible` on a container
122
+ holding them. A page whose body scrolls sideways on a phone is a defect
123
+ regardless of its cause.
124
+ - **Safe-area insets:** `position: fixed`/`sticky` elements pinned to a screen
125
+ edge (bottom bars, floating actions, drawers, modals) with no
126
+ `env(safe-area-inset-*)` allowance, so a notch or home indicator overlaps
127
+ them.
128
+
129
+ ### Touch Ergonomics
130
+
131
+ - **Hover-only interaction:** a `:hover`/`hover:` state that reveals content or
132
+ is the only affordance for an action, with no touch-reachable equivalent
133
+ (a click/tap handler, a focus state, or an always-visible control). On a
134
+ touch device that interaction does not exist.
135
+ - **Control size and spacing:** interactive controls whose rendered box is
136
+ visibly under ~44×44 CSS px, or adjacent tap targets with no separating
137
+ spacing. Report the **measurement** as ergonomic evidence and leave the
138
+ WCAG `2.5.8` verdict to the accessibility lens.
139
+ - **Input ergonomics:** form inputs with a font-size under 16px (iOS Safari
140
+ zooms the whole page on focus), a missing or wrong `inputmode`/`type` for the
141
+ expected keyboard (numeric, email, tel), and `autocomplete` omitted on
142
+ identity or address fields where a small-screen user most needs it.
143
+ - **Gesture conflicts:** custom swipe/drag handlers that call
144
+ `preventDefault()` on `touchstart`/`touchmove` across a scrollable region, or
145
+ scroll containers nested inside a horizontal pager, which strand the user's
146
+ scroll.
147
+
148
+ ### Responsive Assets
149
+
150
+ - **Images:** `<img>` with no `srcset`/`sizes` (or a framework image component
151
+ bypassed for a raw tag) where the same file serves every width; a missing
152
+ intrinsic `width`/`height` or `aspect-ratio`, which shifts the layout as
153
+ images land.
154
+ - **Media and embeds:** `<video>`, `<iframe>`, and map/chart embeds with fixed
155
+ pixel dimensions or no responsive container.
156
+ - **Typography and spacing:** a type or spacing scale with no small-viewport
157
+ step, so a desktop-tuned heading dominates a phone screen.
158
+
159
+ > **Detector output is candidates.** Triage each against the Step 0 baseline
160
+ > before promoting it to a finding — a fixed width inside a design-system
161
+ > primitive that its container query already re-flows, a `100vh` on a
162
+ > deliberately desktop-only admin surface, or a raw `<img>` for a fixed-size
163
+ > icon, is expected, not a defect.
164
+
165
+ ## Step 2: Mobile verification coverage & effectiveness
166
+
167
+ A responsive surface with nothing holding it responsive regresses on the next
168
+ change. This lens owns that one test question, in two parts — report them as
169
+ separate findings, because the fixes differ:
170
+
171
+ 1. **Coverage — is anything exercised at a non-desktop viewport?** Reconcile the
172
+ Step 0 device matrix against the suites that exist: an e2e config with only a
173
+ desktop project, a visual-regression suite with a single wide snapshot width,
174
+ or Gherkin features with no phone/tablet variant all mean the responsive
175
+ behaviour is unverified. Name the specific surfaces in scope that no
176
+ non-desktop run touches.
177
+ 2. **Effectiveness — does that exercise assert anything mobile-specific?** A
178
+ suite that merely replays its desktop assertions at 390px wide proves the
179
+ page renders, not that it works. Look for assertions that could only pass on
180
+ a small viewport: the drawer or hamburger nav opening in place of the desktop
181
+ bar, the absence of horizontal document scroll, a bottom bar clearing the
182
+ safe area, an orientation change, a swipe or long-press gesture, a
183
+ viewport-conditional element being hidden or shown. A mobile project whose
184
+ assertions are viewport-agnostic is a **false-confidence** finding: it is
185
+ reported even though the suite is green, and it is usually more valuable than
186
+ a missing-coverage finding, because the project believes it is covered.
187
+
188
+ Keep the generic test verdicts out of this step — pyramid balance, flake, and
189
+ overall coverage gaps belong to [`/audit-quality`](audit-quality.md). Where a
190
+ fix is a new test, name the viewport and the assertion it should make, not just
191
+ "add mobile tests".
192
+
193
+ ## Step 3: Runtime viewport pass (optional corroboration)
194
+
195
+ Static detection is the default and always runs. The runtime pass is
196
+ **conditional** — it runs only when a live target is configured; its absence
197
+ never blocks the static report.
198
+
199
+ 1. **Resolve the target from config — never a hardcoded URL.** Resolve the
200
+ target through the consumer's `qa.environments.<env>.baseUrl` (via
201
+ [`resolveQaEnvironment`](../scripts/lib/qa/resolve-qa-contract.js), the same
202
+ resolver `/qa-run` uses): an `<env>` argument resolves by exact name or
203
+ origin match; with no argument, enumerate `name → baseUrl` and let the
204
+ operator pick. If **no** `qa.environments` target is configured, **skip this
205
+ step** and note in the report that runtime corroboration was unavailable —
206
+ do not invent a URL and do not start an arbitrary dev server.
207
+ 2. **Sample routes from the navigability SSOT.** Draw the routes to exercise
208
+ from the consumer's route/nav registry (`planning.navigation.navRegistry` /
209
+ `routeGlobs` — the same SSOT [`/audit-navigability`](audit-navigability.md)
210
+ reads), sampling a representative set (key personas' landing routes plus any
211
+ route in the change-set scope) rather than a single hardcoded page.
212
+ 3. **Drive two form factors per route.** Emulate a **phone** and a **tablet**
213
+ viewport — `mcp__chrome-devtools__emulate` for a device profile, or
214
+ `resize_page` for an explicit width/height — then, per route and viewport:
215
+ take a screenshot, and evaluate the two observables static analysis cannot
216
+ resolve — whether `document.scrollingElement.scrollWidth` exceeds the
217
+ viewport width (horizontal overflow), and the rendered box of the
218
+ interactive controls Step 1 flagged as candidates. Reload after switching
219
+ form factor so load-time device gates re-run.
220
+ 4. **Median-of-3 or provisional.** Any runtime measurement is subject to
221
+ run-to-run variance: capture a **median-of-3** (three runs per route, report
222
+ the median) before treating a number as authoritative. A single-run value is
223
+ reported **provisional** and never drives a Critical/High verdict on its own.
224
+ 5. **Leave the viewport as you found it.** Reset the emulation before finishing
225
+ so a following lens or QA run does not inherit a phone viewport.
226
+
227
+ Corroborate static findings against the runtime observations (a statically
228
+ flagged fixed width confirmed by a real horizontal overflow graduates from
229
+ provisional to confirmed), and surface runtime-only defects the static pass
230
+ could not see — an element clipped only once the toolbar collapses, a drawer
231
+ that opens off-screen.
232
+
233
+ ## Report additions
234
+
235
+ Beyond the shared skeleton, the Executive Summary states the runtime mode's
236
+ status (ran against `<env>` / skipped — no target configured) and names the
237
+ narrowest breakpoint the project declares, so a reader can tell what "mobile"
238
+ meant for this run. The report ends with a **Runtime Viewport Pass** section:
239
+ per-route, per-form-factor observations when the runtime mode ran, or
240
+ "*Runtime corroboration unavailable — no `qa.environments` target configured.*"
241
+ Drop every claimed finding that names no concrete element, style rule, or test
242
+ file.
@@ -89,12 +89,17 @@ baseline — a mechanical hit is a *candidate*, not automatically a finding.
89
89
  2. **Error States:** Are form errors clear and helpful, or generic and
90
90
  frustrating?
91
91
  3. **Loading States:** Are there skeletons or spinners for async operations?
92
- 4. **Responsiveness:** Check layouts at mobile, tablet, and desktop breakpoints.
93
- 5. **Accessibility (UX-focused):** Focus on tab order, touch-target sizes, and
94
- whether interaction colours come from a sanctioned token. **WCAG conformance
95
- is out of scope here** — semantic structure, ARIA correctness,
96
- keyboard/focus operability, form labelling, media alternatives, and the WCAG
97
- contrast-ratio verdict are owned by [`/audit-accessibility`](audit-accessibility.md).
92
+ 4. **Accessibility (UX-focused):** Focus on tab order and whether interaction
93
+ colours come from a sanctioned token. **WCAG conformance is out of scope
94
+ here** — semantic structure, ARIA correctness, keyboard/focus operability,
95
+ form labelling, media alternatives, and the WCAG contrast-ratio verdict are
96
+ owned by [`/audit-accessibility`](audit-accessibility.md).
98
97
  This lens keeps token/component design-system adherence; defer every WCAG
99
98
  success-criterion judgement to the accessibility lens so the two never
100
99
  double-report.
100
+
101
+ > **Small-screen behaviour is out of scope here too.** Layout at a phone or
102
+ > tablet viewport, touch-target ergonomics, responsive assets, and whether any
103
+ > suite exercises a non-desktop viewport belong to [`/audit-mobile`](audit-mobile.md).
104
+ > This lens keeps the token/component question at whatever viewport the surface
105
+ > renders.
package/docs/CHANGELOG.md CHANGED
@@ -15,6 +15,13 @@ All notable changes to this project will be documented in this file.
15
15
  -->
16
16
  <!-- markdownlint-disable-file MD004 MD012 MD037 -->
17
17
 
18
+ ## [2.51.0](https://github.com/dsj1984/mandrel/compare/mandrel-v2.50.0...mandrel-v2.51.0) (2026-09-08)
19
+
20
+
21
+ ### Added
22
+
23
+ * **audit:** add the /audit-mobile lens for mobile and tablet UX (refs [#5233](https://github.com/dsj1984/mandrel/issues/5233)) ([#5234](https://github.com/dsj1984/mandrel/issues/5234)) ([eccd505](https://github.com/dsj1984/mandrel/commit/eccd50527f04a25e02d50f57e1c6d760345bc9e8))
24
+
18
25
  ## [2.50.0](https://github.com/dsj1984/mandrel/compare/mandrel-v2.49.0...mandrel-v2.50.0) (2026-09-08)
19
26
 
20
27
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mandrel",
3
- "version": "2.50.0",
3
+ "version": "2.51.0",
4
4
  "description": "Claude Code-first opinionated workflow framework: instructions, skills, rules, and SDLC workflows that govern AI coding assistants.",
5
5
  "files": [
6
6
  ".agents/",