Skip to content

feat: verified tech-stack fingerprint — language mix from merged-PR diff lines #53

Description

@gkanitz

Context

Slice D of the v0.2 "Meaning" wave. Shared design context:
docs/superpowers/specs/2026-07-04-impact-roadmap-design.md (PR #47).

Research says tech-stack fit is a recruiter's first filter — and the
report currently says nothing about stack. This slice adds a verified
language mix derived from the subject's own merged work. Unlike
CodersRank/GitRoll-style profiles it is attested, private-repo, and never
touches code: extensions and line counts only, via #49's GraphQL diff-shape
path.

Goal (vertical slice)

Diff-shape data (#49) → extension→language aggregation → schema block →
rendered share bar, end to end.

In scope

  • Embedded curated extension→language mapping (~40 common languages plus
    bucket categories Config (yml/yaml/json/toml/ini/xml…), Docs
    (md/rst/adoc/txt…), and Other for unknown or extensionless files).
    Table-driven tests over the mapping.
  • Aggregation basis: the subject's merged PRs with diff data; weight =
    additions + deletions per file; window-wide aggregate only (no per-repo
    attribution).
  • Shares as whole percents; every language < 3 % folds into Other
    (privacy safeguard: niche internal tech never leaks).
  • Suppression: section omitted with a
    collaboration.suppressed {section: "language_mix", reason: ...} entry
    when < 5 merged PRs have diff data. (Shared additive suppressed block is
    also described in the PR-size slice; first to merge introduces it.)
  • Schema (additive): collaboration.language_mix {basis: "merged_pr_diff_lines", pr_count, total_lines, languages [{name, share_pct}], other_share_pct}. total_lines is the summed diff-line
    weight behind the shares — the v0.3 career merge needs it to recombine
    mixes from multiple source reports line-weighted (spec: Multi-source
    composition).
  • Render: horizontal share bar (existing SVG chart helpers) with an honesty
    caption: "basis: diff lines across N merged pull requests". Neutral
    presentation — no proficiency claims, this is exposure, not skill grading.

Out of scope

  • The repo Languages API (must not be called — it describes the repo,
    not the subject). Per-language trend over time (later wave). Skill or
    proficiency wording.

Design constraints

Acceptance criteria — TDD

Success (write these tests first; all must pass)

  1. Mapping table test: representative extensions resolve to their language
    (go→Go, ts/tsx→TypeScript, py→Python, …), config/docs extensions
    to their buckets, unknown (xyz) and extensionless (``) to Other.
  2. Weighted aggregation over a multi-PR fixture: shares are line-weighted
    (not file-counted) and sum to 100 ± 1 after rounding; total_lines
    equals the summed additions+deletions of all measured files
    (consistency test).
  3. A language at 2 % in the fixture folds into Other and its name appears
    nowhere in JSON or HTML; at 3 % it appears.
  4. Section omitted + suppressed entry at 4 merged PRs with diff data;
    present at 5.
  5. Provider reports diff shape unsupported → section absent, report still
    validates and renders.
  6. Schema round-trip incl. Validate; pre-v0.2 sample JSON still validates.
  7. Rendered golden: share bar with whole-percent labels and the basis
    caption naming the measured PR count.
  8. No file path and no seeded prohibited string appears anywhere in output
    (extends the seeded-strings test with a below-threshold language name —
    e.g. seed Brainfuck at 1 % and assert absence).
  9. Copy contains no proficiency/grading words (expert, proficient,
    skilled, mastery added to the wordlist test).

Failure — QA red flags (any one observed → reject the PR)

Parallel-work contract

  • Territory: metrics/ (new languages file + embedded mapping),
    render/ (new chart wiring + template partial), goldens.
  • Shared, additive-only: report/report.go (new block only),
    render/templates/sections/30-collaboration.tmpl (include line only).
  • Depends on: feat: GraphQL diff-shape fetch — per-PR file stats without patch content (GitHub + GitLab) #49 (do not start before it merges). Coordinate the shared
    suppressed block with the PR-size slice: identical shape is specified in
    both; whoever merges second rebases.

Definition of done

TDD skill followed; all success criteria green; go test ./... passes;
PR references this issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    readyLoop-ready: this org's picker reads this labelready-for-agentTriage complete; ready for an agent to pick up

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions