Skip to content

chore(scripts): dashboard regen extracts PR# from idea-only legacy folders - #221

Merged
SoundMindsAI merged 3 commits into
mainfrom
feature/chore-dashboard-pr-extraction-from-idea
May 23, 2026
Merged

chore(scripts): dashboard regen extracts PR# from idea-only legacy folders#221
SoundMindsAI merged 3 commits into
mainfrom
feature/chore-dashboard-pr-extraction-from-idea

Conversation

@SoundMindsAI

Copy link
Copy Markdown
Owner

Summary

Extends _extract_pr_number in the dashboard regen script with two new cascade priorities (3.5 + 3.6) that mine idea.md content for own-PR assertions. This closes the data gap where ~50 early MVP1 implemented features with only idea.md artifacts (no spec/plan/pipeline_status) render as Complete instead of [PR #N](url) merged YYYY-MM-DD in the regenerated dashboard.

  • Story 1.1 — adds 5 module-level re.compile'd patterns (3 line-anchored strict patterns + **PR:** frontmatter pattern + metadata-key matcher) and a new _extract_metadata_block helper that bounds the **PR:** search to the idea's metadata cluster (contiguous metadata-key lines stopping at the first ## heading or non-metadata non-blank line; 30-line cap for headingless edge cases). Each pattern's \b boundary sits immediately after the digit capture per GPT-5.5 cycle-2 fix.
  • Story 1.2 — threads idea.md content through _load_implemented + _load_planned via the new 4th arg; adds 27-case test file at backend/tests/unit/scripts/test_dashboard_pr_extraction.py; documents the **PR:** frontmatter convention in architecture.md's new "Dashboard regen" subsection.

Pipeline artifacts

Test coverage

Layer Files Tests
Unit backend/tests/unit/scripts/test_dashboard_pr_extraction.py (new) 27 cases covering all 17 ACs + mutual-exclusion + helper unit cases + regex-constant locks
Integration none — (script is hermetic; no DB/network)
Contract none — (no API surface)
E2E none — (no UI surface)

Existing unit suite remains green: 1190/1190 (1163 baseline + 27 new).

Empirical verification (per spec §14 step 3)

Run make dashboard and compare shipped/planned table PR-number columns:

Forward gain: 3 rows transitioned None → PR#.
  • chore_create_study_modal_e2e_stability → PR #161 (Pattern B precedent)
  • chore_precommit_node_path_resolution → PR #171 (Pattern C precedent)
  • chore_dashboard_pr_extraction_from_idea → PR #4 ← cosmetic anomaly (see note)

Regressions: 0 rows whose PR# changed.

PASS: zero regressions; forward gain documented above.

Forward gain (3) is below the spec's predicted 5–8. During the preflight survey I counted 5–8 candidate features carrying the canonical strict shapes. The regen actually picks up only 3 because the other 2 of the candidates (chore_data_table_columnvisibility_tanstack, feat_contextual_help_mvp2) have their PR# captured earlier in the cascade — by priority 3's fuzzy merged-context match against narrative content in their idea bodies. They were already rendering correctly; the new priority 3.5 doesn't get a chance to fire. Net effect on operator value: the chore still does what it set out to do (legacy idea-only folders now surface their PRs), just slightly less of a forward gain than predicted because the existing priority-3 was doing more work than the preflight assumed.

Cosmetic anomaly for THIS chore's own planned-feature row: the chore appears in the dashboard's Plan section as [PR #4] merged 2026-05-15, which is wrong (PR #4 is infra_foundation, the date is from an AC-1 example body). Root cause: the chore's own spec content contains AC-body examples that quote OTHER features' PR-merge phrases (e.g., AC-4's body **Depends on:** [infra_foundation] — merged via PR #4), which the pre-existing priority-3 fuzzy regex grabs. The anomaly is cosmetic only — resolves automatically when this chore merges and _load_implemented takes over the row rendering. Captured as a separate idea: chore_dashboard_regen_quoted_pr_false_positive for future hardening of the priority-3 fuzzy regex.

Test plan

  • make backend-fmt / make backend-lint / make backend-typecheck — green
  • .venv/bin/ruff format --check backend/ — green (CI parity)
  • make test-unit — 1190 passed in 5.71s (27 new + 1163 baseline)
  • Empirical verification — 3 forward gain, 0 regressions (see above)
  • make dashboard — clean regen, no errors
  • CI green (.github/workflows/pr.yml)
  • Gemini Code Assist review adjudicated
  • Final GPT-5.5 review on merged diff

Tangential capture

docs/02_product/planned_features/chore_dashboard_regen_quoted_pr_false_positive/idea.md captures the pre-existing priority-3 fuzzy regex weakness surfaced during this chore's empirical verification. Out of scope here; provides a future-work target with three implementation options ranked by surgical-ness.

🤖 Generated with Claude Code

…lders

Extends _extract_pr_number in scripts/build_mvp1_dashboard.py with two
new cascade priorities (3.5 + 3.6) that mine idea.md content for own-PR
assertions when pipeline_status / plan / spec are empty — the typical
shape for ~50 early MVP1 features that shipped before /pipeline ceremony.

Story 1.1: 5 module-level re.compile patterns (3 strict Status/Shipped /
Implemented / line-anchored shipped-dateline, 1 **PR:** frontmatter, 1
metadata-key matcher) + _extract_metadata_block helper bounding the
**PR:** search to a contiguous metadata cluster (30-line cap).

Story 1.2: threads idea content through _load_implemented + _load_planned;
adds 27-case test file covering all 17 spec ACs + edge cases; documents
the **PR:** frontmatter convention in architecture.md.

Empirical verification: regen produced 3 newly-resolved PR rows, ZERO
existing PR-linked rows changed. Below predicted 5-8 forward gain — only
~3 of ~50 idea-only folders carry canonical strict shapes; **PR:**
frontmatter is the escape hatch for the rest, applied opportunistically.

Tangential capture: chore_dashboard_regen_quoted_pr_false_positive
documents the pre-existing priority-3 fuzzy-regex weakness that lets
spec/plan content quoting other features' merge phrases trip the regex.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request extends the dashboard regeneration script to extract PR numbers from idea.md files for legacy features that lack formal specification or pipeline status documents. It introduces strict regex patterns and a new **PR:** frontmatter convention to identify a feature's own PR while avoiding false positives from dependency references. The changes include updates to scripts/build_mvp1_dashboard.py, a new comprehensive test suite in backend/tests/unit/scripts/test_dashboard_pr_extraction.py, and documentation updates in architecture.md. Review feedback suggests improving the robustness of the new regex patterns by supporting markdown links consistently and refining the one_liner extraction logic for legacy features.

Comment on lines +509 to +512
_IDEA_STATUS_IMPLEMENTED_RE = re.compile(
r"^\*\*Status:\*\*\s+\*\*Implemented\s*[—\-]\s*PR\s*#(\d+)\b",
re.MULTILINE,
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Pattern B (_IDEA_STATUS_IMPLEMENTED_RE) should support the same markdown link alternation as Pattern A. This ensures robustness if an implemented status line uses a linked PR number, and maintains consistency across the strict idea-body patterns documented in architecture.md.

Suggested change
_IDEA_STATUS_IMPLEMENTED_RE = re.compile(
r"^\*\*Status:\*\*\s+\*\*Implemented\s*[—\-]\s*PR\s*#(\d+)\b",
re.MULTILINE,
)
_IDEA_STATUS_IMPLEMENTED_RE = re.compile(
r"^\*\*Status:\*\*\s+\*\*Implemented\s*[—\-]\s*PR\s*"
r"(?:\[#(\d+)\b\]\([^)]*\)|\[#(\d+)\b\]|#(\d+)\b)",
re.MULTILINE,
)

Comment on lines +517 to +520
_IDEA_SHIPPED_DATELINE_RE = re.compile(
r"^\*\*shipped\s+\d{4}-\d{2}-\d{2}\s+as\s+PR\s*#(\d+)\b",
re.MULTILINE,
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Pattern C (_IDEA_SHIPPED_DATELINE_RE) should support the same markdown link alternation as Pattern A for consistency and robustness against linked PR references in legacy datelines.

Suggested change
_IDEA_SHIPPED_DATELINE_RE = re.compile(
r"^\*\*shipped\s+\d{4}-\d{2}-\d{2}\s+as\s+PR\s*#(\d+)\b",
re.MULTILINE,
)
_IDEA_SHIPPED_DATELINE_RE = re.compile(
r"^\*\*shipped\s+\d{4}-\d{2}-\d{2}\s+as\s+PR\s*"
r"(?:\[#(\d+)\b\]\([^)]*\)|\[#(\d+)\b\]|#(\d+)\b)",
re.MULTILINE,
)

Comment thread scripts/build_mvp1_dashboard.py Outdated
Comment on lines +782 to +783
one_liner = _extract_one_liner(spec, source_dir=folder_path)
pr = _extract_pr_number(pipe, plan, spec)
pr = _extract_pr_number(pipe, plan, spec, idea)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

In _load_implemented, the one_liner extraction should fall back to _extract_idea_problem(idea) if spec is missing, consistent with the logic in _load_planned. This ensures that legacy idea-only features display their problem description in the dashboard summary column instead of falling back to the generic "Complete" status line. Additionally, consider including idea in the status_line extraction (at line 791) for better descriptive coverage of legacy folders.

Suggested change
one_liner = _extract_one_liner(spec, source_dir=folder_path)
pr = _extract_pr_number(pipe, plan, spec)
pr = _extract_pr_number(pipe, plan, spec, idea)
one_liner = (
_extract_one_liner(spec, source_dir=folder_path)
if spec
else _extract_idea_problem(idea, idea_dir=folder_path)
)
pr = _extract_pr_number(pipe, plan, spec, idea)

SoundMindsAI and others added 2 commits May 23, 2026 16:37
Gemini Code Assist surfaced 3 Medium findings on PR #221:

1. Pattern B (`_IDEA_STATUS_IMPLEMENTED_RE`) was missing the markdown-
   link alternation that Pattern A carries. Added the same
   `(?:\[#(\d+)\b\]\([^)]*\)|\[#(\d+)\b\]|#(\d+)\b)` alternation for
   consistency. Purely additive — never reduces matches.

2. Pattern C (`_IDEA_SHIPPED_DATELINE_RE`) — same fix as #1. Symmetric
   alternation across all three strict patterns now.

3. `_load_implemented`'s one-liner extraction used `_extract_one_liner
   (spec)` only — returning empty for legacy idea-only folders. Added
   `_extract_idea_problem(idea)` fallback (symmetric with `_load_planned`)
   so idea-only legacy folders now render their Problem text in the
   dashboard's one-liner column instead of going blank.

Empirical verification re-run: regen produced clean output. Status
columns for the strict-pattern targets (chore_create_study_modal_e2e_
stability → PR #161, chore_precommit_node_path_resolution → PR #171)
remain correctly populated. The new one-liner fallback adds visible
narrative text for many idea-only rows (bug_*, chore_*) that previously
showed empty/Complete-only — material UX improvement on top of the
PR# extraction this chore primarily delivers.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…5 final review)

GPT-5.5 final review caught a subtle bug in `_extract_metadata_block`:
when an idea body begins with metadata-key lines (NO `# ` title at the
top), a later `# ` line within the 30-line cap was treated as the title
(because `title_seen` was only set on `# ` lines) — letting any
`**PR:**` line that followed the body H1 stay inside the metadata-
block search scope, violating FR-3's "title line allowed ONLY as the
first non-blank line" rule.

Fix: replace `title_seen` with `nonblank_seen`. Once ANY non-blank
line (metadata or otherwise) has been processed, a subsequent `# `
is a body heading and stops the block.

New regression test:
`test_h1_after_metadata_is_body_heading_not_title` constructs the
exact case GPT-5.5 flagged (metadata-first, body H1 at line 4,
`**PR:** #999` at line 5) and asserts both the helper and
`_extract_pr_number` reject #999.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@SoundMindsAI

Copy link
Copy Markdown
Owner Author

Review adjudication (Gemini Code Assist + GPT-5.5 final review)

Commits landing fixes: 5a90d989 (Gemini), d03e3d5f (GPT-5.5 final).

Gemini Code Assist (3 findings)

# Sev Location Verdict Notes
1 Medium scripts/build_mvp1_dashboard.py:512 (Pattern B regex) Accepted Fixed in 5a90d989 — added the same markdown-link alternation (?:\[#(\d+)\b\]\([^)]*\)|\[#(\d+)\b\]|#(\d+)\b) Pattern A carries. Purely additive; never reduces matches. Symmetric across all three strict patterns now.
2 Medium scripts/build_mvp1_dashboard.py:520 (Pattern C regex) Accepted Same fix as #1 in 5a90d989.
3 Medium scripts/build_mvp1_dashboard.py:783 (_load_implemented one-liner) Accepted Fixed in 5a90d989 — added _extract_idea_problem(idea) fallback (symmetric with _load_planned). Idea-only legacy folders now render meaningful one-liners in the dashboard instead of empty/Complete-only. Material UX improvement on top of the chore's primary PR# extraction value.

GPT-5.5 final review (2 findings)

# Sev Location Verdict Notes
1 Medium docs/00_overview/MVP1_DASHBOARD.md:151 (this chore's own planned row shows [PR #4] merged 2026-05-15) Deferred Counter-evidence: explicitly documented as cosmetic-only in the PR body's "Cosmetic anomaly" section. The Plan-section row shows misleading PR# (extracted by the pre-existing priority-3 fuzzy regex from AC-body narrative quoting OTHER features' merge events). Resolves automatically when this PR merges — _load_implemented takes over the row rendering and reads the actual PR# from finalization. The underlying priority-3 weakness is captured as chore_dashboard_regen_quoted_pr_false_positive. Tightening the priority-3 fuzzy regex is explicitly out of scope per spec §3 ("Changing _extract_pr_number's priority 1–3 logic" — those paths already work; only the new 3.5/3.6 idea-aware paths are in scope).
2 Medium scripts/build_mvp1_dashboard.py:559-568 (_extract_metadata_block title-once flag) Accepted Real bug. When an idea body begins with metadata-key lines (NO # title at top), a later # within the 30-line cap was treated as the title because title_seen was only ever set on # lines. Fixed in d03e3d5f — replaced title_seen with nonblank_seen. Added regression test test_h1_after_metadata_is_body_heading_not_title locking the exact scenario.

Outcomes

Ready for human review + merge.

@SoundMindsAI
SoundMindsAI merged commit 8a6452d into main May 23, 2026
7 checks passed
SoundMindsAI added a commit that referenced this pull request May 23, 2026
…rge (#222)

* docs: finalize chore_dashboard_pr_extraction_from_idea post-PR-221 merge

Moves the chore folder to implemented_features/2026_05_23_chore_
dashboard_pr_extraction_from_idea/ per the impl-execute skill Step 8
finalization workflow. Updates:

- pipeline_status.md → Implementation: Complete (PR #221 squash
  8a6452d, CI green 5/5 across 3 pushes, Gemini 3/3 accepted, final
  GPT-5.5 1 deferred + 1 accepted)
- implementation_plan.md → Status: Complete (PR #221)
- feature_spec.md → Status: Implemented (PR #221)
- state.md → Recent-changes entry; Current-branch prepend; Active-
  feature notes third MVP1.0-cleanup chore.
- MVP1_DASHBOARD + dashboard.html regenerated by pre-commit (folder
  move shifts the chore into the shipped table).

The tangential idea folder `chore_dashboard_regen_quoted_pr_false_
positive/` stays in `planned_features/` — captured by the chore's
empirical verification, not addressed by it.

Alembic head unchanged at 0017_proposals_last_polled_at.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(docs): Gemini PR #222 — paraphrase merged-date triggers + align P3→P2

Gemini Code Assist on PR #222 surfaced 3 Medium findings:

1. MVP1_DASHBOARD.md line 77 + 2. mvp1_dashboard.html line 1207 —
   chore's row showed `merged 2026-05-15` instead of `2026-05-23`
   because spec/plan content contained literal `(squash-merged
   2026-05-15…)` precedent quotes that `_extract_merged_date` regex
   picked up. Fixed by paraphrasing the two trigger lines in the
   chore's now-implemented spec + plan; regen now shows the correct
   merged 2026-05-23.

3. state.md tier mismatch on chore_dashboard_regen_quoted_pr_false_
   positive — labeled P3 in the idea but coerced to P2 by the dashboard
   regen (only P0/P1/P2/Backlog recognized). Set to P2 explicitly to
   keep the two sources aligned (same fix pattern as
   chore_e2e_seed_acme_idea_obsolete from the prior chore).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
SoundMindsAI added a commit that referenced this pull request May 23, 2026
Merge origin/main into feature/auto-followup-studies; main brought
chore_dashboard_pr_extraction_from_idea (PR #221) +
chore_migration_test_head_brittleness (PR #219) which moved both
folders to implemented_features/ and updated the dashboard regen
script. State.md "most recent meaningful changes" reconciled to
preserve both branches' entries in chronological order. Dashboards
re-rendered via scripts/build_mvp1_dashboard.py.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
SoundMindsAI added a commit that referenced this pull request May 25, 2026
…lf-triggering + capture priority-4 follow-on

GPT-5.5 final-review caught the chore's own dashboard row still showed a
wrong PR# despite the priority-3 fix. Root cause: spec/plan contained
inline `PR #N merged YYYY-MM-DD` example fixtures that the dashboard regen
self-scans.

Fix: rewrite ACs 6, 7, 8, 9, 10, 12 in feature_spec.md and Story 1.3 task
description in implementation_plan.md to reference the test method names
instead of inlining the literal Python source. Keeps human-reader value
(tests remain the source of truth) while removing self-triggering content.

After this rewrite + regen, the dashboard now extracts PR #221 from the
idea.md "Depends on" footnote (priority-4 last-resort fallback), NOT
the priority-3 backtick-quoted false positive this chore addresses.
That's a DIFFERENT bug class, captured as a follow-on chore:
chore_dashboard_regen_priority4_dependency_cite_false_positive.

Tests still pass: 8 in TestBacktickStripPriority3, 35 total in
test_dashboard_pr_extraction.py.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
SoundMindsAI added a commit that referenced this pull request May 25, 2026
…ber priority-3 fuzzy match (#253)

* docs(dashboard-regen-regex): /idea-preflight refreshes 3 stale claims in idea.md

Preflight audit (against current main 2a24fae) found 3 stale references:
1. _extract_pr_number cited at scripts/build_mvp1_dashboard.py:572 -> actual line 581
2. chore_dashboard_pr_extraction_from_idea cited as "PR-TBD" -> shipped as PR #221 on 2026-05-23
3. "Why deferred" section framed sibling chore as pre-ship -> clarified shipped + added line cite

All other concrete claims verified: _strip_dependency_table_rows at line 488,
priority parser at lines 240-245, both regexes (lines 629/632) match
character-for-character, bug_dashboard_depends_on_column_bloat folder exists,
test file backend/tests/unit/scripts/test_dashboard_pr_extraction.py present.

Folder name "chore_dashboard_regen_quoted_pr_false_positive" is acceptable
(6 tokens, intent-clear). No rename needed.

Decision locked: Option A (backtick-scope strip) is the chore's recommended
implementation per idea's Recommendation section. Option C (opt-in marker) as
follow-up if A leaves residual false positives.

Sibling coordination: chore_dashboard_pr_extraction_from_idea (PR #221) +
bug_dashboard_depends_on_column_bloat (PR #208) both shipped 2026-05-23. No
in-flight feature touches scripts/build_mvp1_dashboard.py.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(dashboard-regen-regex): /spec-gen ships feature_spec.md (3 GPT-5.5 cycles)

Generates feature_spec.md and pipeline_status.md for the dev-infra script chore
that adds `_strip_backtick_quoted_segments` to scripts/build_mvp1_dashboard.py
and wires it into priority-3 of `_extract_pr_number` to stop matching
backtick-quoted PR-merge phrases (Option A per idea's Recommendation).

5 FRs, 7 ACs (AC-6 through AC-12), single phase, two-PR rollout.

GPT-5.5 cross-model review converged in 3 cycles:
- Cycle 1: 1 Low (AC-7 missed single-line triple-backtick fences). Accepted ->
  added AC-12, extended FR-1 to enumerate all 3 fence flavors (multi-line,
  single-line, empty), renamed AC-7 to "multi-line", bumped test count 6 -> 7.
- Cycle 2: 2 Low (regex hint `+` would skip empty inline spans per AC-11;
  4 stale "6 tests" references). Both accepted, patched regex hint to `*`
  and updated all 4 references to 7.
- Cycle 3: 0 findings -> stop rule satisfied.

Auto-regenerated MVP1_DASHBOARD.md from mvp1-dashboard-regen pre-commit hook.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(dashboard-regen-regex): /impl-plan-gen ships implementation_plan.md (2 GPT-5.5 cycles)

5 stories across 2 epics: Epic 1 = 4 content stories in PR A; Epic 2 = 1
finalization story in PR B.

GPT-5.5 review converged in 2 cycles:
- Cycle 1: 2 findings -> both accepted, patched.
  - Low: Epic 1 gate commit arithmetic 6 vs 7 -> fixed to 7.
  - Medium: regex matched exactly-3 backticks but spec said 3-or-more ->
    changed to `{3,} for spec-compliance.
- Cycle 2: 0 findings -> stop rule satisfied.

Auto-regenerated dashboards from pre-commit hook.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(dashboard): add _strip_backtick_quoted_segments helper (FR-1, Story 1.1)

New module-level helper at line 499 of scripts/build_mvp1_dashboard.py,
placed immediately after _strip_dependency_table_rows. Removes three
fence flavors (multi-line triple-backtick, single-line triple-backtick,
empty triple-backtick) via Pass A regex `\`{3,}.*?\`{3,}` with re.DOTALL,
then strips inline backtick spans (including empty ``) via Pass B regex
`\`[^\`\n]*\``.

The 3-or-more backtick quantifier accommodates markdown's 4+ backtick
convention for embedding 3-backtick blocks per spec FR-1.

Not yet wired into _extract_pr_number — that's Story 1.2.

DoD verification: function exists at line 499; importable; 5 smoke cases
all return expected output (plain unchanged, multi-line stripped,
single-line stripped, inline stripped, empty inline + empty fence both
removed without raising).

Story 1.1 / FR-1 / AC-10 / AC-11 / AC-12.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(dashboard): wire _strip_backtick_quoted_segments into _extract_pr_number priority-3 (FR-2, Story 1.2)

Modifies the priority-3 combined-text assignment in _extract_pr_number to
run _strip_backtick_quoted_segments BEFORE _strip_dependency_table_rows.
Net effect: backtick-fenced PR# tokens (multi-line, single-line, inline)
never reach the priority-3 fuzzy regexes.

No change to priorities 1, 2, 3.5, 3.6, or 4.

DoD verification: wire-in shape verified by grep; existing
TestPriorityCascade::test_ac9_fuzzy_merged_in_spec_beats_idea regression
guard still PASSED.

Story 1.2 / FR-2 / AC-6 / AC-7 / AC-8 / AC-9.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* test(dashboard): add TestBacktickStripPriority3 with 7 methods (FR-3, Story 1.3)

New test class at line 365 covering AC-6 through AC-12 from the spec.
Adds _strip_backtick_quoted_segments to the existing import block.

DoD: 7 new methods all PASSED; full file = 35 PASSED (28 existing + 7 new).
Regression guard AC-9 confirms priority-3 still matches un-backticked
own-PR prose correctly.

Story 1.3 / FR-3 / AC-6 through AC-12.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(dashboard): note backtick strip in _extract_pr_number priority-3 docstring (FR-4, Story 1.4)

Adds one sentence to the priority-3 description in the _extract_pr_number
docstring (currently lines 615-621) explaining that backtick-fenced
segments are stripped via _strip_backtick_quoted_segments before
dependency-table rows. Cites the new helper by name so future grep finds
the dependency.

No code changes outside the docstring.

DoD: docstring contains both "leak through" sentences (one for backtick
strip, one for dependency-table rows); references new helper by name;
docstring still parses correctly via inspect.

Story 1.4 / FR-4. Completes Epic 1 (PR A content).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(dashboard): backref same-width fence regex + add AC-13 nested-fence test

Phase-gate GPT-5.5 review (Medium finding) caught that the naive regex
`\`{3,}.*?\`{3,}` would close a 4-backtick outer fence at the first inner
3-backtick run, leaving any PR# inside the outer fence after that inner
block un-stripped. Spec FR-1 requires "3 or more backticks", so the
implementation must handle 4+ outer fences containing inner 3-backtick
blocks as one outer unit.

Fix: change the Pass-A regex to `(\`{3,}).*?\1`. The backreference forces
the closing run to be the EXACT same width as the opener, so an inner
3-backtick fence inside a 4-backtick outer doesn't terminate the strip.

Added test_ac13_four_backtick_outer_with_inner_three_backtick_returns_none
to TestBacktickStripPriority3 (now 8 methods covering AC-6..AC-13).

Empirical verification: zero real RelyLoop content uses 4-backtick
fences (grep -r '\`\`\`\`' docs/ scripts/ returned only this chore's own
docstring), so the spec contract was technically violated but no current
content triggered the gap. The fix is preemptive correctness per spec FR-1.

Spec/plan count references (7 → 8) will be updated in the finalization PR
when the folder moves to implemented_features.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(dashboard-regen-regex): rewrite spec+plan to avoid priority-3 self-triggering + capture priority-4 follow-on

GPT-5.5 final-review caught the chore's own dashboard row still showed a
wrong PR# despite the priority-3 fix. Root cause: spec/plan contained
inline `PR #N merged YYYY-MM-DD` example fixtures that the dashboard regen
self-scans.

Fix: rewrite ACs 6, 7, 8, 9, 10, 12 in feature_spec.md and Story 1.3 task
description in implementation_plan.md to reference the test method names
instead of inlining the literal Python source. Keeps human-reader value
(tests remain the source of truth) while removing self-triggering content.

After this rewrite + regen, the dashboard now extracts PR #221 from the
idea.md "Depends on" footnote (priority-4 last-resort fallback), NOT
the priority-3 backtick-quoted false positive this chore addresses.
That's a DIFFERENT bug class, captured as a follow-on chore:
chore_dashboard_regen_priority4_dependency_cite_false_positive.

Tests still pass: 8 in TestBacktickStripPriority3, 35 total in
test_dashboard_pr_extraction.py.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(dashboard): handle double-backtick inline spans in _strip_backtick_quoted_segments

Per Gemini Code Assist High-severity finding on PR #253: the inline-span
regex `\`[^\`\n]*\`` only handled single-backtick spans. Double-backtick
spans like \`\`PR #99 merged\`\` were processed as two empty single-backtick
spans (one at the opener pair, one at the closer pair), leaving the inner
content un-stripped and reaching the priority-3 fuzzy regex as a false
positive.

Fix: change Pass B to `(\`{1,2})[^\n]*?\1` — backreference enforces
same-width close so 2-backtick spans close on 2 backticks (not the inner
single-backtick chars). AC-11's empty `\`\`` still works (group 1 = 1
backtick, `[^\n]*?` = 0 chars, `\1` = second backtick).

Empirical verification:
- AC-11 empty inline still stripped
- New: `\`\`PR #99 merged\`\` more` strips to `text  more` (no PR #99)
- Single-backtick `\`PR #42 merged\`` still stripped
- Full test_dashboard_pr_extraction.py: 36 PASSED

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
SoundMindsAI added a commit that referenced this pull request May 26, 2026
…4 PR# scan (#277)

* fix(dashboard): strip narrative Depends-on footnotes before priority-4 PR# scan

Closes chore_dashboard_regen_priority4_dependency_cite_false_positive
(Option A).

Priority-4's last-resort `#N` fallback at
scripts/build_mvp1_dashboard.py:694 scans the combined pipe+plan+spec
text gated only by `_strip_dependency_table_rows`, which matches
markdown TABLE rows (lines starting with `|`). Narrative inline
footnotes like `**Depends on:** foo PR #208 + bar PR #221 — both
shipped 2026-05-23` flow through unchanged; priority-4 then returns
the first dependency PR# as the feature's own PR.

Surfaced by GPT-5.5 on PR #253's final review when the chore's own
dashboard row showed PR #221 (a sibling's PR) instead of its own.

Fix: add sibling `_strip_dependency_footnote_lines` helper that strips
single-line `**Depends on:**` / `Depends on:` / `**Dependencies:**`
shapes (with optional bullet prefix and optional `**` markers). Apply
after `_strip_dependency_table_rows` in the priority-3/4 composition:
backtick-strip → table-row strip → footnote-strip.

Scope is intentionally narrow:
- Catches `Depends on` / `Dependencies` / `Depended on`, NOT
  `Implemented` (which `_DEP_ROW_RE` catches in tables but is a
  legitimate status line as narrative).
- Single-line only. The idea's cons-list flags multi-line
  `## Dependencies\n\nfoo PR #N` (header form) as a known gap — a
  separate surface that would warrant its own follow-up if observed.

Regression tests (5) in new `TestPriority4DependencyFootnoteFalsePositive`
class:
- minimal two-PR footnote → None
- PR #253's canonical footnote shape → None
- unbolded `- Depends on:` variant → None
- `**Dependencies:**` plural variant → None
- legitimate own-PR `#N` in priority-4 fallback still resolves (negative
  guard against over-stripping)

Live-dashboard verification: running `scripts/build_mvp1_dashboard.py`
against the current working tree reports "no changes (132 features
across 3 release(s))". The fix is forward-looking; no shipped-row
PR# is recomputed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(dashboard): include `+` bullet + singular `Dependency` in footnote strip

Addresses Gemini Code Assist Medium finding on PR #277.

Two minor gaps in `_DEP_FOOTNOTE_RE`'s coverage:

1. `+` bullet marker — standard Markdown allows `+` as a list bullet
   alongside `-` and `*`. Extending `[-*]` → `[-*+]` matches the spec.
2. Singular `Dependency:` — real-world variant for single-dependency
   cites (alongside the existing `Dependencies` plural).

Regex split across continuation strings to satisfy E501 (line-length).

Regression test locks both shapes. Real-data regen still reports
"no changes (132 features across 3 release(s))" — strictly
forward-looking.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@SoundMindsAI
SoundMindsAI deleted the feature/chore-dashboard-pr-extraction-from-idea branch May 31, 2026 20:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant