3.19 Ask for the result, not the steps — a goal view, then English
3.17 wrote the whole pipeline by hand. A realm that ships its stages as views lets a caller write only the last part. The two steps, as the realm ships them:
- name: ProjectEmail description: The people, issues and customer accounts a customer's email states. params: email: { type: string, description: "The email, as text." } cypher: | CALL ai.fromText($email, '(t:Attendee)-[:RAISED]->(i:Issue), (t)-[:WORKS_FOR]->(a:CustomerAccount)') YIELD t RETURN count(t) AS projected
- name: LinkTrackedIssues description: Links each issue a customer raised to the open support cases that are the same problem. cypher: | MATCH (li:Issue)<-[:RAISED]-(raiser:Attendee)-[:WORKS_FOR]->(acct:CustomerAccount)-[:HAS_CASE]->(c:SupportCase) WHERE c.status IN ['open', 'pending'] WITH li, relevant(c, 'the same problem as: ' + li.summary) AS tracked UNWIND tracked AS tc CREATE (li)-[:TRACKED_BY]->(tc) RETURN count(*) AS linkedwith TRACKED_BY: { to: SupportCase, many: true, description: "An open case already about this issue." }
declared on the projected Issue (§7.8). Nobody declares what either view needs or makes; it is read off the
Cypher. ProjectEmail needs text and makes Attendee, Issue, RAISED and WORKS_FOR;
LinkTrackedIssues needs those and makes TRACKED_BY.
The answer, as a goal view:
- name: UntrackedFromEmail description: Issues a customer's email raises that no open support case already tracks. params: email: { type: string, description: "The customer's email, as text." } goal: | MATCH (raisedBy:Attendee)-[:RAISED]->(untracked:Issue) WHERE NOT EXISTS { (untracked)-[:TRACKED_BY]->() } RETURN untracked.summary AS issue, untracked.severity AS severity, raisedBy.name AS personMeans: “From this email, what did the customer raise that we have no open ticket for?” — and nothing
about how. The goal reads Attendee, Issue, RAISED and TRACKED_BY; the planner finds that
TRACKED_BY needs LinkTrackedIssues, which needs what ProjectEmail makes from the email text, and
compiles the two into unit CALL {} subqueries ahead of the goal — the query 3.17 wrote by hand. The world
pins that compiled statement beside the view, and every run executes it without planning again.
Four things to notice:
NOT EXISTSis a need. The goal readsTRACKED_BYonly to test its absence, and that is enough to putLinkTrackedIssuesin the plan. Without it every issue would be “untracked”, because nothing made the edge.- The cheapest route wins, and a tie is said. Each step is costed by what it reaches — a stored read, an API, a model — and the planner takes the route whose costs sum least; two equally cheap routes are reported as a tie, never picked between.
- The names are distinct across the plan —
t,li,raiser,acct,tc,raisedBy,untracked— because the compiled statement is one query, and the compiler refuses a clash rather than rename it. - The realm ships the goal alone.
compiled:andplan:are written by each world that installs the realm, over the steps that world has. Shipping them is a validation error. If a step changes later, the view is refused as stale, naming the step, until someone replans it.
The same answer, asked in English — over MCP, before anything runs:
plan({question: "what did this customer raise that has no ticket?", inputs: {email: {type: "text", value: "Hi — since the upgrade, exports time out…"}}})→ {"outcome": "planned", "question": "…", "worldOnly": false, "goal": "MATCH (raisedBy:Attendee)-[:RAISED]->(untracked:Issue) WHERE NOT EXISTS { … } RETURN …", "steps": [{"from": "ProjectEmail", "adds": ["node:Attendee", "node:Issue", …], …}, {"from": "LinkTrackedIssues", "adds": ["edge:Issue-TRACKED_BY->SupportCase"], …}], "compiled": "CALL { … } CALL { … } MATCH (raisedBy:Attendee)…", "quote": {…, "unpriced": ["ProjectEmail"]}}The question costs one model call — the one that writes the goal — and the answer shows all three layers:
the English, the goal written from it, and the plan. Nothing has run. Read the steps and the quote, then run
exactly what you were shown by passing the returned goal as goal with run: true. Asked with no email,
the same question answers needsInput — {type: "text", why: …} — rather than a guess; asked “which open cases
does Acme have?”, it answers from what the world holds, worldOnly: true, with no steps at all.
Habits: give every step a description, since English mode picks facts by them; name variables for what they hold; and save an answer worth keeping as a goal view, so it is pinned rather than written afresh. See §16 of the spec.

