gha-github-service-proof 1.0.1

GitHub Actions service/API compatibility checker for offline CI: GITHUB_TOKEN permissions, REST/GraphQL/gh CLI calls, OIDC, checks/statuses, releases, and issues
Documentation
# gh-log Canonical JSON Schema (v1)

`gh-log` ingests a stable, tool-agnostic canonical JSON bundle. The format is intentionally boring so adapters (gh CLI debug traces, HAR exports, ci-forge native emit) can target a single shape.

## Top level

```json
{
  "schema_version": 1,
  "tool": { "name": "ci-forge", "version": "0.1.0" },
  "captured_at": "2026-05-12T18:00:00Z",
  "calls": [ ... ]
}
```

- `schema_version` (integer, required) — must be `1` for v1.0. Bundles with other versions are rejected.
- `tool.name` (string, required) — the producer of the bundle (e.g. `ci-forge`, `gh-debug-adapter`, `mitmproxy-adapter`).
- `tool.version` (string, required) — version string for the producer.
- `captured_at` (RFC 3339 timestamp, optional) — when the bundle was captured.
- `calls` (array, required) — zero or more call objects.

## Call object

```json
{
  "id": "call-1",
  "timestamp": "2026-05-12T18:00:00Z",
  "source": "gh",
  "method": "POST",
  "url": "https://api.github.com/repos/wildmason/mortar/releases",
  "path": "/repos/wildmason/mortar/releases",
  "request_headers": {
    "accept": "application/vnd.github+json",
    "authorization": "<redacted>"
  },
  "request_body_excerpt": "{ \"tag_name\": \"v1.0.0\" }",
  "status": 201,
  "response_body_excerpt": "{ \"id\": 123 }",
  "exit_code": 0
}
```

- `id` (string, required) — stable identifier within the bundle.
- `source` (string, required) — origin of the call (`gh`, `curl`, `octokit`, `ci-forge-shim`, etc.).
- `method` (string, required) — uppercase HTTP method.
- `path` (string, required) — the request path used for catalog matching. Query strings are tolerated and stripped before matching.
- `url` (string, optional) — the full URL, retained for receipt provenance.
- `request_headers` (object, optional) — header name to value. Header names are matched case-insensitively.
- `request_body_excerpt` / `response_body_excerpt` (string, optional) — truncated bodies for context. **Never** raw payloads unless the operator has explicitly opted out of redaction.
- `status` (integer, optional) — HTTP status returned by the upstream/shim. Statuses ≥ 400 emit an advisory `gh_log.upstream_error` check.
- `exit_code` (integer, optional) — process exit code for tools like `gh`.

## Redaction by contract

The `authorization` request header must be the literal string `<redacted>`. Bundles that contain anything else (e.g. `Bearer ghp_xxx`) fail with `gh_log.authorization_not_redacted` unless the caller passes `--unsafe-full-payloads`, in which case the bundle is processed and a `gh_log.unsafe_full_payloads` warning is recorded on the receipt.

The same contract applies in spirit to the request and response body excerpts: producers should truncate and de-secret bodies before emit. v1.0 does not enforce a maximum excerpt size or perform content scanning; that is a future enhancement.

## Adapters (deferred to future releases)

v1.0 ships only the canonical JSON ingest. Future adapter flags will translate other capture formats into the canonical shape:

- `--gh-debug <trace.txt>` — parse `GH_DEBUG=api` traces.
- `--har <trace.har>` — parse HAR exports from mitmproxy / Charles / browser devtools.
- ci-forge's API shim is expected to emit the canonical format natively.

The schema is the boundary; adapters are convenience.