Skip to content

ci: Readability-score delta Github Action#2884

Open
mdlinville wants to merge 6 commits into
mainfrom
DOCS-2626
Open

ci: Readability-score delta Github Action#2884
mdlinville wants to merge 6 commits into
mainfrom
DOCS-2626

Conversation

@mdlinville

@mdlinville mdlinville commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Description

Posts an informational, non-blocking PR comment describing how the PR affects the readability of the English docs it changes. It reports the delta (before/after) for well-established formulas (Flesch-Kincaid grade, Flesch reading ease, Gunning fog, SMOG), word-weighted across the changed pages, plus an optional AI-agent-comprehension rating from a W&B Inference LLM judge.

Details

  • Bumps the submodule for dependency on a beta skill in https://github.com/coreweave/docs-skills/
  • Runs when a PR is opened, updated, or reopened.
  • Fork PRs have no access to repo secrets, so the first step detects a fork, posts an Actions notice, and makes the whole
    job a no-op (still reporting success). Forks are uncommon in wandb/docs and coreweave repos cannot use forks at all.
  • The submodule will depend on the DOCENGINE_TOKEN already in wandb/docs for cross-org authentication.
  • The AI agent comprehension judge calls W&B Inference with the WANDB_DOCS_INFERENCE_API_KEY secret (a W&B API key whose entity has Inference credits), passed to the scorer as WANDB_API_KEY. When that secret is absent, the deterministic textstat delta still runs.

Fixes DOCS-2626

Testing

mdlinville and others added 3 commits June 1, 2026 13:11
Depends on a skill in coreweave/docs-skills#42

Adding a submodule reference is a followup action after that
PR merges, some time before merging this into wandb/docs

The submodule will depend on the DOCENGINE_TOKEN already
in wandb/docs for cross-org authentication.
Points the .claude submodule at coreweave/docs-skills main (11d7344),
which lands the readability delta analyzer and AI comprehension scorer
(#42) that the readability-delta CI check imports from .claude/scripts/.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@mdlinville mdlinville requested a review from a team as a code owner July 9, 2026 20:06
@mdlinville mdlinville requested a review from Copilot July 9, 2026 20:06
@w-b-hivemind

w-b-hivemind Bot commented Jul 9, 2026

Copy link
Copy Markdown

HiveMind Sessions

1 session · 8m · $2.23

Session Agent Duration Tokens Cost Lines
Update Documentation Ci Submodule Path
07dfa6e8-3c0a-4e7d-aa2b-5d656efe54ab
claude 8m 41.4K $2.23 +0 -0
Total 8m 41.4K $2.23 +0 -0

View all sessions in HiveMind →

Run claude --resume 07dfa6e8-3c0a-4e7d-aa2b-5d656efe54ab to pickup where you left off.

@socket-security

socket-security Bot commented Jul 9, 2026

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addedpypi/​openai@​2.45.090100100100100
Addedpypi/​weave@​0.53.194100100100100
Addedpypi/​textstat@​0.7.13100100100100100

View full report

@socket-security

socket-security Bot commented Jul 9, 2026

Copy link
Copy Markdown

Warning

Review the following alerts detected in dependencies.

According to your organization's Security Policy, it is recommended to resolve "Warn" alerts. Learn more about Socket for GitHub.

Action Severity Alert  (click "▶" to expand/collapse)
Warn High
License policy violation: pypi pyphen

Location: Package overview

From: ?pypi/textstat@0.7.13pypi/pyphen@0.17.2

ℹ Read more on: This package | This alert | What is a license policy violation?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Find a package that does not violate your license policy or adjust your policy to allow this package's license.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore pypi/pyphen@0.17.2. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn High
License policy violation: pypi pyphen

Location: Package overview

From: ?pypi/textstat@0.7.13pypi/pyphen@0.17.2

ℹ Read more on: This package | This alert | What is a license policy violation?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Find a package that does not violate your license policy or adjust your policy to allow this package's license.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore pypi/pyphen@0.17.2. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn High
License policy violation: pypi setuptools

Location: Package overview

From: ?pypi/textstat@0.7.13pypi/setuptools@83.0.0

ℹ Read more on: This package | This alert | What is a license policy violation?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Find a package that does not violate your license policy or adjust your policy to allow this package's license.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore pypi/setuptools@83.0.0. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn High
License policy violation: pypi setuptools

Location: Package overview

From: ?pypi/textstat@0.7.13pypi/setuptools@83.0.0

ℹ Read more on: This package | This alert | What is a license policy violation?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Find a package that does not violate your license policy or adjust your policy to allow this package's license.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore pypi/setuptools@83.0.0. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

View full report

@mintlify

mintlify Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
wandb 🟢 Ready View Preview Jul 9, 2026, 8:13 PM

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds a new CI workflow that computes and posts an informational readability delta (word-weighted across changed English .mdx files) as an upserted PR comment, backed by a Python reporting script and unit tests. It optionally includes an AI-agent-comprehension judge via W&B Inference when the relevant secret is present.

Changes:

  • Introduces scripts/readability/pr_report.py to diff base/head, score changed pages via the docs-skills submodule analyzer, aggregate results, and build Markdown.
  • Adds a new workflow .github/workflows/readability-delta.yml to run on PRs touching .mdx and post/upsert a single PR comment.
  • Adds supporting docs, requirements, and pytest coverage for parsing/aggregation/Markdown generation.

Reviewed changes

Copilot reviewed 8 out of 9 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
scripts/readability/pr_report.py Implements the diff → score → aggregate → Markdown report pipeline, plus optional LLM judge integration.
scripts/readability/README.md Documents the readability-delta check, dependencies, behavior, and local run instructions.
scripts/readability/requirements.txt Declares Python dependencies for deterministic scoring and optional judge.
scripts/readability/tests/test_pr_report.py Unit tests for parsing changed files, aggregation, and Markdown formatting; includes an optional integration test.
scripts/readability/tests/conftest.py Registers the integration pytest marker to avoid unknown-mark warnings.
scripts/readability/tests/__init__.py Marks the tests directory as a package for test discovery/import behavior.
.github/workflows/readability-delta.yml New workflow to run the script, write a fallback notice on failure, and upsert a single PR comment.
.github/workflows/README.md Adds a section describing the new readability-delta workflow and its configuration/auth.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread scripts/readability/pr_report.py Outdated
Comment on lines +140 to +147
status = parts[0]
# Renames/copies: use the new path (last field).
path = parts[-1]
if not path.endswith(".mdx"):
continue
if path.startswith(_LOCALE_PREFIXES):
continue
entries.append({"status": status[0], "path": path})

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good catch — fixed in 9c13165. parse_changed_files now keeps old_path for rename/copy rows (old_path = parts[1]), so scoring can read the base version from the old path.

Comment on lines +174 to +181
path = entry["path"]
status = entry["status"]

if status == "D":
return {"path": path, "status": "deleted"}

before_text = "" if status == "A" else git_show(f"{base}:{path}", repo_root)
after_text = git_show(f"{head}:{path}", repo_root)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in 9c13165. score_entry now reads the before-text from old_path, and the result row carries old_path so the comprehension-judge loop does the same. A renamed + edited page now scores as a real delta instead of being reported as new.

# Rename rows have three tab fields: status, old path, new path.
name_status = "R096\tmodels/old.mdx\tmodels/renamed.mdx"
entries = pr_report.parse_changed_files(name_status)
assert entries == [{"status": "R", "path": "models/renamed.mdx"}]

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Updated in 9c13165 — the rename test now asserts old_path is retained. I also added test_score_entry_rename_reads_base_from_old_path (mocks git_show) so a regression that reads base from the new path fails the suite.

Comment thread .github/workflows/readability-delta.yml Outdated
Comment thread .github/workflows/readability-delta.yml Outdated
Comment thread .github/workflows/readability-delta.yml Outdated
Comment on lines +82 to +85
- name: Check out docs-skills submodule
if: steps.fork.outputs.is_fork != 'true'
env:
DOCENGINE_TOKEN: ${{ secrets.DOCENGINE_TOKEN }}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in 9c13165 — added continue-on-error: true. If the submodule fetch fails, the report step detects the missing analyzer and posts the informational fallback comment, so the check stays green and never blocks the PR.

Comment on lines +106 to +108
- name: Install dependencies
if: steps.fork.outputs.is_fork != 'true'
run: pip install -r scripts/readability/requirements.txt

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in 9c13165 — added continue-on-error: true. If dependency install fails, the report step's try/fallback writes the informational notice instead of failing the job.

Comment thread scripts/readability/requirements.txt Outdated
Comment on lines +5 to +9
textstat
# AI agent comprehension judge (optional; only when WANDB_API_KEY is set).
# Imported lazily from the submodule's _docs_eval_lib.py:
openai
weave

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in 9c13165 — pinned textstat==0.7.13, openai==2.45.0, weave==0.53.1 (the versions verified working in CI and locally), matching the repo's == pinning convention.

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

📚 Mintlify Preview Links

🔗 View Full Preview

✨ Added (1 total)

⚙️ Other (1)
File
scripts/readability/README.md

📝 Changed (2 total)

📄 Pages (1)

File Preview
models/artifacts/data-privacy-and-compliance.mdx Data Privacy And Compliance
⚙️ Other (1)
File
.github/workflows/README.md

🤖 Generated automatically when Mintlify deployment succeeds
📍 Deployment: 35bea82 at 2026-07-09 20:38:56 UTC

…degradation

- Preserve the old path for renamed/copied .mdx so the base version is read
  from the old path; a renamed+edited page is now scored as a delta instead
  of being misreported as brand-new. Covers both the deterministic scorer and
  the comprehension judge. Adds parse + score_entry unit tests.
- Pin actions/checkout, actions/setup-python, actions/cache to the commit
  SHAs already used across this repo's workflows (supply-chain hardening).
- Mark the submodule-fetch and dependency-install steps continue-on-error so a
  transient failure degrades to the informational fallback comment instead of
  failing the check, matching the workflow's "never blocks a PR" contract.
- Pin textstat/openai/weave to the verified-working versions, matching the
  repo's requirements-pinning convention.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@mdlinville

Copy link
Copy Markdown
Contributor Author

Warning

Review the following alerts detected in dependencies.

According to your organization's Security Policy, it is recommended to resolve "Warn" alerts. Learn more about Socket for GitHub.

Action Severity Alert  (click "▶" to expand/collapse)
Warn High
License policy violation: pypi pyphen
Location: Package overview

From: ?pypi/textstat@0.7.13pypi/pyphen@0.17.2

ℹ Read more on: This package | This alert | What is a license policy violation?

Next steps: Take a moment to review the security alert above. Review
the linked package source code to understand the potential risk. Ensure the
package is not malicious before proceeding. If you're unsure how to proceed,
reach out to your security team or ask the Socket team for help at
support@socket.dev.

Suggestion: Find a package that does not violate your license policy or adjust your policy to allow this package's license.

_Mark the package as acceptable risk_. To ignore this alert only
in this pull request, reply with the comment
`@SocketSecurity ignore pypi/pyphen@0.17.2`. You can
also ignore all packages with `@SocketSecurity ignore-all`.
To ignore an alert for all future pull requests, use Socket's Dashboard to
change the [triage state of this alert](https://socket.dev/dashboard/org/wandb/diff-scan/4c859df7-c56d-4b2a-99d5-2ae502e10b84/alert/Q6bjQxgIYySKBM7ScspgLycCHAbnYgYhHVRZ-2F2E_UE).

Warn High
License policy violation: pypi pyphen
Location: Package overview

From: ?pypi/textstat@0.7.13pypi/pyphen@0.17.2

ℹ Read more on: This package | This alert | What is a license policy violation?

Next steps: Take a moment to review the security alert above. Review
the linked package source code to understand the potential risk. Ensure the
package is not malicious before proceeding. If you're unsure how to proceed,
reach out to your security team or ask the Socket team for help at
support@socket.dev.

Suggestion: Find a package that does not violate your license policy or adjust your policy to allow this package's license.

_Mark the package as acceptable risk_. To ignore this alert only
in this pull request, reply with the comment
`@SocketSecurity ignore pypi/pyphen@0.17.2`. You can
also ignore all packages with `@SocketSecurity ignore-all`.
To ignore an alert for all future pull requests, use Socket's Dashboard to
change the [triage state of this alert](https://socket.dev/dashboard/org/wandb/diff-scan/4c859df7-c56d-4b2a-99d5-2ae502e10b84/alert/QXBO5h2PeuSAvOrzccErXrKLgn2o9YPQM0ZVvA3c9j4Q).

Warn High
License policy violation: pypi setuptools
Location: Package overview

From: ?pypi/textstat@0.7.13pypi/setuptools@83.0.0

ℹ Read more on: This package | This alert | What is a license policy violation?

Next steps: Take a moment to review the security alert above. Review
the linked package source code to understand the potential risk. Ensure the
package is not malicious before proceeding. If you're unsure how to proceed,
reach out to your security team or ask the Socket team for help at
support@socket.dev.

Suggestion: Find a package that does not violate your license policy or adjust your policy to allow this package's license.

_Mark the package as acceptable risk_. To ignore this alert only
in this pull request, reply with the comment
`@SocketSecurity ignore pypi/setuptools@83.0.0`. You can
also ignore all packages with `@SocketSecurity ignore-all`.
To ignore an alert for all future pull requests, use Socket's Dashboard to
change the [triage state of this alert](https://socket.dev/dashboard/org/wandb/diff-scan/4c859df7-c56d-4b2a-99d5-2ae502e10b84/alert/QhPDKYzPKjgIJtGAJPhxIu2Q6u7HWARu_J_Kx0Ys67dI).

Warn High
License policy violation: pypi setuptools
Location: Package overview

From: ?pypi/textstat@0.7.13pypi/setuptools@83.0.0

ℹ Read more on: This package | This alert | What is a license policy violation?

Next steps: Take a moment to review the security alert above. Review
the linked package source code to understand the potential risk. Ensure the
package is not malicious before proceeding. If you're unsure how to proceed,
reach out to your security team or ask the Socket team for help at
support@socket.dev.

Suggestion: Find a package that does not violate your license policy or adjust your policy to allow this package's license.

_Mark the package as acceptable risk_. To ignore this alert only
in this pull request, reply with the comment
`@SocketSecurity ignore pypi/setuptools@83.0.0`. You can
also ignore all packages with `@SocketSecurity ignore-all`.
To ignore an alert for all future pull requests, use Socket's Dashboard to
change the [triage state of this alert](https://socket.dev/dashboard/org/wandb/diff-scan/4c859df7-c56d-4b2a-99d5-2ae502e10b84/alert/QagscmSIaet4RDOP11Jcicryy2k6ncICw4OJif9jKVFA).

View full report

These are noise: We are using these tools to evaluate readability but we are not shipping these packages anywhere.

@mdlinville

Copy link
Copy Markdown
Contributor Author

Thanks for the review, @copilot — all nine comments had merit and are addressed in 9c13165:

Rename scoring (correctness)git diff --name-status emits R###/C### rows as status\told\tnew, and the parser kept only the new path, so a renamed page's base version was looked up at the new path (empty) and it was misreported as brand-new. parse_changed_files now retains old_path; both the deterministic scorer and the comprehension judge read the base from old_path. Added a parser test and a score_entry test (mocking git_show) that fails if the base is ever read from the new path again.

Action SHA pinningactions/checkout, actions/setup-python, and actions/cache are now pinned to the exact SHAs used elsewhere in this repo (checkout v6→v7, cache v5→v6 to match).

"Never blocks a PR" contract — the submodule-fetch and dependency-install steps are now continue-on-error: true; on failure the report step falls back to the informational notice and the check stays green.

Dependency pinningtextstat==0.7.13, openai==2.45.0, weave==0.53.1, matching the repo's == convention (versions verified working in CI and locally).

All 14 unit tests pass and the workflow YAML validates. Ready for another look.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 8 out of 9 changed files in this pull request and generated 1 comment.

Comment thread scripts/readability/pr_report.py Outdated
f"**{summary['weighted_fk_delta']:+.1f} ({summary['direction']})**."
)
else:
lines.append("No pages had enough prose to score a readability delta.")

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Agreed — fixed in dffc509. aggregate() returns None for any PR with no scorable before-and-after page (add-only, delete-only, or insufficient prose), so the message now reads "No changed page had a scorable before-and-after version, so there is no readability delta to report. See the per-page details below." and defers specifics to the per-page table.

mdlinville and others added 2 commits July 9, 2026 13:36
aggregate() returns None whenever no page has a scorable before-and-after
version — which includes PRs that only add new pages or only delete pages,
not just insufficient prose. Generalize the message and point at the
per-page table for specifics. Addresses Copilot review follow-up.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Temporary prose simplification (FK 10.0 -> 9.5, "easier") to trigger and
demonstrate the readability-delta workflow on this PR. REVERT before merge.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

🔗 Link Checker Results

All links are valid!

No broken links were detected.

Checked against: https://wb-21fd5541-docs-2626.mintlify.app

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Readability impact

Word-weighted Flesch-Kincaid grade change across 1 changed page: -0.5 (easier).

Lower Flesch-Kincaid grade and higher reading ease both mean easier to read. This check is informational and never blocks a PR.

Human readability

Page FK grade before FK grade after FK Δ Reading ease Δ Direction
models/artifacts/data-privacy-and-compliance.mdx 10.0 9.5 -0.5 +2.7 easier

AI agent comprehension

Rated 0-3 (higher is easier for an agent to parse and act on).

Page Before After Δ
models/artifacts/data-privacy-and-compliance.mdx 2 2 +0

Curated-docs baseline median FK grade by type: conceptual 10.5, procedural 8.8, reference 9.4.

From workflow run 29048591939

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 9 out of 10 changed files in this pull request and generated 4 comments.

Comment on lines +290 to +296
weighted_delta = round(weighted_sum / weight_total, 1)
if weighted_delta < 0:
direction = "easier"
elif weighted_delta > 0:
direction = "harder"
else:
direction = "unchanged"
Comment on lines +110 to +115
- name: Install dependencies
# Non-fatal: if deps fail to install, the report step still runs and
# falls back to the informational notice rather than failing the PR.
continue-on-error: true
if: steps.fork.outputs.is_fork != 'true'
run: pip install -r scripts/readability/requirements.txt
---

Files are uploaded to a Google Cloud bucket managed by W&B when you log artifacts. The contents of the bucket are encrypted both at rest and in transit. Artifact files are only visible to users who have access to the corresponding project.
When you log artifacts, W&B uploads the files to a Google Cloud bucket. W&B encrypts the bucket at rest and in transit. Only users with access to the project can see the files.
Comment on lines +90 to +92
run: |
git config --global url."https://x-access-token:${DOCENGINE_TOKEN}@github.com/".insteadOf "https://github.com/"
git submodule update --init --recursive .claude
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.

2 participants