feat(mine): enrich decisions with GitHub PR text (kb mine --prs, ADR slice 2)#36
Merged
Conversation
…slice 2) New kb.git.forge module - the ONLY networked step in the toolchain, strictly opt-in: PRText/PRProvider protocol + GitHubPRProvider (stdlib urllib against api.github.com; GITHUB_TOKEN/GH_TOKEN optional, anonymous works for public repos), origin_slug (https/ssh forms) and pr_number_from_subject (squash '(#NN)' anchor; the Revert case yields the revert's own PR). A mined commit whose subject carries (#NN) is enriched: PR title/body feed the prompt (own system prompt - the plain one says 'ONLY the commit message') and land in the payload (capped). PR text is context and a payload fact - never grounding. Because PR text is MUTABLE after merge, a digest of the capped text is folded into framework_versions (identity-bearing, the sink-registry precedent): an edited PR yields a NEW artifact id, never a silent payload swap. The enriched prompt pins its own prompt_version '2+pr1' (the describe repo-prompt precedent); plain prompts and plain artifact ids stay byte-identical. A failed fetch (404/network/rate limit) degrades softly to the byte-identical plain artifact and is counted per run (pr_enriched / pr_fetch_failed in the CLI summary) - a failure is a property of the RUN, not of the knowledge; exactly two identities exist per (sha, model): plain and enriched(digest). Merge commits stay skipped (squash flow is fully covered; grounding a classic merge on its first-parent diff is an open question). docs-only commits pay neither LLM nor network. ADR-mining gate grows six tests (enrichment identity, floor under enrichment, post-merge-edit -> new id, fetch-failure degradation, no-PR byte-compat, slug/subject/provider parsing incl. fail-soft HTTP paths). Headline HARD gates stay fifteen. Verified live against real GitHub + LLM: 2 decisions enriched, digests identity-bearing, body cap exercised, 0 fetch failures.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
The network slice of ADR mining:
kb mine --prsenriches decisions mined from squash-merged commits (subject ending in(#NN)) with the pull request's title/body via the newkb.git.forgemodule —PRProviderprotocol +GitHubPRProvider(stdlib urllib;GITHUB_TOKEN/GH_TOKENoptional, anonymous works for public repos;--repo-slugoverrides the origin-derived slug).Strictly opt-in and the only networked step in the toolchain — without
--prs, behavior is byte-identical to slice 1.The identity story (the design core)
PR text is mutable after merge — without an identity pin, editing a PR and re-mining with
--forcewould silently swap the payload under an unchangedartifact_id(the silent-collision class this repo fixed twice). Per the sink-registry precedent, a digest of the capped PR text is folded intoframework_versions(identity-bearing): an edited PR yields a new artifact id and the manifest re-points. The enriched prompt runs under its own system prompt and pins its ownprompt_version="2+pr1"(the describe repo-prompt precedent); plain prompts and plain ids stay byte-identical.A failed fetch (404 / network / rate limit) degrades softly to the byte-identical plain artifact and is counted per run (
pr_enriched/pr_fetch_failedin the CLI summary) — a failure is a property of the run, not the knowledge. Exactly two identities exist per (sha, model): plain and enriched(digest). PR text stays context + payload fact — never grounding (D5: the decision remains grounded on the commit's changed spans).Gates (stay fifteen)
ADR-mining gate grows six tests: enrichment identity, floor under enrichment (REAL kept / FAKE dropped), post-merge-edit → new id, fetch-failure degradation, no-PR byte-compat, slug/subject/provider parsing incl. fail-soft HTTP paths (monkeypatched urllib — no network in CI).
Verified live before this PR
GITHUB_TOKEN=$(gh auth token) kb mine . --prs --force --max-commits 6on the dogfood DB: 2 decisions enriched with real PR bodies (titles matchgh pr view), digests identity-bearing (prompt_version=2+pr1), the 2000-char body cap exercised on a real long PR body, confidence 0.833 (Laplace), 0 fetch failures.Local:
ruffclean,mypy --strictclean,pytest -q→ 122 passed, 1 skipped.