Skip to content

docs: expand usage guide — architecture, GHA/K8s recipes, troubleshooting#14

Merged
stephane-segning merged 1 commit into
mainfrom
docs/expand-usage-guide
May 25, 2026
Merged

docs: expand usage guide — architecture, GHA/K8s recipes, troubleshooting#14
stephane-segning merged 1 commit into
mainfrom
docs/expand-usage-guide

Conversation

@stephane-segning
Copy link
Copy Markdown
Contributor

Closes #12.

Summary

Adds a docs/ directory at the repo root with five focused pages, ships a reusable workflow_call workflow consumers can pin against, and slims both READMEs so the canonical configuration reference stays in the package README while the long-form recipes live alongside.

Every claim in the docs was checked against the actual source — config field defaults, error event names, cache filename patterns, env-var contracts, the isTokenValid machine-flow split, the TTY-aware warmup detection, scrubSecrets substring patterns, all of it — by reading packages/opencode-oauth2/src/{config,cache,oauth/*,plugin,opencode,logging,model-discovery}.ts rather than guessing.

Files added

  • docs/architecture.md (275 lines) — the two hooks (config at load, chat.headers per request), token lifecycle per flow with a state-machine table, isTokenValid policy and the machine-flow split, TTY-aware warmup detection, cache layout per OS + file shape + eviction rules, sync scheduler failure handling, structured logging events table, redaction layers (field-name + scrubSecrets substring), and a mermaid sequenceDiagram showing on-demand auth on opencode run.
  • docs/github-actions.md (290 lines) — Keycloak setup walkthrough (Identity Provider, client, Token Exchange permissions, claim mapping — verified against auth.verif.fyi/realms/camer-digital), shorter Auth0 / Okta sections with vendor-doc links, the shipped reusable workflow, a minimal worked example (workflow + committed opencode.json), matrix builds, audience pinning rationale and per-workflow audience table, fork-PR limitations with three workaround tiers (push-only, pull_request_target with label gating, restricted-scope reusable).
  • docs/kubernetes.md (374 lines) — CronJob as the headline (full manifest with projected SA token volume, scheduled summarization use case), Job (minimal), Deployment with the kubelet-rotation-is-transparent story, multi-provider pods with multiple tokenPaths and audiences, IdP setup for Keycloak/Dex including how to discover the cluster's OIDC issuer (kubectl get --raw /.well-known/openid-configuration), explicit "the SA needs no RBAC" section, honest OpenShift caveats ("don't assume parity without testing").
  • docs/local-development.md (190 lines) — OPENCODE_CONFIG_DIR=/tmp/... sandbox, plugin re-export trick (re-export from dist/), fixed redirectPort vs random tradeoffs per IdP, force re-auth one-liners per OS with the "Keycloak refresh preserves originally-granted scopes" rationale, dev-only env subject token source for testing federated flows without a live runner.
  • docs/troubleshooting.md (251 lines) — symptom-keyed (8 entries): /models empty, redirect_uri_mismatch, model discovery failed (403), oauth_client_credentials_failed 401, jwt_bearer 401, headless hang, projected-token rotation drift, missing npm provenance badge, ERR_PNPM_IGNORED_BUILDS. Each entry: what's happening internally, which log event to grep for, and a curl/kubectl/jq diagnostic the reader can run.
  • .github/workflows/opencode-run.yml (124 lines) — workflow_call reusable workflow with inputs for model, prompt, opencode-config-path, node-version, runs-on, opencode-version, plugin-version. Grants id-token: write so federated identity flows work; uploads stdout as an artifact.

Files modified

  • README.md (root) — added a small mermaid block at the top, trimmed duplicated material, replaced it with a docs index table linking all five new pages.
  • packages/opencode-oauth2/README.md — kept the canonical configuration field reference (it's THE reference; expanded the optional-fields table with nameOverrides, syncIntervalMinutes, jwksUri, and the top-level cacheNamespace / httpTimeoutMs / tokenExpirySkewMs block). Condensed the long Federated Identity section to short quick-reference YAML snippets plus links to docs/github-actions.md and docs/kubernetes.md for the full recipes.

Verification

  • pnpm -r typecheck — green
  • pnpm -r test — 94/94 passing
  • pnpm -r build — green
  • .github/workflows/opencode-run.yml parses with js-yaml (alongside the existing publish.yml and ci.yml)
  • Every YAML and JSON code block in all five docs pages + both READMEs parses with js-yaml / JSON.parse
  • pnpm lint / pnpm format:check fail with "No files were processed" at the workspace level — this is pre-existing on main (Biome's biome.json excludes .md and the project-level scripts pass . to biome which then reports nothing to do). Spot-checked npx biome check packages/opencode-oauth2/src/config.ts works.

Honest punts

  • OpenShift section in docs/kubernetes.md covers the documented projected-token differences and SCC implications, then explicitly says: "the maintainer hasn't validated this end-to-end on OpenShift, so don't assume parity with upstream Kubernetes without testing." Better than fabricating.
  • Auth0 federated identity — pointed at vendor docs for the Custom Token Exchange feature (Enterprise) rather than reproducing Auth0's action DSL inline. The Keycloak walkthrough is the verified-against-production one; Auth0/Okta are described at the same depth as their vendor docs warrant.
  • Symptom-keyed troubleshooting intentionally doesn't try to enumerate every IdP-specific 401 cause — kept Keycloak as the worked example since that's what's verified.

Test plan

  • CI green on this branch
  • Docs render correctly on github.com (especially the mermaid sequenceDiagram in architecture.md and the flowchart LR in root README)
  • All cross-doc links resolve (docs/architecture.md../packages/opencode-oauth2/src/..., root README → docs/*.md, package README → ../../docs/*.md)
  • Reusable workflow file is syntactically valid (parsed locally; GitHub will validate on first call)

🤖 Generated with Claude Code

…ooting

Closes #12.

Add `docs/` at repo root with five new pages: `architecture.md` (hook model,
token lifecycle per flow, cache layout, sync scheduler, TTY-aware warmup,
logging + scrubbing), `github-actions.md` (Keycloak/Auth0/Okta IdP setup,
reusable workflow, matrix builds, audience pinning, fork-PR limitations),
`kubernetes.md` (CronJob as headline + Job/Deployment, multi-provider pods,
IdP setup, RBAC, OpenShift caveats), `local-development.md` (sandbox config,
plugin re-export trick, force re-auth, dev-only env subject token), and
`troubleshooting.md` (symptom-keyed: model list empty, redirect_uri_mismatch,
403 model discovery, invalid_client, headless hang, token-rotation drift,
provenance badge missing, ERR_PNPM_IGNORED_BUILDS).

Ship `.github/workflows/opencode-run.yml` as a `workflow_call` reusable
workflow consumers can pin via `uses: vymalo/opencode-oauth2/.github/workflows/opencode-run.yml@v0.x`.

Slim both READMEs: root README adds a small mermaid diagram and a docs
index; package README condenses the federated-identity section to short
quick-references plus links to the full recipes in docs/. The canonical
configuration field reference stays in the package README.

Every claim traces to source — config field defaults, error event names,
cache filename patterns, env-var contracts, and the isTokenValid
machine-flow split were all read off
packages/opencode-oauth2/src/{config,cache,oauth/*,plugin,opencode}.ts
rather than guessed. All YAML/JSON snippets parse with js-yaml / JSON.parse.
typecheck / test (94/94) / build all green.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces comprehensive documentation for the @vymalo/opencode-oauth2 plugin, including new guides for architecture, GitHub Actions, Kubernetes, local development, and troubleshooting. The README files were updated to include a Mermaid flowchart and link to these new resources. Feedback was provided to correct a missing this. prefix in a code snippet within the architecture documentation to ensure it matches the actual implementation.

Comment thread docs/architecture.md
// user flows: treat undefined expiry as VALID (cost of re-auth is high)
return !machineFlows.includes(this.server.authFlow);
}
return Date.now() + tokenExpirySkewMs < token.expiresAt;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The code snippet is missing the this. prefix for tokenExpirySkewMs. In the actual implementation in packages/opencode-oauth2/src/oauth/client.ts, this is a class property.

Suggested change
return Date.now() + tokenExpirySkewMs < token.expiresAt;
return Date.now() + this.tokenExpirySkewMs < token.expiresAt;

@stephane-segning stephane-segning merged commit b56749b into main May 25, 2026
3 checks passed
@stephane-segning stephane-segning deleted the docs/expand-usage-guide branch May 25, 2026 00:40
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: dddbcd1d16

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

if: always()
uses: actions/upload-artifact@v4
with:
name: opencode-stdout-${{ github.run_id }}-${{ github.run_attempt }}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Make artifact names unique per invocation

In .github/workflows/opencode-run.yml, the uploaded artifact name is derived only from github.run_id and github.run_attempt, so every invocation of this reusable workflow within the same caller workflow run uses the same name. With actions/upload-artifact@v4, artifact names must be unique per run; if a caller uses this reusable workflow in multiple jobs or a matrix, later uploads fail with a conflict error, breaking those jobs even though opencode run succeeded.

Useful? React with 👍 / 👎.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

docs: expand usage guide — architecture overview + production CI/K8s recipes

1 participant