Context
The weaver-spec defines ChoiceCard as a menu containing multiple SelectableItems — a bounded decision set presented to the LLM:
# Spec: ChoiceCard (1:N — menu of items)
@dataclass
class ChoiceCard:
id: str
items: list[SelectableItem] # multiple items per card
context_hint: Optional[str] = None
metadata: Dict[str, Any] = {}
contextweaver's ChoiceCard is a compact view of a single item (1:1):
# Current: ChoiceCard (1:1 — compact view of one item)
@dataclass
class ChoiceCard:
id: str
name: str
description: str
tags: list[str] = []
kind: str = "tool"
namespace: str = ""
has_schema: bool = False
score: float | None = None
cost_hint: float = 0.0
side_effects: bool = False
These are semantically different types with the same name. The spec's ChoiceCard is a group/menu; contextweaver's is an item summary. This mismatch blocks spec-compliant RoutingDecision construction (#151), contract adapter round-trips (#143), and cross-repo interop.
Why it matters
Decision Required
There are two alignment strategies:
Option A: Rename + Restructure (recommended)
- Rename current
ChoiceCard → ItemSummary (or CompactItem) — it represents a single-item compact view.
- Add a new
ChoiceCard matching the spec: a group/menu containing multiple ItemSummary items.
make_choice_cards() now groups items into menus (the ChoiceGraph nodes already provide natural groupings).
Option B: Adapter-only
Acceptance Criteria
Implementation Notes
The ChoiceGraph DAG already provides natural groupings — each node's children are a bounded set of options. The TreeBuilder creates exactly these groups. The spec's ChoiceCard should map to one level of the graph traversal: "here are 5 groups of tools; pick a group, then pick within it."
Files likely touched:
src/contextweaver/envelope.py — type rename/restructure
src/contextweaver/routing/cards.py — rendering functions
src/contextweaver/context/manager.py — prompt building
src/contextweaver/__init__.py — exports
- Multiple test files
Dependencies
References
Context
The weaver-spec defines
ChoiceCardas a menu containing multipleSelectableItems — a bounded decision set presented to the LLM:contextweaver's
ChoiceCardis a compact view of a single item (1:1):These are semantically different types with the same name. The spec's
ChoiceCardis a group/menu; contextweaver's is an item summary. This mismatch blocks spec-compliantRoutingDecisionconstruction (#151), contract adapter round-trips (#143), and cross-repo interop.Why it matters
RoutingDecision.choice_cards([routing] Add RoutingDecision contract type to match weaver-spec output shape #151) expects a list of menus, each containing multiple items. If contextweaver'sChoiceCardis 1:1, the structure is flat, losing the grouping that helps LLMs navigate large tool sets.ChoiceCardis the simplified view: a bounded choice set presented as a menu, not a flat list of 50 individual tool summaries.Decision Required
There are two alignment strategies:
Option A: Rename + Restructure (recommended)
ChoiceCard→ItemSummary(orCompactItem) — it represents a single-item compact view.ChoiceCardmatching the spec: a group/menu containing multipleItemSummaryitems.make_choice_cards()now groups items into menus (theChoiceGraphnodes already provide natural groupings).Option B: Adapter-only
ChoiceCardas-is.ChoiceCards into specChoiceCardmenus.Acceptance Criteria
RoutingDecision.choice_cards([routing] Add RoutingDecision contract type to match weaver-spec output shape #151) matches the spec'sChoiceCardshaperender_cards_text()updated to render grouped choice menusitem_to_card()updated or replaced to work with the new structureImplementation Notes
The
ChoiceGraphDAG already provides natural groupings — each node's children are a bounded set of options. TheTreeBuildercreates exactly these groups. The spec'sChoiceCardshould map to one level of the graph traversal: "here are 5 groups of tools; pick a group, then pick within it."Files likely touched:
src/contextweaver/envelope.py— type rename/restructuresrc/contextweaver/routing/cards.py— rendering functionssrc/contextweaver/context/manager.py— prompt buildingsrc/contextweaver/__init__.py— exportsDependencies
contracts/python/src/weaver_contracts/core.pyReferences