jekyll-theme-zer0 1.28.0 → 1.30.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +1143 -13
- data/_data/README.md +2 -0
- data/_data/ai.yml +5 -3
- data/_data/ai_pricing.yml +36 -0
- data/_data/backlog.yml +507 -2
- data/_data/consumers.yml +157 -9
- data/_data/features.yml +303 -20
- data/_data/feedback_types.yml +17 -12
- data/_data/i18n/fr.yml +12 -7
- data/_data/i18n/manifest.yml +39 -12
- data/_data/ingredient_densities.yml +122 -0
- data/_data/landing.yml +5 -2
- data/_data/navigation/main.yml +16 -0
- data/_data/navigation/quickstart.yml +4 -0
- data/_data/recipe_courses.yml +64 -0
- data/_data/site_builder.yml +874 -0
- data/_data/theme-manifest.yml +160 -124
- data/_data/ui-text.yml +26 -0
- data/_includes/README.md +26 -2
- data/_includes/analytics/posthog.html +2 -2
- data/_includes/components/admin-links.html +2 -2
- data/_includes/components/admin-tabs.html +2 -2
- data/_includes/components/ai-chat.html +14 -11
- data/_includes/components/analytics-dashboard.html +8 -8
- data/_includes/components/author-bio.html +1 -1
- data/_includes/components/author-card.html +10 -2
- data/_includes/components/author-eeat.html +4 -4
- data/_includes/components/background-customizer.html +10 -10
- data/_includes/components/background-image.html +114 -0
- data/_includes/components/background-settings.html +28 -15
- data/_includes/components/collection-manager.html +5 -5
- data/_includes/components/component-showcase.html +13 -13
- data/_includes/components/config-editor.html +12 -12
- data/_includes/components/config-viewer.html +8 -8
- data/_includes/components/cookie-consent.html +15 -15
- data/_includes/components/cta-button.html +7 -2
- data/_includes/components/dev-shortcuts.html +7 -7
- data/_includes/components/env-dashboard.html +8 -8
- data/_includes/components/env-switcher.html +9 -9
- data/_includes/components/feature-card.html +2 -2
- data/_includes/components/halfmoon.html +2 -2
- data/_includes/components/info-section.html +42 -37
- data/_includes/components/js-cdn.html +15 -15
- data/_includes/components/language-toggle.html +168 -21
- data/_includes/components/mermaid.html +72 -435
- data/_includes/components/nanobar.html +5 -5
- data/_includes/components/nav-editor.html +2 -2
- data/_includes/components/nav-export.html +2 -2
- data/_includes/components/nav-overview.html +2 -2
- data/_includes/components/page-feedback.html +45 -30
- data/_includes/components/page-views-init.html +55 -0
- data/_includes/components/page-views.html +33 -0
- data/_includes/components/post-card.html +22 -22
- data/_includes/components/post-type-badge.html +2 -2
- data/_includes/components/powered-by.html +2 -2
- data/_includes/components/preview-image.html +6 -0
- data/_includes/components/quick-index.html +2 -2
- data/_includes/components/recipe-card.html +67 -0
- data/_includes/components/recipe-duration.html +50 -0
- data/_includes/components/recipe-grams.html +58 -0
- data/_includes/components/recipe-index.html +96 -0
- data/_includes/components/recipe-ingredients.html +90 -0
- data/_includes/components/recipe-meta.html +96 -0
- data/_includes/components/recipe-nutrition.html +57 -0
- data/_includes/components/recipe-qty.html +73 -0
- data/_includes/components/recipe-ratio.html +151 -0
- data/_includes/components/recipe-scaler.html +73 -0
- data/_includes/components/recipe-steps.html +86 -0
- data/_includes/components/recipe-temp.html +45 -0
- data/_includes/components/search-modal.html +29 -4
- data/_includes/components/searchbar.html +2 -2
- data/_includes/components/shortcuts-modal.html +3 -0
- data/_includes/components/svg-background.html +2 -2
- data/_includes/components/theme-customizer.html +2 -2
- data/_includes/components/theme-info.html +14 -7
- data/_includes/components/theme-preview-gallery.html +22 -22
- data/_includes/content/giscus.html +2 -2
- data/_includes/content/intro.html +8 -8
- data/_includes/content/jsonld-faq.html +2 -2
- data/_includes/content/jsonld-software.html +24 -5
- data/_includes/content/seo.html +4 -4
- data/_includes/content/sitemap.html +27 -27
- data/_includes/content/toc.html +183 -183
- data/_includes/core/branding.html +6 -6
- data/_includes/core/console-capture.html +32 -74
- data/_includes/core/favicon.html +49 -7
- data/_includes/core/footer-fabs.html +17 -3
- data/_includes/core/footer.html +49 -34
- data/_includes/core/head.html +110 -86
- data/_includes/core/header.html +76 -54
- data/_includes/docs/bootstrap-docs.html +8 -8
- data/_includes/landing/landing-install-cards.html +2 -2
- data/_includes/landing/landing-quick-links.html +1 -1
- data/_includes/navigation/admin-nav.html +2 -2
- data/_includes/navigation/nav-tree.html +8 -8
- data/_includes/navigation/navbar.html +12 -12
- data/_includes/navigation/section-sidebar.html +109 -27
- data/_includes/navigation/sidebar-config.html +36 -2
- data/_includes/navigation/sidebar-left.html +17 -16
- data/_includes/navigation/sidebar-right.html +8 -7
- data/_includes/obsidian/full-graph.html +2 -2
- data/_includes/setup/claude-session.html +72 -0
- data/_includes/setup/prereq-checklist.html +90 -0
- data/_includes/setup/wizard.html +924 -222
- data/_includes/stats/stats-categories.html +8 -8
- data/_includes/stats/stats-header.html +14 -14
- data/_includes/stats/stats-metrics.html +14 -14
- data/_includes/stats/stats-no-data.html +12 -12
- data/_includes/stats/stats-overview.html +6 -6
- data/_includes/stats/stats-tags.html +8 -8
- data/_layouts/404.html +38 -24
- data/_layouts/README.md +2 -0
- data/_layouts/admin.html +24 -24
- data/_layouts/article.html +43 -33
- data/_layouts/author.html +20 -20
- data/_layouts/authors.html +2 -2
- data/_layouts/book-abc.html +12 -12
- data/_layouts/book-story.html +15 -15
- data/_layouts/book.html +12 -12
- data/_layouts/collection.html +33 -33
- data/_layouts/cookbook.html +88 -0
- data/_layouts/default.html +31 -28
- data/_layouts/home.html +23 -23
- data/_layouts/index.html +10 -10
- data/_layouts/landing.html +17 -17
- data/_layouts/news.html +44 -44
- data/_layouts/note.html +38 -38
- data/_layouts/notebook.html +34 -34
- data/_layouts/recipe.html +274 -0
- data/_layouts/root.html +92 -55
- data/_layouts/section.html +62 -33
- data/_layouts/setup.html +3 -3
- data/_layouts/sitemap-collection.html +49 -49
- data/_layouts/stats.html +40 -40
- data/_layouts/tag.html +12 -12
- data/_layouts/welcome.html +21 -21
- data/_sass/components/_callout.scss +1 -1
- data/_sass/components/_footer.scss +37 -1
- data/_sass/components/_mermaid.scss +375 -0
- data/_sass/components/_page-views.scss +36 -0
- data/_sass/components/_recipe.scss +506 -0
- data/_sass/components/_setup-wizard.scss +764 -0
- data/_sass/components/_ui-enhancements.scss +6 -6
- data/_sass/core/_navbar.scss +261 -46
- data/_sass/layouts/_landing.scss +2 -2
- data/_sass/layouts/_navbar-extras.scss +14 -4
- data/_sass/tokens/_color.scss +6 -0
- data/_sass/tokens/_index.scss +2 -0
- data/_sass/tokens/_radius.scss +21 -0
- data/_sass/tokens/_typography.scss +4 -0
- data/_sass/utilities/_focus.scss +14 -0
- data/assets/css/main.scss +4 -0
- data/assets/js/ai-chat.js +47 -5
- data/assets/js/fleet-feedback-capture.js +124 -0
- data/assets/js/fleet-feedback.js +853 -0
- data/assets/js/mermaid-diagrams.js +1267 -0
- data/assets/js/modules/navigation/config.js +9 -6
- data/assets/js/modules/navigation/navbar.js +55 -0
- data/assets/js/modules/navigation/scroll-spy.js +315 -80
- data/assets/js/modules/theme/appearance.js +8 -2
- data/assets/js/obsidian-wiki-links.js +8 -3
- data/assets/js/page-feedback.js +125 -192
- data/assets/js/page-views.js +372 -0
- data/assets/js/recipe-scaler.js +501 -0
- data/assets/js/search-modal.js +36 -0
- data/assets/js/setup-wizard.js +2279 -226
- data/assets/js/site-builder.js +1834 -0
- data/assets/js/ui-enhancements.js +11 -3
- data/scripts/README.md +44 -0
- data/scripts/ai/README.md +38 -0
- data/scripts/ai/api_call.rb +124 -0
- data/scripts/ai/usage.rb +314 -0
- data/scripts/ai/usage_report.rb +225 -0
- data/scripts/bin/audit-consumer +39 -7
- data/scripts/bin/giscus-discussions +213 -14
- data/scripts/bin/manifest +35 -12
- data/scripts/ci/agent_review_result.py +164 -0
- data/scripts/ci/test_agent_review_result.py +172 -0
- data/scripts/ci/test_visual_evidence_autogen.py +341 -0
- data/scripts/ci/visual_evidence_autogen.py +1060 -0
- data/scripts/content-review.rb +20 -1
- data/scripts/design-system-check.rb +170 -0
- data/scripts/lib/audit.sh +42 -2
- data/scripts/lint-liquid-raw.rb +137 -0
- data/scripts/test/integration/mermaid +22 -8
- data/scripts/test/lib/run_tests.sh +3 -1
- data/scripts/test/lib/test_agent_review_result.sh +27 -0
- data/scripts/test/lib/test_visual_evidence_autogen.sh +24 -0
- data/scripts/translate.rb +94 -16
- metadata +48 -2
data/_data/README.md
CHANGED
|
@@ -7,6 +7,8 @@ This directory contains YAML data files that power the Zer0-Mistakes Jekyll them
|
|
|
7
7
|
| File | Purpose | Auto-Generated |
|
|
8
8
|
|------|---------|----------------|
|
|
9
9
|
| `navigation/` | Site navigation menus | No |
|
|
10
|
+
| `ai.yml` | The one place the AI model is configured (read by the hub's `bamr87/bamr87/.github/actions/claude-run@main` runner, consumed by reference) | No |
|
|
11
|
+
| `ai_pricing.yml` | API list prices used to *estimate* AI spend for calls that report tokens but no cost (part of the shared `ai-runner` kit) | No |
|
|
10
12
|
| `authors.yml` | Author profile information | No |
|
|
11
13
|
| `content_statistics.yml` | Site content analytics | **Yes** |
|
|
12
14
|
| `roadmap.yml` | Single source of truth for the project roadmap (drives the README mermaid diagram and the `/roadmap/` Jekyll page) | No |
|
data/_data/ai.yml
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
# =============================================================================
|
|
2
2
|
# _data/ai.yml — one place the AI model is configured for zer0-mistakes agents
|
|
3
3
|
# -----------------------------------------------------------------------------
|
|
4
|
-
# Read by
|
|
5
|
-
#
|
|
6
|
-
#
|
|
4
|
+
# Read by the fleet's ai-runner kit — bamr87/bamr87/.github/actions/claude-run
|
|
5
|
+
# (consumed by reference; the issue-autopilot's AI step). Change the model
|
|
6
|
+
# here and every agent call uses it; AI_MODEL (or the action's `model` input)
|
|
7
|
+
# overrides it for one run. Auth is NOT here — it comes from the
|
|
8
|
+
# CLAUDE_CODE_OAUTH_TOKEN (preferred) or ANTHROPIC_API_KEY secret.
|
|
7
9
|
# =============================================================================
|
|
8
10
|
provider: anthropic
|
|
9
11
|
model: claude-opus-4-8
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# =============================================================================
|
|
2
|
+
# ai_pricing.yml — API list prices used to ESTIMATE AI spend (per million tokens)
|
|
3
|
+
# -----------------------------------------------------------------------------
|
|
4
|
+
# The telemetry layer (scripts/ai/usage.rb) prefers the cost the Claude Code CLI
|
|
5
|
+
# itself reports (`total_cost_usd`) — that number is authoritative and this file
|
|
6
|
+
# is never consulted for it. This table exists for the paths that report tokens
|
|
7
|
+
# but no dollars: the raw Claude API fallback (scripts/ai/api_call.rb) and any
|
|
8
|
+
# execution log that predates cost reporting. Those records get cost_source:
|
|
9
|
+
# "estimated", computed as
|
|
10
|
+
#
|
|
11
|
+
# input×in + output×out + cache_read×(0.1×in)
|
|
12
|
+
# + cache_write_5m×(1.25×in) + cache_write_1h×(2×in)
|
|
13
|
+
#
|
|
14
|
+
# which reproduces the CLI's own arithmetic to the cent (validated 2026-07-14
|
|
15
|
+
# against a live run). Prices are USD per MTok at standard API list rates —
|
|
16
|
+
# subscription (OAuth) runs have no marginal dollar cost, so every published
|
|
17
|
+
# figure is labeled "API-equivalent". Source: platform.claude.com/docs/en/pricing
|
|
18
|
+
# (cached 2026-07-14). Update this file when Anthropic changes list prices;
|
|
19
|
+
# estimates are marked as such everywhere they surface.
|
|
20
|
+
# =============================================================================
|
|
21
|
+
multipliers:
|
|
22
|
+
cache_read: 0.1 # × input price
|
|
23
|
+
cache_write_5m: 1.25 # × input price (5-minute TTL — the CLI default)
|
|
24
|
+
cache_write_1h: 2.0 # × input price (1-hour TTL)
|
|
25
|
+
|
|
26
|
+
# Matched by longest model-id prefix, so dated snapshots (claude-haiku-4-5-20251001)
|
|
27
|
+
# resolve to their family row. `default` catches unknown models (opus-tier, so an
|
|
28
|
+
# unknown model over- rather than under-estimates).
|
|
29
|
+
models:
|
|
30
|
+
claude-opus-4-8: { input: 5.00, output: 25.00 }
|
|
31
|
+
claude-opus-4-7: { input: 5.00, output: 25.00 }
|
|
32
|
+
claude-opus-4-6: { input: 5.00, output: 25.00 }
|
|
33
|
+
claude-sonnet-5: { input: 3.00, output: 15.00 }
|
|
34
|
+
claude-sonnet-4-6: { input: 3.00, output: 15.00 }
|
|
35
|
+
claude-haiku-4-5: { input: 1.00, output: 5.00 }
|
|
36
|
+
default: { input: 5.00, output: 25.00 }
|
data/_data/backlog.yml
CHANGED
|
@@ -62,8 +62,8 @@
|
|
|
62
62
|
|
|
63
63
|
meta:
|
|
64
64
|
title: "zer0-mistakes Backlog"
|
|
65
|
-
updated: 2026-
|
|
66
|
-
next_id:
|
|
65
|
+
updated: 2026-09-05
|
|
66
|
+
next_id: 52
|
|
67
67
|
|
|
68
68
|
tasks:
|
|
69
69
|
# --- Housekeeping (seeded so the loop has work on day one) ------------------
|
|
@@ -916,3 +916,508 @@ tasks:
|
|
|
916
916
|
links: { issue: 302, pr: null, roadmap: null }
|
|
917
917
|
created: 2026-07-12
|
|
918
918
|
updated: 2026-07-16
|
|
919
|
+
|
|
920
|
+
- id: T-035
|
|
921
|
+
title: "Adopt --zer0-radius-* and display-size tokens across the remaining Sass partials"
|
|
922
|
+
status: open
|
|
923
|
+
priority: P2
|
|
924
|
+
area: feat
|
|
925
|
+
risk: low
|
|
926
|
+
effort: M
|
|
927
|
+
source: issue
|
|
928
|
+
route: theme-ui
|
|
929
|
+
summary: >-
|
|
930
|
+
The design-system alignment PR #389 (ZER0-081) introduced --zer0-radius-* and
|
|
931
|
+
--zer0-text-display-* tokens and adopted them in the partials the Claude
|
|
932
|
+
Design system names (callout, landing, ui-enhancements). Hardcoded radii
|
|
933
|
+
remain in _navbar.scss (~15 sites), notebooks.scss, code-copy.scss,
|
|
934
|
+
_docs-code-examples.scss, and others; hero .display-4 mobile overrides in
|
|
935
|
+
_ui-enhancements.scss (2rem and 1.75rem blocks — the two @media blocks
|
|
936
|
+
overlap, later wins) predate the fluid clamp tokens. Sweep them onto the
|
|
937
|
+
tokens value-preservingly where values match the scale, and reconcile the
|
|
938
|
+
duplicate hero override blocks; anything intentionally off-scale keeps a
|
|
939
|
+
literal plus a comment.
|
|
940
|
+
acceptance:
|
|
941
|
+
- "No border-radius literal in _sass/** that duplicates a --zer0-radius-* value (grep-clean or commented as intentional)."
|
|
942
|
+
- "Hero display sizing states one rule set; duplicate @media blocks reconciled."
|
|
943
|
+
- "scripts/design-system-check.rb still green; compiled CSS visually identical (evidence or skip-evidence rationale)."
|
|
944
|
+
- "regression test added"
|
|
945
|
+
- "before/after evidence committed"
|
|
946
|
+
links: { issue: null, pr: null, roadmap: null }
|
|
947
|
+
created: 2026-08-14
|
|
948
|
+
updated: 2026-08-14
|
|
949
|
+
|
|
950
|
+
# --- UI/UX fix list intake (hand-written review, 2026-08-18) ----------------
|
|
951
|
+
|
|
952
|
+
- id: T-036
|
|
953
|
+
title: "Remove hover transforms that cause pointer-edge flicker in the navbar"
|
|
954
|
+
status: done
|
|
955
|
+
priority: P1
|
|
956
|
+
area: feat
|
|
957
|
+
risk: standard
|
|
958
|
+
effort: S
|
|
959
|
+
source: user
|
|
960
|
+
route: theme-ui
|
|
961
|
+
summary: >-
|
|
962
|
+
.nav-link:hover, .nav-search-button:hover and .nav-settings-button:hover in
|
|
963
|
+
_sass/core/_navbar.scss apply transform: translateY(-1px) (icons scale 1.1,
|
|
964
|
+
chevron :hover::after translateY(2px)), so the element moves out from under
|
|
965
|
+
a pointer parked on its edge, hover exits, it returns — infinite flicker.
|
|
966
|
+
Delete every transform from :hover rules (keep background/color
|
|
967
|
+
transitions; a pressed cue may use :active translateY(1px) only) and audit
|
|
968
|
+
_sass/components/_ui-enhancements.scss and card hover styles for the same
|
|
969
|
+
pattern.
|
|
970
|
+
acceptance:
|
|
971
|
+
# Scoped to the navbar per the issue's Option A. Criterion 1 was
|
|
972
|
+
# originally "no transform in any :hover rule under _sass/" — that is 42
|
|
973
|
+
# rules across ~15 files (card lifts, book tilts, recipe hovers) and a
|
|
974
|
+
# visual redesign of a published theme, not this defect. It also flagged
|
|
975
|
+
# `transform: none`, which is the CORRECTIVE pattern this repo already
|
|
976
|
+
# uses in _post-navigation.scss and the prefers-reduced-motion blocks.
|
|
977
|
+
# A theme-wide motion policy belongs in its own task.
|
|
978
|
+
# Stated as the COMPUTED value, not "no matching rule": these controls
|
|
979
|
+
# are `.btn`s and _ui-enhancements.scss's theme-wide
|
|
980
|
+
# `.btn:hover { translateY(-2px) }` still matches them and always will.
|
|
981
|
+
# It is overridden by `transform: none`, not deleted, so a rule-existence
|
|
982
|
+
# check would be permanently red. That inherited lift is why deleting the
|
|
983
|
+
# navbar's own translateY was not sufficient on its own.
|
|
984
|
+
- "getComputedStyle(control).transform is `none` while hovered, for every navbar control."
|
|
985
|
+
# Direction corrected: translateY(-1px) moves the element UP, so the row
|
|
986
|
+
# it stops covering is the BOTTOM one. A test parked on the top edge
|
|
987
|
+
# passes without exercising the bug.
|
|
988
|
+
- "Pointer parked on the bottom edge of any nav item or utility button does not flicker."
|
|
989
|
+
# Note: `#bdNavbar .nav-link:hover`, named in the summary as the primary
|
|
990
|
+
# cause, was dead code — its lift sits inside a container query that never
|
|
991
|
+
# matches at desktop widths (measured 1040/1140/1200/1280px on the built
|
|
992
|
+
# site, `none` at every one, on main too). The observable flicker was on
|
|
993
|
+
# the utility buttons and the FABs.
|
|
994
|
+
- "regression test added"
|
|
995
|
+
- "before/after evidence committed"
|
|
996
|
+
links: { issue: 404, pr: null, roadmap: null }
|
|
997
|
+
created: 2026-08-18
|
|
998
|
+
updated: 2026-09-03
|
|
999
|
+
|
|
1000
|
+
- id: T-037
|
|
1001
|
+
title: "Navbar width recovery: two clean label tiers, merged chevron, centered grid, no subtitle"
|
|
1002
|
+
status: open
|
|
1003
|
+
priority: P2
|
|
1004
|
+
area: feat
|
|
1005
|
+
risk: standard
|
|
1006
|
+
effort: M
|
|
1007
|
+
source: user
|
|
1008
|
+
route: theme-ui
|
|
1009
|
+
summary: >-
|
|
1010
|
+
Top nav is cramped and truncates labels ("Quicksta…"). Keep per-item icons
|
|
1011
|
+
at every tier but only two states — icon + full label (wide container) and
|
|
1012
|
+
the existing icon-only tier (narrow) — removing the intermediate ellipsized
|
|
1013
|
+
state (_includes/navigation/navbar.html + _sass/core/_navbar.scss container
|
|
1014
|
+
queries). Merge each dropdown's separate 22-24px chevron button into the
|
|
1015
|
+
parent link's padding box (position:absolute overlay, shared hover
|
|
1016
|
+
background on the li, button kept for a11y). Use grid-template-columns:
|
|
1017
|
+
1fr auto 1fr on .navbar-main so the menu stays optically centered. Retire
|
|
1018
|
+
the navbar subtitle (_includes/core/branding.html — home hero only).
|
|
1019
|
+
Clarify the three toggles: labeled "Menu" text button below lg, gear moves
|
|
1020
|
+
into the unified drawer on mobile so only two toggles coexist.
|
|
1021
|
+
acceptance:
|
|
1022
|
+
- "At 1024px and 1280px with 5 nav items every label is fully visible or the whole row is icon-only — no ellipses anywhere."
|
|
1023
|
+
- "Dropdown chevron shares the parent row's hover zone; no dead zone between link and chevron."
|
|
1024
|
+
- "Navbar carries logo + title only; subtitle appears on the home hero."
|
|
1025
|
+
- "regression test added"
|
|
1026
|
+
- "before/after evidence committed"
|
|
1027
|
+
links: { issue: null, pr: null, roadmap: null }
|
|
1028
|
+
created: 2026-08-18
|
|
1029
|
+
updated: 2026-08-18
|
|
1030
|
+
|
|
1031
|
+
- id: T-038
|
|
1032
|
+
title: "Language switcher: icon-only trigger and a compact, positive menu"
|
|
1033
|
+
status: done
|
|
1034
|
+
priority: P2
|
|
1035
|
+
area: feat
|
|
1036
|
+
risk: standard
|
|
1037
|
+
effort: S
|
|
1038
|
+
source: user
|
|
1039
|
+
route: theme-ui
|
|
1040
|
+
summary: >-
|
|
1041
|
+
_includes/components/language-toggle.html: drop the EN text span and the
|
|
1042
|
+
Bootstrap caret (38-40px square icon button; title + aria-label carry the
|
|
1043
|
+
name). In the menu, mark the current language with a check icon + tint
|
|
1044
|
+
(not .active primary fill); keep untranslated languages clickable
|
|
1045
|
+
(navigate to source page, set zer0-lang); mark machine translations with a
|
|
1046
|
+
small "auto" chip; replace per-row "(Not yet translated)" with one
|
|
1047
|
+
footnote line under a divider; menu width <= 220px.
|
|
1048
|
+
acceptance:
|
|
1049
|
+
- "Menu shows no disabled rows; widest row <= 220px; current language visually distinct without primary fill."
|
|
1050
|
+
- "Trigger is icon-only at all widths with an accessible name."
|
|
1051
|
+
- "regression test added"
|
|
1052
|
+
- "before/after evidence committed"
|
|
1053
|
+
links: { issue: 406, pr: 431, roadmap: null }
|
|
1054
|
+
created: 2026-08-18
|
|
1055
|
+
updated: 2026-09-01
|
|
1056
|
+
- id: T-039
|
|
1057
|
+
title: "Eliminate page-transition layout shift (fixed-nav offset, scrollbar gutter, server-rendered slots)"
|
|
1058
|
+
status: open
|
|
1059
|
+
priority: P1
|
|
1060
|
+
area: perf
|
|
1061
|
+
risk: standard
|
|
1062
|
+
effort: M
|
|
1063
|
+
source: user
|
|
1064
|
+
route: theme-ui
|
|
1065
|
+
summary: >-
|
|
1066
|
+
Navigation between pages visibly bounces. Define --zer0-nav-height in
|
|
1067
|
+
:root, derive body padding-top and every sticky offset (admin.html's
|
|
1068
|
+
top: 5rem, TOC, sidebars) and scroll-margin-top from it (no JS
|
|
1069
|
+
measurement). Add html { scrollbar-gutter: stable }. Render banner/nanobar
|
|
1070
|
+
slots server-side with fixed height (nanobar 3px strip always present;
|
|
1071
|
+
setup banner via Liquid when site_needs_setup, not JS insert). Verify
|
|
1072
|
+
explicit width/height on content images and font-display: swap + preload
|
|
1073
|
+
for bootstrap-icons woff2. Progressive enhancement: @view-transition
|
|
1074
|
+
{ navigation: auto } with a 120ms root fade.
|
|
1075
|
+
acceptance:
|
|
1076
|
+
- "Lighthouse CLS < 0.02 on landing, docs, and admin pages."
|
|
1077
|
+
- "No visible reflow when navigating between short and long pages (scrollbar gutter stable)."
|
|
1078
|
+
- "All sticky offsets derive from --zer0-nav-height (no hardcoded top: 5rem)."
|
|
1079
|
+
- "regression test added"
|
|
1080
|
+
- "before/after evidence committed"
|
|
1081
|
+
links: { issue: null, pr: null, roadmap: null }
|
|
1082
|
+
created: 2026-08-18
|
|
1083
|
+
updated: 2026-08-18
|
|
1084
|
+
|
|
1085
|
+
- id: T-040
|
|
1086
|
+
title: "Setup wizard: live YAML preview, vertical stepper, draft persistence, stable panel height, inline validation"
|
|
1087
|
+
status: done
|
|
1088
|
+
priority: P2
|
|
1089
|
+
area: feat
|
|
1090
|
+
risk: standard
|
|
1091
|
+
effort: M
|
|
1092
|
+
source: user
|
|
1093
|
+
route: theme-ui
|
|
1094
|
+
summary: >-
|
|
1095
|
+
_includes/setup/wizard.html + assets/js/setup-wizard.js: replace the
|
|
1096
|
+
step-5-only <pre> with a persistent sticky preview panel regenerated on
|
|
1097
|
+
every input (copy/download always enabled); replace nav-pills tabs with a
|
|
1098
|
+
left vertical stepper showing done/active/upcoming state (steps unlock on
|
|
1099
|
+
validation, Back always allowed, remove the "N% complete" math); persist
|
|
1100
|
+
the draft to localStorage under zer0-setup-draft (debounced 300ms, restore
|
|
1101
|
+
on load, "Draft saved" chip, clear on download); give the panel container
|
|
1102
|
+
a min-height equal to the tallest step so Back/Next never move vertically;
|
|
1103
|
+
validate email/URL on blur with is-invalid + message and list unfilled
|
|
1104
|
+
recommended fields as warnings on the Review step.
|
|
1105
|
+
acceptance:
|
|
1106
|
+
- "YAML preview visible and live at lg+; Back/Next buttons never shift vertically between steps."
|
|
1107
|
+
- "Reload mid-wizard restores the draft; invalid email/URL flagged on blur."
|
|
1108
|
+
- "regression test added"
|
|
1109
|
+
- "before/after evidence committed"
|
|
1110
|
+
links: { issue: 408, pr: 432, roadmap: null }
|
|
1111
|
+
created: 2026-08-18
|
|
1112
|
+
updated: 2026-09-01
|
|
1113
|
+
- id: T-041
|
|
1114
|
+
title: "Admin layout: actions reachable on mobile, grouped sidebar, shared sticky offset, single heading"
|
|
1115
|
+
status: open
|
|
1116
|
+
priority: P2
|
|
1117
|
+
area: feat
|
|
1118
|
+
risk: standard
|
|
1119
|
+
effort: M
|
|
1120
|
+
source: user
|
|
1121
|
+
route: theme-ui
|
|
1122
|
+
summary: >-
|
|
1123
|
+
_layouts/admin.html + _includes/navigation/admin-nav.html: the
|
|
1124
|
+
admin_actions wrapper is d-none d-md-flex so actions are unreachable on
|
|
1125
|
+
phones — render the first action as a visible button at all widths with
|
|
1126
|
+
the rest in a "..." dropdown. Group sidebar items under small-caps headers
|
|
1127
|
+
(Configure / System / Links) via a group: key in
|
|
1128
|
+
_data/navigation/admin.yml; counts as plain numerals, statuses as colored
|
|
1129
|
+
dot + word; active item = tint + semibold, not solid primary fill. Replace
|
|
1130
|
+
style="top: 5rem" with top: calc(var(--zer0-nav-height) + 1rem) (depends
|
|
1131
|
+
on T-039). Keep the "Administration" heading in the offcanvas header only.
|
|
1132
|
+
acceptance:
|
|
1133
|
+
- "Every admin action reachable at 375px width."
|
|
1134
|
+
- "Sidebar grouped; no solid-primary active fill; sticky offset uses the shared variable."
|
|
1135
|
+
- "regression test added"
|
|
1136
|
+
- "before/after evidence committed"
|
|
1137
|
+
links: { issue: null, pr: null, roadmap: null }
|
|
1138
|
+
created: 2026-08-18
|
|
1139
|
+
updated: 2026-08-18
|
|
1140
|
+
depends_on: [T-039]
|
|
1141
|
+
|
|
1142
|
+
- id: T-042
|
|
1143
|
+
title: "Skin contrast sweep: AA link params, tertiary meta text, per-skin badge/button audit"
|
|
1144
|
+
status: open
|
|
1145
|
+
priority: P1
|
|
1146
|
+
area: a11y
|
|
1147
|
+
risk: standard
|
|
1148
|
+
effort: M
|
|
1149
|
+
source: user
|
|
1150
|
+
route: a11y
|
|
1151
|
+
summary: >-
|
|
1152
|
+
_sass/theme/_skins.scss: several skins omit the zer0-skin-palette mixin's
|
|
1153
|
+
$link-light/$link-dark params and fall back to $brand/$accent, which fail
|
|
1154
|
+
4.5:1 (yellow/orange/cyan brands on white, saturated brands on #212529) —
|
|
1155
|
+
pass explicit AA-checked values for every skin with a comment table of
|
|
1156
|
+
measured ratios. text-body-tertiary on 11-12px meta text (admin header
|
|
1157
|
+
"Updated…", wizard hints) falls below AA — use --bs-secondary-color at
|
|
1158
|
+
small sizes, tertiary only >= 16px. Audit .btn-primary text per skin
|
|
1159
|
+
(auto-switch to dark text when brand luminance > 0.55 via color-contrast()
|
|
1160
|
+
or a precomputed token).
|
|
1161
|
+
acceptance:
|
|
1162
|
+
- "axe/Lighthouse contrast passes on light + dark for all skins."
|
|
1163
|
+
- "Every skin passes explicit link colors; measured-ratio table committed as comments."
|
|
1164
|
+
- "regression test added"
|
|
1165
|
+
- "before/after evidence committed"
|
|
1166
|
+
links: { issue: null, pr: null, roadmap: null }
|
|
1167
|
+
created: 2026-08-18
|
|
1168
|
+
updated: 2026-08-18
|
|
1169
|
+
|
|
1170
|
+
- id: T-043
|
|
1171
|
+
title: "Mermaid diagrams: render-in-place (no CLS), token-driven theming, figure shell, flash-free theme switch"
|
|
1172
|
+
status: open
|
|
1173
|
+
priority: P2
|
|
1174
|
+
area: feat
|
|
1175
|
+
risk: standard
|
|
1176
|
+
effort: L
|
|
1177
|
+
source: user
|
|
1178
|
+
route: theme-ui
|
|
1179
|
+
summary: >-
|
|
1180
|
+
_includes/components/mermaid.html: the hidden pre > code is replaced by a
|
|
1181
|
+
min-height:100px div that grows to 300-500px on render, shifting the page —
|
|
1182
|
+
render in place with the placeholder inheriting the code block's height
|
|
1183
|
+
and animate the swap. Delete the ~20 !important SVG overrides that fight
|
|
1184
|
+
JS themeVariables (forced white text breaks colored nodes; light mode uses
|
|
1185
|
+
#007bff vs site primary #0d6efd; skins don't affect diagrams) — build
|
|
1186
|
+
themeVariables at init from live tokens (getComputedStyle on --bs-primary
|
|
1187
|
+
/ --bs-body-bg / --bs-border-color / --bs-body-color), re-run on
|
|
1188
|
+
data-bs-theme AND data-theme-skin change. Wrap each diagram in a
|
|
1189
|
+
figure.mermaid-figure with type chip, optional title, copy-source /
|
|
1190
|
+
download-SVG / fullscreen toolbar (reuse the code-copy button pattern) and
|
|
1191
|
+
figcaption. On theme switch render the new SVG off-DOM and cross-fade
|
|
1192
|
+
120ms (instant under prefers-reduced-motion). Builds on T-039.
|
|
1193
|
+
acceptance:
|
|
1194
|
+
- "CLS contribution from a page with 3 diagrams < 0.01."
|
|
1195
|
+
- "No !important SVG overrides remain; diagrams follow theme AND skin tokens live."
|
|
1196
|
+
- "Theme switch shows no blank flash."
|
|
1197
|
+
- "regression test added"
|
|
1198
|
+
- "before/after evidence committed"
|
|
1199
|
+
links: { issue: null, pr: null, roadmap: null }
|
|
1200
|
+
created: 2026-08-18
|
|
1201
|
+
updated: 2026-08-18
|
|
1202
|
+
depends_on: [T-039]
|
|
1203
|
+
|
|
1204
|
+
- id: T-044
|
|
1205
|
+
title: "Playwright suite aborts: duplicate openDialog declaration in accessibility.spec.js"
|
|
1206
|
+
status: done
|
|
1207
|
+
priority: P1
|
|
1208
|
+
area: tests
|
|
1209
|
+
risk: low
|
|
1210
|
+
effort: S
|
|
1211
|
+
source: issue
|
|
1212
|
+
route: test-author
|
|
1213
|
+
summary: >-
|
|
1214
|
+
test/visual/core/accessibility.spec.js declares `async function
|
|
1215
|
+
openDialog` twice — at line 172 (page, selector) and again at line 425
|
|
1216
|
+
(page, selector, kind), the latter added by 98fd6f9 (#387) without
|
|
1217
|
+
removing the former. Two function declarations of the same name in one
|
|
1218
|
+
module scope is a SyntaxError, so Playwright fails to parse the file and
|
|
1219
|
+
the WHOLE run aborts before any test executes: "Identifier 'openDialog'
|
|
1220
|
+
has already been declared. (425:15)". This takes down the critical and
|
|
1221
|
+
smoke tiers together, on every branch, and has been red on main since
|
|
1222
|
+
2026-08-14. Discovered during #414, whose own new spec
|
|
1223
|
+
(test/visual/features/recipes.spec.js) therefore cannot run in CI. The
|
|
1224
|
+
three-argument version is a strict superset — with `kind` undefined it
|
|
1225
|
+
resolves to Ctor='Modal' and 'shown.bs.modal', exactly what the
|
|
1226
|
+
two-argument one does — so deleting the earlier declaration (lines
|
|
1227
|
+
165-184, comment included) is behaviour-preserving.
|
|
1228
|
+
acceptance:
|
|
1229
|
+
- "test/visual/core/accessibility.spec.js parses; `npx playwright test --project=critical` runs to completion."
|
|
1230
|
+
- "Only one openDialog declaration remains, and its callers all still pass."
|
|
1231
|
+
- "No behavioural change to the modal/offcanvas a11y tests."
|
|
1232
|
+
links: { issue: 416, pr: null, roadmap: null }
|
|
1233
|
+
created: 2026-08-23
|
|
1234
|
+
updated: 2026-08-23
|
|
1235
|
+
|
|
1236
|
+
- id: T-045
|
|
1237
|
+
title: "Homepage snapshot baselines were regenerated without the 1967px drift being diagnosed"
|
|
1238
|
+
status: done
|
|
1239
|
+
priority: P2
|
|
1240
|
+
area: tests
|
|
1241
|
+
risk: low
|
|
1242
|
+
effort: S
|
|
1243
|
+
source: issue
|
|
1244
|
+
route: test-author
|
|
1245
|
+
summary: >-
|
|
1246
|
+
The Visual Snapshots tier fails all 9 `Theme skins > homepage visual
|
|
1247
|
+
snapshot` cases with the SAME diff — 1967 pixels (ratio 0.01) — against
|
|
1248
|
+
test/visual/snapshots/features/appearance-snapshot.spec.js-snapshots/homepage-*-snapshots-linux.png,
|
|
1249
|
+
well over the maxDiffPixels 150 budget. The count being identical across
|
|
1250
|
+
air/aqua/contrast/dark/dirt/neon/mint/plum/sunrise points at one shared,
|
|
1251
|
+
skin-independent region rather than a palette regression. Verified during
|
|
1252
|
+
#414 that it is NOT that PR's doing: building origin/main and the PR
|
|
1253
|
+
branch and screenshotting the homepage at the spec's own 1280x720
|
|
1254
|
+
viewport produced BYTE-IDENTICAL PNGs (same md5), so the branch renders
|
|
1255
|
+
the homepage exactly as main does and the drift is between the committed
|
|
1256
|
+
baselines and what main itself now renders. Note while investigating:
|
|
1257
|
+
_includes/components/theme-info.html renders a minute-resolution build
|
|
1258
|
+
stamp, site.time | date "%b %d, %H:%M" — it currently sits in a collapsed
|
|
1259
|
+
offcanvas (measured 0x0, not in the viewport) so it is not the cause
|
|
1260
|
+
today, but it is a live non-determinism hazard the moment that panel is
|
|
1261
|
+
shown by default, and worth masking regardless. UPDATE 2026-08-23: #413
|
|
1262
|
+
regenerated all 9 baselines when it merged, so the check is green again —
|
|
1263
|
+
resolved by re-blessing rather than by diagnosis, which is what the first
|
|
1264
|
+
acceptance criterion was meant to prevent. Diffing the old vs new CI
|
|
1265
|
+
baselines (homepage-air, 2596f866 vs e488c4c) puts the whole 5016px delta
|
|
1266
|
+
in two bands: y21-41 (a wide navbar strip, 4688px) and y626 (328px).
|
|
1267
|
+
page-views does render on the homepage so part of that is legitimately
|
|
1268
|
+
#413, but a navbar strip is not where a view-count badge belongs.
|
|
1269
|
+
Separating the two needs the diff artifact from a pre-#413 failing run,
|
|
1270
|
+
which has rolled off. What remains is confirming the y21-41 band is
|
|
1271
|
+
accounted for. UPDATE 2026-08-25: the y21-41 band is the navbar
|
|
1272
|
+
reflowing, and the reason it RECURS is structural — a path-filter gap.
|
|
1273
|
+
ci.yml's `styling` filter (which gates the snapshots job) lists only code
|
|
1274
|
+
paths; `_data/**` appears solely under `content`, which gates no visual
|
|
1275
|
+
job. So #419's nav item changed the chrome of every page with Visual
|
|
1276
|
+
Snapshots SKIPPED on both the PR and the main push, and the drift
|
|
1277
|
+
surfaced on #420, an unrelated PR. The y626 band is now UNRECOVERABLE:
|
|
1278
|
+
both artifact uploads use 14-day retention (ci.yml, nightly-extended.yml)
|
|
1279
|
+
and every pre-#413 failing run is past that window. Recording that rather
|
|
1280
|
+
than leaving it open — no evidence survives to diagnose it from.
|
|
1281
|
+
acceptance:
|
|
1282
|
+
- "_data/** (or at minimum _data/navigation/**) is covered by the `styling` filter in ci.yml, so a nav/chrome data change runs Visual Snapshots instead of skipping it."
|
|
1283
|
+
- "A CI guard pins that coverage, so the gap cannot silently reopen (lint-workflows.yml)."
|
|
1284
|
+
- "A PR touching only _data/navigation/main.yml runs Visual Snapshots — demonstrated on the checks list, not asserted."
|
|
1285
|
+
- "Visual Snapshots passes on main and on a fresh branch with no source changes."
|
|
1286
|
+
- "Any genuinely time- or build-varying content inside the snapshot region is masked or stubbed, so the tier cannot drift again."
|
|
1287
|
+
- "No baseline PNG is regenerated as part of this work; any diff is diagnosed in the PR before it is blessed."
|
|
1288
|
+
- "The y626 band is explained, or recorded as unrecoverable with the reason. (Recorded: artifacts past 14-day retention.)"
|
|
1289
|
+
links: { issue: 417, pr: 425, roadmap: null }
|
|
1290
|
+
created: 2026-08-23
|
|
1291
|
+
updated: 2026-09-01
|
|
1292
|
+
|
|
1293
|
+
- id: T-046
|
|
1294
|
+
title: "Retire the now-dead gotoBeforeScrollSpy fixture and cover the mobile offcanvas TOC spy"
|
|
1295
|
+
status: open
|
|
1296
|
+
priority: P3
|
|
1297
|
+
area: tests
|
|
1298
|
+
risk: low
|
|
1299
|
+
effort: S
|
|
1300
|
+
source: issue
|
|
1301
|
+
route: test-author
|
|
1302
|
+
summary: >-
|
|
1303
|
+
Discovered while fixing the TOC scroll spy: test/visual/fixtures.js
|
|
1304
|
+
exports gotoBeforeScrollSpy(), which strips data-bs-spy/data-bs-target
|
|
1305
|
+
from <body> before Bootstrap auto-initializes so its native ScrollSpy
|
|
1306
|
+
cannot clear server-rendered .active classes off admin sidebar links.
|
|
1307
|
+
That attribute no longer exists — _layouts/root.html dropped it (and
|
|
1308
|
+
_layouts/default.html dropped the second copy on .bd-main) so the theme's
|
|
1309
|
+
own scroll-spy.js is the single owner of .active on TOC links — which
|
|
1310
|
+
makes the fixture a no-op that still reads as load-bearing. Replace its
|
|
1311
|
+
call sites in test/visual/features/admin.spec.js with the plain
|
|
1312
|
+
waitForJekyll/gotoOrSkip helpers and delete it, keeping the admin
|
|
1313
|
+
active-link assertions that motivated it. While there, add the coverage
|
|
1314
|
+
test/visual/features/scroll-spy.spec.js deliberately left out: the mobile
|
|
1315
|
+
offcanvas TOC, where .offcanvas-body rather than .bd-toc is the scroll
|
|
1316
|
+
container the spy keeps the active link visible in.
|
|
1317
|
+
acceptance:
|
|
1318
|
+
- "gotoBeforeScrollSpy is removed from test/visual/fixtures.js and from its call sites; no spec references it."
|
|
1319
|
+
- "The admin specs that used it still pass, asserting the same server-rendered active nav links."
|
|
1320
|
+
- "A spec exercises the TOC scroll spy below the lg breakpoint with the offcanvas TOC open, asserting the active entry tracks scrolling and stays visible inside .offcanvas-body."
|
|
1321
|
+
- "npm run test:smoke is green."
|
|
1322
|
+
links: { issue: null, pr: null, roadmap: null }
|
|
1323
|
+
created: 2026-09-05
|
|
1324
|
+
updated: 2026-09-05
|
|
1325
|
+
|
|
1326
|
+
- id: T-047
|
|
1327
|
+
title: "pages/_docs/features/toc.md documents a TOC API the theme does not implement"
|
|
1328
|
+
status: open
|
|
1329
|
+
priority: P3
|
|
1330
|
+
area: docs
|
|
1331
|
+
risk: low
|
|
1332
|
+
effort: S
|
|
1333
|
+
source: issue
|
|
1334
|
+
route: content-reviewer
|
|
1335
|
+
summary: >-
|
|
1336
|
+
Discovered while correcting the scroll-spy sections of
|
|
1337
|
+
pages/_docs/features/toc.md: the page's Implementation and Configuration
|
|
1338
|
+
halves describe a table of contents this theme does not have. "TOC
|
|
1339
|
+
Generation" shows a Kramdown `{{ content | toc_only }}` snippet and a
|
|
1340
|
+
hand-rolled `page.content | split: '<h'` extractor, neither of which the
|
|
1341
|
+
theme uses — the real TOC comes from _includes/content/toc.html (the
|
|
1342
|
+
allejo/jekyll-toc parser) invoked by _includes/navigation/sidebar-right.html.
|
|
1343
|
+
"Enable TOC" documents front-matter keys that nothing reads; the
|
|
1344
|
+
`toc.min_level` / `toc.max_level` pair in the same section was already
|
|
1345
|
+
corrected (grep confirms no include, layout, plugin or _config.yml
|
|
1346
|
+
references either key). A reader following this page cannot reproduce the
|
|
1347
|
+
theme's behaviour. Rewrite the two sections against the actual include,
|
|
1348
|
+
its parameters, and the front-matter keys that really gate the panel.
|
|
1349
|
+
acceptance:
|
|
1350
|
+
- "Every Liquid snippet in toc.md matches an include the theme actually ships, verified by path."
|
|
1351
|
+
- "Front-matter keys documented on the page are read somewhere in _includes, _layouts, _plugins or _config.yml."
|
|
1352
|
+
- "scripts/content-review.rb still scores the page in the green band."
|
|
1353
|
+
- "Jekyll build with the layered dev configs is green and the page's anchors keep resolving."
|
|
1354
|
+
|
|
1355
|
+
- id: T-048
|
|
1356
|
+
title: "Site-level theme_color re-pins --zer0-color-primary over the active skin"
|
|
1357
|
+
status: open
|
|
1358
|
+
priority: P2
|
|
1359
|
+
area: feat
|
|
1360
|
+
risk: low
|
|
1361
|
+
effort: S
|
|
1362
|
+
source: issue
|
|
1363
|
+
summary: "Discovered while making Mermaid diagrams follow the skin (ZER0-013 rework): the skin mixin (_sass/theme/_skins.scss) writes both --bs-primary and --zer0-color-primary under [data-theme-skin], but _includes/core/tokens-inline.html emits `:root { --zer0-color-primary: <theme_color.main> }` AFTER main.css, and :root ties [data-theme-skin] on specificity, so the later inline rule wins. Result on this site: buttons/links follow the skin (#6fa8dc on air, #8338ec on neon) while every custom component that reads --zer0-color-primary (callouts, code-block accent border, focus rings) stays on the config #007bff regardless of skin. Mermaid works around it by reading --bs-primary first; the token layer should agree with itself instead."
|
|
1364
|
+
acceptance:
|
|
1365
|
+
- "With theme_color.main set, switching skin changes --zer0-color-primary as well as --bs-primary (probe getComputedStyle on <html>)."
|
|
1366
|
+
- "Decide and document the precedence: skin over site theme_color (recommended) or the reverse — one rule, applied to every --zer0-color-* the mixin sets."
|
|
1367
|
+
- "A smoke test asserts --zer0-color-primary === --bs-primary after setSkin('neon')."
|
|
1368
|
+
- "before/after evidence committed"
|
|
1369
|
+
links: { issue: null, pr: null, roadmap: null }
|
|
1370
|
+
created: 2026-09-05
|
|
1371
|
+
updated: 2026-09-05
|
|
1372
|
+
|
|
1373
|
+
- id: T-049
|
|
1374
|
+
title: "test_core.sh: Liquid nested-tag check and gem-content check can never fail"
|
|
1375
|
+
status: open
|
|
1376
|
+
priority: P3
|
|
1377
|
+
area: tests
|
|
1378
|
+
risk: low
|
|
1379
|
+
effort: S
|
|
1380
|
+
source: audit
|
|
1381
|
+
summary: "Found while reviewing CI logs for PR #455: test/test_core.sh prints '[ERROR] Nested Liquid output tags found in _includes/navigation/sidebar-pagetree.html' on every run and still reports the Liquid validation as passed. Two defects: (1) the check is `grep -q \"{{.*{{\"`, which flags any line with two output tags — sidebar-pagetree.html:65 is `{{ _base }}{{ _section }}` inside a capture, valid Liquid — and the `return 1` sits inside a `find | while read` pipeline subshell, so it can never fail the function; (2) the gem-content check runs `tar -tzf` on the .gem, but a gem is an uncompressed tar (metadata.gz, data.tar.gz, checksums.yaml.gz), so gzip prints 'stdin: not in gzip format' four times and both branches always fall through to the 'Gem may not contain…' warnings without inspecting anything."
|
|
1382
|
+
acceptance:
|
|
1383
|
+
- "The nested-tag check only flags a genuinely nested output tag (e.g. `{{ a {{ b }} }}`), not two sibling tags on one line, and a positive match fails the test (no subshell swallowing the return)."
|
|
1384
|
+
- "The gem-content check lists data.tar.gz inside the .gem (`tar -xOf … data.tar.gz | tar -tzf -`) and asserts _layouts/ and assets/ are present; a gem missing them fails the test."
|
|
1385
|
+
- "./test/test_core.sh runs clean: no '[ERROR]' line on a passing run and no gzip/tar noise."
|
|
1386
|
+
links: { issue: null, pr: null, roadmap: null }
|
|
1387
|
+
created: 2026-09-05
|
|
1388
|
+
updated: 2026-09-05
|
|
1389
|
+
|
|
1390
|
+
- id: T-050
|
|
1391
|
+
title: "Visual Snapshots tier: LiveReload reloads the page mid-test because npm ci lands after Jekyll starts watching"
|
|
1392
|
+
status: open
|
|
1393
|
+
priority: P2
|
|
1394
|
+
area: tests
|
|
1395
|
+
risk: low
|
|
1396
|
+
effort: S
|
|
1397
|
+
source: audit
|
|
1398
|
+
summary: "The snapshots project shows a retried test on most CI runs — '[snapshots] › appearance-snapshot.spec.js › skin: <random> › homepage visual snapshot' fails with 'page.evaluate: Execution context was destroyed, most likely because of a navigation' and passes on retry (aqua on PR #455, mint on main 5ff38bf). Nothing on the homepage navigates; the likely trigger is Jekyll's LiveReload. test/update-snapshots.sh runs `docker compose up -d` (jekyll serve --watch --livereload, repo bind-mounted at /site) and only then starts the Playwright container, which runs `npm ci` into the same bind mount. jekyll-watch 2.2.1 registers an ignore pattern only for exclude paths that EXIST when serve starts (`next unless absolute_path.exist?` in listen_ignore_paths), and a fresh CI checkout has no node_modules/, so the thousands of files npm ci writes fire the watcher, the site regenerates, and LiveReload pushes a reload to every open page over localhost:35729 (reachable: the Playwright container uses --network host). Whichever skin is mid-step when the regeneration finishes fails; Playwright's CI retry (retries: 1) masks it, at the cost of one retry per run and a false 'flaky' signal that would hide a real regression."
|
|
1399
|
+
acceptance:
|
|
1400
|
+
- "Jekyll in the snapshot stack cannot reload the browser during a run: either node_modules/ exists before `docker compose up` (run `npm ci` first, or `mkdir -p node_modules`) or the test stack serves without --livereload (compose override or a JEKYLL_LIVERELOAD toggle)."
|
|
1401
|
+
- "Confirmed with the Playwright trace or `docker compose logs jekyll` showing no 'Regenerating' during a run."
|
|
1402
|
+
- "Ten consecutive CI runs of the snapshots project report 0 flaky tests."
|
|
1403
|
+
- "Root cause noted in the header of test/update-snapshots.sh so the ordering is not undone."
|
|
1404
|
+
links: { issue: null, pr: null, roadmap: null }
|
|
1405
|
+
created: 2026-09-05
|
|
1406
|
+
updated: 2026-09-05
|
|
1407
|
+
|
|
1408
|
+
- id: T-051
|
|
1409
|
+
title: "Preview-image engine: the xAI default model grok-2-image is retired — default to grok-imagine-image-2.0"
|
|
1410
|
+
status: open
|
|
1411
|
+
priority: P2
|
|
1412
|
+
area: infra
|
|
1413
|
+
risk: low
|
|
1414
|
+
effort: S
|
|
1415
|
+
source: issue
|
|
1416
|
+
summary: "Discovered while adding the xAI provider to the chat proxy and Site Builder (ZER0-087): scripts/lib/preview_generator.py's XAIProvider.default_model() still returns 'grok-2-image', which xAI has retired in favour of the Grok Imagine family (grok-imagine-image-2.0, per docs.x.ai release notes). A site with preview_images.provider: xai and no explicit model gets an upstream error. The Site Builder now writes preview_images.model explicitly for generated sites, so only the engine default (and the .env.example comment for IMAGE_MODEL) is stale. scripts/lib/ is CODEOWNERS-owned, so this is a human-review change."
|
|
1417
|
+
acceptance:
|
|
1418
|
+
- "XAIProvider.default_model() returns grok-imagine-image-2.0 and the provider table comment in the engine header matches."
|
|
1419
|
+
- "The image request keeps working with the current xAI response shape (data[0].url or b64_json)."
|
|
1420
|
+
- "scripts/lib/README.md / .env.example mention the new default."
|
|
1421
|
+
links: { issue: null, pr: null, roadmap: null }
|
|
1422
|
+
created: 2026-09-07
|
|
1423
|
+
updated: 2026-09-07
|