Project P158

Bug triage

Two findings with one shared cause patched where each was seen, one report with two causes patched to its own inputs, and a backlog that outruns its fixes worked in arrival order and worst first.

2 modules · 2 recorded sessionstext-menu UI in the terminalupdated 2026-10-18

Every screen below was recorded under CPython. When this page was built, the EML interpreter replayed each session from the same input and printed the same bytes.

About

Three ways a bug report misleads the people who fix it: two findings with one cause, one report with two, and a backlog that grows faster than it is fixed.

  • main.eml - the menu, the two findings, the one report, and the backlog worked two ways
  • triage.eml - the calendar screens and the date parser they share, the states as fixes go in, the balance as shown and the fixes for it, the findings in the backlog, and working them

How each part works:

  • As in the corpus case two-findings-one-defect, the weekly report starts a day late and reminders come a day late. Each candidate cause is run alone: the shared date parser makes the report, the reminder and the audit log wrong; each screen's own code only itself. Only the parser explains both findings, and it predicts a third nobody filed. Patched where each was seen, both findings close and the audit log stays wrong; fix the parser later and the two patches make their screens wrong again.
  • As in the corpus case one-report-two-mechanisms, one report of three wrong balances - -4, 150, -7 - has two causes: the sign dropped and anything past 99 clamped. Special-casing the reported inputs makes the report pass and leaves 4 of 12 inputs wrong, each explained by one mechanism run alone; fixing both mechanisms leaves none.
  • As in the corpus case finding-outruns-fixing, two findings arrive in each of five periods. Fixing one a period, the queue never empties, and working the worst first instead of in arrival order cuts the harm from 127 to 71 with the same fixes; fixing two a period, the queue empties and the order changes nothing.

What is checked: menu choices 1 to 4; fixes each period 1 or 2. An empty answer cancels.

Sessions: sessions/basic.in gives: - the two findings and the one report; - the backlog at one fix a period and at two.

sessions/bad-input.in gives: - menu choices 0 and x; - fixes each period: a cancel, 3 and x; then the one report.

Built on the verified corpus cases two-findings-one-defect (two symptoms patched locally over one shared cause), one-report-two-mechanisms (a patch fitted to the reported inputs) and finding-outruns-fixing (the same fixing capacity in arrival order and by harm).

Recorded sessions

What the screen shows while someone uses the program. Each typed line appears after its prompt, the way a terminal shows it.

bad-input

interpreter: byte-equal
== Bug triage ==
Two findings with one cause, one report with two, and a backlog that outruns its fixes.

1) two findings  2) one report  3) the backlog  4) quit
choice> 0
Pick a number from 1 to 4.

1) two findings  2) one report  3) the backlog  4) quit
choice> x
Pick a number from 1 to 4.

1) two findings  2) one report  3) the backlog  4) quit
choice> 3
fixes each period (1 or 2)> 
Cancelled.

1) two findings  2) one report  3) the backlog  4) quit
choice> 3
fixes each period (1 or 2)> 3
Type 1 or 2.

1) two findings  2) one report  3) the backlog  4) quit
choice> 3
fixes each period (1 or 2)> x
Type 1 or 2.

1) two findings  2) one report  3) the backlog  4) quit
choice> 2
One report, three wrong balances:
     -4 shows    4, should be -4
    150 shows   99, should be 150
     -7 shows    7, should be -7
Over the 12 inputs -9, -4, 0, 3, 42, 99, 100, 150, 260, -7, -1, 77:
  fix                   wrong
  none                  7   -9, -4, 100, 150, 260, -7, -1
  the reported inputs   4   -9, 100, 260, -1
  keep the sign         3   100, 150, 260
  no clamp at 99        4   -9, -4, -7, -1
  both                  0   none
Fitted to the report, the report passes and 4 failures remain; each mechanism run alone accounts for its share:
  the sign dropped:      -9, -1
  past 99 clamped:       100, 260
The report could not show that two of its rows came from one cause and the third from another.

1) two findings  2) one report  3) the backlog  4) quit
choice> 4
Bye.
What was typed (10 lines)
0
x
3

3
3
3
x
2
4

basic

interpreter: byte-equal
== Bug triage ==
Two findings with one cause, one report with two, and a backlog that outruns its fixes.

1) two findings  2) one report  3) the backlog  4) quit
choice> 1
Two findings, filed a week apart: the weekly report starts a day late; reminders come a day late.
Each candidate cause alone, and the screens it makes wrong on the days 3, 10, 17, 24 and 31:
  the date parser:      report, reminder, audit
  the report's code:    report
  the reminder's code:  reminder
Only the parser explains both findings, and it predicts a third nobody filed: the audit log.
Days right of 5, as the fixes go in:
                              report  reminder  audit
  as shipped                       0         0      0
  patched where seen               5         5      0
  parser fixed                     5         5      5
  parser fixed, patches left       0         0      5
Patched where seen, both findings close and the audit log stays wrong; fix the parser later and the two patches make their screens wrong again.

1) two findings  2) one report  3) the backlog  4) quit
choice> 2
One report, three wrong balances:
     -4 shows    4, should be -4
    150 shows   99, should be 150
     -7 shows    7, should be -7
Over the 12 inputs -9, -4, 0, 3, 42, 99, 100, 150, 260, -7, -1, 77:
  fix                   wrong
  none                  7   -9, -4, 100, 150, 260, -7, -1
  the reported inputs   4   -9, 100, 260, -1
  keep the sign         3   100, 150, 260
  no clamp at 99        4   -9, -4, -7, -1
  both                  0   none
Fitted to the report, the report passes and 4 failures remain; each mechanism run alone accounts for its share:
  the sign dropped:      -9, -1
  past 99 clamped:       100, 260
The report could not show that two of its rows came from one cause and the third from another.

1) two findings  2) one report  3) the backlog  4) quit
choice> 3
fixes each period (1 or 2)> 1
Two findings arrive in each of periods 1 to 5; 1 fixed a period; the harm each does every period it waits is summed over 6 periods.
  in arrival order:  harm 127; still open: f7, f8, f9, f10
  worst first:       harm  71; still open: f1, f3, f5, f9
The same number fixed each period, and the order changes the harm by 56: once findings outrun fixes, the order is not a preference.

1) two findings  2) one report  3) the backlog  4) quit
choice> 3
fixes each period (1 or 2)> 2
Two findings arrive in each of periods 1 to 5; 2 fixed a period; the harm each does every period it waits is summed over 6 periods.
  in arrival order:  harm  48; still open: none
  worst first:       harm  48; still open: none
The order changes nothing here.
With fixes keeping up, the queue empties either way.

1) two findings  2) one report  3) the backlog  4) quit
choice> 4
Bye.
What was typed (7 lines)
1
2
3
1
3
2
4

Modules

The program as written, entry module first. Each module transpiles to its own Python file, which is what eml project run executes.

main.eml(entry)

eml
# P158 bug triage: two findings with one cause, one report with two causes,
# and a backlog that grows faster than it is fixed.
import triage

def plain(s):
    0 => i
    len(s) => j
    while i < j and s[i] == " ":
        i + 1 => i
    while j > i and s[j - 1] == " ":
        j - 1 => j
    return s[i:j]

def pad(s, n):
    s => out
    while len(out) < n:
        out + " " => out
    return out

def lpad(s, n):
    s => out
    while len(out) < n:
        " " + out => out
    return out

def listed(xs):
    "" => out
    for x in xs:
        if out == "":
            str(x) => out
        else:
            out + ", " + str(x) => out
    if out == "":
        return "none"
    return out

def wrong_screens(parser_bug, report_bug, reminder_bug):
    [] => out
    for d in triage.days():
        if triage.report(d, parser_bug, report_bug) != d % 7:
            out + ["report"] => out
        if triage.reminder(d, parser_bug, reminder_bug) != d % 7:
            out + ["reminder"] => out
        if triage.audit(d, parser_bug) != d % 7:
            out + ["audit"] => out
    [] => names
    for s in ["report", "reminder", "audit"]:
        for x in out:
            if x == s:
                False => have
                for n in names:
                    if n == s:
                        True => have
                if not have:
                    names + [s] => names
    return names

def two_findings():
    "Two findings, filed a week apart: the weekly report starts a day late; reminders come a day late." ^0
    "Each candidate cause alone, and the screens it makes wrong on the days 3, 10, 17, 24 and 31:" ^0
    ("  the date parser:      " + listed(wrong_screens(True, False, False))) ^0
    ("  the report's code:    " + listed(wrong_screens(False, True, False))) ^0
    ("  the reminder's code:  " + listed(wrong_screens(False, False, True))) ^0
    "Only the parser explains both findings, and it predicts a third nobody filed: the audit log." ^0
    "Days right of 5, as the fixes go in:" ^0
    ("  " + pad("", 28) + "report  reminder  audit") ^0
    for st in triage.states():
        ("  " + pad(st[0], 28) + lpad(str(triage.right_days("report", st[1], st[2])), 6) + lpad(str(triage.right_days("reminder", st[1], st[2])), 10) + lpad(str(triage.right_days("audit", st[1], st[2])), 7)) ^0
    "Patched where seen, both findings close and the audit log stays wrong; fix the parser later and the two patches make their screens wrong again." ^0

def one_report():
    "One report, three wrong balances:" ^0
    for r in triage.reported():
        ("  " + lpad(str(r), 5) + " shows " + lpad(triage.render(r, True, True), 4) + ", should be " + triage.truth(r)) ^0
    ("Over the " + str(len(triage.inputs())) + " inputs " + listed(triage.inputs()) + ":") ^0
    ("  " + pad("fix", 22) + "wrong") ^0
    for fx in ["none", "fitted", "sign", "clamp", "both"]:
        [] => bad
        for v in triage.inputs():
            if triage.shown(v, fx) != triage.truth(v):
                bad + [v] => bad
        if fx == "fitted":
            "the reported inputs" => name
        elif fx == "sign":
            "keep the sign" => name
        elif fx == "clamp":
            "no clamp at 99" => name
        else:
            fx => name
        ("  " + pad(name, 22) + pad(str(len(bad)), 4) + listed(bad)) ^0
    [] => s
    [] => c
    0 => left
    for v in triage.inputs():
        if triage.shown(v, "fitted") != triage.truth(v):
            left + 1 => left
            if triage.render(v, True, False) != triage.truth(v):
                s + [v] => s
            if triage.render(v, False, True) != triage.truth(v):
                c + [v] => c
    ("Fitted to the report, the report passes and " + str(left) + " failures remain; each mechanism run alone accounts for its share:") ^0
    ("  the sign dropped:      " + listed(s)) ^0
    ("  past 99 clamped:       " + listed(c)) ^0
    "The report could not show that two of its rows came from one cause and the third from another." ^0

def backlog():
    plain(input("fixes each period (1 or 2)> ")) => t
    if t == "":
        "Cancelled." ^0
        return
    if t != "1" and t != "2":
        "Type 1 or 2." ^0
        return
    int(t) => cap
    ("Two findings arrive in each of periods 1 to 5; " + t + " fixed a period; the harm each does every period it waits is summed over 6 periods.") ^0
    triage.work("fifo", cap, 6) => a
    triage.work("harm", cap, 6) => b
    ("  in arrival order:  harm " + lpad(str(a[0]), 3) + "; still open: " + listed(a[2])) ^0
    ("  worst first:       harm " + lpad(str(b[0]), 3) + "; still open: " + listed(b[2])) ^0
    if a[0] != b[0]:
        ("The same number fixed each period, and the order changes the harm by " + str(a[0] - b[0]) + ": once findings outrun fixes, the order is not a preference.") ^0
    else:
        "The order changes nothing here." ^0
    if len(a[2]) == 0 and len(b[2]) == 0:
        "With fixes keeping up, the queue empties either way." ^0

"== Bug triage ==" ^0
"Two findings with one cause, one report with two, and a backlog that outruns its fixes." ^0
True => running
while running:
    "" ^0
    "1) two findings  2) one report  3) the backlog  4) quit" ^0
    plain(input("choice> ")) => choice
    if choice == "1":
        two_findings()
    elif choice == "2":
        one_report()
    elif choice == "3":
        backlog()
    elif choice == "4":
        False => running
    else:
        "Pick a number from 1 to 4." ^0
"Bye." ^0
Python projection (main.py)
import triage

def plain(s):
    i = 0
    j = len(s)
    while i < j and s[i] == " ":
        i = i + 1
    while j > i and s[j - 1] == " ":
        j = j - 1
    return s[i:j]

def pad(s, n):
    out = s
    while len(out) < n:
        out = out + " "
    return out

def lpad(s, n):
    out = s
    while len(out) < n:
        out = " " + out
    return out

def listed(xs):
    out = ""
    for x in xs:
        if out == "":
            out = str(x)
        else:
            out = out + ", " + str(x)
    if out == "":
        return "none"
    return out

def wrong_screens(parser_bug, report_bug, reminder_bug):
    out = []
    for d in triage.days():
        if triage.report(d, parser_bug, report_bug) != d % 7:
            out = out + ["report"]
        if triage.reminder(d, parser_bug, reminder_bug) != d % 7:
            out = out + ["reminder"]
        if triage.audit(d, parser_bug) != d % 7:
            out = out + ["audit"]
    names = []
    for s in ["report", "reminder", "audit"]:
        for x in out:
            if x == s:
                have = False
                for n in names:
                    if n == s:
                        have = True
                if not have:
                    names = names + [s]
    return names

def two_findings():
    print("Two findings, filed a week apart: the weekly report starts a day late; reminders come a day late.")
    print("Each candidate cause alone, and the screens it makes wrong on the days 3, 10, 17, 24 and 31:")
    print("  the date parser:      " + listed(wrong_screens(True, False, False)))
    print("  the report's code:    " + listed(wrong_screens(False, True, False)))
    print("  the reminder's code:  " + listed(wrong_screens(False, False, True)))
    print("Only the parser explains both findings, and it predicts a third nobody filed: the audit log.")
    print("Days right of 5, as the fixes go in:")
    print("  " + pad("", 28) + "report  reminder  audit")
    for st in triage.states():
        print("  " + pad(st[0], 28) + lpad(str(triage.right_days("report", st[1], st[2])), 6) + lpad(str(triage.right_days("reminder", st[1], st[2])), 10) + lpad(str(triage.right_days("audit", st[1], st[2])), 7))
    print("Patched where seen, both findings close and the audit log stays wrong; fix the parser later and the two patches make their screens wrong again.")

def one_report():
    print("One report, three wrong balances:")
    for r in triage.reported():
        print("  " + lpad(str(r), 5) + " shows " + lpad(triage.render(r, True, True), 4) + ", should be " + triage.truth(r))
    print("Over the " + str(len(triage.inputs())) + " inputs " + listed(triage.inputs()) + ":")
    print("  " + pad("fix", 22) + "wrong")
    for fx in ["none", "fitted", "sign", "clamp", "both"]:
        bad = []
        for v in triage.inputs():
            if triage.shown(v, fx) != triage.truth(v):
                bad = bad + [v]
        if fx == "fitted":
            name = "the reported inputs"
        elif fx == "sign":
            name = "keep the sign"
        elif fx == "clamp":
            name = "no clamp at 99"
        else:
            name = fx
        print("  " + pad(name, 22) + pad(str(len(bad)), 4) + listed(bad))
    s = []
    c = []
    left = 0
    for v in triage.inputs():
        if triage.shown(v, "fitted") != triage.truth(v):
            left = left + 1
            if triage.render(v, True, False) != triage.truth(v):
                s = s + [v]
            if triage.render(v, False, True) != triage.truth(v):
                c = c + [v]
    print("Fitted to the report, the report passes and " + str(left) + " failures remain; each mechanism run alone accounts for its share:")
    print("  the sign dropped:      " + listed(s))
    print("  past 99 clamped:       " + listed(c))
    print("The report could not show that two of its rows came from one cause and the third from another.")

def backlog():
    t = plain(input("fixes each period (1 or 2)> "))
    if t == "":
        print("Cancelled.")
        return
    if t != "1" and t != "2":
        print("Type 1 or 2.")
        return
    cap = int(t)
    print("Two findings arrive in each of periods 1 to 5; " + t + " fixed a period; the harm each does every period it waits is summed over 6 periods.")
    a = triage.work("fifo", cap, 6)
    b = triage.work("harm", cap, 6)
    print("  in arrival order:  harm " + lpad(str(a[0]), 3) + "; still open: " + listed(a[2]))
    print("  worst first:       harm " + lpad(str(b[0]), 3) + "; still open: " + listed(b[2]))
    if a[0] != b[0]:
        print("The same number fixed each period, and the order changes the harm by " + str(a[0] - b[0]) + ": once findings outrun fixes, the order is not a preference.")
    else:
        print("The order changes nothing here.")
    if len(a[2]) == 0 and len(b[2]) == 0:
        print("With fixes keeping up, the queue empties either way.")

print("== Bug triage ==")
print("Two findings with one cause, one report with two, and a backlog that outruns its fixes.")
running = True
while running:
    print("")
    print("1) two findings  2) one report  3) the backlog  4) quit")
    choice = plain(input("choice> "))
    if choice == "1":
        two_findings()
    elif choice == "2":
        one_report()
    elif choice == "3":
        backlog()
    elif choice == "4":
        running = False
    else:
        print("Pick a number from 1 to 4.")
print("Bye.")

triage.eml

eml
# P158 bug triage - three ways a bug report misleads the people who fix it.
# As in the corpus case two-findings-one-defect, two findings on two
# screens, a report a day late and a reminder a day late, come from one
# shared date parser; patched where each was seen, both go quiet, a third
# consumer stays wrong, and fixing the parser later breaks the two patches.
# As in the corpus case one-report-two-mechanisms, one report of three wrong
# outputs has two causes underneath, and a patch fitted to the reported
# inputs fixes the report and neither cause. As in the corpus case
# finding-outruns-fixing, once findings arrive faster than they are fixed
# the queue never empties, and the order it is worked in decides the harm.

def days():
    return [3, 10, 17, 24, 31]

def weekday(day, parser_bug):
    if parser_bug:
        return (day + 1) % 7
    return day % 7

def report(day, parser_bug, patched):
    # the first weekday of the weekly report; the local patch takes a day off
    weekday(day, parser_bug) => w
    if patched:
        return (w + 6) % 7
    return w

def reminder(day, parser_bug, patched):
    weekday(day, parser_bug) => w
    if patched:
        return (w + 6) % 7
    return w

def audit(day, parser_bug):
    return weekday(day, parser_bug)

def states():
    # [name, parser bug, local patches]
    return [["as shipped", True, False], ["patched where seen", True, True], ["parser fixed", False, False], ["parser fixed, patches left", False, True]]

def right_days(screen, parser_bug, patched):
    0 => n
    for d in days():
        if screen == "report":
            report(d, parser_bug, patched) => v
        elif screen == "reminder":
            reminder(d, parser_bug, patched) => v
        else:
            audit(d, parser_bug) => v
        if v == d % 7:
            n + 1 => n
    return n

def truth(v):
    if v < 0:
        return "-" + str(0 - v)
    return str(v)

def render(v, sign_bug, clamp_bug):
    # the balance as shown: the sign dropped, and anything past 99 clamped
    v => x
    if sign_bug and x < 0:
        0 - x => x
    if clamp_bug and x > 99:
        99 => x
    if x < 0:
        return "-" + str(0 - x)
    return str(x)

def reported():
    return [0 - 4, 150, 0 - 7]

def inputs():
    return [0 - 9, 0 - 4, 0, 3, 42, 99, 100, 150, 260, 0 - 7, 0 - 1, 77]

def shown(v, fix):
    # the balance under a fix: none, fitted (the reported inputs special
    # cased), sign, clamp, or both
    if fix == "fitted":
        for r in reported():
            if r == v:
                return truth(v)
        return render(v, True, True)
    return render(v, fix != "sign" and fix != "both", fix != "clamp" and fix != "both")

def findings():
    # [name, period it arrives, harm each period it stays unfixed]
    return [["f1", 1, 1], ["f2", 1, 9], ["f3", 2, 2], ["f4", 2, 8], ["f5", 3, 1], ["f6", 3, 7], ["f7", 4, 3], ["f8", 4, 6], ["f9", 5, 1], ["f10", 5, 10]]

def work(policy, capacity, periods):
    # [harm in all, fixed in order, still waiting]; each period the arrivals
    # join, every waiting finding does its harm, then capacity are fixed
    [] => waiting
    [] => fixed
    0 => harm
    1 => p
    while p <= periods:
        for f in findings():
            if f[1] == p:
                waiting + [f] => waiting
        for f in waiting:
            harm + f[2] => harm
        0 => k
        while k < capacity and len(waiting) > 0:
            0 => pick
            if policy == "harm":
                0 => i
                for f in waiting:
                    if f[2] > waiting[pick][2]:
                        i => pick
                    i + 1 => i
            fixed + [waiting[pick][0]] => fixed
            [] => rest
            0 => i
            for f in waiting:
                if i != pick:
                    rest + [f] => rest
                i + 1 => i
            rest => waiting
            k + 1 => k
        p + 1 => p
    [] => names
    for f in waiting:
        names + [f[0]] => names
    return [harm, fixed, names]
Python projection (triage.py)
def days():
    return [3, 10, 17, 24, 31]

def weekday(day, parser_bug):
    if parser_bug:
        return (day + 1) % 7
    return day % 7

def report(day, parser_bug, patched):
    w = weekday(day, parser_bug)
    if patched:
        return (w + 6) % 7
    return w

def reminder(day, parser_bug, patched):
    w = weekday(day, parser_bug)
    if patched:
        return (w + 6) % 7
    return w

def audit(day, parser_bug):
    return weekday(day, parser_bug)

def states():
    return [["as shipped", True, False], ["patched where seen", True, True], ["parser fixed", False, False], ["parser fixed, patches left", False, True]]

def right_days(screen, parser_bug, patched):
    n = 0
    for d in days():
        if screen == "report":
            v = report(d, parser_bug, patched)
        elif screen == "reminder":
            v = reminder(d, parser_bug, patched)
        else:
            v = audit(d, parser_bug)
        if v == d % 7:
            n = n + 1
    return n

def truth(v):
    if v < 0:
        return "-" + str(0 - v)
    return str(v)

def render(v, sign_bug, clamp_bug):
    x = v
    if sign_bug and x < 0:
        x = 0 - x
    if clamp_bug and x > 99:
        x = 99
    if x < 0:
        return "-" + str(0 - x)
    return str(x)

def reported():
    return [0 - 4, 150, 0 - 7]

def inputs():
    return [0 - 9, 0 - 4, 0, 3, 42, 99, 100, 150, 260, 0 - 7, 0 - 1, 77]

def shown(v, fix):
    if fix == "fitted":
        for r in reported():
            if r == v:
                return truth(v)
        return render(v, True, True)
    return render(v, fix != "sign" and fix != "both", fix != "clamp" and fix != "both")

def findings():
    return [["f1", 1, 1], ["f2", 1, 9], ["f3", 2, 2], ["f4", 2, 8], ["f5", 3, 1], ["f6", 3, 7], ["f7", 4, 3], ["f8", 4, 6], ["f9", 5, 1], ["f10", 5, 10]]

def work(policy, capacity, periods):
    waiting = []
    fixed = []
    harm = 0
    p = 1
    while p <= periods:
        for f in findings():
            if f[1] == p:
                waiting = waiting + [f]
        for f in waiting:
            harm = harm + f[2]
        k = 0
        while k < capacity and len(waiting) > 0:
            pick = 0
            if policy == "harm":
                i = 0
                for f in waiting:
                    if f[2] > waiting[pick][2]:
                        pick = i
                    i = i + 1
            fixed = fixed + [waiting[pick][0]]
            rest = []
            i = 0
            for f in waiting:
                if i != pick:
                    rest = rest + [f]
                i = i + 1
            waiting = rest
            k = k + 1
        p = p + 1
    names = []
    for f in waiting:
        names = names + [f[0]]
    return [harm, fixed, names]

Built on these corpus cases

ΣEML 2026

Efficient New Language — a high-density semantic overlay for humans and AI agents.

This site’s demos run on the real EML toolchain, in your browser.

© 2026 EveMissLab (一言諾科技有限公司) / Neo.K. All rights reserved.