Skip to content

feat: flag "date back from" as blend of "date from" and "date back to"#2976

Merged
elijah-potter merged 4 commits intomasterfrom
unknown repository
Mar 24, 2026
Merged

feat: flag "date back from" as blend of "date from" and "date back to"#2976
elijah-potter merged 4 commits intomasterfrom
unknown repository

Conversation

@ghost
Copy link
Copy Markdown

@ghost ghost commented Mar 19, 2026

Summary

Adds a many-to-many phrase set correction for "date back from", which is a nonstandard blend of two correct phrases:

  • "date from" (originate in a time period)
  • "date back to" (extend back to a time period)

Examples

Input Suggestions
"issues that date back from 4 years ago" "date from" or "date back to"
"this code dates back from 2014" "dates from" or "dates back to"

All inflections covered: date/dates/dated/dating back from.

Test plan

  • cargo test -p harper-core --lib -- phrase_set_corrections::tests::corrects_date - 2 true positives pass
  • cargo test -p harper-core --lib -- phrase_set_corrections::tests::allows_date - 1 true negative passes
  • Full test suite passes with no snapshot changes

Closes #2864

Add a many-to-many phrase set correction for "date back from" which
is a nonstandard blend of "date from" and "date back to". Suggests
both correct alternatives.

Covers all inflections: date/dates/dated/dating back from.

Closes #2864
@elijah-potter
Copy link
Copy Markdown
Collaborator

It looks like you need to run just format.

assert_suggestion_result(
"There are too many open issues that date back from 4 years ago.",
lint_group(),
"There are too many open issues that date from 4 years ago.",
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.

Have a look at assert_good_and_bad_results() - it is designed to check linters that can produce multiple suggestions (or might potentially produce bad ones) - you can include both "There are too many open issues that date from 4 years ago." and "There are too many open issues that date back to 4 years ago." - for these you would leave the bad array empty. But you'd want to use them judiciously since sometimes one seems to be much more appropriate than the other for reasons that are hard to pin down when you're a native speaker but can feel intuitively.

So yeah if both sound good to you then use assert_good_and_bad_results but if only one sounds good then just stick with assert_suggestion_result for that one.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Good call, I updated both tests to use assert_good_and_bad_suggestions() with both corrections as good suggestions. For these two sentences both "date from" and "date back to" sound equally natural to me so it made sense to verify both are offered.

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.

I see that I listed a good bunch of potential false positives in the original issue. It's probably a good idea to test against all of them unless some are too close to identical.

I also noticed you included all four verb inflections but both the original issue and your tests only cover two of them. You should hunt for real-world examples of the two other tenses to make sure they're actually real mistakes people really make, and not more likely to be false positives.

I recommend trying to do full-text searches on GitHub via its own search interface or using Google if you can. Real-word examples are a lot more informative than making up sentences.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I removed 'dated back from' and 'dating back from' since I couldn't find real-world examples of those being actual mistakes (only the present tense forms appear in the issue examples). Kept just 'date back from' and 'dates back from'.

I also tested the false positives from your issue ('the date back from a client', 'get dates back from Mongoid') and confirmed they do trigger. Unfortunately phrase_set can't distinguish noun 'date' from verb 'date' here. I documented this as a known limitation. This might need a POS-aware approach if the false positive rate is too high.

Charlie Tonneslan added 2 commits March 20, 2026 09:13
Verify both "date from" and "date back to" are offered as suggestions,
per review feedback.
- Remove 'dated back from' and 'dating back from' since no real-world
  examples were found to confirm these are actual mistakes
- Keep only 'date back from' and 'dates back from' which have clear
  real-world examples in the issue
- Document known false positives where 'date' is a noun (e.g.,
  'get the date back from a client')
Copy link
Copy Markdown
Collaborator

@elijah-potter elijah-potter left a comment

Choose a reason for hiding this comment

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

This code looks good to me! Thanks!

@elijah-potter elijah-potter added this pull request to the merge queue Mar 24, 2026
Merged via the queue into Automattic:master with commit 581c6a3 Mar 24, 2026
11 checks passed
tmeijn pushed a commit to tmeijn/dotfiles that referenced this pull request Apr 9, 2026
⚠️ **CAUTION: this is a major update, indicating a breaking change!** ⚠️

This MR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [Automattic/harper/harper-ls](https://github.com/Automattic/harper) | major | `v1.12.0` → `v2.0.0` |

MR created with the help of [el-capitano/tools/renovate-bot](https://gitlab.com/el-capitano/tools/renovate-bot).

**Proposed changes to behavior should be submitted there as MRs.**

---

### Release Notes

<details>
<summary>Automattic/harper (Automattic/harper/harper-ls)</summary>

### [`v2.0.0`](https://github.com/Automattic/harper/releases/tag/v2.0.0)

[Compare Source](Automattic/harper@v1.12.0...v2.0.0)

#### What's Changed

Hey all! We're finally releasing Harper 2.0. Why?

It isn't because we have any new groundbreaking features in this release, because we don't let major versioning stop us from pushing those out as soon as they're ready. It's because we have some breaking changes.

The biggest one only applies to you if you consume `harper.js`. From now on, instead of importing your binary from the main Harper module, you'll import it from one of four specialized modules.

Previously, you'd import the Harper WebAssembly binary with:

```javascript
import { LocalLinter, binary } from "harper.js";
```

As of Harper 2.0, you'll import it like this:

```javascript
import { LocalLinter } from "harper.js";
import { binary } from "harper.js/binary"; 
```

It's that simple! Thanks to this change, you'll find that your applications are more conducive to tree-shaking and therefore might even be a bit smaller!

In addition to that large breaking change, we also have a bunch of smaller improvements rolling out. I won't go through them one by one, but you're free to read through any of the linked pull requests below.

- refactor(core): use `Option::get_or_insert_with` by [@&#8203;86xsk](https://github.com/86xsk) in [#&#8203;2977](Automattic/harper#2977)
- test(linting): add comprehensive test cases for were/where lint rule by [@&#8203;estefafdez](https://github.com/estefafdez) in [#&#8203;2984](Automattic/harper#2984)
- feat: means a lot for→means a lot to by [@&#8203;hippietrail](https://github.com/hippietrail) in [#&#8203;2982](Automattic/harper#2982)
- feat: add subcommand to generate shell completions by [@&#8203;deckstose](https://github.com/deckstose) in [#&#8203;2978](Automattic/harper#2978)
- refactor(core): extract indefinite article logic into its own module by [@&#8203;mvanhorn](https://github.com/mvanhorn) in [#&#8203;2980](Automattic/harper#2980)
- feat(web): auto-detect dark theme from OS preference in [#&#8203;2963](Automattic/harper#2963)
- build(deps): bump tar from 0.4.44 to 0.4.45 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;2986](Automattic/harper#2986)
- feat: as evident by -> as evidenced by by [@&#8203;mvanhorn](https://github.com/mvanhorn) in [#&#8203;2985](Automattic/harper#2985)
- fix(core): `SplitWords` allowing uncommon merges by [@&#8203;elijah-potter](https://github.com/elijah-potter) in [#&#8203;2874](Automattic/harper#2874)
- feat: add lint rule for flaunt/flout mix-up in [#&#8203;2962](Automattic/harper#2962)
- test: add regression tests for need\_to\_noun false positives ([#&#8203;2320](Automattic/harper#2320)) by [@&#8203;majiayu000](https://github.com/majiayu000) in [#&#8203;3014](Automattic/harper#3014)
- fix: case-insensitive same-form check in SimplePastToPastParticiple by [@&#8203;saschabuehrle](https://github.com/saschabuehrle) in [#&#8203;3012](Automattic/harper#3012)
- build(deps): bump pulldown-cmark from 0.13.1 to 0.13.3 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;3002](Automattic/harper#3002)
- build(deps): bump tree-sitter-rust from 0.24.0 to 0.24.1 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;3003](Automattic/harper#3003)
- build(deps): bump zip from 8.1.0 to 8.3.1 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;3000](Automattic/harper#3000)
- build(deps): bump cached from 0.56.0 to 0.59.0 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;3001](Automattic/harper#3001)
- chore(harper.js): update `raw-web` example to `1.12.0` by [@&#8203;elijah-potter](https://github.com/elijah-potter) in [#&#8203;3015](Automattic/harper#3015)
- feat: "a" & "an" both OK for "URL" by [@&#8203;hippietrail](https://github.com/hippietrail) in [#&#8203;2981](Automattic/harper#2981)
- feat: except of→except for / exception of by [@&#8203;hippietrail](https://github.com/hippietrail) in [#&#8203;2997](Automattic/harper#2997)
- build(deps): bump rustls-webpki from 0.103.8 to 0.103.10 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;2991](Automattic/harper#2991)
- feat: aspire for → aspire to by [@&#8203;hippietrail](https://github.com/hippietrail) in [#&#8203;3004](Automattic/harper#3004)
- docs: added link to agent policy by [@&#8203;elijah-potter](https://github.com/elijah-potter) in [#&#8203;3016](Automattic/harper#3016)
- fix(lint-framework): reconnect popup host after DOM replacement by [@&#8203;k4sperski](https://github.com/k4sperski) in [#&#8203;2998](Automattic/harper#2998)
- fix(harper-cli): return exit code 0 when no lints are found by [@&#8203;Ryujiyasu](https://github.com/Ryujiyasu) in [#&#8203;2836](Automattic/harper#2836)
- chore: dictionary curation 2026-03-19 by [@&#8203;hippietrail](https://github.com/hippietrail) in [#&#8203;2968](Automattic/harper#2968)
- Added native Neovim LSP config to docs by [@&#8203;RobertCrummett](https://github.com/RobertCrummett) in [#&#8203;2987](Automattic/harper#2987)
- fix: don't flag "more orange than red" etc. by [@&#8203;hippietrail](https://github.com/hippietrail) in [#&#8203;2928](Automattic/harper#2928)
- perf(core): cache `WordSet` in `ModalVerb` by [@&#8203;86xsk](https://github.com/86xsk) in [#&#8203;3017](Automattic/harper#3017)
- feat: flag "use to" when "used to" is intended in [#&#8203;2975](Automattic/harper#2975)
- feat: flag nonstandard "verse" used as a verb (from "versus") in [#&#8203;2973](Automattic/harper#2973)
- feat: flag "date back from" as blend of "date from" and "date back to" in [#&#8203;2976](Automattic/harper#2976)
- feat(core): allow users to include dictionaries in Weirpacks by [@&#8203;elijah-potter](https://github.com/elijah-potter) in [#&#8203;2922](Automattic/harper#2922)
- feat: try out one's luck→try one's luck by [@&#8203;hippietrail](https://github.com/hippietrail) in [#&#8203;2916](Automattic/harper#2916)
- fix(chrome-ext): reverse the toggle button to it appears "on" by [@&#8203;elijah-potter](https://github.com/elijah-potter) in [#&#8203;3026](Automattic/harper#3026)
- chore: dictionary curation by [@&#8203;hippietrail](https://github.com/hippietrail) in [#&#8203;3023](Automattic/harper#3023)
- Improve embedded form support in iframes by [@&#8203;k4sperski](https://github.com/k4sperski) in [#&#8203;3010](Automattic/harper#3010)
- refactor: compact token/lint content & char comparison by [@&#8203;hippietrail](https://github.com/hippietrail) in [#&#8203;2957](Automattic/harper#2957)
- feat: expression to match pronoun-be, word pair or contraction by [@&#8203;hippietrail](https://github.com/hippietrail) in [#&#8203;2944](Automattic/harper#2944)
- fix(chrome-ext): persist lint rule changes from settings page by [@&#8203;queelius](https://github.com/queelius) in [#&#8203;3028](Automattic/harper#3028)
- feat: in 1 day from now→in one day/one day from now by [@&#8203;hippietrail](https://github.com/hippietrail) in [#&#8203;3049](Automattic/harper#3049)
- build(deps): bump tree-sitter-ink-lbz from 0.0.1 to 0.0.5 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;3064](Automattic/harper#3064)
- build(deps): bump ordered-float from 5.1.0 to 5.3.0 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;3063](Automattic/harper#3063)
- build(deps): bump zip from 8.3.1 to 8.4.0 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;3065](Automattic/harper#3065)
- feat: support Quarto qmd files as markdown by [@&#8203;itamarst](https://github.com/itamarst) in [#&#8203;3053](Automattic/harper#3053)
- feat: thrive off (of)→thrive on by [@&#8203;hippietrail](https://github.com/hippietrail) in [#&#8203;3055](Automattic/harper#3055)
- perf(core): optimizations in `LintGroup` by [@&#8203;86xsk](https://github.com/86xsk) in [#&#8203;3052](Automattic/harper#3052)
- feat: worth while/worth-while → worthwhile by [@&#8203;hippietrail](https://github.com/hippietrail) in [#&#8203;3056](Automattic/harper#3056)
- refactor(core)!: `Lrc<[char]>` instead of `Lrc<Vec<char>>` by [@&#8203;86xsk](https://github.com/86xsk) in [#&#8203;3060](Automattic/harper#3060)
- chore: dictionary curation by [@&#8203;hippietrail](https://github.com/hippietrail) in [#&#8203;3041](Automattic/harper#3041)
- build(deps): bump tree-sitter-rust from 0.24.1 to 0.24.2 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;3061](Automattic/harper#3061)
- fix(obsidian): OOM error by reducing WASM bundle size by [@&#8203;elijah-potter](https://github.com/elijah-potter) in [#&#8203;3050](Automattic/harper#3050)
- build(deps): bump tree-sitter-scala from 0.24.0 to 0.25.0 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;3062](Automattic/harper#3062)
- fix(lint): add 'side' to ignore list for effect/affect rule (fix issue [#&#8203;2958](Automattic/harper#2958)) by [@&#8203;estefafdez](https://github.com/estefafdez) in [#&#8203;2983](Automattic/harper#2983)
- perf(spell): skip redundant lowercase DFA search in FstDictionary by [@&#8203;k4sperski](https://github.com/k4sperski) in [#&#8203;3025](Automattic/harper#3025)
- refactor!: take argument by value instead of mut ref by [@&#8203;86xsk](https://github.com/86xsk) in [#&#8203;3051](Automattic/harper#3051)
- feat: Sneaked vs snuck by [@&#8203;hippietrail](https://github.com/hippietrail) in [#&#8203;2209](Automattic/harper#2209)
- feat: skeleton for new `ExprLinter` modules by [@&#8203;hippietrail](https://github.com/hippietrail) in [#&#8203;3024](Automattic/harper#3024)
- feat: web scrapping → web scraping by [@&#8203;hippietrail](https://github.com/hippietrail) in [#&#8203;3059](Automattic/harper#3059)
- fix: add key stroke→keystroke to key stoke→keystroke by [@&#8203;hippietrail](https://github.com/hippietrail) in [#&#8203;3067](Automattic/harper#3067)
- perf(core): avoid conversion between string and char array by [@&#8203;86xsk](https://github.com/86xsk) in [#&#8203;3074](Automattic/harper#3074)
- fix: don't flag "each of whom" by [@&#8203;hippietrail](https://github.com/hippietrail) in [#&#8203;3078](Automattic/harper#3078)
- docs(web): add link to [@&#8203;KraXen72](https://github.com/KraXen72)'s work by [@&#8203;elijah-potter](https://github.com/elijah-potter) in [#&#8203;3079](Automattic/harper#3079)
- feat: at all cost → at all costs by [@&#8203;hippietrail](https://github.com/hippietrail) in [#&#8203;3082](Automattic/harper#3082)
- fix(core): address recent false positives and negatives by [@&#8203;elijah-potter](https://github.com/elijah-potter) in [#&#8203;3090](Automattic/harper#3090)
- feat: add styling for user-defined monospace fonts by [@&#8203;stanley-910](https://github.com/stanley-910) in [#&#8203;3105](Automattic/harper#3105)
- feat: I am bias/you are prejudice→biased/prejudiced by [@&#8203;hippietrail](https://github.com/hippietrail) in [#&#8203;3058](Automattic/harper#3058)
- fix: don't flag "to" before "only" in ToTwoToo by [@&#8203;joaquinhuigomez](https://github.com/joaquinhuigomez) in [#&#8203;3093](Automattic/harper#3093)
- feat: ppl→people by [@&#8203;hippietrail](https://github.com/hippietrail) in [#&#8203;3116](Automattic/harper#3116)
- feat/obsidian web lint styling by [@&#8203;stanley-910](https://github.com/stanley-910) in [#&#8203;3104](Automattic/harper#3104)
- fix(lint-framework): preserve cursor position when dismissing suggestion popup by [@&#8203;draphy](https://github.com/draphy) in [#&#8203;3112](Automattic/harper#3112)
- build(deps): bump uuid from 1.22.0 to 1.23.0 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;3117](Automattic/harper#3117)
- fix: skip PronounVerbAgreement for hyphenated compounds by [@&#8203;mvanhorn](https://github.com/mvanhorn) in [#&#8203;3095](Automattic/harper#3095)
- fix(harper-tex): mask additional LaTeX math environments by [@&#8203;jurajkl](https://github.com/jurajkl) in [#&#8203;3103](Automattic/harper#3103)
- feat: look forward for→look forward to by [@&#8203;hippietrail](https://github.com/hippietrail) in [#&#8203;3109](Automattic/harper#3109)
- build(deps): bump tempfile from 3.20.0 to 3.27.0 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;3118](Automattic/harper#3118)
- build(deps): bump indexmap from 2.13.0 to 2.13.1 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;3121](Automattic/harper#3121)
- build(deps): bump tracing-subscriber from 0.3.22 to 0.3.23 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;3120](Automattic/harper#3120)
- build(deps): bump zip from 8.4.0 to 8.5.0 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;3119](Automattic/harper#3119)
- fix(core): exclude prepositions and conjunctions from QuiteQuiet pattern by [@&#8203;draphy](https://github.com/draphy) in [#&#8203;3127](Automattic/harper#3127)
- feat: arrive to → arrive at/in by [@&#8203;hippietrail](https://github.com/hippietrail) in [#&#8203;3125](Automattic/harper#3125)
- feat(core): create `UseEllipsisCharacter` rule by [@&#8203;elijah-potter](https://github.com/elijah-potter) in [#&#8203;3099](Automattic/harper#3099)
- Fix indentation handling in harper-tex by [@&#8203;jurajkl](https://github.com/jurajkl) in [#&#8203;3106](Automattic/harper#3106)
- feat: will ran → will run / ran by [@&#8203;hippietrail](https://github.com/hippietrail) in [#&#8203;2268](Automattic/harper#2268)
- feat: in the best of times→at the best of times by [@&#8203;hippietrail](https://github.com/hippietrail) in [#&#8203;3133](Automattic/harper#3133)
- feat: render configuration structurally by [@&#8203;elijah-potter](https://github.com/elijah-potter) in [#&#8203;3123](Automattic/harper#3123)
- fix(chrome-ext): issues with Google Docs by [@&#8203;elijah-potter](https://github.com/elijah-potter) in [#&#8203;3141](Automattic/harper#3141)

#### New Contributors

- [@&#8203;estefafdez](https://github.com/estefafdez) made their first contribution in [#&#8203;2984](Automattic/harper#2984)
- [@&#8203;deckstose](https://github.com/deckstose) made their first contribution in [#&#8203;2978](Automattic/harper#2978)
- [@&#8203;mvanhorn](https://github.com/mvanhorn) made their first contribution in [#&#8203;2980](Automattic/harper#2980)
- [@&#8203;majiayu000](https://github.com/majiayu000) made their first contribution in [#&#8203;3014](Automattic/harper#3014)
- [@&#8203;saschabuehrle](https://github.com/saschabuehrle) made their first contribution in [#&#8203;3012](Automattic/harper#3012)
- [@&#8203;k4sperski](https://github.com/k4sperski) made their first contribution in [#&#8203;2998](Automattic/harper#2998)
- [@&#8203;Ryujiyasu](https://github.com/Ryujiyasu) made their first contribution in [#&#8203;2836](Automattic/harper#2836)
- [@&#8203;RobertCrummett](https://github.com/RobertCrummett) made their first contribution in [#&#8203;2987](Automattic/harper#2987)
- [@&#8203;queelius](https://github.com/queelius) made their first contribution in [#&#8203;3028](Automattic/harper#3028)
- [@&#8203;itamarst](https://github.com/itamarst) made their first contribution in [#&#8203;3053](Automattic/harper#3053)
- [@&#8203;joaquinhuigomez](https://github.com/joaquinhuigomez) made their first contribution in [#&#8203;3093](Automattic/harper#3093)
- [@&#8203;jurajkl](https://github.com/jurajkl) made their first contribution in [#&#8203;3103](Automattic/harper#3103)

**Full Changelog**: <Automattic/harper@v1.12.0...v2.0.0>

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever MR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this MR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this MR, check this box

---

This MR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xMDkuMyIsInVwZGF0ZWRJblZlciI6IjQzLjEwOS4zIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJSZW5vdmF0ZSBCb3QiLCJhdXRvbWF0aW9uOmJvdC1hdXRob3JlZCIsImRlcGVuZGVuY3ktdHlwZTo6bWFqb3IiXX0=-->
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.

Flag "date/dates back from" used when "date from" or "date back to" is meant

2 participants