Skip to content

Harden shared spelling rollout - #49

Merged
leynos merged 4 commits into
mainfrom
typos-roll-out-hardening
Jul 13, 2026
Merged

Harden shared spelling rollout#49
leynos merged 4 commits into
mainfrom
typos-roll-out-hardening

Conversation

@leynos

@leynos leynos commented Jul 13, 2026

Copy link
Copy Markdown
Owner

Summary

This branch hardens the shared en-GB-oxendict rollout after downstream review found that HTTP freshness validators could cross source boundaries and that consumer spelling gates did not reject stale generated configuration. It also adds the generic Oxford italicize family harvested from mxd.

No matching roadmap task, implementation ExecPlan in this repository, or open issue was found for this follow-up.

Review walkthrough

Validation

  • Focused Red stage: three expected assertion failures.
  • Focused Green stage: 3 tests passed.
  • make ci: 129 tests passed, including 3 snapshots; syntax, shell syntax, home-phase boundary, type checking, generated-config drift and pinned spelling all passed.
  • mbake validate Makefile: passed.
  • git diff --check: passed.

Notes

A standalone whole-repository ShellCheck still reports findings in unchanged legacy scripts notdeadyet and python-setup; ShellCheck is not part of this repository's make ci gate and this branch does not modify those files.

Summary by Sourcery

Harden shared spelling rollout by scoping HTTP cache metadata to each source, enforcing freshness of generated spelling configuration, and extending the shared dictionary with Oxford italicize mappings.

Bug Fixes:

  • Ensure HTTP conditional request validators are discarded when the base dictionary source URL changes, preventing cross-source cache metadata reuse.

Enhancements:

  • Add a Makefile spelling gate check that fails when the generated typos configuration drifts from the committed typos.toml.
  • Extend the shared Oxford dictionary base and generated typos configuration with the italicize/italicise spelling family to support Oxford-preferred forms.

Tests:

  • Add regression tests covering cross-source HTTP metadata isolation, acceptance of Oxford italicized spellings, and Makefile enforcement of up-to-date generated configuration.

Scope conditional HTTP validators to the source that supplied them so a
changed authority cannot reuse stale freshness metadata. Reject generated
`typos.toml` drift in the spelling gate and add the generic Oxford
`italicize` family harvested from the estate.
@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Update Oxford spelling mappings, enforce generated configuration freshness, and prevent HTTP validators from being reused after a source URL changes.

Changes

Spelling and refresh safeguards

Layer / File(s) Summary
Synchronise spelling configuration
data/typos-oxendict-base.toml, typos.toml, Makefile, tests/test_typos_rollout.py
Add italic spelling mappings, include the Oxford stem, and make the spelling target fail when generated configuration is stale or untracked.
Scope refresh validators
scripts/typos_rollout.py, tests/test_typos_rollout.py
Discard saved ETag and modification-time validators for a different source, and verify that the replacement source refreshes without those headers.

Possibly related PRs

Poem

Oxford stems bloom,
Italic words find their form,
Stale guards drift away,
Fresh sources cross the wire,
Typos stand in tidy rows.

🚥 Pre-merge checks | ✅ 18 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
User-Facing Documentation ⚠️ Warning The users’ guide covers spelling tooling, but it never documents the new make spelling drift failure or source-scoped cache invalidation. Update docs/users-guide.md to state that make spelling fails on generated typos.toml drift and that generate --source scopes HTTP cache validators to the chosen source.
Performance And Resource Use ⚠️ Warning Fail: the new spelling-gate tests call make spelling and git via subprocess.run without timeouts, so a stalled uv run can block CI indefinitely. Add bounded timeouts to run_spelling_gate and the new git subprocess calls, or move the slow spelling check behind a cancellable, time-bounded fixture.
✅ Passed checks (18 passed)
Check name Status Explanation
Title check ✅ Passed Match the PR’s main theme: hardening the shared spelling rollout.
Description check ✅ Passed Describe the rollout hardening, validator scoping, spelling gate drift checks, and Oxford italic mappings.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Testing (Overall) ✅ Passed New tests exercise the source-scoped HTTP headers and the Makefile spelling gate end to end, and they fail for the plausible regressions introduced here.
Developer Documentation ✅ Passed Keep this green: docs already cover source-scoped validators and the spelling gate, and no roadmap or execplan item applies here.
Module-Level Documentation ✅ Passed All Python modules have module docstrings, and the changed script and test module clearly describe their roles and relation to the rollout helper.
Testing (Unit And Behavioural) ✅ Passed Accept it: the new tests hit public refresh_base, actual make spelling, and pinned typos output, so they exercise the real workflow boundary and persistence.
Testing (Property / Proof) ✅ Passed PASS: the invariant-bearing Oxford mapping is already covered by Hypothesis (@given over arbitrary stems), and the HTTP source-scope change is a specific regression, not a broad search space.
Testing (Compile-Time / Ui) ✅ Passed No Rust/TypeScript compile-time path changed; the added Makefile and HTTP regressions are focused behavioural tests, and snapshot tests are not required here.
Unit Architecture ✅ Passed PASS: _refresh_http scopes cached validators to the requested source, and the Makefile spelling gate keeps generation, drift checking, and scanning as explicit command steps; tests exercise these...
Domain Architecture ✅ Passed Changes stay in Makefile, config, rollout helper, and tests; they cover infrastructure boundaries only and do not leak HTTP, filesystem, or CLI concerns into domain logic.
Observability ✅ Passed The patch only changes the Makefile and tests; it adds no production telemetry path, and failures remain observable via exit codes/stdout.
Security And Privacy ✅ Passed No secrets, credentials, privilege changes, or unsafe sinks were introduced; the diff only adds a Makefile guard and test fixtures with fake data.
Concurrency And State ✅ Passed State stays file-scoped and atomically replaced; _refresh_http clears mismatched validators, and no shared mutable globals or async tasks were introduced.
Architectural Complexity And Maintainability ✅ Passed Keep the change local: it adds one Makefile guard and small one-off test helpers, with no new layers, registries, cycles, or dependencies.
Rust Compiler Lint Integrity ✅ Passed PR changes only Makefile and Python tests; repo scan found no Rust sources or lint suppressions, so the Rust lint integrity check is not applicable.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch typos-roll-out-hardening

Comment @coderabbitai help to get the list of available commands.

@sourcery-ai

sourcery-ai Bot commented Jul 13, 2026

Copy link
Copy Markdown

Reviewer's Guide

Hardens the shared en-GB Oxford dictionary rollout by scoping HTTP freshness metadata per source, enforcing that the Makefile spelling gate fails on stale generated configuration, and expanding the Oxford-based dictionary with a new italicization spelling family plus corresponding regression tests.

Sequence diagram for source-scoped HTTP metadata in _refresh_http

sequenceDiagram
    participant Caller
    participant typos_rollout as typos_rollout
    participant RemoteSource

    Caller->>typos_rollout: _refresh_http(source, metadata, opener)
    typos_rollout->>typos_rollout: _read_metadata(metadata)
    typos_rollout->>typos_rollout: [saved.source != source]
    alt source_mismatch
        typos_rollout->>typos_rollout: saved = {}
    else source_match
        typos_rollout->>typos_rollout: saved unchanged
    end
    typos_rollout->>typos_rollout: _conditional_headers(saved)
    typos_rollout->>RemoteSource: Request(source, headers)
    RemoteSource-->>typos_rollout: HTTP response
    typos_rollout-->>Caller: RefreshResult
Loading

Flow diagram for strengthened Makefile spelling gate

flowchart LR
    A[spelling target] --> B[generate typos config via typos_rollout_cli.py]
    B --> C[git diff --exit-code -- typos.toml]
    C -->|no drift| D[run typos with typos.toml]
    C -->|drift detected| E[spelling target fails]
Loading

File-Level Changes

Change Details Files
Scope HTTP conditional metadata (ETag/Last-Modified) to the specific dictionary source when refreshing the base cache.
  • Read previously saved HTTP metadata before refresh and discard it entirely when the saved source URL does not match the current source parameter.
  • Construct HTTP requests for refresh using conditional headers only when the metadata belongs to the same source, preventing validators from leaking across sources.
scripts/typos_rollout.py
Enforce that the spelling gate uses up-to-date generated configuration and pinned typos version in CI.
  • Update the spelling Makefile target to run the generator script for typos configuration before invoking typos.
  • Add a git diff --exit-code -- typos.toml check so the spelling target fails if typos.toml is stale relative to the generated configuration.
  • Retain use of the pinned typos@$(TYPOS_VERSION) binary and the --config typos.toml --force-exclude . flags to ensure CI uses the generated config.
Makefile
Expand the shared Oxford-based spelling configuration with an italicization family and its base stem.
  • Add italic to the Oxford stems list so its word family can be generated and shared.
  • Extend the typos configuration with mappings that normalize British and Oxford variants of italicization-related words to the canonical Oxford spelling (e.g., italiciseitalicize, italiciseditalicized).
data/typos-oxendict-base.toml
typos.toml
Add regression tests covering HTTP metadata scoping, Oxford italicization mappings, and the strengthened spelling Makefile gate.
  • Add a test ensuring that when the base dictionary source URL changes, no If-None-Match or If-Modified-Since headers are sent using metadata from the previous source.
  • Extend the shared dictionary tests to assert that both British and Oxford italicization spellings are handled as expected by the mappings.
  • Extend the Makefile spelling gate test to assert that it runs the generator, enforces a clean git diff on typos.toml, uses the pinned typos version, and applies the generated config and exclusions.
tests/test_typos_rollout.py

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@leynos
leynos marked this pull request as ready for review July 13, 2026 19:11
@leynos

leynos commented Jul 13, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hey - I've reviewed your changes and they look great!


Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f197327927

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread Makefile

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/test_typos_rollout.py`:
- Around line 282-288: In the test setup, annotate the captured requests
variable as list[object], and update the Response class to initialize headers in
an __init__ method instead of defining a mutable class-level dictionary.
Preserve the existing status attribute and response behavior.
- Around line 326-332: Extend the refresh assertions in the relevant test to
verify that the persisted cached dictionary contains the replacement content and
that its metadata references the replacement source. Keep the existing
request-header and result.status assertions, and use the test’s established
cache-reading or metadata symbols to validate the stored state after refresh.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 8bbec71e-3338-4279-896e-5493c9aa4252

📥 Commits

Reviewing files that changed from the base of the PR and between 8cd59d2 and f197327.

📒 Files selected for processing (5)
  • Makefile
  • data/typos-oxendict-base.toml
  • scripts/typos_rollout.py
  • tests/test_typos_rollout.py
  • typos.toml

Comment thread tests/test_typos_rollout.py Outdated
Comment thread tests/test_typos_rollout.py Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/test_typos_rollout.py`:
- Around line 506-508: Replace the textual assertion in the relevant test with a
behavioral test that creates or uses stale generated configuration, runs the
spelling target, and asserts a non-zero exit status. Reuse the existing test
helpers and spelling-target invocation patterns in tests/test_typos_rollout.py
rather than checking Makefile contents directly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 570c6adf-4a06-40f8-8b40-8913a4020c8f

📥 Commits

Reviewing files that changed from the base of the PR and between 8cd59d2 and f197327.

📒 Files selected for processing (5)
  • Makefile
  • data/typos-oxendict-base.toml
  • scripts/typos_rollout.py
  • tests/test_typos_rollout.py
  • typos.toml

Comment thread tests/test_typos_rollout.py Outdated
Require `typos.toml` to be indexed before checking generated drift, and
exercise both stale and untracked configurations through the real Makefile
target. Strengthen the source-switch regression to verify persisted state.
@leynos

leynos commented Jul 13, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@leynos

leynos commented Jul 13, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 🎉

Reviewed commit: 92ab655163

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Harvest the generic `underutilize` Oxford family from `rstest-bdd` so
consumers preserve the correct form without repository-local exceptions.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/test_typos_rollout.py`:
- Around line 520-578: Split tests/test_typos_rollout.py into domain-focused
test modules, placing the HTTP-refresh tests and Makefile spelling-gate tests in
separate modules and moving shared setup into conftest.py fixtures. Preserve
existing test behavior and ensure each resulting module stays under the
400-logical-line limit.
- Around line 544-554: Update test_spelling_gate_rejects_stale_generated_config
so it verifies the expected 'mold' entry was present and replaced before writing
the mutated policy. Assert that the replacement changed the file content, then
proceed with the existing fixture setup and assertions.
- Around line 533-541: Add timeouts to the subprocess calls in run_spelling_gate
and the nearby git invocations, using a suitable test-level duration so stalled
dependency resolution or repository commands fail promptly while preserving
existing command behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 05885ffe-ef61-413e-9320-7ef6358fb48e

📥 Commits

Reviewing files that changed from the base of the PR and between f197327 and 92ab655.

📒 Files selected for processing (2)
  • Makefile
  • tests/test_typos_rollout.py

Comment thread tests/test_typos_rollout.py Outdated
Comment thread tests/test_typos_rollout.py Outdated
Comment thread tests/test_typos_rollout.py Outdated
Keep refresh, rendering, and spelling-gate behaviour in focused test modules
below the repository's line limit. Bound subprocess fixtures, verify stale
policy mutation, and retain deliberate spelling samples outside enforcement.
@leynos
leynos merged commit 662d060 into main Jul 13, 2026
5 checks passed
@leynos
leynos deleted the typos-roll-out-hardening branch July 13, 2026 19:58
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.

1 participant