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

Company-scope resolution auto-attaches by normalised key, but #765 and company-key.ts say the key only suggests

Open
#986 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
5/5
Estimated time
Over a week
Newbie friendliness
35/100
Issue type
Refactor
Clarity
Mostly clear
Activity status
Active
Tech stack
typescript

Research direction

Start by comparing #765 with src/lib/storage/company-key.ts:14-19, then inspect src/lib/letters/resolve-letter.ts and src/lib/resume/resolve-variant.ts alongside PRs #906 and #983. Decide whether company matches auto-attach or require confirmation; done means #765, the docblock, both resolver docblocks, and the relevant UI or tests consistently enforce the chosen contract.

Written by the indexing model from the issue text.

Description

architecture question

Problem

The three-tier artifact epic (#765) and its child issues disagree about what a company key is allowed to do.

The written contract says the key only suggests. #765, section "Company identity: never inferred, always confirmed":

the normaliser only ever suggests ("You have a letter for Northwind — start from it?"), and the user picks. A false merge is then a suggestion declined, not a letter silently attached to the wrong employer.

src/lib/storage/company-key.ts:14-19 on main says the same thing:

The key is advisory. Per #765 it only ever drives a suggestion the user confirms … Nothing here auto-attaches a letter to a job, which is what makes a collision affordable … Treat a match as evidence, never as identity.

The resolution chains attach by key automatically. #767 and #770 both specify a job → company → standard chain where the company rung matches by deriveCompanyKey(job.company) === record.companyKey, and nobody confirms the match:

  • src/lib/letters/resolve-letter.ts (PR #906): inheritedLetterForJob returns any company letter whose key matches.
  • src/lib/resume/resolve-variant.ts (PR #983): resolveVariantForJob does the same for résumé variants. #770 AC "Download PDF renders the resolved variant for a job in context" then exports that variant.

Failing case

  1. A user creates a company variant for job A at "Acme Co" (a staffing firm). It is stored with companyKey: "acme".
  2. The user saves job B at "Acme, Inc." (a different employer). deriveCompanyKey maps both names to "acme".
  3. Job B resolves to the Acme Co variant with scope: "company". The Download PDF for job B is the résumé tailored for the staffing firm, and the user never confirmed the match.

Under the #765 rule, the worst outcome of this collision was supposed to be a suggestion the user declines. Under the chains, it is a résumé or letter silently attached to the wrong employer: the exact outcome #765 names as the one to avoid. The scope label ("company") reports which rung the chain used. It does not tell the user that the match is only a guess.

Why this needs a decision rather than a patch

Both readings are defensible:

  • The chain is right, and the contract text is stale. Once a user has explicitly created a company-scoped artifact, applying it to the same company is the whole point of that scope. The #765 rule was written for the start-from suggestion and never updated when #767/#770 made company scope load-bearing. Fix: amend #765 and the company-key.ts docblock to say resolution does attach by key. Say what makes that acceptable (for example, the scope label and a visible company name), and note the collision risk the docblock currently calls affordable.
  • The contract is right, and the chains overreach. The company rung stays a suggestion. The first time a job resolves to a company artifact, the UI asks "Use your Acme Co variant for Acme, Inc.?", and resolution reads that confirmation.

Right now main says one thing, and two open PRs implement the other.

Proposed fix

Decide which reading is right, then make #765, company-key.ts and both resolver docblocks say the same thing. If the confirm reading wins, add the confirmation to the #767 and #770 UI steps before their export and reveal surfaces land.

Acceptance criteria

  • #765's "Company identity" section and the company-key.ts docblock describe what the resolution chains actually do
  • If auto-attach is kept: the docblock states the collision risk plainly instead of calling it affordable, and the UI shows the job's company name next to the company scope label
  • If confirm-first is chosen: neither chain returns a company resolution for a job whose match the user has not confirmed, and a test pins this for both lanes

Found while reviewing #983.

Dominant language
TypeScript
Stars
11
Forks
4
Avg merge
2d 17h
Merged PRs (30d)
40

Contributor guide

Open the contributing guide

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.