Skip to content

De-duplicate 7 more GitHub clients onto github_client (follow-up to #357)#358

Merged
StarshipSuperjam merged 2 commits into
mainfrom
claude/github-client-dedup-followup
Jun 30, 2026
Merged

De-duplicate 7 more GitHub clients onto github_client (follow-up to #357)#358
StarshipSuperjam merged 2 commits into
mainfrom
claude/github-client-dedup-followup

Conversation

@StarshipSuperjam

@StarshipSuperjam StarshipSuperjam commented Jun 30, 2026

Copy link
Copy Markdown
Owner

Follow-up to #357 (now merged) — completes the de-duplication #295 began. Targets main directly; #357's github_client is already on main. Closes no separate issue.

Purpose

Finish the GitHub-client de-duplication: re-point the seven remaining tools that still hand-roll the same authenticated _http onto the shared github_client.

Impact: every GitHub API caller in the engine now builds its request through one place; the duplication #295 named is fully cleared.

Scope

Seven tools re-pointed to github_client.request; each keeps its own transport, error model, and return shape.

  • bootstrap.py, issue_conformance_ci.py, disposition_issue_resolution_check.py, spec_referent.py, milestone_emit.py, projects_sync/projects_sync.py, dependency_discipline/review.py: the inline urllib.request.Request(...) build inside each _http becomes github_client.request(path, token, user_agent=..., method=method, data=data). Each keeps its own urllib.request.urlopen + except blocks and its injectable transport seam. API_ROOT removed from each (now unused).
  • Divergences preserved: bootstrap keeps its 3-tuple (status, json, headers) return (it reads response headers); disposition stays 2-arg (method, path) with no body and no Content-Type; projects_sync keeps its GraphQL POST.

Impact: a uniform request build across all seven, with no change to any caller's behavior.

Out of scope

Everything github_client itself — already shipped in #357 — and backup_vault.

  • No change to github_client.py; this only adds importers. backup_vault stays excluded (a different, hook-safe shape: 10s timeout, never-raise, blob PUT).

Impact: the shared client's surface is unchanged; this PR is purely consumer re-points.

Risk

Low — additive re-points of already-tested code; none of the seven is a privileged pull_request_target guard, follows a response-derived URL, or decodes content.

  • All seven build relative paths only (page-param pagination where they paginate), so the off-host guard is never triggered and behavior is unchanged. The only wire difference is that the six write-capable callers no longer send Content-Type on their bodyless GETs (GitHub ignores it); disposition was already Content-Type-free, so it is byte-identical.
  • Editing these tool files trips engine-guard (the coarse path-prefix classifier), so the PR carries a guardrail-ack; no guardrail is weakened.

Impact: the failure mode is a flagged-but-equivalent move; each tool's own test suite is the regression catch.

Validation

Full suite and validator green.

  • python -m unittest discover -s tools -p 'test_*.py' → 2741 tests OK (2 documented offline skips). Each re-pointed tool's tests inject their transport seam, so they exercise the real logic and pass untouched.
  • validate.py --suite CI → the sole hard finding is the known local no-token state of disposition-issue-resolution (it needs a token to bite, i.e. in CI); the re-point does not change its token logic.
  • graph.json regenerated and in sync; self-map.md unchanged (tool inventory is by glob).

Impact: the behavior-preserving claim rests on seven independent test suites staying green through their transport seams.

Review

A four-lens deliverable-gate cold review ran (spec-conformance, technical-integrity, security/governance, usability); no blocking or serious findings remain — every finding folded.

  • Depth: four independent cold-context lenses read the diff and ran the full suite in throwaway copies. Before building, the seven tools were ground-truthed individually for divergence (3-tuple return, 2-arg transport, GraphQL POST, pagination style, privileged status) so the uniform swap could not flatten a real difference. Spec-conformance and technical-integrity each empirically constructed the old vs new request objects and confirmed them byte-identical (including the GraphQL POST); security/governance confirmed no off-host exposure, no privilege escalation, no token leak, and that the two check rules' (disposition, dependency-review) logic and fail-closed posture are byte-for-byte unchanged.
  • Findings folded (validated by the green suite, not themselves re-reviewed): the usability lens caught three modules (spec_referent, milestone_emit, issue_conformance) whose docstrings still called their _http a "knowing duplicate" tracked for consolidation in Extract a shared GitHub Contents-API client (de-duplicate weakening_guard / audit_digest / lock_integrity) #295 — language Extract a shared github_client; de-duplicate 5 GitHub API clients (#295) #357 stripped from its files but this PR missed; corrected to say the request-build now routes through the shared github_client, with the genuinely-still-duplicated markdown / pipe-table parser notes left intact.
  • Internal, behavior-preserving refactor with no settled product description: no operator-runnable product steps; the evidence is the green suite (2741 tests) and each tool's transport-seam tests.

Impact: the engine's own account of the review — the maintainer's merge is the binding gate.

Files of interest

The seven re-pointed _http boundaries.

  • .engine/tools/bootstrap.py — the one with a 3-tuple return (keeps response headers).
  • .engine/tools/disposition_issue_resolution_check.py — the 2-arg, Content-Type-free (byte-identical) case.
  • .engine/tools/projects_sync/projects_sync.py — the GraphQL POST case.

Impact: these three carry the divergences the uniform swap had to preserve.

Claude involvement

Claude (Opus 4.8) performed the re-points under the maintainer's direction; the maintainer asked for the follow-up and holds the merge.

  • The maintainer chose to complete the de-duplication in a follow-up PR. Each tool was ground-truthed for divergence before the swap; the edits are mechanical.

Impact: AI judgment is load-bearing on what counts as behavior-preserving per tool; the seven transport-seam test suites cover it.

StarshipSuperjam and others added 2 commits June 30, 2026 13:27
…p to #295)

Follow-up to PR #357: the same authenticated _http shape lived in seven more
tools. Re-point each to github_client.request (the shared builder), keeping
each one's own urlopen + status/error model + injectable transport seam:
bootstrap, issue_conformance_ci, disposition_issue_resolution_check,
spec_referent, milestone_emit, projects_sync, dependency_discipline/review.

Behavior-preserving: each transport seam is unchanged, so the per-tool tests
pass untouched. bootstrap keeps its 3-tuple (status, json, headers) return;
disposition stays 2-arg (method, path) with no Content-Type; projects_sync
keeps its GraphQL POST. API_ROOT removed from each (now unused). The inert
GET Content-Type the write-capable callers previously set is dropped (GitHub
ignores it on a bodyless request); disposition was already Content-Type-free.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The usability lens caught that spec_referent / milestone_emit / issue_conformance
still described their _http as a "knowing duplicate" of the gh client tracked for
consolidation in #295 — language #357 stripped from its files but this follow-up
missed. Update those docstrings to say the request-build now goes through the
shared github_client while each keeps its own transport/error handling. The
markdown-parser and pipe-table-parser "knowing duplicate" notes are left intact —
those duplications are real and untouched.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@StarshipSuperjam StarshipSuperjam marked this pull request as ready for review June 30, 2026 20:43
@StarshipSuperjam StarshipSuperjam added the guardrail-ack Deliberately approves a guardrail-weakening change; clears the engine-guard block. label Jun 30, 2026
@StarshipSuperjam StarshipSuperjam merged commit 2bdce78 into main Jun 30, 2026
9 of 10 checks passed
@StarshipSuperjam StarshipSuperjam deleted the claude/github-client-dedup-followup branch June 30, 2026 20:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

guardrail-ack Deliberately approves a guardrail-weakening change; clears the engine-guard block.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant