Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

Edits to a '• 1. …' bullet skip rawText/sections silently: normalizeBulletText strips only one marker

Closed
#999 0 comments 0 reactions 1 assignee View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
66/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Active
Tech stack
typescript

Research direction

Start in src/lib/score/group-bullets.ts and score.ts, tracing normalizeBulletText, bulletId, bulletLineMatcher, and applyBulletTextOverrides through modern and legacy keys. Add regression coverage for glyph-plus-numbered bullets across rawText, sections, description, and removedBullets, then run npm run verify; done means edits and removals stay consistent and stored ids still resolve.

Written by the indexing model from the issue text.

Description

bug goose

Problem

A bullet whose line has a glyph marker followed by a numbered marker, for example • 1. Led team of five engineers, can be edited but the edit never reaches the exported text. Nothing reports the miss.

The cause is that normalizeBulletText (src/lib/score/group-bullets.ts) is not idempotent. LEADING_MARKER_RE strips exactly one leading marker:

input normalizeBulletText(x) applied twice
• 1. Led team 1. led team led team
- - foo - foo foo

The edit fold normalises the same text twice on one side and once on the other, and the two results disagree:

  1. score.ts (~L823, bullet extraction) strips the first marker (BULLET_MARKER_RE, falling back to NUMBERED_BULLET_RE). The observation text is therefore 1. Led team of five engineers.
  2. bulletId(text, 0) normalises that. LEADING_MARKER_RE strips the 1., which gives the id 0|led team of five engineers.
  3. applyBulletTextOverrides hands the id's text to bulletLineMatcher, which normalises it again, giving led team of five engineers.
  4. The rawText/sections line • 1. Led team of five engineers normalises once to 1. led team of five engineers. There is no match.

Repro (verified on origin/main @ ba1d5f8)

applyOverrides with a base whose experience line is • 1. Led team of five engineers, observation text 1. Led team of five engineers, and bulletOverrides: { [bulletId(obsText, 0)]: "Led a team of eight" }:

rawText      "• 1. Led team of five engineers"   ← edit did NOT land
description  "Led a team of eight"               ← landed here only
unresolved   []                                  ← and nothing reports the miss

A legacy numeric key ("0") resolving through byIndex hits the same mismatch.

Why it matters

  • The Download PDF and anything else that reads rawText/sections keeps the old bullet while the on-screen role shows the edit. That is the round-trip divergence the edit seam is meant to prevent.
  • unresolved (#769) reports [] because the description match counts as a match, so the #769 channel can't surface it either.
  • Numbered-inside-glyph bullets come from some template exports, so this happens on real résumés.

Proposed fix

Either:

  1. Make LEADING_MARKER_RE strip repeated markers (^(?:[\s ]*(?:[-*•●–▪◦‣▶►·�]|\d+[.)]) *)+), which makes normalizeBulletText idempotent. Check score.ts's extraction and bulletId stability for existing stored ids, since a changed normalisation re-keys any stored id whose text carried a second marker. A migration note or dual-match may be needed.
  2. Or don't re-normalise an already-normalised id text in the matcher, and compare normalizeBulletText(line) against the id text directly, with the legacy branch normalised once. This fixes the mismatch without re-keying, but leaves the function non-idempotent.

Acceptance criteria

  • A test with a • 1. … line (glyph + numbered marker) edits rawText, sections and description through both a modern id key and a legacy numeric key
  • The same case on the removedBullets channel removes the line from all three containers
  • If option 1: normalizeBulletText(normalizeBulletText(x)) === normalizeBulletText(x) is pinned by a test, and stored ids from before the change still resolve
  • npm run verify green

Provenance: found reviewing PR #998, whose resolveOverrideOriginal docblock asserts normalizeBulletText is idempotent.

Dominant language
TypeScript
Stars
11
Forks
4
Avg merge
18h 56m
Merged PRs (30d)
92

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from offlinecv/OfflineCV

All issues in offlinecv/OfflineCV

Similar issues

More TypeScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.