crates/nornir-funnel-embed/proto/funnel.proto
// funnel.proto — a TRIMMED copy of nornir's `Funnel` read + intake + plan-write
// wire surface.
//
// This is the thin backend-(2) client's ONLY proto: the read-only `Funnel.Show`
// RPC (+ the `FunnelDump*` messages it returns), the `Funnel.SubmitIdea` intake
// RPC (idea/error → `IdRef`), and the PLAN-WRITE trio `CreatePlan` / `AddNode` /
// `Link` (how dwarves' decompose action PERSISTS the plan it produced, so the DAG
// `Show` re-renders is the decomposed one — the "funnel-no-plan" fix). Field
// numbers, message names, and the `nornir.v1` package MUST match the canonical
// `edda/crates/nornir-wire/proto/nornir.proto` exactly (the gRPC method paths are
// `/nornir.v1.Funnel/Show`, `/nornir.v1.Funnel/SubmitIdea`, …), so this client
// talks to the live `nornir-server` without linking the `nornir` crate (which
// would be a dependency cycle: nornir → dwarves already).
//
// Auth: every RPC carries `authorization: Bearer <NORNIR_SERVER_TOKEN>` in its grpc
// metadata (enforced by the server's tonic interceptor). SubmitIdea/CreatePlan/
// AddNode/Link are WRITES: typing an idea/error into the dwarves funnel pane — or
// decomposing one — grows nornir's plan-DAG, which the auto-poll `Show` then
// re-renders.
syntax = "proto3";
package nornir.v1;
message Empty {}
message FunnelDumpNode {
string id = 1;
string kind = 2;
string title = 3;
string status = 4;
repeated string deps = 5;
}
message FunnelDumpPlan {
string id = 1;
string idea_id = 2;
string summary = 3;
repeated FunnelDumpNode nodes = 4;
string status = 5; // PlanStatus Debug repr (Draft|Active|…)
}
message FunnelDumpIdea {
string id = 1;
string text = 2;
repeated FunnelDumpPlan plans = 3;
string source = 4;
string item_kind = 5; // "idea" (default) | "error"
}
message FunnelDump {
repeated FunnelDumpIdea ideas = 1;
}
// Intake (WRITE): a new idea/error id. Mirrors nornir's `IdRef { string id = 1; }`.
message IdRef { string id = 1; }
// Intake (WRITE): submit an idea OR an error into the funnel. Exact field numbers
// of nornir's `SubmitIdeaRequest` (the server routes `item_kind` "idea"|"error";
// empty ⇒ idea).
message SubmitIdeaRequest {
string text = 1;
string source = 2; // optional, e.g. "agent:claude" — dwarves sends "dwarves:funnel-pane"
string item_kind = 3; // "idea" (default) | "error"; empty = idea
}
// Plan-write (the decompose PERSIST leg). Exact field numbers of nornir's
// `CreatePlanRequest` / `AddNodeRequest` / `LinkRequest`.
message CreatePlanRequest {
string idea_id = 1;
string summary = 2;
}
message AddNodeRequest {
string plan_id = 1;
string kind = 2;
string title = 3; // optional
string prompt = 4; // optional
repeated string targets = 5;
repeated string needs = 6; // node ids to depend on (server ids)
}
message LinkRequest {
string plan_id = 1;
string from = 2;
string to = 3;
}
// The read `Show`, the intake `SubmitIdea`, and the plan-write trio this crate
// consumes. The full nornir `Funnel` service has more RPCs (SetStatus/Next/
// History); this thin client needs only these — read the DAG, grow it, and
// persist a decomposed plan into it.
service Funnel {
rpc Show (Empty) returns (FunnelDump);
rpc SubmitIdea (SubmitIdeaRequest) returns (IdRef);
rpc CreatePlan (CreatePlanRequest) returns (IdRef);
rpc AddNode (AddNodeRequest) returns (IdRef);
rpc Link (LinkRequest) returns (Empty);
}