diff --git a/.github/workflows/agent-shield-reusable.yml b/.github/workflows/agent-shield-reusable.yml index a8ed224cc..24210e4ff 100644 --- a/.github/workflows/agent-shield-reusable.yml +++ b/.github/workflows/agent-shield-reusable.yml @@ -32,6 +32,7 @@ on: type: string default: | CLAUDE.md + GEMINI.md AGENTS.md org-standards-ref: description: "String AGENTS.md must reference (regex, basic grep -E)" @@ -89,6 +90,12 @@ jobs: status=1 fi + if [ -f "GEMINI.md" ] && \ + ! grep -qi 'AGENTS.md' GEMINI.md; then + echo "::error file=GEMINI.md::Must reference AGENTS.md" + status=1 + fi + if [ -f "AGENTS.md" ] && \ ! grep -qiE "$ORG_REF" AGENTS.md; then echo "::error file=AGENTS.md::Must reference org standards ($ORG_REF)" diff --git a/GEMINI.md b/GEMINI.md new file mode 100644 index 000000000..823b695c8 --- /dev/null +++ b/GEMINI.md @@ -0,0 +1,5 @@ +# GEMINI.md + +This repository follows the development and agentic architecture standards defined in [AGENTS.md](AGENTS.md) and [`combsmith/.github/AGENTS.md`](https://github.com/combsmith/.github/blob/main/AGENTS.md). + +Read [AGENTS.md](AGENTS.md) for full context, project conventions, testing guidelines, and architectural rules. diff --git a/scripts/compliance-audit.sh b/scripts/compliance-audit.sh index 9acef7b78..e3125f5fa 100755 --- a/scripts/compliance-audit.sh +++ b/scripts/compliance-audit.sh @@ -2477,6 +2477,32 @@ check_claude_md() { fi } +# --------------------------------------------------------------------------- +# Check: GEMINI.md exists and references AGENTS.md +# --------------------------------------------------------------------------- +check_gemini_md() { + local repo="$1" + + local content + content=$(gh_api "repos/$ORG/$repo/contents/GEMINI.md" --jq '.content' 2>/dev/null || echo "") + + if [ -z "$content" ]; then + add_finding "$repo" "standards" "missing-gemini-md" "error" \ + "Missing \`GEMINI.md\` — every repo must have a GEMINI.md that references AGENTS.md" \ + "AGENTS.md" + return + fi + + local decoded + decoded=$(echo "$content" | base64 -d 2>/dev/null || echo "") + + if ! echo "$decoded" | grep -qi 'AGENTS\.md'; then + add_finding "$repo" "standards" "gemini-md-missing-agents-ref" "error" \ + "\`GEMINI.md\` does not reference \`AGENTS.md\`" \ + "AGENTS.md" + fi +} + # --------------------------------------------------------------------------- # Check: AGENTS.md exists and references org .github/AGENTS.md # --------------------------------------------------------------------------- @@ -3062,7 +3088,7 @@ create_umbrella_issue() { "reusable-workflows|Reusable Workflows (disabled_manually)|gh workflow disable -R " "action-pinning|Action SHA Pinning|pin actions to SHA in each workflow file" "dependabot|Dependabot Configuration|per-repo .github/dependabot.yml" - "standards|Agent Standards (CLAUDE.md / AGENTS.md / copilot-setup-steps.yml)|per-repo doc and workflow additions" + "standards|Agent Standards (CLAUDE.md / GEMINI.md / AGENTS.md / copilot-setup-steps.yml)|per-repo doc and workflow additions" ) local body @@ -3657,6 +3683,7 @@ main() { check_verbatim_stubs "$repo" check_centralized_check_names "$repo" check_claude_md "$repo" + check_gemini_md "$repo" check_agents_md "$repo" check_copilot_setup_steps "$repo" check_copilot_instructions "$repo" diff --git a/scripts/compliance-remediate.sh b/scripts/compliance-remediate.sh index 1576c5653..b04b64836 100644 --- a/scripts/compliance-remediate.sh +++ b/scripts/compliance-remediate.sh @@ -874,6 +874,10 @@ remediate_finding() { report_skip "$repo" "$check" \ "CLAUDE.md creation/update requires content knowledge — trigger Claude agent on the finding issue" ;; + standards/missing-gemini-md | standards/gemini-md-missing-agents-ref) + report_skip "$repo" "$check" \ + "GEMINI.md creation/update requires content knowledge — trigger Claude agent on the finding issue" + ;; standards/missing-agents-md | standards/agents-md-missing-org-ref) report_skip "$repo" "$check" \ "AGENTS.md creation/update requires content knowledge — trigger Claude agent on the finding issue" diff --git a/standards/agent-standards.md b/standards/agent-standards.md index c9d465918..6635ad889 100644 --- a/standards/agent-standards.md +++ b/standards/agent-standards.md @@ -1,7 +1,7 @@ # Agent Configuration Standards Standards for repositories that use AI agent configurations (CLAUDE.md, -AGENTS.md, BMAD modules, Claude plugins, MCP server configs). +GEMINI.md, AGENTS.md, BMAD modules, Claude plugins, MCP server configs). --- @@ -12,6 +12,7 @@ Every repository MUST have: | File | Purpose | Compliance Check | |------|---------|-----------------| | `CLAUDE.md` | Project-level instructions for Claude Code | error if missing | +| `GEMINI.md` | Project-level instructions for Gemini CLI / Antigravity | error if missing | | `AGENTS.md` | Development standards for AI agents | error if missing | ## Compliance Exemptions — Files Agents Must Not Modify @@ -37,6 +38,13 @@ to all repos via the `@v1` tag bump. - MUST NOT contain overly permissive tool authorization (e.g., `dangerouslySkipPermissions`) - SHOULD define project-specific context (tech stack, conventions, key files) +### GEMINI.md Requirements + +- MUST reference `AGENTS.md` for development standards +- MUST NOT contain secrets, API keys, or credentials +- MUST NOT contain overly permissive tool authorization +- SHOULD reference the org-level standards (`combsmith/.github/AGENTS.md`) or project-specific context + ### AGENTS.md Requirements - MUST reference the org-level standards: `combsmith/.github/AGENTS.md` @@ -82,8 +90,9 @@ generic AgentShield scanner: | Rule | Severity | Description | |------|----------|-------------| -| `required-files` | error | CLAUDE.md and AGENTS.md must exist | +| `required-files` | error | CLAUDE.md, GEMINI.md, and AGENTS.md must exist | | `claude-reference` | error | CLAUDE.md must reference AGENTS.md | +| `gemini-reference` | error | GEMINI.md must reference AGENTS.md | | `org-reference` | error | AGENTS.md must reference `combsmith/.github/AGENTS.md` | | `valid-frontmatter` | error | All SKILL.md files must have YAML frontmatter with `name` and `description` | diff --git a/test/scripts/compliance-audit/gemini-md.bats b/test/scripts/compliance-audit/gemini-md.bats new file mode 100644 index 000000000..592d8536e --- /dev/null +++ b/test/scripts/compliance-audit/gemini-md.bats @@ -0,0 +1,62 @@ +#!/usr/bin/env bats +# Unit tests for check_gemini_md in scripts/compliance-audit.sh +# (standards/agent-standards.md). + +bats_require_minimum_version 1.5.0 + +REPO_ROOT="$(cd "$BATS_TEST_DIRNAME/../../.." && pwd)" +SCRIPT="$REPO_ROOT/scripts/compliance-audit.sh" + +setup() { + TMPDIR_TEST="$(mktemp -d)" + export TMPDIR_TEST +} + +teardown() { + rm -rf "$TMPDIR_TEST" +} + +run_check_gemini_md() { + local repo="$1" gemini_body="$2" + bash -c ' + set -euo pipefail + export ORG="combsmith" + export OUTPUT_DIR="'"$TMPDIR_TEST"'" + source "'"$SCRIPT"'" + FINDINGS_FILE="$OUTPUT_DIR/findings.json" + echo "[]" > "$FINDINGS_FILE" + findings_count=0 + GEMINI_BODY="$2" + gh_api() { + if [ -z "$GEMINI_BODY" ]; then + return 1 + fi + printf "%s" "$GEMINI_BODY" | base64 | tr -d "\n" + printf "\n" + } + check_gemini_md "$1" + cat "$FINDINGS_FILE" + ' _ "$repo" "$gemini_body" +} + +@test "check_gemini_md: compliant GEMINI.md referencing AGENTS.md produces no finding" { + run run_check_gemini_md "incubator" "# GEMINI.md +See [AGENTS.md](AGENTS.md) and https://github.com/combsmith/.github/blob/main/AGENTS.md" + [ "$status" -eq 0 ] + [ "$output" = "[]" ] +} + +@test "check_gemini_md: missing GEMINI.md raises missing-gemini-md error" { + run run_check_gemini_md "incubator" "" + [ "$status" -eq 0 ] + [[ "$output" == *'"check": "missing-gemini-md"'* ]] + [[ "$output" == *'"severity": "error"'* ]] +} + +@test "check_gemini_md: GEMINI.md without AGENTS.md reference raises gemini-md-missing-agents-ref error" { + run run_check_gemini_md "incubator" "# GEMINI.md +Project instructions without referencing the required file." + [ "$status" -eq 0 ] + [[ "$output" == *'"check": "gemini-md-missing-agents-ref"'* ]] + [[ "$output" == *'"severity": "error"'* ]] +} diff --git a/test/scripts/compliance-remediate/routing-messages.bats b/test/scripts/compliance-remediate/routing-messages.bats index f8aa1de37..6a86a5cf2 100644 --- a/test/scripts/compliance-remediate/routing-messages.bats +++ b/test/scripts/compliance-remediate/routing-messages.bats @@ -160,3 +160,27 @@ teardown() { ! grep -q 'review manually' "$report_dir/skipped.md" } + +# --------------------------------------------------------------------------- +# standards/missing-gemini-md & standards/gemini-md-missing-agents-ref +# --------------------------------------------------------------------------- + +@test "missing-gemini-md and gemini-md-missing-agents-ref route to the content-agent path" { + for check_name in missing-gemini-md gemini-md-missing-agents-ref; do + findings="$(tt_write_finding "broodminder-export" "standards" "$check_name")" + report_dir="${TT_TMP}/report-${check_name}" + + GH_TOKEN=fake \ + FINDINGS_FILE="$findings" \ + REPORT_DIR="$report_dir" \ + DRY_RUN=false \ + run bash "$TT_SCRIPT" + + [ "$status" -eq 0 ] + + grep -q "$check_name" "$report_dir/skipped.md" + ! grep -q "$check_name" "$report_dir/remediation-report.md" + grep -q 'GEMINI.md creation/update requires content knowledge' "$report_dir/skipped.md" + ! grep -q 'review manually' "$report_dir/skipped.md" + done +}