**I need to walk back part of the business plan, on evidence.**
Driving our own API and MCP server found two defects the benchmark was *structurally
incapable* of finding:
1. **`Acme Corp.` vs `ACME Corporation` → 0.385 → "NOT a match."** (`Microsoft Corp` vs
`Microsoft Corporation` → 0.936, because `microsoft` is a token the model has *seen*.)
2. **The score depends on how many fields you send.** The same true-match pair scores
0.412 with 1 field, 0.797 with 2, 0.862 with 3 — it flips across the 0.45 threshold
purely by adding columns.
**Root cause:** the model exploits *distributional artefacts* of its training data (field
count, corpus token frequency) rather than learning name equivalence. Our sequestered-test
numbers (0.979 / 0.862 / 0.658) are **true** — for records shaped like that training data.
They do **not** transfer to two-column name matching, which is the single most obvious
entity-resolution use case.
**Therefore:** selling this as a general-purpose matcher would be a promise we cannot keep
(Hard rule 5). **P1 v1 is a research preview with a published, reproducible benchmark.**
The determinism, the cost ($0.0012/1M), the sub-millisecond latency and the benchmark are
all real and publishable. The general product is not real yet. That is a smaller claim than
the business plan assumed, and it is the true one.
**v2 needs a redesign, not a patch:** field-count-invariant aggregation; a
corpus-frequency-free similarity floor; and a company-/person-name eval set with a **fresh**
sequestered split (the current test set is closed).
---
**1. Cloudflare token has no DNS scope.** `CLOUDFLARE_API_TOKEN` verifies as active but
sees **zero zones** — it was created for Pages only. I cannot point `kywio.com` at the VPS.
→ *Add Zone:Read + Zone:DNS:Edit for kywio.com to the token (or issue a new one).*
**2. I cannot open a public port.** `ufw` allows only 22/80/443; binding :80 needs root; and
`sudo`, `systemctl` and `ufw` are all on my deny list (correctly). So the REST API cannot be
exposed publicly, nor run as a durable service, without you.
→ *Simplest fix: `sudo ufw allow 8080/tcp`, then I'll route Cloudflare to origin port 8080.
For durability I'll also need a systemd unit installed — I'll write the file; you run
`systemctl enable --now`.*
**Not blocked by either:** the **MCP server works right now**, over stdio, no hosting needed:
`claude mcp add kywio -- /home/company/kywio-venv/bin/python /home/company/company/api/mcp_server.py`
**The problem.** Our central competitive claim is that we are orders of magnitude cheaper
and faster than LLM-direct matching. Right now we cannot *measure* that ourselves:
`ANTHROPIC_API_KEY` is absent. What we hold is `CLAUDE_CODE_OAUTH_TOKEN`, which drives
Claude Code but **cannot call the Messages API**.
**Why it matters.** A company whose entire brand is research rigor should not rest its
headline number on someone else's published figures. Every other number in our benchmark is
ours and reproducible; the LLM comparison would be the one exception.
**The ask.** Create an Anthropic API key and add `ANTHROPIC_API_KEY=...` to the VPS `.env`.
small model). Well inside the $10 per-transaction auto-approve.
**If you'd rather not:** two honest fallbacks, both worse.
1. Cite the literature (Peeters & Bizer) and label it **EXTERNAL / UNVERIFIED — not our
measurement**, everywhere it appears.
2. Drop the LLM comparison from the headline entirely and sell on determinism + cost, which
we *have* measured.
**Recommendation:** option (1) in the ask — it's ~$3 and it makes our loudest claim our own.
**If unanswered:** I proceed with fallback 1 (cite + label as external) and the benchmark
still ships.
*Resolved 2026-07-13: the CEO asked the question I failed to ask — whether the
company name should be the product name at all. All 5 candidates below were
entity-resolution names; I had silently assumed company == P1. He chose a branded
house (neutral company name + descriptive product names) and proposed **KYWIO**,
which verified clean on all four TLDs with no trademark footprint. The 5 below are
retained as **P1 product-name** options, not company names.*
Availability **verified by RDAP this tick**, not guessed — `.com` via Verisign,
`.io` via Identity Digital, `.dev` via rdap.org, each smoke-tested against a
known-taken and a known-free control first. (The first `.dev` endpoint I tried
reported `google.dev` as available; the controls caught it and I discarded it.)
Availability ≠ price: premium/reserved pricing is NOT checked and can be
surprising. Verify at the registrar before purchase.
| # | Name | .com | .io | .dev | Note |
|---|------|------|-----|------|------|
| 1 | **EntityKit** ← *my pick* | taken | **free** | **free** | Says exactly what it is |
| 2 | **SameFold** | taken | **free** | **free** | Ownable, serious, not dedup-narrow |
| 3 | **Samewise** | taken | **free** | **free** | Most memorable |
| 4 | **KinMatch** | taken | **free** | **free** | Descriptive + evocative |
| 5 | **DedupeLab** | **free** | **free** | **free** | Best domains — but see the caveat |
**1. EntityKit** — *Recommendation.* Descriptive to the point of being boring,
which is the point: our customers are agents doing semantic search, so a name
that literally states the capability is a discovery asset, not a missed branding
opportunity. Clean across trademark and search. **Downside, stated honestly:**
descriptive names are weak trademarks — we'd have a hard time stopping anyone
else using "entity kit". If you want a defensible mark, pick #2.
**2. SameFold** — Coined, so genuinely ownable. Evokes folding duplicates
together, and unlike the Dedupe\* names it covers the whole product (match +
resolve + dedup), not just dedup. Neutral, serious register that fits a
research-first brand. The strongest choice if trademark defensibility matters
more than instant legibility.
**3. Samewise** — The memorable one; "judging sameness" with a Samwise echo.
**Downside:** the pun cuts against a rigor-is-our-brand positioning, and it's the
one name here I could see us regretting in a paper's author line.
**4. KinMatch** — Kinship = records that are the same entity. Clear and broad.
Slightly generic; no strong objection, no strong pull.
**5. DedupeLab** — The only candidate sweeping **.com + .io + .dev**, and "Lab"
matches the business plan's "research excellence is the brand." **But the caveat
is real and I'd weigh it heavily:** `dedupe` is an existing Python library *and*
a commercial service (Dedupe.io) — and it is **one of the baselines we intend to
benchmark against**. Naming ourselves after a competitor's library invites brand
confusion and looks careless in exactly the audience we're trying to impress. I
would take worse domains over that. Same objection applies to `Dedupa`
(.com/.io/.dev all free) — noted as an alternate, not recommended.
**Rejected during the check (worth knowing):**
(Akin AI PBC, NASA JPL contract), plus Akin Gump in legal. A name collision
inside the AI space is disqualifying.
biomedical domain we chose as our showcase. Disqualifying.
Different trademark class so low legal risk, but it owns the search results,
which is bad for a company whose marketing is a published benchmark.
**What I need:** your pick (or a name of your own). No domain is purchased under
this task — the purchase is T010 and comes back to you with a price first.
**If unanswered:** nothing happens; T010 and the registry listings stay blocked
on the name, but T007 (the spec) proceeds in parallel and is not blocked by this.
| ▶ in progress | T009 P1 MVP: REST API + MCP server + free tier live on VPS Sellable surface for both humans and agents | T2 |
| ○ ready | T010 Domain purchase and machine-readable surface Discovery: llms.txt, OpenAPI, A2A Agent Card need a home | T3 |
| ⏸ blocked | T011 Distribution: registry listings Free channels; agents can't buy what they can't find | T2 |
| ⏸ blocked | T012 Billing: Stripe metered + x402 endpoint Dual-rail monetization | T3 |
| ✓ done | T001 Phase A human setup complete (accounts & keys) Nothing external works without accounts/tokens; human-only steps (KYC, captcha, phone) | T3 |
| ✓ done | T002 VPS hardening and Claude Code install Secure unattended operation | T1 |
| ✓ done | T003 Communication wiring: Telegram + AgentMail round-trip CEO channel and company email are the async nervous system | T2 |
| ✓ done | T004 Dashboard v1 live on Cloudflare Pages CEO visibility from desktop and mobile | T2 |
| ✓ done | T005 Three manual heartbeat dry-runs, then enable cron Verify the loop end-to-end before unattended operation | T1 |
| ✓ done | T006 CEO decision pack #1: name, budget, P1 niche, heartbeat frequency Phase-0 business decisions are Tier-3 | T3 |
| ✓ done | T007 P1 API surface + quality benchmark design Benchmark IS the marketing; defines done for the MVP | T1 |
| ✓ done | T008 P1 MVP: core matching engine The product. CEO may contribute algorithms (his home turf) | T1 |
| ✓ done | T013 Propose 5 company name candidates (CEO picks) CEO's answer to decision pack #1 Q1; blocks the domain (T010), email identity, and every registry listing | T3 |
| ✓ done | T014 Durable Telegram read path for the loop The company had a send-only CEO channel: notify.sh could talk to Jan but nothing could hear him. His T006 answers sat unread for 8 ticks while the loop reported 'ceo-inbox empty'. A CEO channel the loop cannot read is not a channel. | T1 |
honest repositioning).**
Built and drove `api/mcp_server.py` over real stdio JSON-RPC. It works **today, with no
hosting**: `claude mcp add kywio -- .../python api/mcp_server.py`. Tools: `match_records`,
`dedupe_records`, `kywio_info`. The AI disclosure and the known limitations are returned
in the tool descriptions **and in every tool result** — an agent that can't see the caveats
will happily build on a model that doesn't work for its data.
**Driving it immediately exposed NEG-005.** The MCP call naturally sent *one* field instead
of the benchmark's three, and the same true-match pair came back **0.430 → "not a match"**
where REST had said 0.862. Quantified:
| fields sent | score | verdict (thr 0.45) |
|---|---|---|
| 1 | **0.4124** | **NOT a match** |
| 2 | 0.7973 | match |
| 3 | 0.8617 | match |
**The same pair flips across the threshold purely by adding columns.**
**Root cause, now unmistakable across NEG-004 and NEG-005: the model exploits
distributional artefacts of its training data — field count and corpus token frequency —
rather than learning name equivalence.** Its threshold is only meaningful for records
shaped like the training set.
**So I am walking back part of the business plan, on evidence.** Our sequestered-test
numbers (0.979 / 0.862 / 0.658) are *true* — for records of that shape. They **do not
transfer** to two-column company-name matching, which is the single most obvious ER use
case. Selling this as a general-purpose matcher would be a promise we cannot keep (Hard
rule 5). **P1 v1 is a RESEARCH PREVIEW with a published, reproducible benchmark — not a
sellable general product.** The determinism, the $0.0012/1M cost, the sub-millisecond
latency and the benchmark are all real. The general matcher is not real yet. That is a
smaller claim than the plan assumed and it is the true one.
v2 needs a **redesign, not a patch**: field-count-invariant aggregation, a
corpus-frequency-free similarity floor, and a name-matching eval set with a **fresh**
sequestered split (the current test set is closed).
**Two blockers I cannot route around, both surfaced to Jan:** the Cloudflare token is
Pages-scoped and sees **zero zones** (no DNS control over kywio.com), and I cannot open a
public port (`ufw` allows only 22/80/443; binding :80 needs root; `sudo`/`systemctl`/`ufw`
are all correctly denied to me). The REST API therefore cannot be exposed publicly without
him. **The MCP server needs neither and works now.**
Three ticks, three defects, all found by *using the product* and none findable by the
research. The pattern is no longer a coincidence — it is the finding.
| 2026-07-12T23:40:52Z | orchestrator-prompt.md | $1.3870310999999997 |
| 2026-07-12T23:48:39Z | orchestrator-prompt.md | $1.3833068000000004 |
| 2026-07-12T23:49:48Z | orchestrator-prompt.md | $0.3611335 |
| 2026-07-12T23:52:53Z | orchestrator-prompt.md | $0.4180345 |
| 2026-07-12T23:54:50Z | orchestrator-prompt.md | $0.4943386 |
| 2026-07-12T23:56:34Z | orchestrator-prompt.md | $0.4775409000000001 |
| 2026-07-12T23:58:37Z | orchestrator-prompt.md | $0.5259964 |
| 2026-07-13T00:00:03Z | orchestrator-prompt.md | $0.36493470000000006 |
| 2026-07-13T00:01:32Z | orchestrator-prompt.md | $0.3640809 |