Module: OKF::Pro::Conserve
- Defined in:
- lib/okf/pro/conserve.rb
Overview
The write contract, made enforceable.
Additive and targeted, never regenerative. A write verb may append a
line or edit the line it was given. No verb rewrites a file it did not
fully derive from that file's own prior contents.
Failure mode 07 — Agent Drift — is an LLM regenerating a view and dropping
a task, silently: no error, no diff anyone reads, one commitment gone. The
verdict that closed it was "derivation exists as a checker and never as a
generator", and the status quo it was written against is the failure
rather than a defence: today the agent rewrites board.md with a heredoc,
which is exactly the silent-drop hazard performed by exactly the actor the
record names.
So a write verb does not promise to be careful. It states the delta it intends, computes the new text purely, and hands both to this module, which compares the LINE MULTISETS and refuses when the actual delta is not the intended one. A Ruby function that provably cannot drop a line is the remedy for a heredoc that can, and the difference between the two is that this one is checked.
Pure: text in, findings out. No disk, no bundle, no dates.
Class Method Summary collapse
-
.check(before, after, added: [], removed: [], moved: []) ⇒ Object
added:/removed:are the lines the caller means to add and take away. - .counts(text) ⇒ Object
- .counts_of(lines) ⇒ Object
-
.delta_findings(actual, intended, verb) ⇒ Object
One direction of the comparison, both ways round: what happened and was not intended, and what was intended and did not happen.
-
.normalize(line) ⇒ Object
Trailing newline stripped, nothing else.
- .subtract(left, right) ⇒ Object
Class Method Details
.check(before, after, added: [], removed: [], moved: []) ⇒ Object
added: / removed: are the lines the caller means to add and take
away. moved: is the third shape, and it is invisible to a multiset by
construction — a line that changed sections is neither added nor
removed — so it is asserted directly: still there before, still there
after. Without that, "move it" and "delete it and add it back" and "do
nothing" are the same claim.
Returns findings; empty means the file may be written.
38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/okf/pro/conserve.rb', line 38 def check(before, after, added: [], removed: [], moved: []) was = counts(before) now = counts(after) findings = delta_findings(subtract(now, was), counts_of(added), "added") + delta_findings(subtract(was, now), counts_of(removed), "removed") Array(moved).each do |line| key = normalize(line) findings << "conservation: the line to move is not in the file as it stands: #{key}" unless was[key] findings << "conservation: the line to move is gone from the result: #{key}" unless now[key] end findings end |
.counts(text) ⇒ Object
75 76 77 |
# File 'lib/okf/pro/conserve.rb', line 75 def counts(text) counts_of(text.to_s.lines) end |
.counts_of(lines) ⇒ Object
79 80 81 82 83 84 |
# File 'lib/okf/pro/conserve.rb', line 79 def counts_of(lines) Array(lines).each_with_object({}) do |line, acc| key = normalize(line) acc[key] = (acc[key] || 0) + 1 end end |
.delta_findings(actual, intended, verb) ⇒ Object
One direction of the comparison, both ways round: what happened and was not intended, and what was intended and did not happen. Both are refusals — an edit that did less than it said is as much a lie as one that did more, and the second is how a promotion silently no-ops.
57 58 59 60 61 62 63 64 65 |
# File 'lib/okf/pro/conserve.rb', line 57 def delta_findings(actual, intended, verb) findings = subtract(actual, intended).map do |line, n| "conservation: #{n} line(s) #{verb} that the edit did not intend: #{line}" end subtract(intended, actual).each do |line, n| findings << "conservation: #{n} line(s) the edit meant to have #{verb} are not: #{line}" end findings end |
.normalize(line) ⇒ Object
Trailing newline stripped, nothing else. Whitespace inside a line is
content on a board — the leading - is the counters' own grammar —
and normalising it away would let an edit reindent the file past a
guard whose whole job is to notice.
71 72 73 |
# File 'lib/okf/pro/conserve.rb', line 71 def normalize(line) line.to_s.chomp end |
.subtract(left, right) ⇒ Object
86 87 88 89 90 91 |
# File 'lib/okf/pro/conserve.rb', line 86 def subtract(left, right) left.each_with_object({}) do |(line, n), acc| surplus = n - (right[line] || 0) acc[line] = surplus if surplus.positive? end end |