Skip to content

AI collaboration: recognition ruleset + in-adapter GitHub author classification (foundation) (#121) - #129

Merged
gkanitz merged 3 commits into
mainfrom
agent/issue-121
Jul 28, 2026
Merged

AI collaboration: recognition ruleset + in-adapter GitHub author classification (foundation) (#121)#129
gkanitz merged 3 commits into
mainfrom
agent/issue-121

Conversation

@gkanitz

@gkanitz gkanitz commented Jul 27, 2026

Copy link
Copy Markdown
Owner

Closes #121

🤖 Autonomous loop in progress - DA/QAA rounds are posted as comments below.

gkanitz and others added 2 commits July 27, 2026 23:15
Add embedded, versioned airuleset.json and matcher that classifies PR
authors as recognized AI agent, bot, or human. Wire end-to-end in the
GitHub adapter and record the ruleset version in the manifest.

Files changed:
- provider/recognition/airuleset.json  -- embedded recognition ruleset
- provider/recognition/recognition.go  -- matcher (Classify, Version)
- provider/recognition/recognition_test.go -- matcher unit tests
- provider/provider.go  -- add AuthorClass field to Review
- provider/manifest.go  -- add AIRecognitionVersion to Manifest
- provider/github/github.go  -- classify PR author at someone-else-PR branch
- provider/github/github_test.go  -- integration tests for classification
- report/report.go  -- add AIRecognitionVersion to AccessManifest
- report/manifest_test.go  -- manifest version propagation tests

Key decisions:
- Classify uses layered matching: curated ruleset first, structural bot
  (type:Bot / *[bot] login) second, human fallback third.
- Only the class string leaves the adapter -- colleague identity (login,
  ID, type) is never written to the Review.
- No new API endpoints, neverRequested and route tables unchanged.
- AIRecognitionVersion is omitempty with a zero default for backward
  compat with pre-recognition reports.

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

gkanitz commented Jul 27, 2026

Copy link
Copy Markdown
Owner Author

Round 1 — APPROVED

Gate results

Gate Status Exit code
test PASS 0
vet PASS 0
fmt PASS 0

Gate output

test (exit 0 - PASS)

Full gate output

vet (exit 0 - PASS)

(clean pass - no output)

fmt (exit 0 - PASS)

(clean pass - no output)

QAA rationale

recognition_test.go lines 55-60)

  1. Review carries class string: Verified.

    • provider/provider.go lines 87-92: AuthorClass string field added to Review struct
    • provider/github/github.go line 327: recognition.Classify() called and result stored
    • provider/github/github.go line 354: AuthorClass: rv.authorClass written to Review
  2. No colleague identity leakage: Verified.

    • Test TestFetchActivityAuthorClassification() (github_test.go lines 581-658) explicitly checks that no colleague identity escapes:
      • Loop searches Review dump for "copilot[bot]", "999001" (bot ID), "888001" (human ID)
      • All three forbidden strings fail the Contains check, confirming only class string is recorded
    • Code: pendingReview struct (line 274) carries only authorClass, not user login or ID
  3. No new API endpoints: Verified.

    • provider/manifest.go lines 224-234: githubRouteTable unchanged
    • provider/manifest.go lines 247-253: githubNeverRequested unchanged
    • Code: Author data (Login, Type) already in PR response from existing /repos/{owner}/{repo}/pulls endpoint
    • Type field added to apiUser struct (github.go line 212) with omitempty - data already in API response
  4. Transparency manifest records version: Verified.

    • provider/manifest.go lines 30-33: AIRecognitionVersion int field added to Manifest struct
    • provider/github/github.go line 264: as.AccessManifest.AIRecognitionVersion = recognition.Version()
    • report/report.go lines 245-248: Field propagated to AccessManifest struct
    • report/report.go line 476: Field copied in buildAccessManifest()
  5. Class string in report JSON: Verified.

    • report/manifest_test.go lines 651-694: TestManifestAIRecognitionVersion() verifies:
      • Field present in report.Build() output
      • Field survives JSON marshal/unmarshal round-trip
      • Field non-zero after round-trip (line 691-693)
    • Field properly tagged with omitempty (lines 33, 248) to exclude zero values from JSON
  6. All gates pass: Verified.

    • go test ./... PASS
    • go vet ./... PASS
    • gofmt -l . PASS

Code Quality

  • Version consistency guaranteed via sync.Once (recognition.go lines 30, 55, 88)
  • Case-insensitive login matching (recognition.go lines 48, 56)
  • Thread-safe ruleset loading via sync.Once (proper initialization pattern)
  • Comments clearly explain the three-layer classification strategy
  • Test coverage is comprehensive and adversarial, not decorative:
    • Tests the happy path and the failure modes
    • Tests case-insensitivity for curated entries
    • Tests identity leakage protection explicitly
    • Tests version consistency and non-zero semantics
    • Tests omitempty behavior for zero version

No Issues Found

The implementation correctly fulfills all acceptance criteria, maintains the existing data-minimization promise (no colleague profiles leave the adapter), and includes no extraneous changes or scope creep.

@gkanitz
gkanitz marked this pull request as ready for review July 27, 2026 23:19
@gkanitz
gkanitz merged commit fcf40e9 into main Jul 28, 2026
1 check passed
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.

AI collaboration: recognition ruleset + in-adapter GitHub author classification (foundation)

1 participant