diff --git a/src/main/java/dev/marcospaulo/canalhandia/Corrections.java b/src/main/java/dev/marcospaulo/canalhandia/Corrections.java
new file mode 100644
index 0000000..476291b
--- /dev/null
+++ b/src/main/java/dev/marcospaulo/canalhandia/Corrections.java
@@ -0,0 +1,89 @@
+package dev.marcospaulo.canalhandia;
+
+import org.bukkit.configuration.file.YamlConfiguration;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Set;
+
+/**
+ * Operator corrections, injected when a new question resembles one that was
+ * answered wrongly before.
+ *
+ *
This is the cheap alternative to fine-tuning: a wrong answer becomes
+ * context, so the same mistake stops recurring.
+ */
+final class Corrections {
+
+ record Entry(String question, String answer) {
+ }
+
+ private final File file;
+ private final List entries = new ArrayList<>();
+
+ Corrections(File file) {
+ this.file = file;
+ load();
+ }
+
+ void load() {
+ entries.clear();
+ if (!file.exists()) {
+ return;
+ }
+ YamlConfiguration yaml = YamlConfiguration.loadConfiguration(file);
+ for (String key : yaml.getKeys(false)) {
+ String question = yaml.getString(key + ".pergunta");
+ String answer = yaml.getString(key + ".resposta");
+ if (question != null && answer != null) {
+ entries.add(new Entry(question, answer));
+ }
+ }
+ }
+
+ void add(String question, String answer) {
+ entries.add(new Entry(question, answer));
+ YamlConfiguration yaml = new YamlConfiguration();
+ for (int i = 0; i < entries.size(); i++) {
+ yaml.set("c" + i + ".pergunta", entries.get(i).question());
+ yaml.set("c" + i + ".resposta", entries.get(i).answer());
+ }
+ try {
+ yaml.save(file);
+ } catch (Exception e) {
+ throw new IllegalStateException("não consegui gravar " + file, e);
+ }
+ }
+
+ List all() {
+ return List.copyOf(entries);
+ }
+
+ /** Corrections sharing at least one significant word with the question. */
+ static List matching(List all, String question) {
+ Set asked = significantWords(question);
+ List out = new ArrayList<>();
+ for (Entry entry : all) {
+ Set known = significantWords(entry.question());
+ known.retainAll(asked);
+ if (known.size() >= 1) {
+ out.add(entry);
+ }
+ }
+ return out;
+ }
+
+ private static Set significantWords(String text) {
+ Set words = new HashSet<>();
+ for (String word : text.toLowerCase(Locale.ROOT).split("[^\\p{L}0-9]+")) {
+ // Short words are almost all articles and prepositions in Portuguese.
+ if (word.length() > 4) {
+ words.add(word);
+ }
+ }
+ return words;
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/dev/marcospaulo/canalhandia/CorrectionsTest.java b/src/test/java/dev/marcospaulo/canalhandia/CorrectionsTest.java
new file mode 100644
index 0000000..ed80c92
--- /dev/null
+++ b/src/test/java/dev/marcospaulo/canalhandia/CorrectionsTest.java
@@ -0,0 +1,39 @@
+package dev.marcospaulo.canalhandia;
+
+import org.junit.jupiter.api.Test;
+import java.util.List;
+import static org.junit.jupiter.api.Assertions.*;
+
+class CorrectionsTest {
+
+ @Test
+ void matchesOnSharedSignificantWords() {
+ List all = List.of(
+ new Corrections.Entry("como pegar um camelo",
+ "camelos são mansos, basta pôr uma sela"));
+ assertEquals(1, Corrections.matching(all, "como eu pego camelo?").size());
+ }
+
+ @Test
+ void ignoresUnrelatedCorrections() {
+ List all = List.of(
+ new Corrections.Entry("como pegar um camelo", "…"));
+ assertTrue(Corrections.matching(all, "onde acho diamante?").isEmpty());
+ }
+
+ @Test
+ void shortWordsDoNotCreateMatches() {
+ List all = List.of(
+ new Corrections.Entry("o que e um creeper", "explode"));
+ assertTrue(Corrections.matching(all, "o que e um zumbi").isEmpty());
+ }
+
+ @Test
+ void singleSharedContentWordMatches() {
+ // "camelo" is the only word > 4 chars shared with the conjugated
+ // question; the threshold is one, not two, precisely for this case.
+ List all = List.of(
+ new Corrections.Entry("como pegar um camelo", "ponha uma sela"));
+ assertEquals(1, Corrections.matching(all, "como eu pego camelo?").size());
+ }
+}
\ No newline at end of file