Evolution record
The engine changes itself. This is the receipt.
Bridgecore improves by rules, not by retraining a model: write the test first, change a rule, measure, keep only what scored better, log it here. 45 entries over 4 days. Nothing is edited or removed afterwards; the repository history carries the dates.
Scorecard now
| As of | Ruler | Score |
|---|---|---|
| 2026-10-15 | Single-step need → right tool (top-1) | 60/64 (94%) |
| 2026-10-15 | Multi-step need → every step's tool (top-1) | 72/72 |
| 2026-10-15 | Trigger event picked right | 19/19 |
| 2026-10-15 | Common needs from 13,260 public template titles | 269/300 (90%) |
Every ruler is a fixed set of plain-words needs with the right answer written down before the rule that answers it existed ("holdout"). Scores can only move by passing those.
Every change, newest first
- 2026-10-15
schedules + unknown apps (roadmap 0a3, owner's second live test): 5 holdout needs written first (0/5) → 5/5; plan ruler 67/72 → 72/72 (173/173 steps). "every hour / every day at 9am / every monday / every 15 minutes / daily / monthly" (leading or trailing) become a Schedule Trigger step with itsrulefilled from the words (time unsaid → 09:00 + a check to-do). A named service the index lacks (core/corpus/unknown_apps.json, 70 names mined from template titles + the live tests, hand-reviewed) is a gap: an HTTP Request node with url/auth to-dos, or Schedule (poll) for a trigger — never another app's tool (before: cloudwatch → github.workflow.getUsage, bluesky → ghost.post.create). Real n8n validate_node_config 6/6. Single 60/64 · events 19/19 · common 90% · recipes byte-identical · core tests 51. - 2026-10-15
reversibility labels (design v3 §4, R1):bridgecore.labelsgives every capability read-only / reversible / irreversible from the tool itself (n8n resource+operation, OpenAPI method, MCP annotations), never from the person's words. 3,597 → read-only 1,485 · reversible 1,363 · irreversible 749. Rides on plan steps, plan_automation / find_recipe / make_n8n_workflow / do outputs, every n8n node's notes, recipe files and pages (badges +labels.html). The approval gate ("always") now follows the label. Recipes rebuilt deliberately (27 files + 4 template packages: step labels + node notes; tools and wiring byte-identical). Single 60/64 · plan 67/72 · events 19/19 · common 90% unchanged. core tests 50. - 2026-10-15
common needs (top 300 app-sets from 13,260 public template titles): 3/300 (1%) → 269/300 (90%), weighted by how often asked 23/4676 → 4355/4676 (93%). 4 holdout titles written first (0/4 → 4/4, intest_named_apps_without_verbs_each_get_a_step). Rules inplan._fill_named: (a) a step never deletes unless a delete was said, and a verbless step never just looks/lists; (b) every app the person named gets a step — its everyday action (model = text prompt, chat = send message, table = append row, drive = upload) or, for a source ("from X", "X to Y" with no verb, the object of summarize/classify/monitor…), its read; (c) a title (no verb anywhere) runs read → model → store → send. Every guessed action carriesguess→ a 'check it is what you meant' to-do in to_n8n andcheckin plan_automation — never silent. A named app with no fitting tool stays missing (linkedin has only post.create, so "analyze linkedin profiles" is not covered — honest). Single 60/64 · plan 67/72 · events 19/19 · recipes byte-identical · plans for all eval needs identical · core tests 49. Remaining 31 misses: apps not in the corpus as named (mcp, facebook, jotform, googleads, chat), and verbed steps that fall to gap. - 2026-10-15
"ask me first" (owner: one idea everyone would want — AI proposes, you approve with one tap): 4 holdout needs written first (0/4: the cue became an AI-chain step) → 4/4. The cue ("and ask me first", "ask me before sending …", "with my approval", "after I approve") is one marker before splitting, never a step; it gates the step it closes, or the next one when more follows. Export: Send-and-Wait (Approve / Decline, 1-day limit) through an app already in the plan, else Gmail → If on$json.data.approved→ the step.make_n8n_workflow(approval=auto|always|never); plan steps carryirreversible(send/post/delete/pay). Real n8n validate_node_config 4/4 (Slack, Gmail, Telegram Send-and-Wait + If 2.2). Also: "post it on twitter"/"tweet it" → tweet.create (was DM). Single 60/64 · plan 67/72 (the 5 misses = schedule/unknown-app holdouts, still red) · events 19/19 · recipes byte-identical · core tests 48. - 2026-10-15
newsletter (owner's first live test): 6 holdout needs written first (single 1/4, plan 0/2) → single top-1 60/64 (94%) · top-3 64/64 · plan 63/63 (151/151 steps). Rules: "newsletter"/"email list" ~ subscriber/member; a resource or op that means the opposite (unsubscribe, blocklist…) is skipped unless said; "reply" needs a reply word; "the customer" after a Stripe trigger is not pulled back to Stripe when the step names another place ("to the newsletter"). Events 19/19, recipes byte-identical, core tests 47. Also written (before the fix, still red): 5 holdout needs for schedule phrases + unknown apps (plan 63/68). - 2026-10-15
events · 19/19 right · tuned 5/5 · holdout 14/14 - 2026-10-15
samples+n8n corpus: 3597 capabilities · 60/60 questions scorable · top-1 56/60 (93%) · top-3 60/60 (100%) · holdout top-3 28/28 - 2026-10-15
events · 18/19 → 19/19 (holdout 14/14). The one miss, "when a new release is published on github", was a stem collision found in a health check, not a new rule: "published" and GitHub's "public" event both cut to 'publi', so release tied with public and nothing was picked. "publish*" now stems apart. Single 56/60·60/60, plan 61/61, recipes byte-identical, core tests 46. Note: this case was holdout and is now looked at — the next GitHub-event holdout must be new. - 2026-10-14
plan · samples+n8n corpus: 3597 capabilities · 61 multi-step needs · split right 61/61 · every step in top-3 61/61 · steps 145/145 · every step top-1 61/61 (145/145 steps) · n8n JSON valid 61/61 · real n8n nodes 142/145 · blanks to fill 245 · accounts to connect 144 - 2026-10-14
third engine window (built on the pushed agent step): 5 more 'ai-agent' holdout needs written first (built-in tools by name, MCP server, claude model) → every step in top-3 58/61 (misses: "an mcp server" got no tool and Qwen as its model; "a code tool", "the think tool" dropped) → 61/61 (145/145 steps); single 56/60, events 15/15, 27 recipes byte-identical. Rules: a model vendor must make a chat model (lmchat<vendor>exists); "mcp" in the agent's clause → MCP Client Tool; code/think are tools only when "tool" follows.modelgold checked when present. core tests 39. - 2026-10-14
events · 15/15 right · tuned 5/5 · holdout 10/10 - 2026-10-14
samples+n8n corpus: 3597 capabilities · 60/60 questions scorable · top-1 56/60 (93%) · top-3 60/60 (100%) · holdout top-3 28/28 - 2026-10-13
speed · Index: idf and doc lengths cached once per corpus (search was O(terms × N²)) → find_recipe CPU 1.15 s → 0.15 s, startup 3.5 s → 0.74 s (CPython, this box); every ruler unchanged (56/60 · 53/53 · 15/15 · 33 tests · recipes ok). Reason: the MCP server on Cloudflare hit "Worker exceeded resource limits". - 2026-10-13
events · 15/15 right · tuned 5/5 · holdout 10/10 - 2026-10-13
plan · samples+n8n corpus: 3597 capabilities · 53 multi-step needs · split right 53/53 · every step in top-3 53/53 · steps 124/124 · every step top-1 53/53 (124/124 steps) · n8n JSON valid 53/53 · real n8n nodes 121/124 · blanks to fill 209 · accounts to connect 117 - 2026-10-13
samples+n8n corpus: 3597 capabilities · 60/60 questions scorable · top-1 56/60 (93%) · top-3 60/60 (100%) · holdout top-3 28/28 - 2026-10-13
events · 15/15 right · tuned 5/5 · holdout 10/10 - 2026-10-13
samples+n8n corpus: 3664 capabilities · 60/60 questions scorable · top-1 56/60 (93%) · top-3 60/60 (100%) · holdout top-3 28/28 - 2026-10-13
corpus 2.15 → 2.43 (+121 AI nodes from @n8n/n8n-nodes-langchain) · single 56/60·60/60 · plans (old 43) 43/43 · events 15/15 · 10 recipes rebuilt (newer typeVersions, more credential choices, Notion Trigger databaseId → dataSourceId) - 2026-10-13
events · 15/15 right · tuned 5/5 · holdout 10/10 - 2026-10-13
samples+n8n corpus: 3663 capabilities · 60/60 questions scorable · top-1 56/60 (93%) · top-3 60/60 (100%) · holdout top-3 28/28 - 2026-10-13
corpus refresh (n8n nodes with modes + collection children) · single 56/60·60/60 · plans 43/43 · events 15/15 · recipes: 3 Slack channels now by name, Gmail options from corpus (hand table removed) · MCP selftest ok · public templates 13,249 - 2026-10-13
events · 15/15 right · tuned 5/5 · holdout 10/10 - 2026-10-13
samples+n8n corpus: 3384 capabilities · 60/60 questions scorable · top-1 56/60 (93%) · top-3 60/60 (100%) · holdout top-3 28/28 - 2026-10-11
bundle 4 (social) · plans BEFORE 42/43 → AFTER 43/43 ('submit' = create verb) · events 15/15 · single 56/60·60/60 unchanged - 2026-10-11
bundle 3 (docs) · plans BEFORE 38/38 (5 new holdout, all right) · events BEFORE 12/13 → AFTER 13/13 · single 56/60·60/60 unchanged - 2026-10-11
events · BEFORE 3/10 (tuned 1/5 · holdout 2/5) → AFTER 10/10 (tuned 5/5 · holdout 5/5) - 2026-10-11
plan (bundle 2 AFTER) · samples+n8n corpus: 3384 capabilities · 34 multi-step needs · split right 34/34 · every step top-1 34/34 (75/75 steps) · n8n JSON valid 34/34 · blanks to fill 137 · accounts to connect 72 - 2026-10-11
plan (run 11 AFTER) · samples+n8n corpus: 3384 capabilities · 29 multi-step needs · split right 29/29 · every step in top-3 29/29 · steps 63/63 · every step top-1 29/29 (63/63 steps) · n8n JSON valid 29/29 · real n8n nodes 60/63 · blanks to fill 116 · accounts to connect 60 - 2026-10-11
samples+n8n corpus: 3384 capabilities · 60/60 questions scorable · top-1 56/60 (93%) · top-3 60/60 (100%) · holdout top-3 28/28 - 2026-10-11
plan · samples+n8n corpus: 3384 capabilities · 26 multi-step needs · split right 26/26 · every step in top-3 26/26 · steps 56/56 · every step top-1 26/26 (56/56 steps) · n8n JSON valid 26/26 · real n8n nodes 53/56 · blanks to fill 101 · accounts to connect 53 - 2026-10-11
plan · samples+n8n corpus: 3384 capabilities · 26 multi-step needs · split right 26/26 · every step in top-3 26/26 · steps 56/56 · every step top-1 26/26 (56/56 steps) · n8n JSON valid 26/26 · real n8n nodes 53/56 · blanks to fill 112 · AFTER: named app that cannot watch → Step.gap + Schedule Trigger (poll) in the JSON - 2026-10-11
run 9 BEFORE the gap rule (3 new holdout written first, gold GAP: todoist/youtube/quickbooks have no n8n trigger): 26 needs · every step top-1 23/26 — the three trigger steps were filled with other apps (onfleet, box, stripe) - 2026-10-11
samples+n8n corpus: 3384 capabilities · 60/60 questions scorable · top-1 56/60 (93%) · top-3 60/60 (100%) · holdout top-3 28/28 - 2026-10-11
plan · samples+n8n corpus: 3384 capabilities · 23 multi-step needs · split right 23/23 · every step in top-3 23/23 · steps 50/50 · every step top-1 23/23 (50/50 steps) · n8n JSON valid 23/23 · real n8n nodes 50/50 · blanks to fill 99 - 2026-10-11
plan · samples+n8n corpus: 3384 capabilities · 15 multi-step needs · split right 15/15 · every step in top-3 15/15 · steps 33/33 · n8n JSON valid 15/15 · real n8n nodes 33/33 · blanks to fill 57 - 2026-10-11
run 6: plan() v0 (rules: when-clause = trigger, and/then/, + verb = new step). 10 multi-step needs written first → split 10/10, all steps top-3 8/10 (both misses: trigger step won by same-noun actions) → trigger step keeps only watchers: 10/10. Then 5 holdout: 13/15 → 'upload' added as a verb, Microsoft short names (outlook, teams, excel) count as named; one holdout question replaced because its gold (dropbox.trigger) does not exist in n8n · plan · samples+n8n corpus: 3384 capabilities · 15 multi-step needs · split right 15/15 · every step in top-3 15/15 · steps 33/33 - 2026-10-11
run 5: +10 holdout (round 5) first, then verb→intent ×1.4, exact resource ×1.3, multi-word app names ("google calendar"); before the change 60 qs: top-1 42/60 (70%) · top-3 54/60 (90%), round-5 top-3 8/10 → after round-5 top-1 8/10 · top-3 10/10. Ruler change: 'send an sms to a customer' names no app, so any *.sms.send counts (gold_any) — without it top-3 is 59/60 · samples+n8n corpus: 3384 capabilities · 60/60 questions scorable · top-1 53/60 (88%) · top-3 60/60 (100%) · holdout top-3 28/28 - 2026-10-11
samples+n8n corpus: 3384 capabilities · 50/50 questions scorable · top-1 38/50 (76%) · top-3 46/50 (92%) · holdout top-3 16/18 - 2026-10-11
post→send · samples+n8n corpus: 3384 capabilities · 50/50 questions scorable · top-1 39/50 (78%) · top-3 46/50 (92%) · holdout top-3 16/18 - 2026-10-11
corpus re-dump with n8n-core (436 nodes, 2 dump errors; Slack/Gmail/Telegram/Discord/Teams/WhatsApp now in) · 3384 capabilities · 50/50 scorable · top-1 39/50 (78%) · top-3 45/50 (90%) · holdout top-3 16/18 - 2026-10-11
+18 holdout questions · 3189 capabilities · 45/50 scorable · top-1 37/45 (82%) · top-3 42/45 (93%) · holdout top-3 16/18 - 2026-10-11
run 4: trigger boost ×1.5, named-app boost ×1.5, trigger event names indexed · 3189 capabilities · 27/32 scorable · top-1 23/27 (85%) · top-3 26/27 (96%) - 2026-10-11
"when…"→trigger term, add→create etc. · 3189 capabilities · 27/32 scorable · top-1 19/27 (70%) · top-3 22/27 (81%) - 2026-10-11
baseline (before synonym fix) · samples+n8n corpus: 3189 capabilities · 27/32 questions scorable · top-1 17/27 (63%) · top-3 19/27 (70%)