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

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