Skip to content

feat!: adopt the mod-utils v6 module generation (hinode v3)#2004

Merged
markdumay merged 9 commits into
mainfrom
feat/mod-utils-v6-generation
Jul 13, 2026
Merged

feat!: adopt the mod-utils v6 module generation (hinode v3)#2004
markdumay merged 9 commits into
mainfrom
feat/mod-utils-v6-generation

Conversation

@markdumay

@markdumay markdumay commented Jul 13, 2026

Copy link
Copy Markdown
Collaborator

Summary

Stage H1 of the mod-utils v6 adoption program's wave 4 (maintainer-approved): the mechanical
generation pin for Hinode v3. Bumps Hinode's own module path and the module-generation
majors per the decision package,
vendors, and rebuilds the exampleSite clean. Argument-warning cleanup is explicitly out of
scope
for this PR — see the warnings inventory below, which is H2's work list.

Pin table (decision package §1)

Module Release Import path
hinode (this repo) v3.0.0 github.com/gethinode/hinode/v3
mod-utils v6.0.1 github.com/gethinode/mod-utils/v6
mod-fontawesome v6.0.0 github.com/gethinode/mod-fontawesome/v6
mod-flexsearch v5.0.0 github.com/gethinode/mod-flexsearch/v5
mod-leaflet v3.0.0 github.com/gethinode/mod-leaflet/v3
mod-lottie v3.0.0 github.com/gethinode/mod-lottie/v3
mod-mermaid v5.0.0 github.com/gethinode/mod-mermaid/v5
mod-simple-datatables v4.0.0 github.com/gethinode/mod-simple-datatables/v4
mod-blocks (exampleSite only) v2.0.0 github.com/gethinode/mod-blocks/v2
mod-bootstrap-icons (exampleSite only) v2.0.0 github.com/gethinode/mod-bootstrap-icons/v2

mod-bootstrap, mod-csp, mod-katex, mod-google-analytics, mod-cookieyes, and mod-docs
stay on their current lines — none of them depend on mod-utils, and mod-docs is
generation-agnostic (API-stable across v5/v6).

Migration notes

This is a path-bump-only PR. Hinode's own InitArgs.html call sites (~110 of them) are
not migrated to the Args.html API here — that is a deliberate H2-stage decision (see
decision package §2.2: migrate the high-traffic shortcodes/partials, keep the shim for the
tail). See gethinode/mod-utils#334 and mod-utils' v5→v6 migration notes for the engine change
itself.

Generation-mixing warning (decision package §5)

A v5-generation site that adds one v6-generation module flips its entire site onto the v6
validation engine: Hugo resolves a single mod-utils, and import order decides who wins. In
Hinode's own module config every module import precedes mod-utils, so a v6-carrying module
always wins. The engines are API-compatible, but behavior deltas (defaults now apply, new
warnings) arrive wholesale, not incrementally. Adopt the generation together, via this
major
— do not cherry-pick individual v6 modules onto a v2 Hinode site.

Rendered-output deltas (decision package §2.5)

Per the visual baselines captured during the module-wave program, expect (and this PR's own
visual gate confirms, see below) these intended rendered-output changes once the v6 engine's
defaults actually apply, relative to the v5-generation site:

  • section-title width: w-100col-12 col-md-8
  • hero/heading width default: 8
  • illustration.width default: 8 (smaller hero/illustration images where content omits
    widths)

These are pinned in the program's visual baselines with per-page justifications; this PR's own
candidate build was compared against the v6-engine baseline (which already reflects these
deltas), not the v5 baseline, so no new diffs are expected from them here.

Warnings inventory (H1 deliverable — H2's work list)

Full categorized table in .superpowers/visual/wave4-hinode-h1-report.md in the driver's
program workspace (not committed to git, per the program's baseline-workspace convention —
see tests/visual/README.md). Summary: build exits 0, zero ERROR lines, 533 top-level WARN
lines (517 Invalid arguments headers + 16 other Hugo-core WARN lines), the 517 headers
carrying 1,045 individual argument-detail lines that collapse to 57 distinct
[component] argument ... patterns, plus 13 distinct non-argument WARN messages.

  • (a) Hinode call-site bug — 53 patterns, 991 occurrences. Overwhelmingly one root
    mechanism: Hinode's own un-migrated InitArgs.html call sites forward their own
    possibly-unset argument values (which now surface as literal ""/wrong-typed zero-values
    under the v6 engine instead of being silently coerced) into a nested partial's own
    validated argument dict — e.g. card-group.html passing "color" $args.color straight
    through into card.html. Traced with file:line evidence for representative cases
    (card-group.html, image-set.html, sidebar.html, bundlev2.html callers). Also
    includes one structure-file gap fully fixable inside this repo: data/structures/link.yml
    doesn't declare outline, even though assets/links.html reads .outline off every link
    item.
  • (b) exampleSite content issue — 0 patterns. None isolated to content-only causes; every
    pattern traced back to a call-site or schema mechanism.
  • (c) engine/deprecation notice — 13 patterns (all non-argument WARN lines: Hugo-core
    config-key/method deprecations, identical before/after, unrelated to mod-utils).
  • (d) other — 4 patterns, 54 occurrences, all pre-existing mod-utils shared-type schema
    gaps
    , already tracked as maintainer follow-ups in decision package §3 (not fixable inside
    Hinode or mod-blocks alone): testimonials[N] unsupported icon, video unsupported
    media_id and color (this PR's build additionally surfaces color as undeclared on the
    shared video
    type, beyond the id/media-id gap decision package §3 already named).

Gates

  • hugo mod graph -s exampleSite: every gethinode edge on its new-generation major, zero
    old-major edges.
  • pnpm run build:example: exit 0, zero ERROR lines (532-533 WARN lines, inventoried above).
  • Visual regression (tests/visual/visual.mjs) vs. the driver's v6-engine baseline
    (.superpowers/visual/baseline-v6): 41/42 clean, 1 flagged — the known mermaid
    render-race flake (en_docs_components_mermaid.png, 0.248% diff ratio), consistent with the
    documented 0.1-0.3% residual flake. Full report triaged in the H1 report doc.

Not in scope for this PR

  • Hinode's own InitArgsArgs.html call-site migration (H2).
  • Fixing any of the inventoried warnings (H2).
  • The mod-utils shared-type schema gaps (maintainer decision, decision package §3).
  • Downstream sites/themes (template, version-demo, customization-demo, theme-agency,
    gethinode.com) — gated on this PR's release.

This PR is not merged. H2 adds commits to this same branch for the warnings cleanup.

🤖 Generated with Claude Code


Stage H2 — warnings-backlog cleanup

Adds 7 commits on top of H1's mechanical pin: bumps mod-utils to v6.2.0 (the release
containing PR #337's video.color member, on top of v6.1.0's PR #336
testimonials.icon/video.media-id), then fixes the category (a) call-site bugs from H1's
warnings inventory and removes the now-dead deprecated-twin/default-pipe patterns. Full
evidence: .superpowers/visual/wave4-hinode-h2-report.md.

Warnings: before → after

Before (H1, v6.0.1) After (H2, v6.2.0)
Total WARN lines 520-533 36-43
Invalid arguments detail lines 504 22-27
Distinct argument patterns 57 7 (all confirmed out-of-scope — see below)
Category (c) Hugo-core deprecations 16 lines / 13 distinct unchanged
ERROR lines / exit code 0 / 0 0 / 0

46 of H1's 53 numbered category-(a) patterns (964 of 991 occurrences) fixed at their Hinode
call sites — predominantly raw .Get/GetArgParent locals or ad hoc ""/false initializers
forwarded into a nested Args-validated partial instead of the caller's own already-validated
$args envelope (an explicit "" is now a real, rejected value under the v6 engine; only a
true nil is "absent" and eligible for the schema default to apply). Two new Hinode-owned
helpers (utilities/OmitEmpty.html, utilities/ToStringSlice.html) centralize the fix; the
data/structures/table.yml breakpoint: default: "" bug (single highest-count pattern, 70-80
occurrences) was a genuine structure-file default error, fixed directly.

7 patterns (27 occurrences) are NOT fixable in this repo — deeper tracing than H1's initial
categorization showed these are upstream:

  • links[N] outline (section-title/links/hero/about, 12 occurrences): the shared links
    type in mod-utils's vendored data/structures/_types.yml lacks outline — not a Hinode
    link.yml gap as originally attributed (that file only governs the standalone shortcode,
    which doesn't even forward outline). Same class as the already-fixed testimonials.icon/
    video.media-id/video.color gaps; recommend the same upstream-PR treatment.
  • hero-image justify, table pagination, card-group gutter (9 + 2-3 + 2-3
    occurrences): three literal-""-forwarding call-site bugs in mod-blocks v2.0.0
    (assets/hero.html, list.hugo.html, video-message.hugo.html) — same bug class this PR
    fixes throughout Hinode, just in the already-released mod-blocks module. Out of this stage's
    authorized scope (hinode repo only).

Visual triage

40/42 pages clean (≤0.0071% diff). 2 flagged, both triaged:

  • mermaid (0.35% diff) — the documented pre-existing render-race flake, accepted per the
    program's known-flake allowance.
  • card (dimension mismatch, +48px) — intended. Isolated via before/after HTML-source
    diff (not just pixels): header-style's schema default (full) now correctly applies where
    raw "" forwarding previously bypassed it entirely, so several cards' header caption
    (date/reading-time/tag line) now renders instead of staying empty — a real rendering-defect
    fix, not a regression. A same-mechanism, functionally-inert duplicate p-0 class (schema
    default collides with a pre-existing hardcoded literal) was also found and left as-is
    (zero visual effect, out of this PR's scope). Full mechanism write-up in the H2 report.

Commits

build(deps) mod-utils bump · fix(structures) table breakpoint default · feat(utilities)
OmitEmpty/ToStringSlice helpers · fix(images) · fix(cards) · fix(scripts) ·
fix(sidebar).

Still not merged — driver review pending.


Stage H3 — upstream pins close the backlog

acb3bdd1 chore: pin mod-utils v6.3.0 and mod-blocks v2.0.1 — the two upstream releases
fixing everything H2 flagged as out-of-repo (links[].outline shared-type member; mod-blocks'
hero-image justify / list pagination / video-message gutter empty-forwards). Result:
ZERO Invalid arguments warnings (down from 22-27 after H2, 504 after H1); the only
remaining WARN output is the 13 distinct pre-existing Hugo-core deprecation notices (16 lines,
byte-identical to the pre-program state). Verified deterministic across two builds, exit 0.

Visual: 40/42 clean vs baseline-v6, same two flags as H2 — mermaid (0.46%, known render-race
flake; H3-vs-H2 shot comparison shows the same page flickering at 0.107%, confirming flake) and
the card docs page (+65px vs H2): the auto-generated argument-reference table now documents the
new outline link member — intended, mechanism verified by HTML diff.

Bump Hinode's own module path to github.com/gethinode/hinode/v3 and pin
the eight directly-imported modules to their mod-utils v6 generation
majors: mod-flexsearch/v5, mod-fontawesome/v6, mod-leaflet/v3,
mod-lottie/v3, mod-mermaid/v5, mod-simple-datatables/v4, and
mod-utils/v6 v6.0.1. mod-bootstrap, mod-csp, mod-katex, and
mod-google-analytics stay pinned as-is, since they never depended on
mod-utils.

exampleSite/go.mod receives the same generation pin for the modules it
pins directly (mod-fontawesome/v6, mod-utils/v6, mod-blocks/v2,
mod-bootstrap-icons/v2); mod-docs and mod-cookieyes stay untouched
since they are generation-agnostic or outside the program. The
exampleSite's self-require of hinode stays dropped (workspace-resolved
via hinode.work, per the established pattern from the module waves),
now pointing at the /v3 import path.

hugo mod graph -s exampleSite confirms every gethinode edge lands on
its new-generation major with zero old-major edges remaining. The
build exits 0 with zero ERROR lines; the argument-warnings backlog
this surfaces (~57 distinct patterns, mostly Hinode's own un-migrated
InitArgs call sites forwarding empty-string defaults) is inventoried
for the H2 cleanup stage, not fixed here.

BREAKING CHANGE: requires github.com/gethinode/hinode/v3; adopts the
mod-utils v6 module generation across all eight directly-imported
modules (mod-flexsearch/v5, mod-fontawesome/v6, mod-leaflet/v3,
mod-lottie/v3, mod-mermaid/v5, mod-simple-datatables/v4,
mod-utils/v6). Sites must bump their own module import to
github.com/gethinode/hinode/v3 and vendor before upgrading; mixing a
v2 Hinode with any v6-generation module is unsupported.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@netlify

netlify Bot commented Jul 13, 2026

Copy link
Copy Markdown

Deploy Preview for gethinode-demo ready!

Name Link
🔨 Latest commit acb3bdd
🔍 Latest deploy log https://app.netlify.com/projects/gethinode-demo/deploys/6a54718c529f5b00087c4fa1
😎 Deploy Preview https://deploy-preview-2004--gethinode-demo.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

markdumay and others added 8 commits July 13, 2026 06:30
Pins the newest v6 release, which adds the video type's missing `color`
member (mod-utils#337) on top of the `testimonials.icon` and
`video.media-id` additions already shipped in v6.1.0 (mod-utils#336) -
closing the last category-(d) schema gap the H1 warnings inventory found.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…oint

data/structures/table.yml declared default: "" for breakpoint, a select
argument whose global type never lists "" among its valid options
(none/xs/sm/md/lg). Under the v6 engine every unset breakpoint therefore
got defaulted straight into a validation failure. assets/table.html
already treats an absent breakpoint the same as "" via a `with` guard, so
dropping the bogus default (leaving the argument simply optional) is a
no-op for rendering and removes 70-80 warnings per build.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Adds two small, Hinode-owned helpers used by the empty-string-forwarding
fixes in the following commits (do not touch mod-utils' Args/InitArgs
engine itself):

- OmitEmpty.html coerces a falsy raw value (e.g. from
  utilities/GetArgParent.html or a shortcode's own .Get, neither of which
  can represent "absent") into a literal nil, so a nested partial's own
  Args-validated dict sees "not provided" instead of an explicit "" that
  fails select/bool/int type or option checks.
- ToStringSlice.html round-trips a Hugo-built list (append/complement/
  intersect, which yield []interface{} even when every element is a
  string) through delimit/split into a genuine []string, since the v6
  engine matches a "[]string"-typed argument against the exact Go
  reflect type.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Four independent empty-string-forwarding bugs in the image rendering
chain, each fixed at its call site (no validation weakened):

- assets/image.html rewrote priority "auto" (the schema default, a
  valid select value) to "" before forwarding to
  assets/helpers/image-definition.html, which failed since "auto" is not
  a valid select option, but image-definition.html's rendering guard
  checked for any truthy value. Now the raw value is forwarded
  unchanged, and image-definition.html's fetchpriority attribute is
  skipped for both absent and "auto" (same rendered output as before).
- assets/helpers/image-dimension.html initialized $img to "" and only
  reassigned it when a Hugo image resource was actually resolved (e.g.
  never in the ratio-only branch), forwarding a bare string where
  assets/helpers/image-set.html declares img as
  *resources.resourceAdapter. Wrapped with the new OmitEmpty helper.
- page/thumbnail.html initialized $anchor to "" and only set it from a
  map-shaped Thumbnail param, forwarding "" whenever Thumbnail was a
  plain string (e.g. the exampleSite's gotmpl-generated team pages).
- layouts/_shortcodes/img.html, the carousel <img> child shortcode,
  forwarded utilities/GetArgParent.html's raw "" straight into
  assets/carousel-item.html's ratio argument.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The card and card-group shortcodes each ran their own InitArgs.html
validation purely for warnings, then rebuilt the values they actually
forward to the assets partial from raw .Get/GetArgParent locals that
default unset arguments to "" (never nil). Under the v6 engine that
explicit "" fails the nested partial's select/bool/int validation
instead of being treated as absent, most visibly for color, ratio,
gutter, header/body/footer-style, orientation, subtle, button,
icon-rounded, link-icon, link-type, scroll, loading, and anchor.

- layouts/_shortcodes/card-group.html: deleted the redundant raw-.Get
  local variables (including the now-dead manual header/footer/style
  deprecated-name resolution, since InitArgs.html already resolves
  same-key kebab/camelCase twins) and forwards the validated $args
  fields directly, restoring cross-name deprecated-argument combination
  (e.g. header vs header-style, which camelize to different keys and so
  are NOT auto-resolved by InitArgs) with the canonical value taking
  precedence per Args.html's own documented precedence lattice.
- layouts/_shortcodes/card.html: kept utilities/GetArgParent.html (it
  provides parent-shortcode cascading that InitArgs.html does not), but
  wraps its raw "" output with the new OmitEmpty helper before
  forwarding into assets/card.html.
- layouts/_partials/assets/card.html and assets/card-group.html: the
  same "" default and thumbnail-anchor derivation formerly forced a bare
  "" instead of nil.

This lets each field's real schema default apply where "" previously
short-circuited it (e.g. header-style's default is "full", footer-style's
is "none"), which is why some docs pages now render the caption line
(date/reading-time/tags) that was silently blank before - triaged as an
intended rendering fix, not a regression.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ists

- footer/scripts.html rewrote script state "immediate" (a valid select
  value, the "no async/defer attribute" sentinel) to "" before
  forwarding to templates/script.html, which then failed its own
  validation. Forwards the raw value now; templates/script.html (and its
  exampleSite mount-workaround duplicate, which shadows the theme copy
  and needed the identical fix) skips the attribute for both absent and
  "immediate" instead.
- footer/scripts.html and head/stylesheet.html forward JS/SCSS module
  lists built via append/complement/intersect, which yield
  []interface{} even when every element is a string; bundle.yml declares
  "modules" as the raw reflect type "[]string", so the v6 engine's exact
  type match rejected them. Wrapped with the new ToStringSlice helper.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
layouts/docs/all.html coerced a non-slice Scratch "sidebar" value (e.g.
absent) to the string "", forwarded straight into assets/sidebar.html's
menu argument, which declares []interface{} - failing validation instead
of triggering the partial's own auto-generate-menu fallback. Uses the
dict-missing-key nil idiom (the sanctioned way to produce a literal nil
in this Hugo version, per Args.html's own site-param lookup) instead.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Adopts the two upstream releases that close the last argument warnings
flagged by the H2 cleanup: mod-utils v6.3.0 adds the shared links type's
outline member (and carries v6.2.0's video color member), and mod-blocks
v2.0.1 fixes its three empty-string call-site forwards (hero-image
justify, list pagination, video-message gutter). The exampleSite now
builds with ZERO Invalid arguments warnings; only the 13 distinct
pre-existing Hugo-core deprecation notices remain.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@markdumay markdumay merged commit acc3480 into main Jul 13, 2026
16 checks passed
@markdumay

Copy link
Copy Markdown
Collaborator Author

🎉 This PR is included in version 3.0.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant