Repository navigation
refactor(flows): wire the semantic shape through PaperFlow.build and deprecate paper_flow #139
Description
Current state
quantmind/flows/paper/__init__.py exposes two entry points for building paper knowledge artifacts, and they disagree on which one is canonical.
PaperFlow(cfg).build(input)is the config-bound flow. It dispatches on the cfg type, but onlyPaperStructureCfg -> PaperStructureTreeis wired. Any other cfg type (includingPaperFlowCfg) raisesNotImplementedError.paper_flow(input, *, cfg)is a standalone function that still owns the semantic chunk/summary shape (PaperFlowResult) — the fetch/parse, chunking, and bounded map-reduce summary pipeline live in its body.
The module docstring and the architecture constraint both say the cfg type should select the knowledge shape a single config-bound flow produces (PaperFlow(cfg).build(input), typed dispatch, not a hierarchy). Today the semantic shape sits outside that dispatch, so the two shapes are reached through two different call styles, and paper_flow is a second implementation rather than a thin wrapper.
Target
PaperFlow.build becomes the single config-bound entry for both paper shapes, selected by cfg type:
PaperStructureCfg -> PaperStructureTree(unchanged)PaperFlowCfg -> PaperFlowResult(moved in frompaper_flow)- any other cfg type ->
NotImplementedError
paper_flow becomes a deprecated thin wrapper: it emits a DeprecationWarning and delegates to PaperFlow(PaperFlowCfg(...)).build(input). It is kept — not removed — because it is grandfathered by the operation-naming contract (contexts/design/operations/naming.md); its signature stays (input: PaperInput, *, cfg: PaperFlowCfg | None = None) so the magic-input introspection path is unaffected.
The semantic-shape logic moves rather than being duplicated, so there is one implementation of the chunk/summary pipeline.
Migration notes
- Callers move from
await paper_flow(input, cfg=PaperFlowCfg(...))toawait PaperFlow(PaperFlowCfg(...)).build(input).batch_run(flow.build, inputs)is the intended batch shape under one bound setting. build's return type depends on the bound cfg type; the implementation keeps typing precise underbasedpyrightstandard mode so each shape's callers keep their exact result type.- No public behavior of either shape changes; this is a
type: refactor. Tests, the paper example, the paper flow design page, and the component catalog row are updated to the config-bound entry point, and a test covers thepaper_flowdeprecation warning and delegation.
Activity
keli-wen commentedon Jul 23, 2026
Scope update (PR #140): the semantic shape is still folded into
PaperFlow.buildby cfg type as this issue describes, but on owner review two things changed from the original plan.paper_flowis removed outright, not kept as a deprecated wrapper.PaperFlow(cfg).buildis the single entry point for both shapes; the operation-naming contract no longer grandfathers the name, and the magic path now demonstrates oncollect_news(the remaining(input, *, cfg)flow).PaperFlowCfg -> PaperSemanticCfgandPaperFlowResult -> PaperSemanticResult, sincePaperFlowCfgread like a parent ofPaperStructureCfgand nopaper_flowfunction survives to anchor the old name.The typed-dispatch, precise-return, and "moved not duplicated" goals are unchanged.
refactor(flows): wire the semantic shape through PaperFlow.build, ren…