Skip to content

Diagnose provider identity collisions and approve audited GitHub tag repairs - #167

Merged
unbraind merged 4 commits into
mainfrom
feat/identity-collisions
Oct 22, 2026
Merged

unbraind merged 4 commits into
mainfrom
feat/identity-collisions

Conversation

@unbraind

@unbraind unbraind commented Oct 22, 2026 •

Copy link
Copy Markdown
Owner

Result

Agents can diagnose conflicting provider identities offline with pm github identity and the typed exploreGithubIdentities, planGithubIdentityRepair and applyGithubIdentityRepair SDK exports. A copied prose example appears as a mention; a structured provider link retains provider ownership evidence. Exact external_ref, GitHub tags, native source ownership and contradictory identities on one item remain visible.

Before, imports refused ambiguous ownership but offered no local exploration or reviewed repair surface. Now agents receive compact TOON/JSON graphs with counts and pagination, typed refusals with remedies, and an explicit approval digest for one narrowly scoped tag detach.

Design and scope

Reuses certified complete SDK reads, the existing isolated refresh reader, real SDK mutation previews, durable item transactions, optimistic updated_at matching and native append-only audit. Approval is rechecked under the writer lock. Recovery reconstructs the pre-repair graph to verify the approval digest and exact retained tags, and requires the original SDK journal. The native audit comment alone cannot authorize a repair. SDK transactions remain responsible for recovery, compensation and idempotent replay. Ordinary input files are copied before SDK cache writes; linked roots/entries refuse. No git executable or network is needed.

Repairs remove only the selected conflicting GitHub tag. Ambiguous native/source metadata refuses apply. The pinned SDK cannot clear core external_ref through its item mutation surface, so those repairs return unsupported_repair with an owning-provider remedy. Jira/Linear semantics and core metadata validation remain authoritative. No dependency pins, coverage thresholds or release workflows changed.

Acceptance evidence

Criterion Evidence
Synthetic copied examples and genuine multi-provider items remain distinguishable Real non-git SDK trackers cover prose-only examples, structured Linear/Jira links, link-only ownership, native source owners and single-item contradictions.
Ambiguous identities refuse apply Multiple owners, source metadata, native owners, unsupported references, stale approvals and mismatched/invalid audit hints refuse with typed recovery guidance.
Approved repairs are audited and idempotent Native history/comment audit, optimistic match, locked recheck, injected step_applied interruption/recovery and byte-identical repeat apply.

Blocking review fixes

Finding Fix and regression
Fabricated recovery plan can name a nonexistent owner and arbitrary digest Recompute the approved pre-state graph, validate its digest and exact tag delta, require the SDK journal, and refuse unbound hints with stale_approval before any writes. Tests cover nonexistent owners, altered plans/retained tags and missing journals.
CSV serialization splits a retained keep,me tag Use SDK removeTags for the exact GitHub provenance tags. The regression verifies preview, stored literal tag and byte-identical replay.
Owner URL contradicts its github_number Refuse preview and apply with ambiguous_identity before writes; consistent issue-number metadata is also exercised by the successful comma-tag repair.

Each regression was run with only its corresponding function reverted to the pre-fix implementation; tests and the other fixes remained unchanged:

Function reverted Focused regression Result
applyGithubIdentityRepair forged audit plans with nonexistent owners never authorize recovery writes Exit 1; 0 pass, 1 fail; missing expected rejection.
transaction approved tag detach preserves a stored comma tag byte-identical Exit 1; 0 pass, 1 fail; actual keep and me instead of keep,me.
plan an owner with a conflicting github_number cannot authorize detaching another item Exit 1; 0 pass, 1 fail; missing expected rejection.

All functions were restored before validation. Proofs are recorded on the linked pm item.

Real public corpus

Read-only non-git archive of public unbraind/pm-github main 394129e3a8a607bfc13dd8acc8adfe4704165da2, with git absent from PATH: 296 files, 145 all-status items, 9 identities, 0 collisions, 3 prose mentions, 3 returned nodes/edges, no continuation. Compact JSON: 642 bytes; TOON: 551 bytes. All file bytes and inventory unchanged. Zero real collisions is zero-case evidence; synthetic trackers supply nonempty repair evidence. Fingerprint and method: docs/identity-collisions-validation.md.

Validation

Final pushed head 474dbd9004216e0bd43fd3a92d09532f7855c57f: CI run 39853785873 passed, including all four jobs and both native Bun suites. These are measured counts from the completed job logs on that exact head.

Gate Node Passed / failed / skipped Coverage
npm run release:check 22 1021 / 0 / 0 Exact 100/100/100/100, 18 authored modules
npm run release:check 26 1021 / 0 / 0 Exact 100/100/100/100, 18 authored modules
bun run release:check 22 1021 / 0 / 0 Exact 100/100/100/100, 18 authored modules
bun run release:check 26 1021 / 0 / 0 Exact 100/100/100/100, 18 authored modules

Separate npm run test:bun suites passed 1021 / 0 / 0 across 48 files on each Node matrix leg. Full release suites also have zero cancellations and TODO tests. No thresholds, exclusions, dependency pins or workflows changed.

Local node --test test/identity.test.ts passed 20/20, zero failures/skips/cancellations/TODO, through pm test pm-github-identity-collisions --run --progress --timeout 600. Focused identity.ts coverage is exact 100/100/100/100. Build, typecheck, test typecheck, lint, docstring, zero-duplication, privacy, changelog checks and isolated strict tracker health passed. Full gates ran in CI because of shared-host CPU load. Public-corpus validation was rerun and reproduced the measurements above without source writes.

Fix commit: 474dbd9004216e0bd43fd3a92d09532f7855c57f includes source, regressions, docs, and append-only pm evidence together. PM item: pm-github-identity-collisions. It remains in progress and the implementation claim is released for orchestrator verification. The journal must be retained for recovery; core external_ref clearing remains an explicitly refused pinned-SDK limitation.

@sourcery-ai

sourcery-ai Bot commented Oct 22, 2026

Copy link
Copy Markdown

Sorry @unbraind, you've used your own review budget of 250,000 diff characters for the last 7 days.

You can request another review in 1 day and 4 hours by commenting @sourcery-ai review. Upgrade to get a review now.

@greptile-apps greptile-apps 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.

Your trial has ended. Reactivate Greptile to resume code reviews.

@coderabbitai

coderabbitai Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: 90d86e44-d8c8-41ab-ab67-e4cf20a73106
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@sourcery-ai

sourcery-ai Bot commented Oct 22, 2026

Copy link
Copy Markdown

Reviewer's Guide

This PR adds an offline GitHub/provider identity collision explorer plus a tightly constrained, SDK-audited GitHub tag-detach repair flow, exposed through both CLI and typed SDK APIs, with conservative ownership checks, approval digests, lock/revision validation, recovery/idempotency guarantees, and extensive synthetic and public-corpus validation.

Sequence diagram for approved GitHub identity tag repair

sequenceDiagram
    participant Agent
    participant CLI as pm_github_identity
    participant SDK as IdentitySDK
    participant Reader as readRefreshItems
    participant Planner as planGithubIdentityRepair
    participant Writer as commitItemMutations
    participant History as NativeAuditHistory

    Agent->>CLI: --identity --owner --detach
    CLI->>Planner: planGithubIdentityRepair(pmRoot, identity, owner, detach)
    Planner->>Reader: readRefreshItems(pmRoot)
    Reader-->>Planner: complete item graph
    Planner->>SDK: previewItemMutations(transaction)
    SDK-->>Planner: validated plan and approval digest
    Planner-->>CLI: IdentityRepairPlan
    Agent->>CLI: --approve digest
    CLI->>SDK: applyGithubIdentityRepair(request)
    SDK->>Reader: readRefreshItems(pmRoot)
    Reader-->>SDK: current graph and revisions
    SDK->>Writer: commitItemMutations(updated_at match)
    Writer->>History: append audited tag-detach event
    History-->>Writer: durable transaction receipt
    Writer-->>CLI: changed transaction
Loading

Flow diagram for offline identity diagnosis and scoped repair

flowchart TD
    A[pm github identity] --> B[readRefreshItems complete tracker copy]
    B --> C[Build identity graph]
    C --> D{Inspect exact identity evidence}
    D -->|diagnosis only| E[Return nodes edges counts pagination]
    D -->|owner and detach supplied| F[planGithubIdentityRepair]
    F --> G{Ownership and repair checks pass}
    G -->|no| H[Typed refusal with remedy]
    G -->|yes| I[SDK semantic preview]
    I --> J[Approval digest]
    J --> K{Exact digest approved}
    K -->|no| L[No mutation]
    K -->|yes| M[Writer-lock recheck and updated_at match]
    M --> N[Detach selected GitHub tag]
    N --> O[Append native audit event]
    O --> P[Idempotent replay or receipt]
Loading

File-Level Changes

Change Details Files
Adds offline provider-identity graph exploration with conservative ownership classification, collision detection, prose-mention handling, pagination, and typed refusals.
  • Reads complete tracker metadata through isolated SDK refresh reads without git or credentials.
  • Normalizes GitHub issue and pull identities while preserving opaque Jira/Linear references.
  • Distinguishes claims from copied prose mentions and reports native/provider ownership evidence.
  • Adds bounded TOON/JSON CLI output with corpus counts and continuation offsets.
identity.ts
refresh.ts
index.ts
README.md
docs/identity-collisions.md
docs/identity-collisions-validation.md
Adds an explicitly approved, single-item GitHub tag-detach repair workflow backed by SDK validation and durable audit semantics.
  • Plans only a narrowly scoped tag removal after independently verifying ownership and rejecting ambiguous or source-owned cases.
  • Binds approval to the exact graph, request, item revisions, and 64-character digest.
  • Applies under optimistic revision checks and the writer lock using native SDK transactions and audit history.
  • Supports interrupted-transaction recovery and byte-identical idempotent replay; refuses unsupported external_ref repairs.
identity.ts
index.ts
docs/identity-collisions.md
test/identity.test.ts
Exposes the feature through the public CLI and typed SDK surface and documents the operational contract.
  • Registers github identity exploration, preview, and digest-approved apply modes.
  • Exports exploration, planning, application functions and associated report, edge, node, refusal, and plan types.
  • Updates changelog and README with offline usage, review requirements, and repair limitations.
index.ts
CHANGELOG.md
README.md
docs/identity-collisions.md
Validates behavior against real SDK storage, public read-only corpus data, and isolation/idempotency safety requirements.
  • Covers collision classification, pagination, typed refusals, stale approvals, unsupported repairs, malformed audit hints, and concurrency changes.
  • Verifies interruption recovery, audit attribution, no-git operation, symbolic-link rejection, and unchanged bytes for read-only paths.
  • Records public-corpus fingerprint and zero-collision validation measurements.
test/identity.test.ts
docs/identity-collisions-validation.md
.agents/pm/features/pm-github-identity-collisions.toon
.agents/pm/history/pm-github-identity-collisions.jsonl

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@greptile-apps greptile-apps 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.

Your trial has ended. Reactivate Greptile to resume code reviews.

@greptile-apps greptile-apps 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.

Your trial has ended. Reactivate Greptile to resume code reviews.

@unbraind unbraind left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Orchestrator review (codex review agent, reproduced findings; handed to the feature agent):

VERDICT: BLOCK
FINDINGS:

  • [blocking] identity.ts:151 — Recovery accepts fabricated audit plans without validating their approval binding — a forged history marker with a nonexistent owner and arbitrary digest replaces tags with unapproved values while returning changed:false.
  • [blocking] identity.ts:122 — Comma serialization changes retained tags beyond the approved repair — a stored tag keep,me remains intact in the preview but becomes separate keep and me tags after apply.
  • [blocking] identity.ts:100 — Ownership validation ignores conflicting github_number metadata on the selected owner — an owner declaring issue 1’s URL but issue number 2 still authorizes removing another item’s issue 1 tag.
    SUMMARY: The PR adds offline identity diagnosis and audited, digest-approved tag repairs. All 15 supplied identity tests pass, but they miss these three reproduced approval, tag-preservation, and ownership defects.

@greptile-apps greptile-apps 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.

Your trial has ended. Reactivate Greptile to resume code reviews.

@unbraind unbraind left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Orchestrator review (built-in Claude review agent, verified by the orchestrator; bots are not waited for since 2026-10-22):

VERDICT: MERGE
FINDINGS:

  • none
    SUMMARY: Follow-up at 474dbd9 addresses all three blocking findings: recovery revalidates the graph digest, retained tags and the SDK journal so forged audit plans never authorize writes; tag detach uses the SDK removeTags so a stored comma tag survives byte-identical; an owner with a conflicting github_number is refused before preview and apply. Three named regression tests with revert proofs (20/20 identity tests), gates reported green, mergeable_state clean.

@unbraind
unbraind merged commit 313810a into main Oct 22, 2026
11 checks passed
@unbraind
unbraind deleted the feat/identity-collisions branch October 22, 2026 21:34
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