Skip to content

feat(group-td): frontend-group detection + reconcile marker#37

Merged
samestrin merged 4 commits into
mainfrom
feat/group-td-frontend-detection
May 20, 2026
Merged

feat(group-td): frontend-group detection + reconcile marker#37
samestrin merged 4 commits into
mainfrom
feat/group-td-frontend-detection

Conversation

@samestrin

Copy link
Copy Markdown
Owner

Summary

Adds frontend-detection to group_td so consumers can route TD groups to the right resolution flow (browser vs no-browser).

  • New TDGroup.Frontend bool field in JSON output, populated via an any-item rule (one frontend item → group flagged frontend).
  • New marker comment <!-- frontend-groups: N,M --> emitted by writeGroupedMarkdown after each section header.
  • Detection logic ported verbatim from claude-prompts/resolve-td.md:664-670 (extension allowlist, Reflex .py + UI category, category-keyword substring, case-insensitive).

Consumed by claude-prompts#NN (/reconcile-code-review reads the marker and suggests --visual commands paired across --mcp=playwright|devtools for parallel resolution).

Behavior

  • Marker only emitted when ≥1 integer-numbered group is frontend (all-backend sprints → no comment, common case stays clean).
  • Solo groups intentionally excluded — Solo's "number" is 0/"Solo" label, /resolve-td's per-item check handles Solo's visual decision at runtime.
  • Unnumbered groups (--assign-numbers not passed) intentionally excluded — reconcile builds /resolve-td --group=N commands which require integer numbers.
  • Safe for scanExistingActiveGroupNumbers and renumberActiveGroupsInPlace — both only parse | ... | table rows, HTML comments silently skipped.

TDD cadence

5 commits, each pairing test additions with the smallest implementation that makes them pass. Final commit adds adversarial-review edge-case tests (uppercase extensions, no-colon FILE_LINE, Reflex case-insensitive, no-assign-numbers).

Test plan

  • go test ./internal/support/commands/ -cover — 81.0% coverage
  • go test ./... — full repo green, no regressions
  • Integration smoke: 9-item fixture with 3 mixed groups → <!-- frontend-groups: 2 --> written correctly
  • --renumber on file with marker → table preserved, no crash

samestrin added 4 commits May 19, 2026 17:42
Adds two helpers and a Frontend bool field on TDGroup. Mirrors the
per-item frontend rule from claude-prompts resolve-td.md:664-670:

  1. File extension in .tsx/.jsx/.svelte/.vue/.html/.css/.scss
  2. .py with category in ux/accessibility/layout/ui (Reflex)
  3. Category contains any of accessibility/ux/layout/ui/responsive/
     visual/css/touch/frontend (substring, case-insensitive)

detectFrontendGroup uses an any-rule: one frontend item flags the whole
group. Over-recommending is cheap because /resolve-td's per-item visual
check still skips backend items within a frontend-flagged group.

The Frontend field is populated by groupItems in a follow-up commit;
this commit only lands the helpers and field declaration. Tests bundled
because the repo's pre-commit go-vet hook rejects code that won't compile.

Tests: 14 unit tests cover all rule branches, missing-field edges, empty
inputs, case-insensitive matching, and the any-rule for groups.
One-line addition in the final loop that builds the result groups slice:
g.Frontend = detectFrontendGroup(g.Items). Now downstream consumers see
the boolean in JSON output without any other call-site changes.

Tests:
- TestGroupItems_PopulatesFrontendField: split-mode groups (one .tsx,
  one .go) get Frontend=true and false respectively.
- TestGroupItems_FrontendFieldAnyRule: mixed group with one .tsx among
  backend items gets Frontend=true (verifies any-item rule survives
  groupItems boundary, not just the helper).
After the section header, emit a single HTML comment listing the
integer group numbers of frontend groups:

  <!-- frontend-groups: 2,4,7 -->

/reconcile-code-review.md greps this marker to know which groups need
the --visual flag when suggesting /resolve-td commands.

Behavior:
- Only emitted when ≥1 frontend group is present (no comment for
  all-backend sprints — keeps the common case clean).
- Solo group excluded by design: its "number" is 0 / "Solo" label,
  /resolve-td's per-item check handles Solo's visual decision at runtime.
- Unnumbered groups (assignNumbers=false) excluded: reconcile suggests
  commands by group number, which won't exist for these callers.
- Safe for scanExistingActiveGroupNumbers / renumberActiveGroupsInPlace:
  both only parse `| ... |` table rows, HTML comments are silently skipped.

Tests:
- EmitsFrontendComment: mixed frontend/backend → comment present.
- NoFrontendCommentWhenAllBackend: all backend → no comment.
- FrontendCommentSkipsSolo: HIGH .tsx that lands in Solo → no comment.
- FrontendCommentDoesNotBreakRenumber: --renumber on file with comment
  succeeds and preserves table structure.
Added during cumulative adversarial review:

- TestDetectFrontendItem_ExtensionCaseInsensitive: .TSX/.CSS/.HTML
  uppercase extensions still detect (filepath.Ext + ToLower already
  handle this; test pins the contract).
- TestDetectFrontendItem_NoFileLineColon: FILE_LINE without :line suffix
  (legacy sources) still extracts extension correctly.
- TestDetectFrontendItem_ReflexPyCaseInsensitive: explicit verification
  that the Reflex .py + UI-category rule path is case-insensitive too
  (it shares categoryLower with rule 3 but the rubric test missed it).
- TestWriteGroupedMarkdown_NoCommentWithoutAssignNumbers: without
  --assign-numbers, group.Number is nil; comment must be suppressed
  because reconcile builds /resolve-td --group=N commands.

All previously-shipped tests still green. Coverage holds at 81.0%.
@samestrin samestrin merged commit b36751f into main May 20, 2026
8 checks passed
@samestrin samestrin deleted the feat/group-td-frontend-detection branch May 20, 2026 01:39
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