Skip to main content

Comparative attribution analysis tool for take-home hiring submissions on GitHub.

Project description

byline

byline is a comparative attribution toolkit for hiring reviewers. It compares the writing surface of a take-home submission (its READMEs, comments, and shell scripts) against the same candidate's prior public GitHub writing, and reports where the two diverge. Output is framed as a set of stylistic signals for human review, not as a judgement about who wrote the code.

PyPI Python CI License

What this is, what this isn't

byline measures eight stylistic signals on a candidate's submission (em-dash density, emoji-in-headers ratio, sentence length, lexical diversity, typo rate, vocabulary sophistication, banner-comment density, and progress-UX scaffolding), compares each against the candidate's own GitHub baseline, and surfaces the deltas. It also runs a catalogue of phrasing and structural fingerprints against the prose, plus disproportion checks on doc-to-code ratio, diagram inventory, numbered-diagram patterns, and comment density. The intent is to give a reviewer one extra structured data point when deciding whether a submission warrants a follow-up conversation.

byline does not classify writing as machine-authored or human-authored. Nothing in the output asserts authorship, and the framing is comparative attribution analysis rather than detection. The tool is built around the assumption that humans and machines both write prose, and the only signal worth surfacing is whether the submission diverges sharply from the candidate's own observable writing history. Treat every report as one input among many, alongside the interview, code review, and reference checks.

Install

byline ships in two modes. The base install is deterministic and has no LLM dependency; the [llm] extra adds the Anthropic SDK and unlocks the subcommands that call Claude.

The distribution is published on PyPI as byline-audit (the byline name on PyPI was already taken by an unrelated abandoned project); the import name and CLI entry point are still byline.

# Base install (deterministic features only)
pip install byline-audit

# Full install (includes LLM-powered subcommands)
pip install 'byline-audit[llm]'

The questions and chat subcommands require both the [llm] extra and a working ANTHROPIC_API_KEY in the environment. The align subcommand runs deterministically by default; the optional semantic pass is enabled via flag and also needs the extra and the API key. Every other command (scan, baseline, audit, and the deterministic align) works on the base install.

Quickstart

# Audit (now includes history forensics, alignment, voice, boilerplate by default)
byline audit ./candidate-submission --candidate candidate-username

# Standalone alignment check
byline align ./candidate-submission

# Standalone alignment with semantic mode (requires LLM)
byline align ./candidate-submission --with-llm

# Generate interview questions (requires LLM)
byline questions ./candidate-submission --candidate candidate-username -n 8

# Open an interactive chat session over the audit (requires LLM)
byline chat ./candidate-submission --candidate candidate-username

# Just the target, without a baseline
byline scan ./candidate-submission

# Build the baseline alone
byline baseline candidate-username

A byline scan run produces a short Markdown summary. The shape (illustrative, abbreviated):

## Overall signal

**Overall signal: mixed.** Some metrics diverge from baseline while others
align; treat as a soft signal worth a closer look.

## Fingerprint findings

### README.md

- phrase / <pattern>: "<excerpt around the matched phrase>"
- structure / emoji_header_cluster: 6 emoji-prefixed headers
- phrase / <pattern>: "<excerpt around the matched phrase>"

Run byline --help (or byline <command> --help) for the full flag list.

What's new in v0.2

  • Commit history forensics: timeline burst detection, first-commit paste detection, commit-message style profiling against the README, and author identity drift across the commit log.
  • Documentation-implementation alignment: a deterministic pass cross-checks README-documented CLI flags, env vars, commands, and dependencies against the code; an optional semantic pass under [llm] adds Claude-driven gap detection.
  • Within-repo self-baseline: compares the stylistic profile of commit messages, the README, and code comments, and reports the within-repo divergence as consistent, notable, or significant.
  • Voice and AI-use disclosure: first-person voice density in the README is reported as a positive presence signal, and explicit AI-use disclosure is surfaced as a positive trust signal that shifts the overall label toward aligned.
  • Boilerplate meta-file density: measures how completely a canonical meta-file slate is populated, with a severity bump for small repos where a full set is more notable.
  • New CLI subcommands: byline align (deterministic by default), byline questions (interview-question generator, LLM required), and byline chat (interactive REPL over the audit, LLM required).
  • New opt-out flag on byline audit to skip the commit-forensics pass when the input is a directory of files rather than a real git repo.

Limitations

This report presents stylistic signals comparing a candidate's submission to their own observable writing baseline. It is one input into a hiring decision, never a determination of authorship, and must not be treated as evidence of misconduct. False positives are possible — non-native English writers, proofread submissions, tutorial-derived code, and team-authored repos can all produce divergent signals.

Gameability. A candidate who knows byline is part of the process can adjust their style: rewrite the README in their own voice, strip emoji headers, drop the banner-comment scaffolding from shell scripts. The tool is most useful when the comparison is run silently, and when the reviewer treats a clean report as no signal rather than positive evidence.

False positives. Several plausible candidate profiles can produce divergent signals without any underlying authorship problem. Non-native English writers may show shifted typo rates and sentence-length distributions versus a baseline collected from native-language prose. Candidates who proofread their submission heavily can look stylistically different from their casual GitHub commits. Tutorial-derived code carries the tutorial author's voice. Team-authored repositories blend multiple writers. Candidates with sparse public GitHub history have small baselines, and small baselines produce noisy deltas; the report flags this case.

Scope. byline is English-only and GitHub-only. It reads prose and shell scripts; it does not analyse the code itself for stylistic signals, and it does not attempt to identify which model (if any) generated a passage. Those questions are out of scope.

History forensics requires a real git repo. The commit-history pass (history.timeline, history.messages, history.identity, history.file_evolutions) reads from .git. A directory of files that was extracted from a zip or copied without its git history will produce a zeroed HistoryFindings result. When you want history signals, clone the submission with its full git history rather than unpacking a snapshot. The audit command also exposes a flag to skip this pass entirely when you know the input has no usable history.

Ethical use

Disclose to candidates that this analysis is part of your review process before they submit. Use the report as one input alongside the interview, code walkthrough, and reference checks, never as the sole basis for a decision. Do not share the report with the candidate as an accusation; if a follow-up conversation is warranted, ask open questions about how the submission was put together and let the candidate explain. Reviewer judgement matters more than the tool's output. When in doubt, weight the human signal.

How it works

The audit pipeline computes a StyleProfile for the candidate's baseline corpus and a matching profile for the submission, then emits a per-metric ComparativeDelta with a severity bucket (aligned, notable, significant, extreme). A separate pass scans Markdown and shell files for catalogued phrasing and structural patterns; a third pass measures doc-to-code, diagram inventory, and comment-density ratios. The three streams combine into a single overall signal label. See docs/methodology.md for the full breakdown of metrics, fingerprint patterns, disproportion heuristics, and severity scoring.

Contributing

Run tests with pytest. Lint with ruff check .. PRs are welcome; please run the full test suite before submitting, and keep new prose in the docs framed comparatively (signals, divergence, indicators) rather than as detection language.

License

Apache 2.0. See LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

byline_audit-0.2.0.tar.gz (155.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

byline_audit-0.2.0-py3-none-any.whl (121.8 kB view details)

Uploaded Python 3

File details

Details for the file byline_audit-0.2.0.tar.gz.

File metadata

  • Download URL: byline_audit-0.2.0.tar.gz
  • Upload date:
  • Size: 155.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for byline_audit-0.2.0.tar.gz
Algorithm Hash digest
SHA256 2e26c2487a9093bc8790a7c20239fdf55ef334a4611fdc02837b042c78b83a0e
MD5 1f999169e675aa48ae62b74f5fbc7dd3
BLAKE2b-256 29cfb6a7d161dcc841091a32390be3c2e9360d6023787f0a2e86ba3bf1d980fd

See more details on using hashes here.

File details

Details for the file byline_audit-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: byline_audit-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 121.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for byline_audit-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 11732d14e6c6257aecb58a2763cb3c8d8aa1c08925897e5eb98042cbe28dba5f
MD5 9da45cbc0c77e7c6137dd5d781ad7d84
BLAKE2b-256 b5c44274f49531235a0a24780c4f05c16352c639a9f3c498e317e92803245082

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page