Skip to content

feat(context-graph): GitHub repo one-shot ingestion skill + CLI trigger#862

Open
Ruchitha1608 wants to merge 2 commits into
potpie-ai:mainfrom
Ruchitha1608:feat/github-repo-one-shot-ingestion
Open

feat(context-graph): GitHub repo one-shot ingestion skill + CLI trigger#862
Ruchitha1608 wants to merge 2 commits into
potpie-ai:mainfrom
Ruchitha1608:feat/github-repo-one-shot-ingestion

Conversation

@Ruchitha1608

@Ruchitha1608 Ruchitha1608 commented Jun 6, 2026

Copy link
Copy Markdown

Summary

  • Adds domain/playbooks/github_repo_one_shot_ingestion.md — a one-shot ingestion playbook for GitHub repositories, direct sibling to the Linear team skill merged in feat(context-graph): one-shot Linear team ingestion skill + CLI trigger #839. Same 3-phase structure (enumerate → drain batches → finalize), same ontology, adapted for commits, PRs, and issues.
  • Adds potpie pot repo ingest <owner/repo> CLI command — mirrors potpie pot linear-team ingest, submits a (github, github_repo, one_shot_ingest) event to the reconciliation pipeline.
  • Adds 6 contract tests enforcing playbook structure and invariants.

Key design decisions

Fix from merged PRs only — unlike the Linear skill (which never emits Fix), this skill emits Fix entities from merged PRs when they link or label a bug. Issues never emit Fix, matching Linear's rule.

Cross-source BugPattern convergenceBugPattern keys (bug_pattern:github-<repo-slug>:<symptom-slug>) are stable and designed to match keys written by the Linear sibling skill for the same symptom, so nodes from both sources merge in the graph without manual linking.

Merge commit and bot author filtering — merge commits (Merge pull request #..., Merge branch '...') and bot authors (logins ending in [bot]) are explicitly skipped to avoid noise in the Activity and Person graphs.

Test plan

  • All 6 contract tests pass (pytest tests/unit/test_github_repo_one_shot_ingestion_skill.py)
  • Existing Linear skill tests unaffected (pytest tests/unit/test_linear_team_one_shot_ingestion_skill.py)
  • potpie pot repo ingest renders in potpie pot repo --help
  • Invalid repo format (missing /, empty owner, empty repo) exits with error

Adds a one-shot ingestion playbook for GitHub repositories, following the
same pattern as the Linear team skill merged in potpie-ai#839.

- Playbook (domain/playbooks/github_repo_one_shot_ingestion.md): phases to
  enumerate commits, PRs, and issues; emits Activity, Person, Fix (merged PRs
  only), BugPattern, and Decision nodes. Merge commits and bot authors are
  explicitly skipped. BugPattern keys are stable and designed to converge with
  the Linear sibling skill for cross-source merge.
- CLI: adds `potpie pot repo ingest <owner/repo>` with owner/repo validation,
  mirroring `potpie pot linear-team ingest`.
- Tests: 6 contract checks enforcing frontmatter, bounded list calls, Fix-from-
  merged-PR-only rule, and current ontology edge names.
@coderabbitai

coderabbitai Bot commented Jun 6, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

This pull request introduces a complete one-shot GitHub repository ingestion feature, consisting of a CLI entry point, a detailed playbook specification, and comprehensive contract tests. The CLI command submits ingestion events; the playbook defines the full procedure including entity mutations and ontology rules; and the tests validate the playbook against specific behavioral contracts.

Changes

GitHub Repo One-Shot Ingestion

Layer / File(s) Summary
CLI ingest command
potpie/context-engine/adapters/inbound/cli/main.py
Implements pot repo ingest subcommand that validates owner/repo, resolves the target pot from --pot/alias or git --cwd, builds a unique source_id, and submits an HTTP event to the Potpie API with source_system="github", event_type="github_repo", action="one_shot_ingest", and payload including repo and count; formats output as JSON or human-readable message and maps 409 to duplicate status.
Playbook specification and procedure
potpie/context-engine/domain/playbooks/github_repo_one_shot_ingestion.md
Documents the complete one-shot ingestion workflow: frontmatter metadata (source system, event/action identifiers, planner enablement), invocation timing and required inputs, enumeration strategy for commits/PRs/issues with batched draining and parallel hydration, stable entity key construction for Activity/Person/Period/Fix/BugPattern/Decision, conditional mutation rules (always emit Activity/Person, emit Fix only from merged PRs, emit BugPattern/Decision from issues with restrictions), explicit prohibitions on Fix/RESOLVED from issues, timeline ontology markers (PERFORMED/IN_PERIOD/RESOLVED/valid_from), and event contract clarifying behavior inside vs. outside the internal agent pipeline.
Playbook contract tests
potpie/context-engine/tests/unit/test_github_repo_one_shot_ingestion_skill.py
Validates the playbook markdown: frontmatter targets one-shot GitHub event with planner enablement, body uses bounded list API calls for commits/PRs/issues with limit=count and no pagination, Fix emission is restricted to merged PRs, Fix and RESOLVED are prohibited from issues, required timeline ontology markers and daily period label format are present while stale ontology names are absent, and bug pattern key includes repo and symptom slug placeholders with convergence behavior mentioned.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main changes: adding a GitHub repo one-shot ingestion skill (playbook) and a CLI trigger command.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed The PR description is directly related to the changeset, covering all three files: the playbook, CLI command, and unit tests.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


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 and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
potpie/context-engine/tests/unit/test_github_repo_one_shot_ingestion_skill.py (2)

20-31: 💤 Low value

Consider using a YAML parser for frontmatter.

The current frontmatter parsing splits on : which works for simple key-value pairs but won't handle multi-line YAML values, quoted strings with colons, or other YAML features. For contract tests, this is acceptable, but using pyyaml would be more robust if the frontmatter format evolves.

📦 Optional enhancement using PyYAML
+import yaml
+
 def _read_skill() -> tuple[dict[str, str], str]:
     raw = SKILL_PATH.read_text(encoding="utf-8")
     assert raw.startswith("---\n")
     end = raw.find("\n---\n", 4)
     assert end > 0
-    frontmatter: dict[str, str] = {}
-    for line in raw[4:end].splitlines():
-        if ":" not in line:
-            continue
-        key, _, value = line.partition(":")
-        frontmatter[key.strip()] = value.strip()
+    frontmatter = yaml.safe_load(raw[4:end])
     return frontmatter, raw[end + 5:]
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@potpie/context-engine/tests/unit/test_github_repo_one_shot_ingestion_skill.py`
around lines 20 - 31, Replace the ad-hoc frontmatter parsing in _read_skill with
a YAML parser: read the file with SKILL_PATH.read_text, locate the frontmatter
block between the leading "---" and the following "\n---\n" as you do now, then
parse that frontmatter string using yaml.safe_load (from pyyaml) into the
frontmatter dict instead of the manual colon-splitting loop, and return the
parsed frontmatter and the body (raw[end + 5:]) as before; ensure you import
yaml and handle the parsed value being None by returning an empty dict.

62-67: 💤 Low value

Case-insensitive string matching is fragile.

The test lowercases the body and checks for "do not emit \fix` from a github issue"and"do not emit `resolved` from a github issue". This works with the current playbook (lines 290-293: "Do NOT emit \Fix`" and "Do NOT emit `RESOLVED`"), but if the playbook changes capitalization, the test might break. Consider more specific assertions.

🔍 Optional: More robust assertion
-    assert "do not emit `fix` from a github issue" in lowered
-    assert "do not emit `resolved` from a github issue" in lowered
+    # Check for the prohibition regardless of case/punctuation variations
+    import re
+    assert re.search(r"do\s+not\s+emit.*`fix`.*from.*github\s+issue", lowered)
+    assert re.search(r"do\s+not\s+emit.*`resolved`.*from.*issue", lowered)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@potpie/context-engine/tests/unit/test_github_repo_one_shot_ingestion_skill.py`
around lines 62 - 67, The test test_github_repo_skill_forbids_fix_from_issues is
fragile because it lowercases the whole body and asserts exact-cased substrings;
instead, perform a case-insensitive match or more targeted checks on the
original body returned by _read_skill(): for example, use a regex search with
the IGNORECASE flag to look for the phrase "do not emit `fix` from a github
issue" and similarly for "`resolved`", or assert that the sequence of tokens "do
not emit", the backticked token "`fix`" (or "`resolved`"), and "github issue"
appear in order — update the assertions in that test to use re.search(...,
flags=re.IGNORECASE) or equivalent token-order checks against the body variable
rather than lowercasing.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In
`@potpie/context-engine/tests/unit/test_github_repo_one_shot_ingestion_skill.py`:
- Around line 20-31: Replace the ad-hoc frontmatter parsing in _read_skill with
a YAML parser: read the file with SKILL_PATH.read_text, locate the frontmatter
block between the leading "---" and the following "\n---\n" as you do now, then
parse that frontmatter string using yaml.safe_load (from pyyaml) into the
frontmatter dict instead of the manual colon-splitting loop, and return the
parsed frontmatter and the body (raw[end + 5:]) as before; ensure you import
yaml and handle the parsed value being None by returning an empty dict.
- Around line 62-67: The test test_github_repo_skill_forbids_fix_from_issues is
fragile because it lowercases the whole body and asserts exact-cased substrings;
instead, perform a case-insensitive match or more targeted checks on the
original body returned by _read_skill(): for example, use a regex search with
the IGNORECASE flag to look for the phrase "do not emit `fix` from a github
issue" and similarly for "`resolved`", or assert that the sequence of tokens "do
not emit", the backticked token "`fix`" (or "`resolved`"), and "github issue"
appear in order — update the assertions in that test to use re.search(...,
flags=re.IGNORECASE) or equivalent token-order checks against the body variable
rather than lowercasing.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: f810c758-107b-4c0f-a866-6144e0f327dd

📥 Commits

Reviewing files that changed from the base of the PR and between af14184 and 203f9a7.

📒 Files selected for processing (3)
  • potpie/context-engine/adapters/inbound/cli/main.py
  • potpie/context-engine/domain/playbooks/github_repo_one_shot_ingestion.md
  • potpie/context-engine/tests/unit/test_github_repo_one_shot_ingestion_skill.py

Address CodeRabbit review: add docstrings to all test functions and helper
to meet 80% coverage threshold; replace fragile lowercased string checks
with re.search(IGNORECASE) in test_github_repo_skill_forbids_fix_from_issues.
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