Skip to content

feat(mcp)!: expose atomic actor and contribution tools - #268

Merged
morluto merged 9 commits into
mainfrom
agent/atomic-actor-corpus-tools
Aug 3, 2026
Merged

feat(mcp)!: expose atomic actor and contribution tools#268
morluto merged 9 commits into
mainfrom
agent/atomic-actor-corpus-tools

Conversation

@morluto

@morluto morluto commented Aug 3, 2026

Copy link
Copy Markdown
Owner

Description

GitContribute now models GitHub accounts as first-class actors and exposes atomic acquisition and corpus primitives instead of prescriptive landscape and contribution workflows.

The actor corpus keeps stable node-ID identities, observed login aliases, nullable profile facts, independently refreshable facets, and period-scoped contribution data. Live user search records identity stubs only. Exact profile, social-account, organization, pinned-item, repository-relationship, and contribution synchronization remain separate bounded operations. Offline reads return snapshot tokens, explicit observation times, authorization scope, and unknown or truncated coverage without implicit network access.

The GitHub adapter uses the pinned go-github types for REST reads and typed product DTOs at the boundary. GraphQL covers organizations, profile showcase items, contributed repositories, and contribution collections, including GitHub Enterprise endpoint derivation. Complete child sets replace atomically; stale or incomplete observations cannot overwrite a newer complete projection. Contribution search separates global and organization-scoped periods, deduplicates overlapping observations, and binds cursors to every active filter.

Breaking catalog changes

  • corpus.search_code_batch is now corpus.search_code; the old scalar code-search alias is no longer advertised.
  • corpus.list_pull_requests is now corpus.search_pull_requests.
  • github.sync_ci_failures is now github.sync_pull_request_ci.
  • Ranking, issue-set preparation, dossier construction, fix-pattern mining/preview, contribution preflight, related-work lookup, and DeepWiki composite tools are no longer advertised.
  • The replacement catalog exposes facts and coverage; agents choose how to compose them.

Migration 014 creates the actor, alias, observation, profile, relationship, contribution, and FTS projections. Existing repository and thread authors are backfilled case-insensitively. The down migration removes only the new actor projections.

Suggested review order

  1. internal/corpus/migrations/014_actor_corpus.sql, internal/corpus/migrations/015_actor_corpus_revision.sql, internal/corpus/actors.go, and internal/corpus/actor_facets.go
  2. internal/github/client.go, internal/github/user_rest.go, and internal/github/user_graphql.go
  3. internal/app/mcp_actors.go, internal/app/mcp_actor_facets.go, and internal/mcpcontract/actor_contracts.go
  4. internal/mcpserver/actors.go, catalog removals, contract tests, and documentation

The branch contains 38 changed files with 4,327 additions and 689 deletions. Most additions are the actor schema, typed adapters, contract implementation, and behavioral tests; most deletions remove retired workflow documentation and catalog expectations.

Testing

  • make verify passes
  • Focused regression coverage was added for migration casing, stale projection ordering, atomic partial replacement, overlapping contribution periods, organization scope, cursor binding, actor ID resolution, request bounds, Enterprise GraphQL routing, and MCP schemas
  • make test-race passes for storage, concurrency, locking, and cancellation paths
  • make docs passes

Compatibility and scope

  • Storage and side-effect invariants remain intact
  • No unrelated cleanup or generated-output churn is included

morluto added 6 commits August 4, 2026 01:29
BREAKING CHANGE: corpus.search_code_batch is now corpus.search_code, corpus.list_pull_requests is now corpus.search_pull_requests, github.sync_ci_failures is now github.sync_pull_request_ci, and prescriptive composite workflow tools are no longer advertised.
@morluto
morluto marked this pull request as ready for review August 3, 2026 17:37
@cursor

cursor Bot commented Aug 3, 2026

Copy link
Copy Markdown

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c68f7abc3c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread internal/corpus/actors.go Outdated
Comment thread internal/corpus/actor_facets.go

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b1a082e9a0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread internal/corpus/migrations/014_actor_corpus.sql
Comment thread internal/app/mcp_actor_facets.go

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8bc7ca5598

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread internal/corpus/actors.go
Comment thread internal/corpus/actor_facets.go Outdated
@morluto
morluto merged commit 6b6fc6f into main Aug 3, 2026
13 checks passed
@morluto
morluto deleted the agent/atomic-actor-corpus-tools branch August 3, 2026 18:28

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

if err := activateActorAlias(ctx, tx, actorID, input.Provider, input.Login, input.NodeID, encodeTime(input.ObservedAt)); err != nil {

P1 Badge Reject alias changes from stale profiles

When a delayed profile read for node U1 has an older source_updated_at but finishes after its old login has been reassigned to U2, the actor/profile updates above are correctly rejected, yet this unconditional call ranks alias ownership by the later local observed_at and can deactivate U2's current alias. GetActor(login) then resolves U1 even though its retained current_login may differ. Fresh evidence in the final tree is the source-order guard at lines 305-307 followed by this unguarded alias write; apply the same ordering decision to alias activation.

AGENTS.md reference: AGENTS.md:L28-L29


stored, err := c.UpsertRepository(ctx, corpusRepoFromGitHub(remote), string(payload))

P2 Badge Preserve watcher counts during contributed-repository sync

For relationship="contributed", the GraphQL adapter never selects a watcher count, so every returned github.Repository has Watchers == 0. This full projection upsert can therefore replace a previously hydrated nonzero watcher count whenever the GraphQL repository has a newer UpdatedAt, or the same timestamp with a later observation sequence, corrupting repository health, search, and dossier facts. Include the watcher total in that query or merge the sparse result without replacing fields it did not retrieve.


if opts.Relationship == "contributed" {
return c.listUserContributedRepositories(ctx, login, opts)

P2 Badge Honor ordering for contributed repository reads

When callers request relationship="contributed" together with sort or order, this branch accepts those contract fields but the GraphQL helper neither forwards nor applies them. With max_pages or max_items_per_user truncation, the persisted relationship snapshot can therefore contain a different subset from the requested created/updated/pushed/full-name ordering. Either implement equivalent GraphQL ordering or reject these fields for the contributed mode.


coverageActors := in.Actors
if len(coverageActors) == 0 {

P1 Badge Report unknown coverage for unfiltered empty searches

When actors is omitted and the contribution query returns no items, this fallback derives zero coverage actors, leaving coverage nil/empty even if every indexed actor lacks synchronization for the requested period. The caller receives total: 0 without the required unknown-coverage signal and may treat missing data as verified absence; this also makes coverage depend on only the current result page when matches exist. Require explicit actors or return bounded/global coverage that represents actors with no matching items as well.

AGENTS.md reference: AGENTS.md:L5-L6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

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.

1 participant