Module: OKF::Pro::Reconcile
- Defined in:
- lib/okf/pro/reconcile.rb
Overview
Rule 1 — writing is reconciliation.
Fires on Write, not Edit: a new concept is the moment a claim enters the corpus, and the moment both it and whatever it collides with are cheapest to hold in one head. Its reach is bounded by the filename's vocabulary, which is exactly the limit the rule states about itself — it catches collisions as well as your search words do, and no better.
Class Method Summary collapse
- .block_for(target, term) ⇒ Object
-
.matches(target, term) ⇒ Object
The concept being written is excluded (it is not its own collision), and so are the structural files: a hit in README or board.md means they quote a concept, not that they assert against one.
- .search(target, event) ⇒ Object
-
.settled(status) ⇒ Object
§5.4's
status, made operative. - .status_index(bundle) ⇒ Object
- .terms(target) ⇒ Object
Class Method Details
.block_for(target, term) ⇒ Object
35 36 37 38 39 40 41 42 43 44 |
# File 'lib/okf/pro/reconcile.rb', line 35 def block_for(target, term) rows = matches(target, term) return nil if rows.empty? statuses = status_index(target.bundle) body = rows.map do |r| " #{r[:id]}#{settled(statuses[r[:id]])} · #{r[:type]} · #{r[:title]}\n #{r[:snippet]}" end "— '#{term}':\n#{body.join("\n")}" end |
.matches(target, term) ⇒ Object
The concept being written is excluded (it is not its own collision), and so are the structural files: a hit in README or board.md means they quote a concept, not that they assert against one.
68 69 70 71 72 73 |
# File 'lib/okf/pro/reconcile.rb', line 68 def matches(target, term) ::OKF::Bundle::Search.call(target.bundle, term) .reject { |r| r[:id] == target.id } .reject { |r| NO_RECONCILE.include?("#{File.basename(r[:id])}.md") } .first(5) end |
.search(target, event) ⇒ Object
15 16 17 18 19 20 21 22 23 24 25 26 27 |
# File 'lib/okf/pro/reconcile.rb', line 15 def search(target, event) return [] if target.nil? return [] unless event.tool_name == "Write" return [] if target.rel.start_with?("journal/") return [] if NO_RECONCILE.include?(target.basename) hits = terms(target).map { |term| block_for(target, term) }.compact return [] if hits.empty? [ "RULE 1 — reconciliation. Existing concepts share this new concept's vocabulary. " \ "Read them now: contradiction, supersession, or duplicate? Deprecate the loser at this " \ "moment, or file a conflict line on board.md. Do not simply continue.\n#{hits.join("\n")}" ] end |
.settled(status) ⇒ Object
§5.4's status, made operative. The skill teaches status: deprecated
as the machine-readable half of Rule 1's supersession move — correct the
loser NOW, and mark it — and this is what makes that teaching worth
anything: a collision with a concept that has already been deprecated is
a collision somebody already settled, and re-litigating it is the cost
the marking exists to avoid.
It annotates rather than filters. A deprecated concept is "kept for links and history, no longer current" (§5.4), so it is still a real hit and still worth reading — what changes is what the reader does about it. Filtering it out would hide the evidence that the question was answered.
57 58 59 |
# File 'lib/okf/pro/reconcile.rb', line 57 def settled(status) status == "deprecated" ? " [deprecated — this collision was already settled]" : "" end |
.status_index(bundle) ⇒ Object
61 62 63 |
# File 'lib/okf/pro/reconcile.rb', line 61 def status_index(bundle) bundle.concepts.each_with_object({}) { |concept, index| index[concept.id] = concept.status } end |
.terms(target) ⇒ Object
29 30 31 32 33 |
# File 'lib/okf/pro/reconcile.rb', line 29 def terms(target) File.basename(target.rel, ".md").split("-") .reject { |t| t.empty? || STOP_WORDS.include?(t.downcase) } .first(4) end |