Funnel Cards — "JIRA + YouTrack" over the idea funnel
Makes the funnel (the Jira half of "JIRA + Maven = nornir") feel like a real issue tracker: YouTrack-style cards, a kanban board, a smart query, the funnel triggerable from nornir (not just CLI), and a view of how components connect to the DAG plan. Grounded in web research (JIRA / YouTrack / Maven) + the existing funnel + facett facets. Status of each piece marked DONE / NEXT / LATER.
0. The framing — what JIRA, YouTrack, and Maven each give us
| Tool | What it does | nornir equivalent |
| JIRA | Epic → Story/Task → Sub-task hierarchy; typed links (blocks, relates to); Scrum/Kanban boards; sprints; backlog; burndown/velocity |
The funnel plan DAG (Plan{nodes,edges}) + items (Idea/Error/Test) + lineage (history.rs) |
| YouTrack | Same agile boards plus natural-language smart query (for:me state:Open sort:updated), drag-drop board/swimlane editor, in-project workflow scripting |
Smart query over cards (this doc), board lanes from HistoryStatus, workflow = the NodeStatus lifecycle |
| Maven | Reactor build/dependency DAG, build order, coverage report | WorkspaceGraph (src/warehouse/dep_graph.rs) + nornir coverage (coverage-maven.md) |
So nornir already is "JIRA + Maven"; this work makes the JIRA/YouTrack surface first-class and ties it to the Maven DAG. Crucially, in nornir the Maven DAG plans the Jira DAG: plan_from_component (src/funnel/planner.rs) derives the plan's nodes from a change's blast radius through WorkspaceGraph::affected_by_change.
Sources: JetBrains YouTrack vs Jira comparison; Atlassian Jira issue-hierarchy docs; AMD/JetBrains agile-board feature write-ups (June 2026 web research).
1. The card model — DONE (src/funnel/card.rs)
A pure, additive, event-free projection over the funnel's existing HistoryItems — no funnel_events / proto / Iceberg schema change, so it works against the live funnel today and is migration-safe. Fully deterministic (FC-7): same items + query string → bit-identical output, golden-testable with no warehouse, GPU, or clock.
-
Card={ id, title, body, card_type, lane, reporter, created, plan_ids, labels }.CardType(Feature/Bug/Test) fromItemKind(idea/error/test) — the issue-type badge.Lane(Inbox/Accepted/Planned/Dropped) fromHistoryStatus— the kanban column / workflow state.labels= type token + lane token + mined#hashtags(deterministic, sorted, deduped).plan_ids= the card's linked plan lineage (the JIRA "linked work").
-
parse_query/Query/query_cards— the YouTrack smart query. Operators (case-insensitive):type:/kind:,lane:/status:,is:open,reporter:/for:(for:me),label:,has:plan/no:plan,sort:newest|oldest|id; bare words = free-text substring over id+title+body+reporter. Same-facet values OR, cross-facet AND, unknown operators degrade to text (a query is never an error). -
board/Board/Column/board_to_json— groups cards into the four fixed lanes (the kanban board thefacett-boardviz will bind to);board_to_jsonis the LAW-6state_jsonsurface.
Tests (cargo test --lib funnel::card, 6 green): facet projection + label mining, every smart-query operator, the three sorts, board grouping + deterministic json, and an empty-funnel honest-empty board (RAGNARÖK). A functional_status row (nornir::funnel::card / board_projection_groups_lanes) emits under --features testmatrix so the 🧪 Test matrix sees the surface run.
Re-exported from src/funnel/mod.rs.
2. Roadmap — what's next, in priority order
P0 · Surface the cards (NEXT — small, high value)
- CLI:
nornir funnel cards [SMART-QUERY] [--json]andnornir funnel board [--json]— wrapquery_cards/boardinCommandOutcome(therun_funnelpattern insrc/bin/nornir.rs; mirrorrun_funnelhistory shaping). Makes cards a discoverable CLI surface for the completeness gate. - Test-matrix / autonom: the CLI command is new discoverable surface — cover it with an inject-assert test (drive the command, assert
CommandOutcome.data), sonornir test coveragestays green; else a.nornir/autonom-allow.tomlentry with a reason and burn down.
P1 · Make the funnel triggerable from nornir (NEXT)
Today funnel demo (the big-project simulator, src/funnel/demo.rs), decompose, and plan-from are CLI + viz only — not over MCP/RPC. To "trigger it from nornir" (server/agent/remote):
- Add to
proto/nornir.protoservice Funnel(line 619):PlanFrom,Decompose,DemoRPCs wrappingplan_from_component/simulate/run_demo. - Add MCP tools
funnel_plan_from,funnel_decompose,funnel_demoinsrc/bin/nornir-mcp.rs(mirroring the 7 existing funnel tools) so an agent can spin a synthetic big project and funnel it end-to-end remotely. - Board/query parity:
Funnel.Board/Funnel.CardsRPC returningboard_to_json, so the thin viz reads cards over gRPC.
P1 · Visualize component ↔ DAG-plan (NEXT)
The link is already in the data: PlanNode.targets / params["component"] name the component each plan node touches. What's missing is the view. Add a panel/sub-view in src/viz/funnel_tab.rs (or sibling funnel_components.rs) that overlays WorkspaceGraph::component_names() component nodes onto the plan DAG, drawing a link from each plan node to its targets. Natural plug-ins: src/viz/funnel_view.rs (NodeView.targets is already carried) and src/viz/funnel3d.rs (add a component layer + cross-edges). Expose under state_json["funnel"]["components"] + a *_for_test hook for robotui.
P2 · The facett-board facet + card glue (LATER — in the facett repo)
facett already ships the pieces (per the facet inventory): facett-card is a YouTrack-style issue card (Card/CardField/FieldValue with User/Enum/Tags/ Date/Progress/Link); facett-graph::DepGraphView is a layered DAG with click→drill- down; facett-pipeline/facett-jobview model the build/job side. The two genuine gaps:
facett-board— a new Facet: columns-of-cards kanban (lanes fromLane), drag-move between columns (FC-5 stable ids), swimlanes/sprints, WIP limits; composefacett-cardper cell. Build per the FC-1…FC-9 contract (facett/.nornir/ component-contract.md):Facettrait +state_json+ caps + injected-clock determinism + AccessKit nodes on clickable cards.- node→card glue — open a
CardViewwhen a plan-DAG node is clicked (readDepGraphView.selected, render the card for that node's item). - Enrich
facett-card: comments/activity thread, markdown description body, attachments (today it has no comment/description-body/workflow model).
P2 · Persist richer card fields (LATER — migration)
When cards need real assignee / labels / workflow-state / comments (beyond the derived projection), add them as new optional funnel_events columns the same migration-safe way item_kind (col 28) landed — see funnel-intake.md. New events: CardAssigned, CardLabeled, CardCommented, CardStateChanged. The projection in §1 keeps working for legacy rows (null → derived defaults).
P3 · Agile reporting (LATER)
Sprints/iterations, story-point rollup, burndown/velocity — JIRA's structured side. Sprint = a tag/iteration field on cards; burndown = a time-series over NodeStatus→Done transitions already in funnel_events (NodeStatusChanged).
3. What was implemented this pass vs. deferred
- DONE:
src/funnel/card.rs(card projection + smart query + kanban board +state_json), re-exported, 6 green deterministic tests,testmatrixemit. No schema/proto/viz change — zero blast radius on the live funnel. - DEFERRED with a concrete seam (above): CLI
funnel cards/board; MCP/RPCPlanFrom/Decompose/Demo/Board; component↔DAG view;facett-boardfacet + node→card glue +facett-cardenrichment; persisted card events; agile reports.
4. Key files
- New:
src/funnel/card.rs(+src/funnel/mod.rsre-exports). - Funnel core:
src/funnel/{history,state,event,planner,demo,decompose}.rs. - Maven DAG:
src/warehouse/dep_graph.rs(WorkspaceGraph). - Trigger seams:
proto/nornir.proto(service Funnel:619),src/bin/nornir.rs(FunnelOp,run_funnel),src/bin/nornir-mcp.rs. - Viz:
src/viz/{funnel_tab,funnel_view,funnel3d}.rs. - Test matrix / gate:
crates/nornir-testmatrix/src/functional.rs,src/selftest.rs(emit),src/autonom/mod.rs,.nornir/{test-matrix,completeness-gate, autonom-for-idiots}.md. - facett side:
facett/.nornir/component-contract.md,facett/facett-card,facett/facett-graph(DepGraphView).