Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/dwarves

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);
}