Objective
Results / Changelog records at docs/results.html and docs/site-data/results.json showed generic placeholder titles and summaries like “Complete pipeline task (#824)” for 11 pipeline-completed tasks. Reviewers could not tell what shipped. The task required each generic entry’s displayed title to identify the actual delivered work and its description to concisely explain the material change and why it matters using both the linked Beads task and the associated commit as evidence, handling missing/sparse fields without fabricating details, fixing the changelog producer rather than hand-editing generated docs, preserving existing nongeneric entries, and verifying via focused producer and executable page coverage.
Approach
- Classified as
maintenancebounded producer fix (no StrategySpec, indicator, or data-source). No child tasks required. - Inspected
research/reports/results.py:_load_entries— it rendered front-mattertitle/summaryverbatim, so reconstructedresearch/results/qm-*.mdfiles with generic placeholders flowed straight to the payload and HTML. - Added producer enrichment in
research/reports/results.py:_is_generic_entrydetection,_try_load_beads_taskviabd show --json,_try_load_git_commitviagit log/showparsingCommit \sha\`from the markdown body (fallbackgit log --grep=eid), and_enrich_generic_entry` that prefers the Beads task title, falls back to a cleaned commit subject, and builds a concise summary from the Beads description + commit file list/AC without inventing thresholds, handling sparse cases with an explicit “sparse — see commit and task” fallback and truncating safely. - Wired enrichment into
_load_entriesso future generic markdowns are auto-corrected at build time while nongeneric entries pass through unchanged. - Backfilled the 11 source markdowns with grounded titles/summaries derived from
bd showandgit show --stat: qm-p0m.2→ “Extend Signals history with availability-bound aggregate” (commit 8a59458a, 170k-line signals/history.json rebuild)qm-p0m.3→ “Replace indicator dropdown with sortable signal tiles and quality metrics” (fa1a6878, risk_off_history/signals_history)qm-p0m.4→ “Make the aggregate risk gauge interactive from signal tiles” (5922b397, site.js 208 insertions)qm-p0m.5→ “Standardize risk-on trigger markers and underlying indicator charts” (6682b536, charts.js 257 insertions)qm-xz0.2→ “Extract SPYST charts and parse a strict signal schema” (73cd7d3b, 635-line extract.py)qm-xz0.3→ “Validate SPYST parser on history and add a manual-review fallback” (5263cc97, validate.py 437 lines)qm-xz0.4→ “Keep SPYST allocation logic separate and at parity…” (65223265, allocation parity)qm-xz0.5→ “Hook SPYST into refresh with late-mail handling and parse alerts” (e50e4cb1, refresh.py 411 lines)qm-xz0.6→ “Add offline SPYST email-to-allocation regression fixtures” (f99650c2, 386-line regression)qm-7ad→ “Implement max-CAGR-at-vol kernel and wrappers” (6048fd68, 601 insertions)qm-rjo.4→ “Remove the Compare Strategy surface” (efa1b9e1, 428-line comparison.js deletion)
Files / code / data changed
research/reports/results.py— addedimport json, subprocess,_GENERIC_TITLE_RE,_is_generic_entry,_try_load_beads_task,_try_load_git_commit,_enrich_generic_entry, and enrichment wire-in_load_entries(future generic placeholders auto-enriched at build time, sparse handling without fabrication)research/results/qm-p0m.2.md,qm-p0m.3.md,qm-p0m.4.md,qm-p0m.5.md,qm-xz0.2.md,qm-xz0.3.md,qm-xz0.4.md,qm-xz0.5.md,qm-xz0.6.md,qm-7ad.md,qm-rjo.4.md— front-mattertitle/summaryreplaced with grounded copy (titles = Beads task titles verbatim; summaries = 1–2 sentences: task why + commit file evidence with SHA)tests/test_changelog_enrichment.py— new focused producer + executable page coverage (7 tests): generic enriched, summaries grounded in SHAs, nongeneric retained, sparse fallback, producer contains helpers, rendered HTML contains enriched titles with zero generic link placeholders, source markdowns searchable- Generated via producer (not hand-edited):
docs/site-data/results.json(n_entries 483, 0 generic titles),docs/results.html(tbody links enriched),docs/results/qm-*.html(11 detail pages)
Validation
python3 -m research.reports.results— rebuilt deterministically; before 11 generic titles, after 0;docs/results.htmlshows enriched titles, no<td><a>Complete pipeline taskremainspython3 -m pytest -q tests/test_results.py tests/test_changelog_enrichment.py— 14 passed (7 existing + 7 new); nongenericqm-9kwp/qm-avfatitles unchanged, sparse caseqm-test-generic-tmpcorrectly falls back toeid+ “sparse — see commit and task” without fabricatingpython3 research/scripts/check_static_reports.py docs— local bundle OK: 1207 files; 177 canary routespython3 -m research.pipeline verify --offline— status passed (all offline scenarios, includingchangelog_entryartifact contract requiringresearch/results/*.md+docs/site-data/results.json+docs/results.html+docs/results/<id>.htmlviapython3 -m research.reports.results)python3 -m research.pipeline validate— status passed, nodes 28, edges 38, hash sha256:6802…git diff --name-onlyshows nodata/market.sqlitemutation, no private data, no hand-editeddocs/site-data/results.jsonoutside producer
Results
Changelog index now reads as specific delivered work rather than placeholders: each former “Complete pipeline task (#NNN)” row links with its real Beads title (e.g. “Extend Signals history with availability-bound aggregate”, “Remove the Compare Strategy surface”) and the payload summary concisely explains what changed and why (e.g. contemporaneous max, sortable tiles, SPYST refresh cadence) with commit SHA and file evidence. Nongeneric entries (qm-9kwp, qm-avfa) retain intended copy; synthetic generic with missing beads/commit degrades gracefully to a sparse notice. The fix lives in research/reports/results.py and regenerated artifacts, preserving deterministic site-data ownership and enabling git grep over research/results/qm-*.md.
Conclusions
Completed the maintenance fix end-to-end: 11 historical entries enriched, producer hardened for future generics, searchable source markdowns updated, deterministic docs/site-data/results.json/docs/results.html regenerated, and executable coverage ensures no generic placeholders return.
Problems / follow-ups
research/results/qm-*.mdbodies still contain the original reconstructed “Complete pipeline task (#NNN) (commit …)” objective line — front-matter is what the payload renders, so no further change needed; a future pass could rewrite body objectives for completeness.tests/test_reports_scaffold.pyexpects 11 meta strategies but now sees 13 afterqm-7ad’s two “Max CAGR at vol” metas, andresearch.artifactsreports drift — pre-existing fromqm-7ad, not introduced by this task; tracked as independent follow-up.
Links
- Task:
qm-h4fy - Detailed analysis:
research/reports/results.py:_enrich_generic_entry,bd show qm-p0m.2etc. andgit log/showinspection for 11 generic entries - Code changes:
research/reports/results.py(generic detection + Beads/commit enrichment),research/results/qm-p0m.2.mdetc. (11 front-matter enrichments),tests/test_changelog_enrichment.py - Experiments / data:
python3 -m research.reports.results(0 generic titles after),python3 -m pytest -q tests/test_results.py tests/test_changelog_enrichment.py(14 passed),python3 -m research.pipeline verify --offline - Affected website pages:
docs/results.html(index with enriched titles),docs/site-data/results.json(results/v10 generic),docs/results/qm-p0m.2.htmletc. (11 detail pages)