Skip to content

feat: walking skeleton — GitHub repo → metrics → report → HTML (#2) - #13

Merged
gkanitz merged 6 commits into
mainfrom
feat/2-walking-skeleton
Jun 12, 2026
Merged

feat: walking skeleton — GitHub repo → metrics → report → HTML (#2)#13
gkanitz merged 6 commits into
mainfrom
feat/2-walking-skeleton

Conversation

@gkanitz

@gkanitz gkanitz commented Jun 12, 2026

Copy link
Copy Markdown
Owner

Closes #2

Summary

The tracer bullet for CodeRepute: a Go CLI that produces a real schema-v0 report end-to-end against one GitHub repository, exercising every module seam thinly.

  • providerProvider port interface plus the full v1 ActivitySet type shape (pull requests, reviews given, review comments written/received; fields may be unpopulated until later slices).
  • provider/github — REST adapter. Identity is bound to the immutable GitHub account ID resolved via /users/{login} — PRs whose user.id differs are excluded even when the login text matches; git author emails are never consulted. Paginates via Link headers, filters to the report window, captures X-OAuth-Scopes for the coverage stamp. No code path clones the repo or reads file contents — tests assert only /users/* and */pulls endpoints are ever requested.
  • metrics — pure registry; one file per concern registering via init (pullrequests.go computes PRs authored/merged). Follow-ups add files, not edits.
  • report — versioned schema-v0 with mandatory coverage stamp and verification block, optional collaboration/cadence sub-structs. Validate/Parse reject documents missing coverage or verification, with bad schema versions, or unbound subjects. Local builds always emit an explicit "status": "unverified" block.
  • render — report JSON → self-contained HTML (inline CSS, zero external resources), composed from per-section templates under templates/sections/ executed in filename order — new sections are new files.
  • cmd/coderepute — thin wiring: fetch → compute → build → validate → write report.json + report.html.
  • Apache-2.0 LICENSE, README stub, and a CI workflow running go vet ./... + go test ./... on every PR.

Demo evidence

Built the CLI and ran it against the real repo with gh auth token:

$ coderepute -repo grkanitz/CodeRepute -subject grkanitz -out ./out
wrote out/report.json and out/report.html

report.json (zero counts are expected — the repo has no PRs yet; account ID 134092781 confirmed against the live API):

{
  "schema_version": "v0",
  "generated_at": "2026-06-12T00:27:18.723831Z",
  "subject": {
    "platform": "github",
    "username": "grkanitz",
    "account_id": "134092781"
  },
  "coverage": {
    "repos": ["grkanitz/CodeRepute"],
    "window": {
      "since": "2025-06-12T00:27:18.151631Z",
      "until": "2026-06-12T00:27:18.151631Z"
    },
    "token_scope": "admin:public_key, gist, read:org, repo"
  },
  "verification": {
    "status": "unverified",
    "reason": "local run; no CI attestation"
  },
  "collaboration": {
    "pull_requests": { "authored": 0, "merged": 0 }
  }
}

report.html excerpt:

<title>CodeRepute report — grkanitz</title>
...
<h1>grkanitz</h1>
<p class="muted">Collaboration report · github account ID 134092781</p>
...
<span class="badge unverified">unverified</span>

Tests

TDD red-green throughout: report round-trip + table-driven validation rejections; table-driven metrics; GitHub adapter against recorded httptest fixtures (including an impostor PR with identical login text but a different account ID, and a privacy assertion that no content/clone endpoint is ever requested); render self-containment and absent-section behavior; CLI end-to-end against fixtures with negative assertions that seeded PR titles, branch names, and other accounts' IDs never appear in either output.

$ go test -count=1 ./... && go vet ./...
ok  	github.com/grkanitz/coderepute/cmd/coderepute	0.435s
ok  	github.com/grkanitz/coderepute/metrics	0.698s
?   	github.com/grkanitz/coderepute/provider	[no test files]
ok  	github.com/grkanitz/coderepute/provider/github	1.232s
ok  	github.com/grkanitz/coderepute/render	1.023s
ok  	github.com/grkanitz/coderepute/report	0.849s

🤖 Generated with Claude Code

gkanitz and others added 6 commits June 12, 2026 01:19
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…n block

Build/Validate/Parse round-trip; validation rejects missing coverage,
missing verification, bad versions, and unbound subjects. Optional
collaboration/cadence sub-structs establish parallel-work seams.
ActivitySet carries its full v1 shape in the provider package.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
One file per concern registering into the registry; Compute runs all
registered concerns deterministically. Table-driven tests cover empty,
unmerged-only, mixed, and closed-without-merge activity.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…only

Identity is bound to the immutable GitHub account ID resolved through
/users/{login}; PRs by other accounts are excluded even with identical
login text. Paginates via Link headers, filters to the report window,
captures X-OAuth-Scopes for the coverage stamp. httptest fixture tests
assert no content/clone endpoints are ever requested.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sections under templates/sections/ execute in filename order; new
report sections are added as new template files. Inline CSS only, no
external resources. Absent optional sections render nothing.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
coderepute runs against a GitHub repo with a token (flag or
GITHUB_TOKEN), writes validated report.json plus self-contained
report.html. Integration test runs the pipeline against recorded
fixtures and asserts seeded PR titles, branch names, and other
accounts' IDs never reach any output.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@gkanitz

gkanitz commented Jun 12, 2026

Copy link
Copy Markdown
Owner Author

Review round 1 — approved

Independently verified every acceptance criterion: go build/vet/test -count=1 ./... all pass; a live run against grkanitz/CodeRepute produced a valid report.json + self-contained report.html with the correct immutable account ID (134092781) and an explicit unverified verification block, with no PR title or branch name leaking into either output. Schema validation rejects missing coverage/verification (table-driven tests confirm), identity binding is by account ID with an impostor-login fixture proving exclusion, the adapter's recorded-fixture tests assert only /users/* and */pulls endpoints are ever requested (no clone/content paths), and the parallel-work seams (full v1 ActivitySet shape, one-file-per-concern metrics registry, optional collaboration/cadence sub-structs, filename-ordered per-section templates) line up with the territory contracts in #3#6. Non-blocking nits for follow-ups: -repo comma-splitting doesn't trim whitespace; Validate doesn't require a non-empty coverage repo list; #4 will need the one-line cadence wiring in main.go (additive, permitted by its contract). Squash-merging.

@gkanitz
gkanitz merged commit 93c4e3d into main Jun 12, 2026
1 check passed
@gkanitz
gkanitz deleted the feat/2-walking-skeleton branch June 12, 2026 00:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Walking skeleton: GitHub repo → metrics → schema-v0 report → HTML via CLI

1 participant