Skip to content

Run a skill against a simulated GitHub instead of the real one #60

Closed
3 of 3 issues completed
Closed

Description

@glennfaison

Category: feature
Area: Evaluation (tests/)
Impact: Without it nothing can run a skill safely and repeatably, so the scenarios stay a spec that no real run is checked against.
Confidence: traced

Problem (the use case)

A maintainer who wants to see whether a model follows shepherd-github-pr has to point it at a real repository and clean up afterwards. They cannot repeat a run, inject a failure (a merge GitHub rejects, a check that never finishes) or compare two runs.

Proposed solution

Add a gh simulator: an executable named gh, placed first on PATH, that reads and writes a world file (the same format the scenarios use) and appends every call to a log.

Support the subcommands the skills and lib.sh actually use: issue (list, view, edit, close, create, comment, reopen), pr (view, list, edit, create, comment, checks, merge), label (create, list), api (the update-branch PUT, user, and the few --jq reads), run view, repo view, auth status, with --json, --jq, --label, --state and --limit where they are used. Anything else exits non-zero with unsupported: <command> so a new gh call in a skill is noticed.

  • Seed it from a scenario's world. After a run, diffWorlds (the blocking ticket) gives the effects.
  • Fault injection: a scenario may say faults: [{match: "pr merge", fail: "not mergeable"}].
  • Unify with the gh mock that tests/lib.test.sh already has. There should be one mock, not two.

Acceptance criteria

  • Every gh command the skills use is supported, and an unsupported one fails loudly. A test greps the skills for gh calls and checks each is supported or explicitly listed as out of scope.
  • tests/lib.test.sh runs against the shared simulator, and still passes (154 tests).
  • A fault can be injected and is visible in the call log.
  • The world file is the scenarios' format, so any scenario can seed a run.

Non-goals

Matching GitHub's behaviour beyond what the skills depend on (rate limits, pagination, webhooks).

Blocked by: #59
Size: large. Suggested split: (1) the issue and PR read paths, (2) the write paths, (3) api, faults and unification with lib.test.sh.

Activity

  1. glennfaison commented on Nov 9, 2026

    @glennfaison
    OwnerAuthor

    Split as the issue suggests: #86 (world file, call log, read paths), #87 (write paths), #88 (api, faults, one mock for lib.test.sh). Each blocks the next. Working through them in order, one PR each.

  2. glennfaison commented on Nov 11, 2026

    @glennfaison
    OwnerAuthor

    Done. The simulator is in tests/sim and tests/lib.test.sh runs against it, so there is one mock of gh.

    Not done, and not part of this issue: a runner that drives a model against the simulator (#61), and the shepherd skill's check-state one-liner, which expects [] from gh pr checks for a PR with no checks where gh exits 1 (noted in #90, no issue filed). See docs/adr/0014-gh-simulator.md.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions