Skip to content

docs: move the Learn page onto the Astro site and generate its statistics - #324

Merged
Vishnu2707 merged 13 commits into
OWASP:devfrom
parthrohit22:dev
Sep 30, 2026
Merged

Vishnu2707 merged 13 commits into
OWASP:devfrom
parthrohit22:dev

Conversation

@parthrohit22

@parthrohit22 parthrohit22 commented Aug 29, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Moves the Learn page onto the Astro site and computes its statistics when the site is built, so the page cannot go stale and nothing has to push generated numbers to dev.

Why this PR exists

The hosted Learn page was deployed from my fork rather than the upstream repository, so changes merged into OWASP/openshield did not appear there. The page also carried hand-maintained counts that went stale whenever a rule landed. The post-merge job meant to refresh them failed on every run because dev only accepts pull requests. #344 changed that job to open a bot PR instead (which produced #360). This PR removes the need for the job.

Changes

  • Learn route at build time. docs/learn/index.html and docs/_redirects are removed. The page lives at website/src/pages/learn.astro and computes every count from website/src/lib/repoData.ts, the same source /rules/ uses. The build fails if the severity boxes or the category bars do not add up to the rule total.
  • All five contract severity levels. Severity counts cover every level in contracts/severity.v1.json, including INFO. CI accepts INFO rules, so leaving INFO out would fail the whole Pages build on the first one. A fifth severity box shows INFO (0 today).
  • CRITICAL and INFO in the rules gallery and homepage section. Both levels now have the contract colours and labels. The five CRITICAL rules on dev currently render with an empty label and an undefined colour, and as "Low" on the homepage. The gallery also gets a CRITICAL filter button and accepts ?severity=CRITICAL|INFO.
  • README only. README.md is the one file that still states counts. .github/scripts/update_learn_page.py is replaced by update_readme_stats.py, which rewrites only the README and has a --check mode. Its patterns are anchored on the row label and the unit, not the whole sentence.
  • Read-only workflow. update-learn-page.yml is replaced by readme-stats.yml (contents: read). It runs when rules, playbooks or the README change, and reports stale README counts as a warning with a job summary. It never pushes and never opens a PR, so there is no bypass of the ci: declare branch protection as rulesets and audit effective drift (#298) #344 rulesets and no STATS_BOT_TOKEN is needed. docs/ci-pipeline.md is updated to match.
  • Site verification. website/scripts/verify-site.mjs covers the /learn/ route and its canonical URL.

Statistics on the merge target (current dev)

Statistic Value
Azure security rules / matching playbooks 144 / 144
CRITICAL / HIGH / MEDIUM / LOW / INFO 5 / 95 / 40 / 4 / 0 (sums to 144)
Largest category (100% bar) Network, 35

These are no longer committed to the page. They are what the build renders today.

Validation

  • npm run check in website/: build, configure-cms and verify pass for 15 HTML pages.
  • INFO-rule reproduction: I changed one rule to SEVERITY = "INFO" locally, and the build still succeeded and rendered INFO 1 instead of failing reconciliation. Then I reverted the rule.
  • python .github/scripts/update_readme_stats.py --check: README already current (144 / 144).
  • pytest tests/test_update_readme_stats.py tests/test_check_branch_protection.py: 21 passed. Full backend suite: 1485 passed, 3 skipped.
  • ruff check / ruff format --check: clean.
  • Merged together with fix(website): harden Astro CSP and verify the built output against it #318, npm run check still passes. The new route adds no inline script, so it satisfies fix(website): harden Astro CSP and verify the built output against it #318's script-src 'self' verifier.

After merge

#360 is superseded and can be closed.

@parthrohit22 parthrohit22 changed the title Dev docs: sync fork dev and refresh Learn page statistics Aug 29, 2026
@parthrohit22 parthrohit22 self-assigned this Aug 29, 2026
@parthrohit22
parthrohit22 requested a review from m-khan-97 August 29, 2026 12:36

@ritiksah141 ritiksah141 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The updates are internally consistent and the mechanics are clean (docs-only, no leftover stale counts, DCO signed, CI green), but the numbers were computed against a dev snapshot from before #277 and #320 merged. Since your fork sync, #277 added 10 new perimeter rules (az_net_018 through az_net_027) plus 10 playbooks, so every headline number is wrong at the merge target:

Stat This PR Actual at dev tip
Azure security rules 96 106
Remediation playbooks 96 106 per-rule (107 .sh files including the review playbook)
HIGH checks 58 67
MEDIUM checks 32 33
Network category bar 23 (untouched) 33

Compute 5 is the only value that still matches. Related issues that come with the same root cause:

  1. The category bar widths are scaled to Network 23 as the max, so they need rescaling to 33 = 100% after the rebase.
  2. The severity boxes do not sum to the headline: 58 + 32 + 4 = 94 vs a headline of 96, because there is no CRITICAL box. The repo has 2 CRITICAL rules. At dev tip the real split is HIGH 67, MEDIUM 33, LOW 4, CRITICAL 2.
  3. The "4 Compliance frameworks" metric: compliance/frameworks/ now holds 6 JSON files (CIS, NIST CSF, ISO 27001, SOC 2, ENISA PQC, NCSC PQC). If 4 is deliberate (core mapper frameworks only), fine as-is; otherwise update to 6.

This is timing, not process: your sync landed before those merges. The fix is to rebase onto current dev and regenerate: rules and playbooks to 106, HIGH 67, MEDIUM 33, LOW 4, add a CRITICAL 2 severity box, Network bar to 33 with rescaled widths, and the README feature table plus mermaid diagram to 106. Happy to re-review once that lands.

@parthrohit22

Copy link
Copy Markdown
Collaborator Author

@ritiksah141 Rebased onto current dev and recomputed everything against the real tip: rules/playbooks 106, HIGH 67, MEDIUM 33, added the missing CRITICAL box (2), Network bar rescaled to 33.

On the "4 vs 6" compliance frameworks question — good catch flagging it rather than guessing. Turns out 4 is deliberate: .github/scripts/update_learn_page.py hardcodes COMPLIANCE_FRAMEWORK_COUNT = 4 # CIS, NIST, ISO 27001, SOC 2 on purpose, separately from the 2 PQC framework files. I actually got this wrong on my first pass (changed it to 6 since FRAMEWORK_FILE_MAP in the API has 6 entries) — the repo's own auto-update workflow caught it and reverted that one field back to 4 on push. Left as-is now, matches the existing convention.

CI's green on the current head.

ritiksah141
ritiksah141 previously approved these changes Sep 1, 2026

@ritiksah141 ritiksah141 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All good from my side. approving it

@TFT444 TFT444 left a comment •

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Docs-only change, clean diff, DCO signed, CI green. The internal consistency of the PR is good: the category bars sum to 106, bar widths are correctly scaled to Network=33 as 100%, and the severity boxes (CRITICAL 2 + HIGH 67 + MEDIUM 33 + LOW 4) sum exactly to 106. The addition of the CRITICAL severity box and the rescaling of bar widths are correct.

However, the headline number is stale. The PR was generated from a fork snapshot that matches dev after #277 (az_net_018..027, 10 new network rules) but before #279 (az_cache_001, az_cosmos_001, az_cosmos_002, az_db_005..007, az_idn_016..025, az_stor_006..009 20 rules across four categories). Current dev tip has 126 rules, not 106. The delta breaks down as:

Category This PR dev tip Delta
Network 33 35 +2
Identity 15 25 +10 (AZ-IDN-016..025)
Database 4 8 +4 (cosmos_001, db_005..007)
Storage 5 9 +4 (stor_006..009)
Total 106 126 +20

Severity at dev tip: CRITICAL 3, HIGH 82, MEDIUM 37, LOW 4 (total 126). The PR's severity split is correct for its 106-rule snapshot but wrong relative to the actual merge target.

What needs updating before merge:

  1. README and docs/learn/index.html headline rule/playbook count: 106 → 126
  2. Category bars: Network 33→35, Identity 15→25, Database 4→8, Storage 5→9, with bar widths rescaled to Network=35 as 100%
  3. Severity boxes: CRITICAL 3, HIGH 82, MEDIUM 37, LOW 4
  4. HIGH-severity checks metric card: 67 → 82

The "4 Compliance frameworks" metric is fine as a deliberate choice (CIS, NIST CSF, ISO 27001, SOC 2 the two PQC-specific frameworks are not part of the general compliance mapper narrative).

Happy to re-review once rebased to current dev tip and statistics regenerated.

Signed-off-by: parthrohit22 <parthrohit60@gmail.com>
github-actions Bot and others added 2 commits September 6, 2026 02:24
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Signed-off-by: parthrohit22 <parthrohit60@gmail.com>
@parthrohit22

Copy link
Copy Markdown
Collaborator Author

@TFT444 rebased onto current dev and re-ran .github/scripts/update_learn_page.py against the tip. It reports "already current; nothing to do" — the earlier regeneration commits (c6a8ea6, 5aaab48) already brought every count to the current dev state, and #278 (the only commit merged since) was rule corrections, not new rules, so no count moved.

Verified against the repo at dev tip:

  • 126 Azure security rules / 126 per-rule playbooks (127 .sh files incl. review_enterprise_resilience.sh)
  • Severity boxes: CRITICAL 3, HIGH 82, MEDIUM 37, LOW 4 (sum 126)
  • Category bars: Network 35, Identity 25, Security Operations 10, Storage 9, Database 8, Supply Chain 8, Kubernetes 6, KeyVault 6, Serverless 5, Compute 5, Backup 4, PostQuantum 3, Data Link 2
  • README feature table and mermaid diagram: 126

Net diff vs dev is README.md + docs/learn/index.html only. CI green. Re-requesting review.

@parthrohit22
parthrohit22 requested a review from TFT444 September 8, 2026 17:16
@parthrohit22

Copy link
Copy Markdown
Collaborator Author

@TFT444 re-review please. All four items from your Sep 4 review are on 89c6a24, and I've re-verified them against the current dev tip (b7e9a40) rather than re-running the generator and trusting its "nothing to do".

The branch is 0 commits behind dev, so these are the merge-target numbers, not a snapshot's.

Ground truth, via the repo's own collect_rule_stats():

severity:   {'CRITICAL': 3, 'HIGH': 82, 'MEDIUM': 37, 'LOW': 4, 'INFO': 0}
categories: Network 35, Identity 25, Security Operations 10, Storage 9, Database 8,
            Supply Chain 8, Kubernetes 6, KeyVault 6, Serverless 5, Compute 5,
            Backup 4, PostQuantum 3, Data Link 2
count_rules: 126

What's rendered, item by item:

Your item State on 89c6a24
1. Headline rule/playbook count 106 → 126 126 Azure security rules; metric cards 126 scan rules / 126 CLI remediation playbooks; README feature table and mermaid diagram both 126
2. Network 33→35, Identity 15→25, Database 4→8, Storage 5→9, rescaled to Network=35 All four match; Network is the 100% bar
3. Severity boxes CRITICAL 3, HIGH 82, MEDIUM 37, LOW 4 Match
4. HIGH-severity metric card 67 → 82 <strong>82</strong><span>High-severity checks</span>

Internal consistency, checked rather than assumed — I parsed the rendered bars back out of docs/learn/index.html and recomputed the widths:

categories: 13   sum: 126   width mismatches: []

Severity boxes sum to 3 + 82 + 37 + 4 = 126, and the category bars sum to 126 independently. Every bar width equals round(count / 35 * 100).

The 4 Compliance frameworks metric is unchanged, per your note that it's a deliberate choice — update_learn_page.py hardcodes COMPLIANCE_FRAMEWORK_COUNT = 4 separately from the two PQC framework files.

Net diff against dev is still README.md + docs/learn/index.html only. All 21 checks green, DCO signed.

Signed-off-by: parthrohit22 <parthrohit60@gmail.com>
Signed-off-by: parthrohit22 <parthrohit60@gmail.com>
Comment thread website/scripts/verify-site.mjs Fixed
Signed-off-by: parthrohit22 <parthrohit60@gmail.com>
The statistics in this PR were computed from an older dev snapshot. Ran
.github/scripts/update_learn_page.py against the current merge target: 143
rules and 143 matching playbooks, CRITICAL 5 / HIGH 94 / MEDIUM 40 / LOW 4
(sums to 143), and the category chart rescaled to Network 35 as 100% with
Kubernetes and Compute moved into their correct positions.

The script itself failed on the two README feature rows first: their prose had
been reworded upstream (the category list gained 'Kubernetes workloads', the
playbook row became 'review-gated remediation script'), and the patterns pinned
the whole sentence. Both now anchor on the row label and the unit that follows
the number instead, so an unrelated reword no longer blocks a count refresh
while the counts go stale - losing the row or the count shape still fails
loudly. Two tests cover both directions.

Signed-off-by: parthrohit22 <parthrohit60@gmail.com>
@parthrohit22 parthrohit22 changed the title docs: sync fork dev and refresh Learn page statistics docs: move the Learn page onto the Astro site and generate its statistics Sep 20, 2026
@parthrohit22

Copy link
Copy Markdown
Collaborator Author

@TFT444 @ritiksah141 statistics regenerated against the current dev tip. The branch is already level with upstream/dev (0 behind), so no rebase was needed — the numbers were simply stale.

Rather than hand-editing them again, I ran .github/scripts/update_learn_page.py, which recomputes everything from scanner/rules/ and playbooks/cli/:

Statistic Was Now
Azure security rules 126 143
Matching playbooks 126 143
CRITICAL / HIGH / MEDIUM / LOW 3 / 82 / 37 / 4 5 / 94 / 40 / 4 (sums to 143)
Largest category (100% baseline) Network 35 Network 35

The category chart rescaled and re-sorted itself — Kubernetes moved to 21 and Compute to 7, so both jumped several rows. README feature table and both Mermaid nodes updated to 143.

Worth flagging, since it is the root cause of this PR going stale twice: the script failed before it could update anything. The two README feature rows had been reworded upstream (the category list gained "Kubernetes workloads", the playbook row became "review-gated remediation script"), and the patterns pinned the entire sentence, so both matched zero times and the script exited 1 by design. That is the failure mode where a count silently goes stale while the automation looks healthy. Both patterns are now anchored on the row label and the unit that follows the number instead of the surrounding prose — losing the row itself, or the Runs N Azure security rules / (N playbooks) shape, still fails loudly. Two tests cover both directions.

Verification: the script is idempotent (second run produces no diff, so CI commits only on a real change); pytest tests/test_update_learn_page.py 4 passed; ruff check and ruff format --check clean; npm run check in website/ passes for 15 HTML pages.

On the "4 Compliance frameworks" metric — keeping it at 4 as you both agreed: CIS, NIST CSF, ISO 27001, SOC 2, with the two PQC framework files deliberately outside that narrative.

The PR description was still describing the old 96-rule docs-only change, so it has been rewritten to match what this diff actually is. Re-requesting review.

@TFT444

TFT444 commented Sep 24, 2026

Copy link
Copy Markdown
Collaborator

All four items from my Sep 4 review are addressed and the numbers look correct at 143 rules on current dev. The branch is currently conflicting against dev. Please rebase onto current dev, re-run python .github/scripts/update_learn_page.py to pick up any rules that landed since Sep 20, and push. Once that is done I will approve.

- docs/learn/index.html: kept this branch's deletion; the page now lives
  at website/src/pages/learn.astro, so dev's CRITICAL severity-box edit
  there is already covered by the Astro page.
- .github/scripts/update_learn_page.py: kept this branch's version. It
  anchors README rows on their label and unit instead of the full prose
  (which is what OWASP#350 had to patch by hand) and validates that the
  CRITICAL/HIGH/MEDIUM/LOW boxes sum to the headline.
- Regenerated statistics against current dev: 144 rules and 144
  playbooks (AZ-STOR-010 from OWASP#327), CRITICAL 5 / HIGH 95 / MEDIUM 40 /
  LOW 4, Storage 10.

Signed-off-by: parthrohit22 <parthrohit60@gmail.com>
@parthrohit22

Copy link
Copy Markdown
Collaborator Author

Merged current dev in (287e133). It's mergeable again.

npm run check passes (both CMS-disabled and CMS-enabled builds, and verification).

@TFT444 your 4 Sep request (stale numbers against the merge target) should be resolved now. Could you re-review? @ritiksah141 your approval was dismissed along the way, so re-requesting you too. One heads-up: rule counts drift every time a rule PR merges, so if something else lands first I'll just rerun the script.

The "Update Learn Page and README Stats" workflow committed regenerated
numbers and pushed them straight to dev. dev only accepts changes through
pull requests, so the push was rejected (GH006) on every one of its 27
runs since it was added, and the numbers were never actually refreshed.

- learn.astro now derives every count (rules, playbooks, severity boxes,
  category chart) from repoData at build time, the same source the rules
  page already uses. The build fails if the severity or category totals
  don't reconcile with the rule count, replacing validate_statistics().
- The script is now README-only (update_readme_stats.py) with a --check
  mode, since README.md is the one file that still states counts.
- The workflow (readme-stats.yml) is read-only: after merges touching
  rules, playbooks or README it runs --check and reports drift as a
  warning plus job summary. It never pushes, so it needs no bypass of
  the dev ruleset.
- repoData's Rule.severity type now includes CRITICAL.

Signed-off-by: parthrohit22 <parthrohit60@gmail.com>
@parthrohit22

Copy link
Copy Markdown
Collaborator Author

One more change in 6dc8726, since this PR owns the Learn page and its workflow.

Why: the post-merge "Update Learn Page and README Stats" job has failed on every run since it was added (27 so far). It commits regenerated numbers and pushes straight to dev, and dev only accepts PRs (GH006: Changes must be made through a pull request). So the numbers were never actually refreshed after merges, which is why this PR kept going stale. Giving the bot a bypass would contradict the zero-bypass rulesets in #344, so I removed the push instead.

What changed:

  • learn.astro computes every count at build time from repoData, the same source /rules/ already uses. The rendered output is identical to the committed numbers: 144 / 144, CRITICAL 5 / HIGH 95 / MEDIUM 40 / LOW 4, and the same category bars and widths. It can't drift anymore. The build fails if the severity or category totals don't match the rule count.
  • The script is now README-only, update_readme_stats.py, with a --check mode.
  • The workflow is now readme-stats.yml. It needs only contents: read, runs only when rules, playbooks or the README change, and reports stale README counts as a warning with a job summary instead of pushing.

npm run check and the full backend suite pass locally.

@Vishnu2707

Copy link
Copy Markdown
Collaborator

@TFT444 @ritiksah141 - Guys do review this PR and take necessary action, I am planning to get the things on prod asap, so we don't want anything vulnerable going through!

@ritiksah141

Copy link
Copy Markdown
Collaborator

Full review of the current head (6dc8726) is done. I checked the branch out in a clean worktree, ran the new script in --check mode, ran the new pytest suite, built the website, and verified every count against the current dev tip. All of it passes: README (144 rules / 144 playbooks) matches the tip exactly, severities reconcile (5/95/40/4 = 144), categories sum to 144, every rule has a matching playbook, and the build emits /learn/index.html with the canonical URL the verifier expects. From my side this PR is approved and mergeable as it stands.

There is one robustness bug I would still like folded into this same PR before merging. It is small, it only touches files this PR already introduces, and doing it now saves a full follow-up PR cycle (branch, CI, review, merge) later.

The bug: one INFO-severity rule breaks the entire website build

learn.astro reconciles the severity boxes against the headline rule count:

const SEVERITIES = ['CRITICAL', 'HIGH', 'MEDIUM', 'LOW'] as const;
...
if (severityTotal !== ruleCount || categoryTotal !== ruleCount) {
  throw new Error(...);
}

But INFO is a fifth canonical level in contracts/severity.v1.json, and CI's Rule & Compliance Validation explicitly accepts it (CANONICAL_SEVERITIES is built from the contract levels). So a perfectly valid INFO rule would pass scanner CI, then fail the Astro build for the whole site, not just /learn/. Reproduced locally by adding one INFO rule:

Error: Learn statistics do not reconcile with the rule total
(rules: 145, CRITICAL/HIGH/MEDIUM/LOW: 144, categories: 145)

The script this PR replaced handled INFO gracefully (it kept an INFO slot and printed an excluded-severities warning instead of failing). Today dev has zero INFO rules so CI is green, but the first INFO rule merged after this PR would break the Pages deployment and cost an urgent fix.

The fix: three small edits, all in files this PR already touches

  1. website/src/lib/repoData.ts: widen the severity union so INFO is representable (without this the filter below will not typecheck):
severity: 'CRITICAL' | 'HIGH' | 'MEDIUM' | 'LOW' | 'INFO';
  1. website/src/pages/learn.astro frontmatter: count INFO like the others. The reconcile check itself stays as-is; with INFO counted it can always be satisfied:
const SEVERITIES = ['CRITICAL', 'HIGH', 'MEDIUM', 'LOW', 'INFO'] as const;
  1. website/src/pages/learn.astro markup and style: render a fifth severity box after the LOW box:
<div class="severity-box info"><strong>{severityCounts.INFO}</strong><span>INFO</span></div>

and in the scoped style change the .severity grid from repeat(4, 1fr) to repeat(5, 1fr) plus a neutral INFO treatment consistent with the contract (#6b7280 is the contract INFO color):

.info { background: #f1f5f9; color: #334155; }

The 560px breakpoint (repeat(2, 1fr)) still wraps fine with five boxes, and an INFO box showing 0 while no INFO rules exist is fine and keeps the display honest.

Please sign the new commits (git commit -s) so DCO stays green.

Optional adjacent cleanup (pre-existing on dev, not introduced by this PR)

website/src/pages/rules.astro has no CRITICAL (or INFO) key in SEV_TEXT / SEV_DOT / SEV_LABEL, so the 5 CRITICAL rules already on dev render in the rules gallery with an empty label and color:undefined. Adding both keys (contract dot colors: CRITICAL #b91c1c, INFO #6b7280) is a few lines while you are in the same code. Fine to include here or as a small follow-up, whichever you prefer.

Validation after the change

  • cd website && npm run build && npm run verify: expect 15 pages including /learn/index.html.
  • No Python, workflow, or test changes needed; the new pytest suite and update_readme_stats.py --check are unaffected.

Everything else looks right: moving the statistics to build time is the correct design, the new readme-stats.yml is read-only and never pushes (an improvement over the deleted contents: write workflow), verify-site.mjs covers the new route, and removing docs/_redirects and docs/learn/index.html leaves no dangling references anywhere in the repo. With the INFO fix in, this is good to land.

parthrohit22 and others added 2 commits September 27, 2026 14:54
Resolve the modify/delete conflict on update-learn-page.yml by keeping
this branch's deletion. OWASP#344 changed that job to open a bot PR instead of
pushing to dev; this PR removes the need for it entirely, since the Learn
page computes its statistics at build time and readme-stats.yml only
reports README drift. docs/ci-pipeline.md now describes that flow.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JMtsuR7tvJTsoq5KueraLf
Signed-off-by: parthrohit22 <parthrohit60@gmail.com>
INFO is a canonical level in contracts/severity.v1.json and CI accepts
INFO rules, but learn.astro reconciled only CRITICAL/HIGH/MEDIUM/LOW
against the rule total, so the first INFO rule would have failed the
whole Pages build. Count INFO, render a fifth severity box (0 while no
INFO rules exist) and widen the severity grid to five columns.

The rules gallery and the homepage rules section had no CRITICAL or
INFO entries in their severity maps, so the five CRITICAL rules on dev
rendered with an empty label and an undefined colour (and as "Low" on
the homepage). Add both levels with the contract colours, a CRITICAL
filter button, and accept both in the ?severity= query parameter.

Verified: npm run check passes (15 pages); marking one rule INFO locally
builds cleanly and renders INFO 1 instead of failing reconciliation.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JMtsuR7tvJTsoq5KueraLf
Signed-off-by: parthrohit22 <parthrohit60@gmail.com>
@parthrohit22

Copy link
Copy Markdown
Collaborator Author

@ritiksah141 your INFO fix is in 382d622, along with the adjacent cleanup:

  • repoData.ts severity union includes INFO, learn.astro counts all five contract levels, the fifth box renders INFO, and .severity is repeat(5, 1fr) with the neutral .info style.
  • rules.astro has CRITICAL and INFO in SEV_TEXT / SEV_DOT / SEV_LABEL with the contract colours, a CRITICAL filter button, and accepts both in ?severity=. RulesSection.astro on the homepage had the same gap: CRITICAL rules were labelled "Low". Fixed there too.
  • Reproduced your case: with one rule locally set to SEVERITY = "INFO", the build succeeds and renders INFO 1 instead of throwing. Reverted afterwards.

Also merged current dev (b9edbd1), which is what made it mergeable again. The only conflict was update-learn-page.yml: #344 changed it to open a bot PR, and this PR deletes it. I kept the deletion, because the Learn page computes its numbers at build time and readme-stats.yml is read-only. docs/ci-pipeline.md now describes that flow instead of the STATS_BOT_TOKEN setup. Once this lands, #360 is superseded.

npm run check passes (15 pages), update_readme_stats.py --check is current at 144/144, the backend suite passes (1485 passed), and ruff is clean. Commits are signed off. The PR description is rewritten to match the diff.

@TFT444 your 4 Sep change request is still the formal blocker. The numbers now come from the build, so they can't go stale again. Could you re-review?

parthrohit22 pushed a commit to parthrohit22/openshield that referenced this pull request Sep 27, 2026
Resolve modify/delete conflict on .github/scripts/update_learn_page.py:
OWASP#362 refined the script's patterns, but this PR replaces the static Learn
page and its update script with build-time stats in website/src/pages/
learn.astro (which already renders the CRITICAL severity box), so the
deletion is kept.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MDxfYrq7uecZbnEkEesWbJ
Resolve the modify/delete conflict on .github/scripts/update_learn_page.py. OWASP#362 refined that script, but this PR replaces the static Learn page and its update script with build-time stats in website/src/pages/learn.astro, which already renders the CRITICAL severity box, so the deletion is kept.

Signed-off-by: parthrohit22 <parthrohit60@gmail.com>

@TFT444 TFT444 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All concerns from my 2026-09-04 review are addressed. The architectural fix is the right call: moving Learn page statistics to build-time derivation in repoData.ts and learn.astro eliminates the stale-stats problem structurally rather than patching it with a regeneration script. The old broken workflow (27 failed pushes to a protected branch) is gone. readme-stats.yml is read-only, correctly pinned, and surfaces README drift as a warning rather than a hard failure. Tests are solid. Approving.

@Vishnu2707 Vishnu2707 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved. LGTM!

@Vishnu2707
Vishnu2707 merged commit 399bb54 into OWASP:dev Sep 30, 2026
21 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants