<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://invarians.org/index.php?action=history&amp;feed=atom&amp;title=The_Principia_Machina%2FTPC-PY%2Ftpc_hunk.py</id>
	<title>The Principia Machina/TPC-PY/tpc hunk.py - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://invarians.org/index.php?action=history&amp;feed=atom&amp;title=The_Principia_Machina%2FTPC-PY%2Ftpc_hunk.py"/>
	<link rel="alternate" type="text/html" href="https://invarians.org/index.php?title=The_Principia_Machina/TPC-PY/tpc_hunk.py&amp;action=history"/>
	<updated>2026-10-21T11:16:25Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.46.2</generator>
	<entry>
		<id>https://invarians.org/index.php?title=The_Principia_Machina/TPC-PY/tpc_hunk.py&amp;diff=4219&amp;oldid=prev</id>
		<title>BFP Rauch: 1 revision imported</title>
		<link rel="alternate" type="text/html" href="https://invarians.org/index.php?title=The_Principia_Machina/TPC-PY/tpc_hunk.py&amp;diff=4219&amp;oldid=prev"/>
		<updated>2026-09-28T04:37:36Z</updated>

		<summary type="html">&lt;p&gt;1 revision imported&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw-interface=&quot;&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 04:37, 28 September 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;4&quot; class=&quot;diff-notice&quot; lang=&quot;en&quot;&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;(No difference)&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;!-- diff cache key pma_cutover_20261020t051351z-soft_:diff:1.41:old-4218:rev-4219 --&gt;
&lt;/table&gt;</summary>
		<author><name>BFP Rauch</name></author>
	</entry>
	<entry>
		<id>https://invarians.org/index.php?title=The_Principia_Machina/TPC-PY/tpc_hunk.py&amp;diff=4218&amp;oldid=prev</id>
		<title>BFP Rauch: TPC-PY source tpc_hunk.py (0.1.0), SHA-256 b1662188a9ae9340; conformed TPS 0.3.0; PROPOSED, not declared (CO-8)</title>
		<link rel="alternate" type="text/html" href="https://invarians.org/index.php?title=The_Principia_Machina/TPC-PY/tpc_hunk.py&amp;diff=4218&amp;oldid=prev"/>
		<updated>2026-09-27T15:43:18Z</updated>

		<summary type="html">&lt;p&gt;TPC-PY source tpc_hunk.py (0.1.0), SHA-256 b1662188a9ae9340; conformed TPS 0.3.0; PROPOSED, not declared (CO-8)&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;&amp;quot;&amp;quot;&amp;quot;tpc_hunk 0.1.0 (DRAFT, pending D151): hunk_apply, the page write of a&lt;br /&gt;
PATCH falcon&amp;#039;s approved hunks.&lt;br /&gt;
&lt;br /&gt;
Reference implementation, Python standard library only. DATA for landing&lt;br /&gt;
round 8 of branch tpm_project_closeout (the falcon speculation 0.1.0&lt;br /&gt;
section 7&amp;#039;s approval-form step and section 8&amp;#039;s signature; PMP-TPM 0.12.0&lt;br /&gt;
FALCONS, APPROVAL AND APPLICATION; record D151.1 (b), (g)); not a&lt;br /&gt;
declared TPC-PY version and not TPX code. A pure function of its&lt;br /&gt;
arguments. Every refused argument raises ValueError with a short fixed&lt;br /&gt;
message. render_hunk() gives the canonical text the PHP residence&lt;br /&gt;
(tpc_hunk.php) reproduces byte for byte. Kept in its own module so that&lt;br /&gt;
tpc_falcon 0.1.1&amp;#039;s source_match amendment (agent BC) and this function&lt;br /&gt;
never touch one file.&lt;br /&gt;
&lt;br /&gt;
hunk_apply(base_text, hunks) -&amp;gt; dict&lt;br /&gt;
  base_text: the target page&amp;#039;s text at the falcon&amp;#039;s base revision, a&lt;br /&gt;
    string (TPX has already refused BASE MOVED, D151.1 (g)).&lt;br /&gt;
  hunks: the approved hunks, a list of objects {old, new} (the optional&lt;br /&gt;
    keys n, anchor and count of the landing rounds&amp;#039; hunk files are&lt;br /&gt;
    accepted and read by nothing), old and new strings; applied in list&lt;br /&gt;
    order. Anything else raises ValueError(&amp;quot;hunks&amp;quot;); a base that is not a&lt;br /&gt;
    string raises ValueError(&amp;quot;base&amp;quot;).&lt;br /&gt;
  Result: {status: OK, applied: the hunk count, sha256: the SHA-256 of&lt;br /&gt;
    the result&amp;#039;s UTF-8, text: the result}, or {status: REFUSED, reason,&lt;br /&gt;
    hunk: the 1-based index of the hunk refused}. TPX saves the OK text&lt;br /&gt;
    as the approver&amp;#039;s own revision and reads back its SHA-1 (D151.1 (b));&lt;br /&gt;
    on REFUSED nothing is saved.&lt;br /&gt;
  Rule (the falcon speculation 8, hunk_apply: &amp;quot;each old string occurs&lt;br /&gt;
  exactly once in the base and no two hunks overlap, else REFUSED;&lt;br /&gt;
  applied in order&amp;quot;):&lt;br /&gt;
  HK1 EMPTY. An old string that is empty occurs at every position, never&lt;br /&gt;
      exactly once: REFUSED, reason EMPTY.&lt;br /&gt;
  HK2 EXACTLY ONCE. Each old string is located in the BASE TEXT, exactly&lt;br /&gt;
      as given (no normalization: the approved text was drawn from the&lt;br /&gt;
      same base by exact replacement, D151.1 (b)); every start position&lt;br /&gt;
      is counted, overlapping occurrences included, so &amp;quot;aa&amp;quot; in &amp;quot;aaa&amp;quot;&lt;br /&gt;
      occurs twice. None: REFUSED, reason ABSENT; two or more: REFUSED,&lt;br /&gt;
      reason MULTIPLE.&lt;br /&gt;
  HK3 NO OVERLAP. The located ranges [start, start + len(old)) of any two&lt;br /&gt;
      hunks are disjoint; adjacent ranges (one ending where the next&lt;br /&gt;
      begins) do not overlap. A hunk whose range meets an earlier hunk&amp;#039;s&lt;br /&gt;
      range: REFUSED, reason OVERLAP.&lt;br /&gt;
  HK4 APPLICATION. Each old string is replaced by its new string at its&lt;br /&gt;
      located position; the ranges being disjoint in the base, the&lt;br /&gt;
      result is the same whichever hunk is applied first, and equals the&lt;br /&gt;
      sequential application of the list. Reading taken by delegation&lt;br /&gt;
      2026-09-26 (spec note PD-OC-3): &amp;quot;in order&amp;quot; names the sequence of&lt;br /&gt;
      application, not the positions: the hunk list need not be sorted&lt;br /&gt;
      by position (the landing rounds&amp;#039; hunk sets are not, and every one&lt;br /&gt;
      of them replays under this rule). The alternative, REFUSED with a&lt;br /&gt;
      reason ORDER when positions do not ascend with the list, is in the&lt;br /&gt;
      spec note.&lt;br /&gt;
  HK5 An empty hunk list gives OK with the base unchanged (spec note&lt;br /&gt;
      PD-OC-4; alternative: REFUSED, reason NONE). A hunk whose new&lt;br /&gt;
      string equals its old string is a no-op and is applied.&lt;br /&gt;
  The first hunk that fails HK1-HK3 in list order names the refusal;&lt;br /&gt;
  every hunk is located before any is applied, so a refusal changes&lt;br /&gt;
  nothing.&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
import hashlib&lt;br /&gt;
&lt;br /&gt;
VERSION = &amp;quot;0.1.0&amp;quot;&lt;br /&gt;
REASONS = (&amp;quot;EMPTY&amp;quot;, &amp;quot;ABSENT&amp;quot;, &amp;quot;MULTIPLE&amp;quot;, &amp;quot;OVERLAP&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def _esc(s):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;Render escape: &amp;quot;|&amp;quot; and &amp;quot;\\&amp;quot; backslashed; C0 controls and DEL as&lt;br /&gt;
    \\xHH; every other character as it is.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    out = []&lt;br /&gt;
    for ch in s:&lt;br /&gt;
        o = ord(ch)&lt;br /&gt;
        if ch == &amp;quot;|&amp;quot; or ch == &amp;quot;\\&amp;quot;:&lt;br /&gt;
            out.append(&amp;quot;\\&amp;quot; + ch)&lt;br /&gt;
        elif o &amp;lt; 0x20 or o == 0x7F:&lt;br /&gt;
            out.append(&amp;quot;\\x%02x&amp;quot; % o)&lt;br /&gt;
        else:&lt;br /&gt;
            out.append(ch)&lt;br /&gt;
    return &amp;quot;&amp;quot;.join(out)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def _is_text(s):&lt;br /&gt;
    if type(s) is not str:&lt;br /&gt;
        return False&lt;br /&gt;
    for ch in s:&lt;br /&gt;
        if 0xD800 &amp;lt;= ord(ch) &amp;lt;= 0xDFFF:&lt;br /&gt;
            return False&lt;br /&gt;
    return True&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def _check(base_text, hunks):&lt;br /&gt;
    if not _is_text(base_text):&lt;br /&gt;
        raise ValueError(&amp;quot;base&amp;quot;)&lt;br /&gt;
    if type(hunks) is not list:&lt;br /&gt;
        raise ValueError(&amp;quot;hunks&amp;quot;)&lt;br /&gt;
    for h in hunks:&lt;br /&gt;
        if type(h) is not dict or &amp;quot;old&amp;quot; not in h or &amp;quot;new&amp;quot; not in h:&lt;br /&gt;
            raise ValueError(&amp;quot;hunks&amp;quot;)&lt;br /&gt;
        for k in h:&lt;br /&gt;
            if k not in (&amp;quot;old&amp;quot;, &amp;quot;new&amp;quot;, &amp;quot;n&amp;quot;, &amp;quot;anchor&amp;quot;, &amp;quot;count&amp;quot;):&lt;br /&gt;
                raise ValueError(&amp;quot;hunks&amp;quot;)&lt;br /&gt;
        if not _is_text(h[&amp;quot;old&amp;quot;]) or not _is_text(h[&amp;quot;new&amp;quot;]):&lt;br /&gt;
            raise ValueError(&amp;quot;hunks&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def count_occurrences(text, needle):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;Every start position of a non-empty needle, overlapping included.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    n = 0&lt;br /&gt;
    i = text.find(needle)&lt;br /&gt;
    while i != -1:&lt;br /&gt;
        n += 1&lt;br /&gt;
        i = text.find(needle, i + 1)&lt;br /&gt;
    return n&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def hunk_apply(base_text, hunks):&lt;br /&gt;
    _check(base_text, hunks)&lt;br /&gt;
    located = []&lt;br /&gt;
    for idx, h in enumerate(hunks):&lt;br /&gt;
        old = h[&amp;quot;old&amp;quot;]&lt;br /&gt;
        if old == &amp;quot;&amp;quot;:&lt;br /&gt;
            return {&amp;quot;status&amp;quot;: &amp;quot;REFUSED&amp;quot;, &amp;quot;reason&amp;quot;: &amp;quot;EMPTY&amp;quot;, &amp;quot;hunk&amp;quot;: idx + 1}&lt;br /&gt;
        c = count_occurrences(base_text, old)&lt;br /&gt;
        if c == 0:&lt;br /&gt;
            return {&amp;quot;status&amp;quot;: &amp;quot;REFUSED&amp;quot;, &amp;quot;reason&amp;quot;: &amp;quot;ABSENT&amp;quot;, &amp;quot;hunk&amp;quot;: idx + 1}&lt;br /&gt;
        if c &amp;gt; 1:&lt;br /&gt;
            return {&amp;quot;status&amp;quot;: &amp;quot;REFUSED&amp;quot;, &amp;quot;reason&amp;quot;: &amp;quot;MULTIPLE&amp;quot;,&lt;br /&gt;
                    &amp;quot;hunk&amp;quot;: idx + 1}&lt;br /&gt;
        start = base_text.find(old)&lt;br /&gt;
        end = start + len(old)&lt;br /&gt;
        for s2, e2 in located:&lt;br /&gt;
            if start &amp;lt; e2 and s2 &amp;lt; end:&lt;br /&gt;
                return {&amp;quot;status&amp;quot;: &amp;quot;REFUSED&amp;quot;, &amp;quot;reason&amp;quot;: &amp;quot;OVERLAP&amp;quot;,&lt;br /&gt;
                        &amp;quot;hunk&amp;quot;: idx + 1}&lt;br /&gt;
        located.append((start, end))&lt;br /&gt;
    order = sorted(range(len(hunks)), key=lambda i: located[i][0])&lt;br /&gt;
    pieces = []&lt;br /&gt;
    cur = 0&lt;br /&gt;
    for i in order:&lt;br /&gt;
        start, end = located[i]&lt;br /&gt;
        pieces.append(base_text[cur:start])&lt;br /&gt;
        pieces.append(hunks[i][&amp;quot;new&amp;quot;])&lt;br /&gt;
        cur = end&lt;br /&gt;
    pieces.append(base_text[cur:])&lt;br /&gt;
    text = &amp;quot;&amp;quot;.join(pieces)&lt;br /&gt;
    return {&amp;quot;status&amp;quot;: &amp;quot;OK&amp;quot;, &amp;quot;applied&amp;quot;: len(hunks),&lt;br /&gt;
            &amp;quot;sha256&amp;quot;: hashlib.sha256(text.encode(&amp;quot;utf-8&amp;quot;)).hexdigest(),&lt;br /&gt;
            &amp;quot;text&amp;quot;: text}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def render_hunk(d):&lt;br /&gt;
    if d[&amp;quot;status&amp;quot;] == &amp;quot;REFUSED&amp;quot;:&lt;br /&gt;
        return &amp;quot;REFUSED|%s|%d&amp;quot; % (d[&amp;quot;reason&amp;quot;], d[&amp;quot;hunk&amp;quot;])&lt;br /&gt;
    return &amp;quot;OK|%d|%s\ntext|%s&amp;quot; % (d[&amp;quot;applied&amp;quot;], d[&amp;quot;sha256&amp;quot;], _esc(d[&amp;quot;text&amp;quot;]))&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
FNS = (&amp;quot;hunk&amp;quot;,)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def run_case(fn, args):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;One corpus case: the render, or &amp;quot;ERROR:&amp;quot; and the message.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    if fn not in FNS:&lt;br /&gt;
        raise ValueError(&amp;quot;fn&amp;quot;)&lt;br /&gt;
    try:&lt;br /&gt;
        return render_hunk(hunk_apply(args[&amp;quot;base&amp;quot;], args[&amp;quot;hunks&amp;quot;]))&lt;br /&gt;
    except ValueError as ex:&lt;br /&gt;
        return &amp;quot;ERROR:&amp;quot; + str(ex)&lt;br /&gt;
&lt;/div&gt;</summary>
		<author><name>BFP Rauch</name></author>
	</entry>
</feed>