Codex GitHub Upstream Conformance

August 15, 2026 · View on GitHub

Maintainer-facing record of how this pack maps onto the OpenAI Codex GitHub plugin, produced by the final conformance audit. The goal is workflow semantics, not copy-identical text. Any future change to a skill should be checked against this matrix so intentional differences are not accidentally "fixed" back toward Codex, and genuine gaps are not introduced silently.

Baselines (pinned at audit time)

BaselineIdentity
Local installed Codex GitHub plugin~/.codex/plugins/cache/openai-curated-remote/github/0.1.8-2841cf9749ae/ (cache mtime 2026-07-10)
Public upstream commitopenai/plugins@4c2b32e42cf50cea9599bb8a167c1db759e6ce40 (2026-06-23; latest commit touching plugins/github at audit time)
Local vs public file diffidentical for github/SKILL.md, gh-address-comments/*, gh-fix-ci/*; only yeet/SKILL.md differs (local: branch agent/{desc}, PR title {desc}; public: branch codex/{desc}, PR title [codex] {desc}) — branding only, no workflow-semantic change

The public plugin declares a GitHub MCP server (.mcp.json, bearer_token_env_var: GITHUB_PAT_TOKEN) that the local 0.1.8 install does not carry; neither is relevant to DSH (see Intentional omissions).

Behavior matrices

Verdict legend: equivalent · equivalent via DSH capability · intentionally different · intentionally omitted · GAP.

1. github umbrella

BehaviorCodex local/publicdsh-github-skillsVerdict
Resolve operating context firstyesyesequivalent
Identify repo / PR / issue / local branchyesyesequivalent
Classify: triage / review / CI / publishyesyesequivalent
Route immediately once intent is clearyesyesequivalent
Umbrella does not duplicate specialist workflowsyesyesequivalent
Structured GitHub capability firstconnector app firstbest visible DSH GitHub tool firstequivalent via DSH capability
Align connector state with local checkoutyesyesequivalent
Never pretend a capability existsask for repo, don't invent searchcatalog detection, no invented tool namesequivalent
Final output: inspected / state / nextyesyesequivalent
Tool-name collisions across providersn/a (single connector)match exact full name + signature + description (gh_* shared by ZariaEcho/PerryLink)DSH-specific addition

2. gh-address-comments

BehaviorCodexdsh-github-skillsVerdict
Explicit repo + PRyesyesequivalent
PR URLyesyesequivalent
Current-branch PRhead repo via headRepositoryOwner/headRepositoryPR canonical URL → target repointentionally different (see fork PR note)
Fork / cross-repo PR"works by reading head repo" — queries head repoqueries the repo that owns the PR (target)intentionally different (corrected upstream bug)
Three layers: conversation comments / reviews / reviewThreadsyesyesequivalent
Thread fields: isResolved, isOutdated, path, line, diffSide, startLine, startDiffSide, originalLine, originalStartLine, resolvedBy, comments, paginationyesyesequivalent
Only unresolved actionable feedback is acted onyesyesequivalent
Explicit thread classificationnot hard-coded7 classes (actionable/informational/approval/resolved/outdated/duplicate/ambiguous)DSH-specific addition
"Address the review" authorizes local editsyesyes, without mechanical re-askingequivalent
Remote writes (reply/resolve/submit review/push) need explicit askyesyesequivalent
Comment asking for explanation → draft response, not forced code changeyesyesequivalent

Fork PR note (high-priority audit item). Codex fetch_comments.py resolves the current-branch PR from headRepositoryOwner/headRepository and queries repository(owner, name) { pullRequest(number) } with it. For a fork PR the PR object — including its reviewThreads — lives in the target repository, not the fork head; querying the head repo can return null or, worse, an unrelated PR with the same number. gh 2.97 exposes no baseRepository JSON field, but the canonical PR url always identifies the target repo. fetch-review-threads.mjs therefore prefers the URL and falls back to the head repo only for same-repository PRs. This is an intentional correction of upstream behavior.

3. gh-fix-ci / inspect-pr-checks

Robustness behaviorCodex (inspect_pr_checks.py)dsh (inspect-pr-checks.mjs)Verdict
gh availability / auth checkyesyesequivalent
Current PR resolutiongh pr view --json numbersameequivalent
Explicit PRyesyesequivalent
gh pr checks JSON field drift fallback"Available fields" retrysameequivalent
conclusion / state / bucket normalizationfailure/cancelled/timed_out/action_required; fail bucketsame setsequivalent
Actions run id extraction/actions/runs/(\d+), /runs/(\d+)sameequivalent
Job id extraction/actions/runs/\d+/job/(\d+), /job/(\d+)sameequivalent
External provider detectionno run id → external, report-onlysame; never calls run/log APIsequivalent
Run metadatagh run view --json …same fieldsequivalent
Run log retrievalgh run view <id> --logsameequivalent
Pending logsmarker detection ("still in progress", "log will be available…")sameequivalent
Job-log fallbackgh api /repos/…/jobs/<id>/logs when run log pendingsameequivalent
Zip payload handlingdetects PK → reports error, no fake successsameequivalent
Failure marker selectionscan from end for error/fail/traceback/…same markersequivalent
Bounded context snippetmarker ± context, capped at max-linessameequivalent
Log taillast max-linessameequivalent
Malformed JSON handlingexplicit errorsameequivalent
Exit code semantics0 no failures, 1 failures remainsame, plus 2 for blocked/usageequivalent / intentionally different (DSH adds 2)
Workflow: summary → plan → approval → implementapproval before any fixlocal fix allowed when the user explicitly says "fix the CI"; diagnosis-only never edits; push/rerun/comment still need explicit intentintentional UX adaptation

4. yeetgh-publish

BehaviorCodex (yeet local/public)dsh-github-skillsVerdict
Inspect git status firstyesyes (+ preflight)equivalent via DSH capability
Inspect diff before stagingyesyes (+ numstat)equivalent
Mixed-worktree detectionask which filesdeterministic mixedWorktree flagequivalent via DSH capability
Never default git add -A on mixed treeyesyes (hard rule)equivalent
Branch strategyagent/ (local) / codex/ (public) prefixfollow repo conventions; dsh/<desc> only when noneintentionally different
Explicit-file stagingyesyes, plus partially staged (MM) rule: never blindly re-git add a file with unstaged hunks; git add -p or report ambiguityequivalent + DSH addition
Untracked filesneither auto-included nor auto-excluded; judged against task scopeDSH addition
Committerse messageterse, repo conventions, hooks respectedequivalent
Relevant checksyesyes, minimal scopeequivalent
Pushgit push -u origintracked remote first (preflight upstream), never assume originintentionally different
Draft PR defaultyesyesequivalent
Existing PR on branchnot handledcheck gh pr view first; never create a duplicate PRDSH addition (closes gap)
Repo / head / base resolutionconnector + gh repo viewpreflight + gh repo view --json defaultBranchRefequivalent via DSH capability
Fork / cross-repogh pr create fallbackpush to fork remote, gh pr create --head <fork>:<branch> --repo <target>, fail closed when unclearintentionally different / equivalent
PR body real Markdown + newlinesemphasized, temp fileemphasized; temp file for CLI fallbackequivalent
Final evidence summaryyesyesequivalent
codex/ branch / [codex] PR title brandinglocal yeet drops it; public keeps itnever adoptedintentionally omitted

Intentional omissions from Codex

Codex artifactWhy DSH should not copy it
OpenAI App connector metadata (.app.json)binds to Codex's connector runtime; DSH has no single connector
GitHub MCP declaration (.mcp.json, GITHUB_PAT_TOKEN)Codex API-key-session mechanism; DSH auth flows through gh/DSH providers
Codex agent UI metadata (agents/openai.yaml, interface fields)Codex-specific presentation surface
codex/ branch naming + [codex] PR title prefixbranding; this pack follows target-repo conventions
Python helpersDSH guarantees Node; zero-dependency .mjs preferred
Resident prompt injectionthis pack is progressive disclosure; catalog = name + description only

DSH-specific additions

  • Multi-provider capability matrix (references/capability-matrix.md)
  • dsh-ci-doctor (ci_diagnose) as preferred CI primitive when visible
  • dsh-gitflow tools as the git fallback layer
  • DSH approval model: remote writes need explicit intent or the host gate
  • ctx.skills bundle shim (lib/index.js) with lazy bodies and directory resourceBase
  • publish-preflight.mjs deterministic scope evidence
  • Fork-PR target-repo resolution correction (see above)
  • Explicit 7-class thread classification
  • Partially-staged (MM) staging rules, existing-PR detection, non-origin remote handling

GAP ledger (audit outcome)

All gaps found in this audit were closed in the same audit:

SeverityGapFix
highfork-PR current-branch resolution queried the head repo for reviewThreadsresolve target repo from the PR canonical URL (helper + fork tests)
mediumpartially staged files had no staging ruleSKILL rule (never blindly re-git add an MM file) + preflight MM test + static assertion
mediumexisting PR on branch would be blindly re-createdSKILL rule (check gh pr view, never duplicate) + static assertion
mediumpush hard-coded originSKILL rule (tracked remote first, fail closed) + static assertion
lowfork publish lacked push-to-fork-remote guidanceSKILL rule (git push -u <fork-remote> + --head <fork>:<branch> --repo <target>, fail closed) + static assertion
lowmulti-provider tool-name collisions under-specifiedumbrella wording (exact full name + signature + description)
lowCLI-fallback PR body newline handling not statedSKILL rule (temp file preserves newlines)

Remaining known differences are all intentional (matrices above). No critical or high gaps remain.

Post-conformance adversarial hardening

The conformance audit proves workflow-semantic parity; the adversarial hardening pass fixed issues that are NOT Codex-conformance gaps — they are either upstream-equivalent behavior with boundary bugs, DSH-specific helper bugs, security hardening, or release engineering. They are tracked here so they are not re-labeled as conformance regressions later:

CategoryIssueFix
securitycredential-bearing https remote URL leaked to stdoutlib/redact.mjs applied to every helper output path (URL userinfo + token shapes)
securitypasted tokens in remote content (comments, CI logs) and gh/git stderrsame redaction with stable placeholders; safety-model wording corrected
helper bugunequal pagination re-appended finished collectionsper-collection independent paginators with own cursors
helper bugthread comments >100 silently truncatedexplicit commentsTruncated + commentsPageInfo
helper buggeneric /runs/<id> misdetected as Actionsstrict /actions/runs/<id> detection (github.com + GHES)
helper bugrun/job queries bound to implicit cwd repoexplicit -R <owner/repo> target context everywhere
helper semanticsmixedWorktree too narrowobjective class signals + redefined conservative flag
mock qualityfake returned pages by call countprotocol-aware fake (cursor matching, -R verification, fail loud)
release engno CI, npm-install README overstated.github/workflows/ci.yml (Node 22.19/24), truthful install sections, metadata, prepublishOnly

Maintaining conformance

  • Re-pin the baselines when a new audit runs; record the public commit SHA, not "main".
  • Before editing a SKILL.md or helper, check the corresponding matrix row: preserve the verdict unless the change is itself a deliberate, documented divergence.
  • New DSH-specific additions belong in this file's addition list, not silently in code.