All work

inTact

Heals file edits that drifted out of date before an agent applied them.

Source on GitLab Python · Apache-2.0 · v1.2.1
A stale quoted edit descends a ladder of seven match strategies, from EXACT to FUZZY. It stops at the first rung with exactly one candidate and applies there; when a rung finds two tied candidates it refuses instead of guessing, and nothing is written. Both outcomes shown here happened at the INDENT rung in a real run. DEBUG = True EXACT CANON RSTRIP INDENT SUBLINE REFLOW FUZZY DEBUG = False 2 matches → refuse

Coding agents edit files by quoting the text they want to replace, and that quote goes stale all the time (a formatter runs, a line wraps, someone else touches the file). inTact heals those edits. It climbs a ladder of seven increasingly forgiving match strategies, stops at the first unambiguous match, tells you which rung it used, and refuses outright when two candidates tie.

I measured it against 59 real edit failures from my own agent sessions. Of the 56 that can be replayed, 42 resolve uniquely, 13 are refused because nothing matches, and 1 because two candidates tie. My false-heal check finds none among the seven pairs it can check, though it missed two wrong heals that had inflated the count to 44 until version 1.2.1 refused them. It ships on PyPI as a library, a CLI, and an MCP server.

$ cat config.txt
panel = canvas - warm
title = Portfolio

$ tact --json check config.txt --old 'panel = canva - warm' --new 'panel = paper - warm' | jq '.results[0] | {ok, rung, fuzz}'
{
  "ok": true,
  "rung": "FUZZY",
  "fuzz": 0.9523809523809523
}

$ tact edit config.txt --old 'panel = canva - warm' --new 'panel = paper - warm'
applied=True drift_detected=False
  [0] ok=True rung=FUZZY fuzz=0.9523809523809523 range=(0, 1) ambiguous=False overlap=False

$ cat config.txt
panel = paper - warm
title = Portfolio
Four real tact runs, each a different kind of drift: smart quotes resolve at CANON, trailing whitespace at RSTRIP, a re-indented line at INDENT (the tact README's own example), and rewrapped prose at REFLOW. A fifth run shows two equally good candidates refusing until --near picks one. The summary below is the tact README's public replay for version 1.2.1: of 59 public fixtures, 42 resolve uniquely, 13 are no-match refusals, 1 is an ambiguity refusal, and 3 are unreplayable, with zero false-heal candidates among 7 checkable same-intent pairs. CANON She said “hello” to the room. She said "hi" to the room. RSTRIP name = "demo"··· name = "final" INDENT return 41 return 42 REFLOW The reconciliation ladder tries seven strategies in order. The reconciliation ladder tries seven ordered strategies. 2 candidates line 1: return None line 4: return None --near 1 line 1: return True tact: 59 public fixtures → 42 resolved uniquely tact: 13 no-match refusals, 1 ambiguity refusal, 3 unreplayable tact: false-heal candidates 0 of 7 checkable pairs
Isometric staircase of the seven rungs a quoted old_block descends, in the order the code tries them: EXACT, CANON, RSTRIP, INDENT, SUBLINE, REFLOW, FUZZY. The stair descends because each rung tolerates more drift than the one above it, and the first rung with exactly one candidate stops the descent. Cyan steps match whole lines; the two amber steps, SUBLINE and REFLOW, marked mid-line, can match part of a line. The staircase stands on a slate slab, the undo journal. Along its front edge lies a strip of 32 cells, the ring of pre-images kept for each file. An amber arrow marks the newest cell: when an edit is applied, the file is stashed into the journal first and then written atomically. EXACT CANON RSTRIP INDENT SUBLINEmid-line REFLOWmid-line FUZZY old_block undo journal ring: 32 pre-images per file unique hit: stash, then write