update
This commit is contained in:
@@ -1323,8 +1323,8 @@ async def _proc_grouping(ctx: GenContext, flow: Flow, cards):
|
||||
# ONE wave: TOP + all cluster judges in parallel. The used-ties precedence lives in the
|
||||
# ORDER of `sources` (TOP first), not in execution order — a failed judge simply leaves
|
||||
# no valid file and is skipped in the collection below (legacy semantics).
|
||||
jobs = [("TOP", "Scan the ENTIRE block list below and propose EVERY genuine umbrella "
|
||||
"you find — do not restrict yourself to any subset.", n)]
|
||||
jobs = [("TOP", "Card-sort the ENTIRE list below into themes: assign as MANY items as "
|
||||
"possible to a coherent theme, each item into exactly one.", n)]
|
||||
jobs += [(str(ci), "\n".join(f"{g + 1}. {texts[g]}" for g in cluster), len(cluster))
|
||||
for ci, cluster in enumerate(multi)]
|
||||
await asyncio.gather(*[_assess(tag, cand, count) for tag, cand, count in jobs],
|
||||
@@ -1346,16 +1346,10 @@ async def _proc_grouping(ctx: GenContext, flow: Flow, cards):
|
||||
members = [m for m in members if m not in used]
|
||||
if len(members) < 2:
|
||||
continue
|
||||
# Bottom-up card-sorting: keine type-gate/min-cos-Vetos mehr — jedes Item soll in
|
||||
# ein Thema; ein „Fehl-Merge" ist billig (Item bleibt als Sub erhalten, keine Lücke).
|
||||
mrows = [rows[m - 1] for m in members]
|
||||
if any(_GROUP_STANDALONE.search(r["title"]) for r in mrows):
|
||||
skipped.append({"umbrella": title, "grund": "type-gate",
|
||||
"mitglieder": [r["title"] for r in mrows]})
|
||||
continue
|
||||
mc = _min_cos([m - 1 for m in members])
|
||||
if mc < GROUP_MIN_COS_FLOOR:
|
||||
skipped.append({"umbrella": title, "grund": "min-cos", "min_cos": mc,
|
||||
"mitglieder": [r["title"] for r in mrows]})
|
||||
continue
|
||||
unorm = _norm_title(title)
|
||||
member_norms = {r["title_norm"] for r in mrows}
|
||||
if unorm not in member_norms and unorm in seen_norm:
|
||||
@@ -1412,7 +1406,7 @@ async def _proc_grouping(ctx: GenContext, flow: Flow, cards):
|
||||
add = []
|
||||
for k, new_members in (add or []):
|
||||
for m in new_members:
|
||||
if m in used or not (1 <= m <= n) or _GROUP_STANDALONE.search(rows[m - 1]["title"]):
|
||||
if m in used or not (1 <= m <= n):
|
||||
continue
|
||||
used.add(m)
|
||||
chosen[k]["members"].append(m)
|
||||
@@ -1622,6 +1616,19 @@ async def _proc_done(ctx: GenContext, flow: Flow, cards):
|
||||
await db.upsert_block(topic, norm, title, p.get("description", ""), p.get("sources") or [])
|
||||
await db.set_block_status(topic, norm, "consensus",
|
||||
title=title, description=p.get("description", ""))
|
||||
# Bottom-up-Persistenz: die geclusterten Atome bleiben als Subs (jedes Atom genau
|
||||
# ein Sub). Ein childless Standalone-Block ist sein eigener einziger Sub. Board 2
|
||||
# reichert diese an, entdeckt sie nie neu — so überlebt jedes Board-1-Atom.
|
||||
sub_titles = [(ch.get("title") if isinstance(ch, dict) else ch)
|
||||
for ch in (p.get("children") or [])]
|
||||
sub_titles = [s for s in sub_titles if s] or [title]
|
||||
seen_sub: set[str] = set()
|
||||
for st in sub_titles:
|
||||
sn = _norm_title(st)
|
||||
if not sn or sn in seen_sub:
|
||||
continue
|
||||
seen_sub.add(sn)
|
||||
await db.put_subblock(topic, norm, sn, title, st, status="consensus")
|
||||
mirrored[norm] = c["card_id"]
|
||||
p.update(mirrored_norm=norm, title=title)
|
||||
await db.kanban_set_payload(topic, BOARD, c["card_id"], p)
|
||||
|
||||
Reference in New Issue
Block a user