From 49322ff000532b105b3495123f58ed8dbe2b6706 Mon Sep 17 00:00:00 2001 From: Steven Welch Date: Thu, 27 Aug 2026 19:53:18 -0600 Subject: [PATCH 1/2] docs: scope GitHub root agent guidance --- AGENTS.md | 141 ++------------------------------------------------ opencode.json | 36 +------------ 2 files changed, 4 insertions(+), 173 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 4c23da9..9f612a0 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,142 +1,7 @@ # Agent Instructions -## Repository Purpose +OpenTofu root for Make IT Work Cloud GitHub organization infrastructure. -OpenTofu root module for GitHub organization infrastructure. +This root centrally manages organization policy, repository protections, Dependabot callers, and distributed Actions configuration. Before adding a centrally managed path, verify that no target repository owns that same path; preserve the `_dependabot-notify.yml` collision boundary in `shared-workflows`. -## Git Workflow - -Use a feature branch and open a pull request rather than pushing directly to -`main`. A push to `main` can invoke `apply` after tests pass and configured -environment gates approve it. Do not push any branch unless explicitly -requested. - -PRs are squash-merged. If a branch contains commits that already landed on -`main` via a squash merge (stacked PRs), a plain rebase or merge replays them -and produces phantom conflicts on the open PR. Rebase with -`git rebase --onto origin/main ` so only the unique -commits replay. - -## Branch Protection - -Branch protection on `main` is intentionally relaxed for this solo-maintainer, -personal-dev organization: no required status check contexts and zero required -approving reviews (see the comment in `gh-protections.tf`). PRs are used for CI -validation, plan output, and change history, not as a review gate. Do not -tighten `contexts` or `required_approving_review_count` unless explicitly -requested. The `admins` team may also force-push (`force_push_bypassers`) for -history maintenance; all other force pushes remain blocked. - -GitHub silently drops branch-protection bypass actors that have no repository -access at write time — the apply succeeds but the stored rule omits them, so -config and live state diverge on every plan. The `admins` bypass entries here -are only valid because `gh-iam.tf` grants the team admin access to every -active repository (`github_team_repository.admins`); never remove those -grants while the bypass entries exist, and grant access to any future bypass -team in the same apply. - -## Pre-commit Configuration - -Pre-commit configuration is centralized at -`https://raw.githubusercontent.com/makeitworkcloud/images/main/tfroot-runner/pre-commit-config.yaml`. The root -`.pre-commit-config.yaml` is generated and ignored; do not edit it. - -For local development, run: -```bash -make test -``` - -This refreshes the generated config from the canonical source on every run and -replaces it only when the content changed. - -## CI/CD - -This repo uses the shared `opentofu.yml` workflow from `shared-workflows`. Jobs -run natively on `arc-tf`; the runner pod already uses the `tfroot-runner` image, -so the workflow does not start a nested container. The shared workflow fetches -the canonical pre-commit config at runtime; this repository does not provide a -tracked copy. - -### Failure Modes - -**"manifest unknown" error:** The `tfroot-runner:latest` image doesn't exist in GHCR. Check if the `images` repo Build workflow succeeded. - -**Pre-commit failures:** If hooks fail unexpectedly, the canonical config may -have changed. Re-run `make test` to refresh it and run the checks. - -## Dependency Updates - -Dependabot version updates are managed here in `gh-dependabot.tf` via -`github_repository_file` resources, so all active repositories receive their -`.github/dependabot.yml` from one place. To change update policy, edit the -`dependabot_ecosystems` map; do not hand-edit `.github/dependabot.yml` in -downstream repositories. Pre-commit hook revisions are not covered by -Dependabot: they are owned by the canonical config in -`images/tfroot-runner/pre-commit-config.yaml`. - -Every `github_repository_file` path is force-written to all repositories in -its `for_each` — including a repository that hand-authors a file at the same -path (observed 2026-08-24: the managed `dependabot-notify.yml` caller -overwrote the reusable workflow in `shared-workflows`, breaking it). Before -adding a managed file, check that no target repository owns that path; when a -repository must own a file itself, place it at a path no managed distribution -covers (see `_dependabot-notify.yml`). - -## Dependabot PR Alerting - -When Dependabot opens a PR, the managed caller workflow -(`.github/workflows/dependabot-notify.yml`, from `gh-dependabot.tf`) invokes -the `dependabot-notify` reusable workflow in `shared-workflows` -(`.github/workflows/_dependabot-notify.yml` — the underscore path keeps it -clear of this managed file's target, which is written to every repository -including `shared-workflows`), which posts a -synthetic alert to the cluster Alertmanager (`alertmanager.makeitwork.cloud`, -kube-prometheus-stack) behind the Cloudflare Access app managed in -`tfroot-cloudflare/cf-access-alertmanager.tf`. Delivery goes to Discord via -the Alertmanager config Secret in `kustomize-cluster/operators/kube-prometheus-stack`. - -The only required secrets are `CLOUDFLARE_AUTH_CLIENT_ID` / -`CLOUDFLARE_AUTH_CLIENT_SECRET` — the "GitHub Actions" Cloudflare Access -service token, distributed here to all active repositories. Alertmanager has -no auth of its own; the Access app is the only gate. - -Verify delivery end to end (posts a test message to Discord): - -```bash -CF_ID=$(AWS_PROFILE=makeitwork sops decrypt --extract '["cloudflare_auth_client_id"]' secrets/secrets.yaml) -CF_SECRET=$(AWS_PROFILE=makeitwork sops decrypt --extract '["cloudflare_auth_client_secret"]' secrets/secrets.yaml) -curl -fsS -X POST -H "CF-Access-Client-Id: $CF_ID" -H "CF-Access-Client-Secret: $CF_SECRET" \ - -H "Content-Type: application/json" \ - -d '[{"labels":{"alertname":"DependabotPR","severity":"info"},"annotations":{"summary":"E2E"}}]' \ - https://alertmanager.makeitwork.cloud/api/v2/alerts # expect HTTP 200 -``` - -A genuinely new Dependabot PR fires `opened` and notifies; `@dependabot -recreate` fires `synchronize`, which the caller's actor filter excludes. - -## SOPS Secrets - -`secrets/secrets.yaml` is the org secret source (SOPS, AWS KMS; decrypt with -`AWS_PROFILE=makeitwork`). Never print decrypted values: move secrets through -subprocesses (decrypt into a shell variable consumed in the same shell), never -into chat, logs, or tracked plaintext. - -To resolve a git conflict on an encrypted file without decrypting, compare the -key sets and per-key ciphertext hashes on both sides. If one side contains -every key the other has, with identical ciphertext except for intended changes, -take that side wholesale. - -## Related Repositories - -- `images` - Contains tfroot-runner image and canonical pre-commit config -- `shared-workflows` - Contains the reusable OpenTofu workflow - -## Import ID Formats - -Use the provider's resource-specific ID format when adopting existing GitHub -objects: - -- repositories: `` -- `main` branch protections: `:main` -- Actions secrets: `/` -- repository files: `/` (append `:` for non-default branches) +Use GitHub MCP and PR CI plans as validation authority. `main` is an environment-gated apply path; use scoped branches and PRs, never direct pushes. Do not run OpenTofu, secret-decryption, curl, import, state, or apply commands from this server. Never expose encrypted secret content, credentials, state, or sensitive plans. diff --git a/opencode.json b/opencode.json index f7777ca..6376bc7 100644 --- a/opencode.json +++ b/opencode.json @@ -1,38 +1,4 @@ { "$schema": "https://opencode.ai/config.json", - "mcp": { - "agent-hub": {"type": "remote", "url": "http://127.0.0.1:8776/mcp", "enabled": true, "oauth": false}, - "context-mode": {"type": "local", "command": ["context-mode"], "enabled": true}, - "context7": {"type": "remote", "url": "https://mcp.context7.com/mcp", "enabled": true}, - "github": {"type": "remote", "url": "https://api.githubcopilot.com/mcp/", "enabled": true, "oauth": false, "headers": {"Authorization": "Bearer {env:GITHUB_TOKEN}"}}, - "opentofu-docs": {"type": "remote", "url": "https://mcp.opentofu.org/mcp", "enabled": true}, - "opencode-docs": {"enabled": false}, - "aws-docs": {"enabled": false}, - "kubernetes": {"enabled": false}, - "tmux": {"enabled": false}, - "linear": {"enabled": false}, - "notion": {"enabled": false}, - "aws-staging": {"enabled": false}, - "aws-prod": {"enabled": false}, - "grafana": {"enabled": false}, - "terraform-docs": {"enabled": false}, - "argocd-makeitwork": {"enabled": true}, - "argocd-staging-eks": {"enabled": false}, - "argocd-prod-eks": {"enabled": false} - }, - "tools": { - "opencode-docs_*": false, - "aws-docs_*": false, - "kubernetes_*": false, - "tmux_*": false, - "linear_*": false, - "notion_*": false, - "aws-staging_*": false, - "aws-prod_*": false, - "grafana_*": false, - "terraform-docs_*": false, - "argocd-makeitwork_*": true, - "argocd-staging-eks_*": false, - "argocd-prod-eks_*": false - } + "instructions": ["AGENTS.md"] } From e445f864f4a6dd84dc7c816d04207993536bdaab Mon Sep 17 00:00:00 2001 From: Steven Welch Date: Thu, 27 Aug 2026 20:01:33 -0600 Subject: [PATCH 2/2] chore: remove obsolete local OpenCode overlay --- opencode.json | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 opencode.json diff --git a/opencode.json b/opencode.json deleted file mode 100644 index 6376bc7..0000000 --- a/opencode.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "$schema": "https://opencode.ai/config.json", - "instructions": ["AGENTS.md"] -}