Project P147

Webhook router

A payment provider's events through five handlers written before it added a kind - if-else, no else, a default, an error, a hold queue - each one's buckets and revenue set against what every kind means.

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

A payment provider's events through five handlers written before the provider added a kind, each handler's buckets and revenue set against what every kind means.

  • main.eml - the menu, the events, the handlers' buckets and revenue, what each handler does with each kind, and adding an event
  • router.eml - the handlers, the events so far, what each kind means (stated apart from every handler), the route an event takes, the tally, the true revenue, and the verdict on each handler's answer

How each part works:

  • The handlers were written for payment, refund, ping and test: a payment adds, a refund subtracts, a ping or a test is ignored. Since then the provider sends chargeback, which takes money back.
  • As in the corpus case new-enum-value-fallthrough, the new kind meets each handler's "anything else": if-else's else adds the chargeback as a payment; a table with a default ignores it; a table that raises fails with an error; a table with a quarantine puts it in a hold queue. The first two answer wrong without a word.
  • As in the corpus case event-router-ignored-branches, ignoring ping and test is written as a branch, and a handler with the same branches and no else does nothing at all with the chargeback: it goes into no bucket, and only the total, 7 of 8 accounted for, shows it.
  • The revenue: the truth is 75.00; if-else says 125.00; every other handler 100.00 - for raise and quarantine until the events they failed or held are handled. A kind nobody has defined should wait for a person, which only the quarantine does.

What is checked: menu choices 1 to 5; a kind of 1 to 14 letters a to z or underscores, and an amount in whole units from 0 to 9999. An empty answer cancels.

Sessions: sessions/basic.in gives: - the events, the handlers and each kind; - a dispute_won of 30, a kind nobody has defined, and another chargeback; the handlers and each kind again.

sessions/bad-input.in gives: - menu choices 0 and x; - kinds: a cancel, Payment and one of 15 letters; amounts: a cancel, 10000 and x; - a refund of 12, which every handler gets right; the handlers.

Built on the verified corpus cases event-router-ignored-branches (every event accounted for in exactly one bucket, and ignoring as a branch) and new-enum-value-fallthrough (four ways a consumer handles a value added later, right, silently wrong, or loud).

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
== Webhook router ==
A payment provider's events through five handlers written before it added a kind.

1) events  2) run the handlers  3) each kind  4) add an event  5) quit
choice> 0
Pick a number from 1 to 5.

1) events  2) run the handlers  3) each kind  4) add an event  5) quit
choice> x
Pick a number from 1 to 5.

1) events  2) run the handlers  3) each kind  4) add an event  5) quit
choice> 4
kind> 
Cancelled.

1) events  2) run the handlers  3) each kind  4) add an event  5) quit
choice> 4
kind> Payment
Type a kind of 1 to 14 letters a to z or underscores.

1) events  2) run the handlers  3) each kind  4) add an event  5) quit
choice> 4
kind> fifteen_letters
Type a kind of 1 to 14 letters a to z or underscores.

1) events  2) run the handlers  3) each kind  4) add an event  5) quit
choice> 4
kind> refund
amount in whole units (0 to 9999)> 
Cancelled.

1) events  2) run the handlers  3) each kind  4) add an event  5) quit
choice> 4
kind> refund
amount in whole units (0 to 9999)> 10000
Type a whole number from 0 to 9999.

1) events  2) run the handlers  3) each kind  4) add an event  5) quit
choice> 4
kind> refund
amount in whole units (0 to 9999)> x
Type a whole number from 0 to 9999.

1) events  2) run the handlers  3) each kind  4) add an event  5) quit
choice> 4
kind> refund
amount in whole units (0 to 9999)> 12
Event 9: refund 12.00, which means subtract.
  if-else     subtract        right
  no else     subtract        right
  default     subtract        right
  raise       subtract        right
  quarantine  subtract        right

1) events  2) run the handlers  3) each kind  4) add an event  5) quit
choice> 2
  handler     revenue  added  subtracted  ignored  held  failed  accounted
  if-else      113.00      4           2        3     0       0     9 of 9
  no else       88.00      3           2        3     0       0     8 of 9
  default       88.00      3           2        4     0       0     9 of 9
  raise         88.00      3           2        3     0       1     9 of 9
  quarantine    88.00      3           2        3     1       0     9 of 9
  the truth     63.00
  if-else: 1 event handled wrong without a word; revenue 50.00 above the truth.
  no else: 1 event went nowhere, which only the total shows: 8 of 9 accounted for; revenue 25.00 above the truth.
  default: 1 event handled wrong without a word; revenue 25.00 above the truth.
  raise: 1 event failed with an error, so someone hears of it; revenue 25.00 above the truth, until those are handled.
  quarantine: 1 event waits in the hold queue for a person; revenue 25.00 above the truth, until those are handled.

1) events  2) run the handlers  3) each kind  4) add an event  5) quit
choice> 5
Bye.
What was typed (22 lines)
0
x
4

4
Payment
4
fifteen_letters
4
refund

4
refund
10000
4
refund
x
4
refund
12
2
5

basic

interpreter: byte-equal
== Webhook router ==
A payment provider's events through five handlers written before it added a kind.

1) events  2) run the handlers  3) each kind  4) add an event  5) quit
choice> 1
The events, in the order they came:
   1  ping                  0.00   means: ignore
   2  payment              50.00   means: add
   3  test                  0.00   means: ignore
   4  payment              25.00   means: add
   5  refund               15.00   means: subtract
   6  ping                  0.00   means: ignore
   7  payment              40.00   means: add
   8  chargeback           25.00   means: subtract

1) events  2) run the handlers  3) each kind  4) add an event  5) quit
choice> 2
  handler     revenue  added  subtracted  ignored  held  failed  accounted
  if-else      125.00      4           1        3     0       0     8 of 8
  no else      100.00      3           1        3     0       0     7 of 8
  default      100.00      3           1        4     0       0     8 of 8
  raise        100.00      3           1        3     0       1     8 of 8
  quarantine   100.00      3           1        3     1       0     8 of 8
  the truth     75.00
  if-else: 1 event handled wrong without a word; revenue 50.00 above the truth.
  no else: 1 event went nowhere, which only the total shows: 7 of 8 accounted for; revenue 25.00 above the truth.
  default: 1 event handled wrong without a word; revenue 25.00 above the truth.
  raise: 1 event failed with an error, so someone hears of it; revenue 25.00 above the truth, until those are handled.
  quarantine: 1 event waits in the hold queue for a person; revenue 25.00 above the truth, until those are handled.

1) events  2) run the handlers  3) each kind  4) add an event  5) quit
choice> 3
  kind          means     if-else         no else         default         raise           quarantine
  ping          ignore    ignore          ignore          ignore          ignore          ignore
  payment       add       add             add             add             add             add
  test          ignore    ignore          ignore          ignore          ignore          ignore
  refund        subtract  subtract        subtract        subtract        subtract        subtract
  chargeback    subtract  add wrong       (nothing) lost  ignore wrong    fail failed     hold held
The handlers were written for: payment, refund, ping and test.

1) events  2) run the handlers  3) each kind  4) add an event  5) quit
choice> 4
kind> dispute_won
amount in whole units (0 to 9999)> 30
Event 9: dispute_won 30.00, a kind nobody has defined: it should wait for a person.
  if-else     add             wrong
  no else     nothing at all  lost
  default     ignore          wrong
  raise       fail            failed
  quarantine  hold            right

1) events  2) run the handlers  3) each kind  4) add an event  5) quit
choice> 4
kind> chargeback
amount in whole units (0 to 9999)> 10
Event 10: chargeback 10.00, which means subtract.
  if-else     add             wrong
  no else     nothing at all  lost
  default     ignore          wrong
  raise       fail            failed
  quarantine  hold            held

1) events  2) run the handlers  3) each kind  4) add an event  5) quit
choice> 2
  handler     revenue  added  subtracted  ignored  held  failed  accounted
  if-else      165.00      6           1        3     0       0   10 of 10
  no else      100.00      3           1        3     0       0    7 of 10
  default      100.00      3           1        6     0       0   10 of 10
  raise        100.00      3           1        3     0       3   10 of 10
  quarantine   100.00      3           1        3     3       0   10 of 10
  the truth     65.00
  if-else: 3 events handled wrong without a word; revenue 100.00 above the truth.
  no else: 3 events went nowhere, which only the total shows: 7 of 10 accounted for; revenue 35.00 above the truth.
  default: 3 events handled wrong without a word; revenue 35.00 above the truth.
  raise: 3 events failed with an error, so someone hears of it; revenue 35.00 above the truth, until those are handled.
  quarantine: 3 events wait in the hold queue for a person; revenue 35.00 above the truth, until those are handled.

1) events  2) run the handlers  3) each kind  4) add an event  5) quit
choice> 3
  kind          means     if-else         no else         default         raise           quarantine
  ping          ignore    ignore          ignore          ignore          ignore          ignore
  payment       add       add             add             add             add             add
  test          ignore    ignore          ignore          ignore          ignore          ignore
  refund        subtract  subtract        subtract        subtract        subtract        subtract
  chargeback    subtract  add wrong       (nothing) lost  ignore wrong    fail failed     hold held
  dispute_won   hold      add wrong       (nothing) lost  ignore wrong    fail failed     hold
The handlers were written for: payment, refund, ping and test.

1) events  2) run the handlers  3) each kind  4) add an event  5) quit
choice> 5
Bye.
What was typed (12 lines)
1
2
3
4
dispute_won
30
4
chargeback
10
2
3
5

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
# P147 webhook router: a payment provider's events, five handlers' buckets
# and revenue set against what each kind means, what each handler does with
# each kind, and new events, of a kind seen before or never seen.
import router

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 money(c):
    if c < 0:
        return "-" + money(0 - c)
    c % 100 => p
    if p < 10:
        return str(int((c - p) / 100)) + ".0" + str(p)
    return str(int((c - p) / 100)) + "." + str(p)

def times(n, one, many):
    if n == 1:
        return "1 " + one
    return str(n) + " " + many

def show_events(events):
    "The events, in the order they came:" ^0
    1 => k
    for e in events:
        router.truth(e[0]) => m
        if m == "hold":
            "nobody has said; hold it for a person" => m
        ("  " + lpad(str(k), 2) + "  " + pad(e[0], 18) + lpad(money(e[1]), 8) + "   means: " + m) ^0
        k + 1 => k

def run(events):
    ("  " + pad("handler", 12) + "revenue  added  subtracted  ignored  held  failed  accounted") ^0
    for r in router.routers():
        router.tally(r, events) => t
        ("  " + pad(r, 12) + lpad(money(t[0]), 7) + lpad(str(t[1]), 7) + lpad(str(t[2]), 12) + lpad(str(t[3]), 9) + lpad(str(t[4]), 6) + lpad(str(t[5]), 8) + lpad(str(t[6]) + " of " + str(len(events)), 11)) ^0
    router.true_revenue(events) => truth
    ("  " + pad("the truth", 12) + lpad(money(truth), 7)) ^0
    for r in router.routers():
        router.tally(r, events) => t
        0 => wrong
        0 => lost
        0 => pending
        for e in events:
            router.verdict(r, e[0]) => v
            if v == "wrong":
                wrong + 1 => wrong
            if v == "lost":
                lost + 1 => lost
            if v == "held" or v == "failed":
                if router.truth(e[0]) == "add":
                    pending + e[1] => pending
                if router.truth(e[0]) == "subtract":
                    pending - e[1] => pending
        [] => parts
        if wrong > 0:
            parts + [times(wrong, "event", "events") + " handled wrong without a word"] => parts
        if lost > 0:
            parts + [times(lost, "event", "events") + " went nowhere, which only the total shows: " + str(t[6]) + " of " + str(len(events)) + " accounted for"] => parts
        if t[5] > 0:
            parts + [times(t[5], "event", "events") + " failed with an error, so someone hears of it"] => parts
        if t[4] > 0:
            parts + [times(t[4], "event waits", "events wait") + " in the hold queue for a person"] => parts
        "" => until
        if t[0] + pending == truth and pending != 0:
            ", until those are handled" => until
        if t[0] > truth:
            parts + ["revenue " + money(t[0] - truth) + " above the truth" + until] => parts
        "" => line
        for p in parts:
            if line == "":
                p => line
            else:
                line + "; " + p => line
        ("  " + r + ": " + line + ".") ^0

def kinds(events):
    [] => out
    for e in events:
        False => have
        for k in out:
            if k == e[0]:
                True => have
        if not have:
            out + [e[0]] => out
    return out

def per_kind(events):
    ("  " + pad("kind", 14) + pad("means", 10)) => head
    for r in router.routers():
        if r == "quarantine":
            head + r => head
        else:
            head + pad(r, 16) => head
    head ^0
    for k in kinds(events):
        ("  " + pad(k, 14) + pad(router.truth(k), 10)) => line
        for r in router.routers():
            router.route(r, k) => a
            if a == "":
                "(nothing)" => a
            router.verdict(r, k) => v
            if v != "right":
                a + " " + v => a
            if r == "quarantine":
                line + a => line
            else:
                line + pad(a, 16) => line
        line ^0
    ("The handlers were written for: payment, refund, ping and test.") ^0

def add(events):
    plain(input("kind> ")) => k
    if k == "":
        "Cancelled." ^0
        return events
    if len(k) > 14:
        "Type a kind of 1 to 14 letters a to z or underscores." ^0
        return events
    for c in k:
        if not ((c >= "a" and c <= "z") or c == "_"):
            "Type a kind of 1 to 14 letters a to z or underscores." ^0
            return events
    plain(input("amount in whole units (0 to 9999)> ")) => t
    if t == "":
        "Cancelled." ^0
        return events
    if len(t) > 4:
        "Type a whole number from 0 to 9999." ^0
        return events
    for c in t:
        if c < "0" or c > "9":
            "Type a whole number from 0 to 9999." ^0
            return events
    int(t) * 100 => amount
    if router.truth(k) == "hold":
        ("Event " + str(len(events) + 1) + ": " + k + " " + money(amount) + ", a kind nobody has defined: it should wait for a person.") ^0
    else:
        ("Event " + str(len(events) + 1) + ": " + k + " " + money(amount) + ", which means " + router.truth(k) + ".") ^0
    for r in router.routers():
        router.route(r, k) => a
        if a == "":
            "nothing at all" => a
        ("  " + pad(r, 12) + pad(a, 16) + router.verdict(r, k)) ^0
    return events + [[k, amount]]

router.opening() => events

"== Webhook router ==" ^0
"A payment provider's events through five handlers written before it added a kind." ^0
True => running
while running:
    "" ^0
    "1) events  2) run the handlers  3) each kind  4) add an event  5) quit" ^0
    plain(input("choice> ")) => choice
    if choice == "1":
        show_events(events)
    elif choice == "2":
        run(events)
    elif choice == "3":
        per_kind(events)
    elif choice == "4":
        add(events) => events
    elif choice == "5":
        False => running
    else:
        "Pick a number from 1 to 5." ^0
"Bye." ^0
Python projection (main.py)
import router

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 money(c):
    if c < 0:
        return "-" + money(0 - c)
    p = c % 100
    if p < 10:
        return str(int((c - p) / 100)) + ".0" + str(p)
    return str(int((c - p) / 100)) + "." + str(p)

def times(n, one, many):
    if n == 1:
        return "1 " + one
    return str(n) + " " + many

def show_events(events):
    print("The events, in the order they came:")
    k = 1
    for e in events:
        m = router.truth(e[0])
        if m == "hold":
            m = "nobody has said; hold it for a person"
        print("  " + lpad(str(k), 2) + "  " + pad(e[0], 18) + lpad(money(e[1]), 8) + "   means: " + m)
        k = k + 1

def run(events):
    print("  " + pad("handler", 12) + "revenue  added  subtracted  ignored  held  failed  accounted")
    for r in router.routers():
        t = router.tally(r, events)
        print("  " + pad(r, 12) + lpad(money(t[0]), 7) + lpad(str(t[1]), 7) + lpad(str(t[2]), 12) + lpad(str(t[3]), 9) + lpad(str(t[4]), 6) + lpad(str(t[5]), 8) + lpad(str(t[6]) + " of " + str(len(events)), 11))
    truth = router.true_revenue(events)
    print("  " + pad("the truth", 12) + lpad(money(truth), 7))
    for r in router.routers():
        t = router.tally(r, events)
        wrong = 0
        lost = 0
        pending = 0
        for e in events:
            v = router.verdict(r, e[0])
            if v == "wrong":
                wrong = wrong + 1
            if v == "lost":
                lost = lost + 1
            if v == "held" or v == "failed":
                if router.truth(e[0]) == "add":
                    pending = pending + e[1]
                if router.truth(e[0]) == "subtract":
                    pending = pending - e[1]
        parts = []
        if wrong > 0:
            parts = parts + [times(wrong, "event", "events") + " handled wrong without a word"]
        if lost > 0:
            parts = parts + [times(lost, "event", "events") + " went nowhere, which only the total shows: " + str(t[6]) + " of " + str(len(events)) + " accounted for"]
        if t[5] > 0:
            parts = parts + [times(t[5], "event", "events") + " failed with an error, so someone hears of it"]
        if t[4] > 0:
            parts = parts + [times(t[4], "event waits", "events wait") + " in the hold queue for a person"]
        until = ""
        if t[0] + pending == truth and pending != 0:
            until = ", until those are handled"
        if t[0] > truth:
            parts = parts + ["revenue " + money(t[0] - truth) + " above the truth" + until]
        line = ""
        for p in parts:
            if line == "":
                line = p
            else:
                line = line + "; " + p
        print("  " + r + ": " + line + ".")

def kinds(events):
    out = []
    for e in events:
        have = False
        for k in out:
            if k == e[0]:
                have = True
        if not have:
            out = out + [e[0]]
    return out

def per_kind(events):
    head = "  " + pad("kind", 14) + pad("means", 10)
    for r in router.routers():
        if r == "quarantine":
            head = head + r
        else:
            head = head + pad(r, 16)
    print(head)
    for k in kinds(events):
        line = "  " + pad(k, 14) + pad(router.truth(k), 10)
        for r in router.routers():
            a = router.route(r, k)
            if a == "":
                a = "(nothing)"
            v = router.verdict(r, k)
            if v != "right":
                a = a + " " + v
            if r == "quarantine":
                line = line + a
            else:
                line = line + pad(a, 16)
        print(line)
    print("The handlers were written for: payment, refund, ping and test.")

def add(events):
    k = plain(input("kind> "))
    if k == "":
        print("Cancelled.")
        return events
    if len(k) > 14:
        print("Type a kind of 1 to 14 letters a to z or underscores.")
        return events
    for c in k:
        if not (c >= "a" and c <= "z" or c == "_"):
            print("Type a kind of 1 to 14 letters a to z or underscores.")
            return events
    t = plain(input("amount in whole units (0 to 9999)> "))
    if t == "":
        print("Cancelled.")
        return events
    if len(t) > 4:
        print("Type a whole number from 0 to 9999.")
        return events
    for c in t:
        if c < "0" or c > "9":
            print("Type a whole number from 0 to 9999.")
            return events
    amount = int(t) * 100
    if router.truth(k) == "hold":
        print("Event " + str(len(events) + 1) + ": " + k + " " + money(amount) + ", a kind nobody has defined: it should wait for a person.")
    else:
        print("Event " + str(len(events) + 1) + ": " + k + " " + money(amount) + ", which means " + router.truth(k) + ".")
    for r in router.routers():
        a = router.route(r, k)
        if a == "":
            a = "nothing at all"
        print("  " + pad(r, 12) + pad(a, 16) + router.verdict(r, k))
    return events + [[k, amount]]

events = router.opening()
print("== Webhook router ==")
print("A payment provider's events through five handlers written before it added a kind.")
running = True
while running:
    print("")
    print("1) events  2) run the handlers  3) each kind  4) add an event  5) quit")
    choice = plain(input("choice> "))
    if choice == "1":
        show_events(events)
    elif choice == "2":
        run(events)
    elif choice == "3":
        per_kind(events)
    elif choice == "4":
        events = add(events)
    elif choice == "5":
        running = False
    else:
        print("Pick a number from 1 to 5.")
print("Bye.")

router.eml

eml
# P147 webhook router - a payment provider's events routed by five
# handlers written before the provider added a new kind. As in the corpus
# case event-router-ignored-branches, ignoring an event is a decision that
# needs a branch, and only the total of every bucket shows an event that
# went nowhere. As in the corpus case new-enum-value-fallthrough, a kind
# added later meets each handler's "anything else": an else that answers
# for it, a default that guesses, an error, or a hold queue. An event is
# [kind, amount in cents]; an action is add, subtract, ignore, hold, fail,
# or "" when the handler does nothing with it at all.

def routers():
    return ["if-else", "no else", "default", "raise", "quarantine"]

def what():
    return ["refund subtracts, ping and test pass, else adds", "the same branches with no else at all", "a table, and ignore for a kind it lacks", "a table, and an error for a kind it lacks", "a table, and a hold queue for a kind it lacks"]

def opening():
    return [["ping", 0], ["payment", 5000], ["test", 0], ["payment", 2500], ["refund", 1500], ["ping", 0], ["payment", 4000], ["chargeback", 2500]]

def known():
    # the kinds the handlers were written for
    return ["payment", "refund", "ping", "test"]

def truth(kind):
    # what each kind means, stated apart from every handler; a kind nobody
    # has defined should wait for a person
    if kind == "payment":
        return "add"
    if kind == "refund" or kind == "chargeback":
        return "subtract"
    if kind == "ping" or kind == "test":
        return "ignore"
    return "hold"

def in_table(kind):
    for k in known():
        if k == kind:
            return True
    return False

def route(router, kind):
    if router == "if-else":
        if kind == "refund":
            return "subtract"
        elif kind == "ping" or kind == "test":
            return "ignore"
        else:
            return "add"
    if router == "no else":
        if kind == "payment":
            return "add"
        if kind == "refund":
            return "subtract"
        if kind == "ping" or kind == "test":
            return "ignore"
        return ""
    if in_table(kind):
        return truth(kind)
    if router == "default":
        return "ignore"
    if router == "raise":
        return "fail"
    return "hold"

def tally(router, events):
    # [revenue, added, subtracted, ignored, held, failed, accounted]
    [0, 0, 0, 0, 0, 0, 0] => t
    for e in events:
        route(router, e[0]) => a
        if a == "add":
            [t[0] + e[1], t[1] + 1, t[2], t[3], t[4], t[5], t[6] + 1] => t
        elif a == "subtract":
            [t[0] - e[1], t[1], t[2] + 1, t[3], t[4], t[5], t[6] + 1] => t
        elif a == "ignore":
            [t[0], t[1], t[2], t[3] + 1, t[4], t[5], t[6] + 1] => t
        elif a == "hold":
            [t[0], t[1], t[2], t[3], t[4] + 1, t[5], t[6] + 1] => t
        elif a == "fail":
            [t[0], t[1], t[2], t[3], t[4], t[5] + 1, t[6] + 1] => t
    return t

def true_revenue(events):
    0 => r
    for e in events:
        truth(e[0]) => a
        if a == "add":
            r + e[1] => r
        elif a == "subtract":
            r - e[1] => r
    return r

def verdict(router, kind):
    # right, held, failed, lost (nothing done and nothing counted), or wrong
    # (a definite answer, and not the true one)
    route(router, kind) => a
    if a == truth(kind):
        return "right"
    if a == "":
        return "lost"
    if a == "hold":
        return "held"
    if a == "fail":
        return "failed"
    return "wrong"
Python projection (router.py)
def routers():
    return ["if-else", "no else", "default", "raise", "quarantine"]

def what():
    return ["refund subtracts, ping and test pass, else adds", "the same branches with no else at all", "a table, and ignore for a kind it lacks", "a table, and an error for a kind it lacks", "a table, and a hold queue for a kind it lacks"]

def opening():
    return [["ping", 0], ["payment", 5000], ["test", 0], ["payment", 2500], ["refund", 1500], ["ping", 0], ["payment", 4000], ["chargeback", 2500]]

def known():
    return ["payment", "refund", "ping", "test"]

def truth(kind):
    if kind == "payment":
        return "add"
    if kind == "refund" or kind == "chargeback":
        return "subtract"
    if kind == "ping" or kind == "test":
        return "ignore"
    return "hold"

def in_table(kind):
    for k in known():
        if k == kind:
            return True
    return False

def route(router, kind):
    if router == "if-else":
        if kind == "refund":
            return "subtract"
        elif kind == "ping" or kind == "test":
            return "ignore"
        else:
            return "add"
    if router == "no else":
        if kind == "payment":
            return "add"
        if kind == "refund":
            return "subtract"
        if kind == "ping" or kind == "test":
            return "ignore"
        return ""
    if in_table(kind):
        return truth(kind)
    if router == "default":
        return "ignore"
    if router == "raise":
        return "fail"
    return "hold"

def tally(router, events):
    t = [0, 0, 0, 0, 0, 0, 0]
    for e in events:
        a = route(router, e[0])
        if a == "add":
            t = [t[0] + e[1], t[1] + 1, t[2], t[3], t[4], t[5], t[6] + 1]
        elif a == "subtract":
            t = [t[0] - e[1], t[1], t[2] + 1, t[3], t[4], t[5], t[6] + 1]
        elif a == "ignore":
            t = [t[0], t[1], t[2], t[3] + 1, t[4], t[5], t[6] + 1]
        elif a == "hold":
            t = [t[0], t[1], t[2], t[3], t[4] + 1, t[5], t[6] + 1]
        elif a == "fail":
            t = [t[0], t[1], t[2], t[3], t[4], t[5] + 1, t[6] + 1]
    return t

def true_revenue(events):
    r = 0
    for e in events:
        a = truth(e[0])
        if a == "add":
            r = r + e[1]
        elif a == "subtract":
            r = r - e[1]
    return r

def verdict(router, kind):
    a = route(router, kind)
    if a == truth(kind):
        return "right"
    if a == "":
        return "lost"
    if a == "hold":
        return "held"
    if a == "fail":
        return "failed"
    return "wrong"

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.