Metadata-Version: 2.5
Name: ireadthecode
Version: 0.0.1
Summary: A lightweight, dependency-free code review coverage tracker — mark what's actually been read, exclude human-written code, track coverage toward 100%.
Author-email: Jacob Schwartz <jaschwa@umich.edu>
License: MIT
License-File: LICENSE
Keywords: audit,cli,code-review,coverage,developer-tools
Classifier: Development Status :: 2 - Pre-Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Quality Assurance
Classifier: Topic :: Software Development :: Testing
Requires-Python: >=3.8
Description-Content-Type: text/markdown

# ireadthecode

<!-- readcode:badge:start -->
![audit coverage](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fraw.githubusercontent.com%2Fjhschwartz%2Fireadthecode%2Fmain%2F.readcode.json&query=%24.summary.coverage_pct&suffix=%25&label=audit%20coverage&color=red)
<!-- readcode:badge:end -->

> **AI-generated code, under human review.** This codebase was written by
> Claude (Sonnet, Anthropic). The badge above, auto-generated by `readcode
> badge --update-readme README.md`, reflects the percentage of lines a
> human (the author) has actually read and confirmed — not that the code
> is bug-free, secure, or complete, just that someone has looked at it. A
> fresh `init` starts at (or near) 0%; that's expected, not a bug. It rises
> only as lines are actually reviewed and marked.

A lightweight, dependency-free code review coverage tracker — mark what's
actually been read, exclude human-written code, and track coverage toward
100%.

## Why

It's easy to *say* you reviewed an AI-generated codebase and much harder to
prove it, even to yourself. `readcode` tracks, per line, whether a human has
actually looked at it. State lives in a single JSON file (`.readcode.json`)
at the repo root — nothing is sent anywhere, and the file is safe to commit
or gitignore, your choice.

## Install

Not yet published to PyPI. For now:

```bash
pip install -e .
```

(Once published: `pip install ireadthecode`.)

Either gives you the `readcode` command; `python -m ireadthecode` also works.

## Usage

### Core workflow

```bash
readcode init                       # scan repo, seed the manifest
readcode status                     # overall + per-file coverage
readcode status --files             # ...with a per-file breakdown
readcode next                       # suggest the biggest unreviewed file
readcode show path/to/file.py       # print a file with review markers
readcode mark path/to/file.py 10 40   # mark lines 10-40 reviewed
readcode unmark path/to/file.py 10 40 # undo that
readcode note path/to/file.py 22 "double-check this SQL"
```

`mark` and `review` record *who* reviewed each line, for team use — see
[Reviewer attribution](#reviewer-attribution) below.

### Excluding human-written code from the audit

Excluded lines never count toward the audit denominator, so coverage reflects
"percent of code that actually needs review, that has been reviewed."

```bash
readcode exclude-file path/to/hand_written.py
readcode include-file path/to/hand_written.py   # undo

readcode exclude path/to/file.py 40 60          # manual line range
readcode include path/to/file.py 40 60          # undo

readcode exclude-block path/to/file.py 47       # Python-only heuristic:
                                                  # finds the enclosing
                                                  # def/class around line 47
                                                  # and excludes the whole
                                                  # block. For other
                                                  # languages, use `exclude`
                                                  # with a manual range.
```

### Stepwise interactive review

```bash
readcode review                     # walk every file, chunk by chunk
readcode review --file app.py       # just one file
readcode review --chunk-size 15     # lines per chunk (default 20)
```

At each chunk:

| Input | Action |
|---|---|
| `<Enter>` or `r` | mark the whole chunk reviewed, move on |
| `s` | skip, leave as-is, move on |
| `x` | mark the whole chunk excluded (human-written), move on |
| `r <start> <end>` | mark a sub-range within the chunk reviewed |
| `x <start> <end>` | mark a sub-range within the chunk excluded |
| `n <line> <text>` | attach a note to a line, stay on this chunk |
| `q` | save and quit |

### Reviewer attribution

For teams: every `mark` and `review` records who did the reviewing, alongside
the line's content hash, so `show` and `review` display e.g. `(reviewed by
Jane Doe <jane@example.com>)`. Identity resolves in this order:

1. `--reviewer "Name <email>"` on `mark` or `review`
2. the `READCODE_REVIEWER` environment variable
3. `git config user.name` / `user.email` (scoped to this repo)
4. `$USER` / `$USERNAME`, or `unknown` as a last resort

Attribution is stored *inside* the same mark as the content hash (not a
separate line-number-keyed table), so it migrates exactly like the review
status itself under reconciliation — see Safety model below. Marks made
before this feature existed just show as reviewed, unattributed.

### README badge

```bash
readcode badge                            # print a markdown badge line
readcode badge --update-readme README.md  # insert/update it in place
readcode badge --dynamic --update-readme README.md  # see below
```

By default the badge bakes the current percentage into a static
`img.shields.io/badge/...` URL — accurate as of the last time you ran the
command, but it needs re-running (and a new commit) after every review
session to stay current.

`--dynamic` instead points a [shields.io dynamic JSON
badge](https://shields.io/badges/dynamic-json-badge) straight at this repo's
`.readcode.json` on GitHub (`$.summary.coverage_pct`), so the number on the
badge is always whatever's currently committed — no re-run needed after a
review session, just `git push`. It requires a GitHub `origin` remote (auto-detected via `git remote get-url origin`); the badge *color* is still
fixed at whatever it was when you last ran `--dynamic`.

## Safety model

This is the whole point of the tool, so it's worth spelling out clearly:
**every command re-scans the repo first and reconciles marks (both reviewed
and excluded) against current file content — by content hash, not just line
number.**

If a marked line's content changed and no identical line is found nearby, the
mark is **dropped**. Practically, this means:

- Coverage can only go *down* on an edit, never falsely stay up. Editing a
  reviewed line un-reviews it; you have to look at it again.
- Reviewer attribution rides along with the mark: if unrelated lines shift
  elsewhere in the file, a reviewed line's "reviewed by" note follows it to
  its new line number the same way the review status does, via content hash
  — not a separate lookup that could point at the wrong line.
- Exclusions never silently survive a change to the code they were meant to
  exempt. Edit a line you'd marked as human-written/excluded, and it goes
  back into the audit pool.
- Whole-file exclusions (`exclude-file`) only survive if the file is
  byte-for-byte (line-hash-for-line-hash) identical to when it was excluded —
  any change reverts the exclusion.

In short: the tool is built to err on the side of making you review *more*,
never less, after code changes.

## License

MIT — see [LICENSE](LICENSE). 
