任务:质量看板(能力 6b)

只读事实型任务包,开始运行时由 Hub 直接算出并存下结果(不需要模型提交)。

  • 包目录(只改这里):packs/workflow/quality-board/**
  • 先读:AGENTS.md、docs/hub-r4-architecture.md(第 2、5、6a、6b 节)、docs/hub-r4-handoff.md、contracts/src/pack.ts、contracts/src/views.ts、一个已有的只读事实型包(packs/workflow/template-gap 或 packs/workflow/case-location)。
  • 依赖:知识包已能提供 knowledge:impact|facets|index 视图(已提交),产品包的用例索引(packs/product/famx 的 cases 生产器)由另一个任务完成;这个包的测试用手搭的视图和一个假的知识读取器,真实读取器上的端到端测试等用例索引提交后再补。
  • 复核重点(自己做完再对照一遍):Are the metrics exactly the definitions below, computed from the facet counts with no rounding before the final ratio, and do they equal an independent computation on a random corpus? Are the definitions of missing and vague expected results the ones of the real-sample measurement (quoted in the spec) and not new ones? Is the board advisory only (no blocking violation), and does it say what the index cannot see?

规格

PACKAGE quality-board - capability 6b (quality board), a production-run workflow pack: fact producers only. Read first: contracts/src/pack.ts and views.ts (facet-view@1), packs/workflow/template-gap and case-location, packs/product/famx README (the case entry data fields written by the cases producer: document, line, module, priority, negative, has_expected, vague_expected, …), brief sections 6a and 6b. Semantics (write them first as tests): one required input slot facets = knowledge:facets::?kind=case&by=line,module,has_expected,vague_expected,negative (the caller may add priority); the Hub's reader answers with facet-view@1. Definitions (they are the ones used by the owner's real-sample measurement; do not invent others): a case WITHOUT an expected result has has_expected false (no leaf child and no steps under it); a case with only VAGUE expected results has has_expected true and vague_expected true (every expected text is one of the vague phrases: success, configuration success, normal, device normal, in effect, OK, passed, consistent, no abnormality ...); the NEGATIVE share is the cases with negative true over all cases. Items: one per (line, module) group of the view (module null is the group 'unplaced'), id = '/', label = the pair, summary at most 200 characters (cases, without expected percent, vague percent, negative percent). Fields: counts and the ratios as exact fractions {num, den} and as numbers rounded only for display. Requirements: board (fact, item, static, bookkeeping: always support with the metrics as claim data); thresholds (advisory, fact): parameters max_missing_ratio (default 0.05), max_vague_ratio (default 0.05), min_negative_ratio (default 0.02): an advisory violation with codes quality.missing_expected, quality.vague_expected, quality.negative_share when the group exceeds or falls below; never a blocking violation, because these are management signals, not defects. Run-level claims: totals over the whole view (cases, missing, vague, negative) and the note that the index only holds cases that name a resolvable command (state its share when the view carries it) so the board describes the indexed cases, not the whole suite; when the view states skipped sources (skipped above zero) the totals note names that count. Deterministic and order independent. Deliver under packs/workflow/quality-board the same file set as regression-scope; SKILL.md says how to read the board and what it cannot see. Tests: hand-built facet views (known counts, a null module, a null line, rows that split a group by the other fields and must be summed, an empty view), an independent computation in the test (plain loops over a random corpus of 100,000 synthetic cases, grouped and counted, compared with the pack's items), threshold boundaries (equal to the threshold is not a violation), order independence, the publish check, a production run end to end with a fake knowledge reader.