diff --git a/docs/skills/INDEX.md b/docs/skills/INDEX.md new file mode 100644 index 00000000..716b115b --- /dev/null +++ b/docs/skills/INDEX.md @@ -0,0 +1,9 @@ +# docs/skills — Index + +Agent skill docs for the `projectbluefin/common` repo. + +| File | What it covers | +|---|---| +| [hive-review.md](hive-review.md) | `~/src/hive-status` — session start, P0/P1 triage, hive label taxonomy | +| [queue-dashboard.md](queue-dashboard.md) | queue.projectbluefin.io — PR tiers, merge ruleset (2 approvals), refresh cadence | +| [e2e-ci.md](e2e-ci.md) | Post-merge E2E CI architecture — common suite, brew tools masked in CI, MOTD fix, known quarantined scenarios | diff --git a/docs/skills/e2e-ci.md b/docs/skills/e2e-ci.md new file mode 100644 index 00000000..d8afde70 --- /dev/null +++ b/docs/skills/e2e-ci.md @@ -0,0 +1,94 @@ +# E2E CI Architecture — projectbluefin/common + +Reference for agents working on test failures in the post-merge E2E suite. + +## How the common suite runs + +The common post-merge E2E (`common/.github/workflows/e2e.yml`) calls the reusable +workflow at `projectbluefin/testsuite/.github/workflows/e2e.yml@main` with `suites: common`. + +**The common suite is special** — it runs behave directly on the GHA runner (not inside +a pre-built container). The runner SSHes to the VM at `127.0.0.1:2222` as `bluefin-test`. + +```yaml +# testsuite e2e.yml (simplified) +if: env.SUITE == 'common' + run: | + python3 -m pip install behave + behave tests/common/features/ +else + # Load pre-built runner container, then run behave inside it +``` + +The pre-built runner container does **not** affect the common suite because of this conditional. + +## VM kernel args + +``` +systemd.mask=brew-setup.service +``` + +`brew-setup.service` is masked for every test VM. This means: + +- Homebrew itself is present at `/home/linuxbrew/.linuxbrew/bin/brew` +- **Brew packages are NOT installed** — `eza`, `fd`, `rg`, `bat`, `fzf`, `starship`, etc. + are all from `cli.Brewfile` and require brew-setup to run first +- Any test that checks for these tools will fail in CI + +## Known CI failures and their status + +### brew CLI tools (eza, fd, ripgrep, bat, fzf, starship) — QUARANTINED + +**Root cause:** These are `cli.Brewfile` packages. `brew-setup.service` is masked. +The `ublue-os/brew` image only ships a bare Homebrew tarball at `/usr/share/homebrew.tar.zst`. + +**Status:** Quarantined in `tests/common/features/common_shell.feature` via `@quarantine`. +Tracking issue: projectbluefin/testsuite#210 + +**Options to unblock:** +1. Un-mask `brew-setup.service` in CI (adds ~60s) +2. Install tools as RPMs in the Containerfile +3. Add a CI step to `brew bundle install` before the suite runs + +### zsh / fish — QUARANTINED + +**Root cause:** zsh and fish ARE installed as RPMs (`/usr/bin/zsh`, `/usr/bin/fish`). +However, under the `bash -lc '...brew_shellenv...; zsh --version'` SSH command that +`environment.py` uses, they return `command not found`. PATH does not include +`/usr/bin` in this non-interactive login context for the fresh `bluefin-test` user. + +**Status:** Quarantined. Tracking issue: projectbluefin/testsuite#210 + +### Dakota MOTD — FIXED (testsuite PR #208) + +**Root cause:** `run_ssh()` in `ssh_steps.py` wraps commands in `bash -lc` (login shell) +when `ssh_command_prefix` is set. This triggers `/etc/profile.d/ublue-motd.sh`, which +calls `ublue-motd` and prints the MOTD to stdout. The `vm_reachable_over_ssh` step +checked `stdout == "ok"` (exact match) but got MOTD prepended. + +Only Dakota prints a MOTD; Bluefin stable/LTS pass unaffected. + +**Fix (testsuite PR #208):** +- Creates `~/.config/no-show-user-motd` for the CI user in VM setup +- Changes assertion to `stdout.strip().split('\n')[-1] == "ok"` + +## SSH command execution model + +```python +# testsuite/tests/shared/ssh_steps.py +# When context.ssh_command_prefix is set (always true for common suite): +cmd_wrapped = f"bash -lc {shlex.quote(f'{prefix}; {cmd}')}" +``` + +`environment.py` sets `ssh_command_prefix` to include `eval $(brew shellenv)` so brew +tools are on PATH inside the VM. Side effect: login shell triggers profile.d scripts. + +## Images tested + +| Job | Image | +|---|---| +| E2E — Bluefin LTS | `ghcr.io/ublue-os/bluefin:lts` | +| E2E — Bluefin Stable | `ghcr.io/ublue-os/bluefin:latest` | +| E2E — Dakota | `ghcr.io/projectbluefin/dakota:latest` | + +All three run `suites: common` only. Post-merge only — not triggered on PRs. diff --git a/docs/skills/queue-dashboard.md b/docs/skills/queue-dashboard.md new file mode 100644 index 00000000..d339827b --- /dev/null +++ b/docs/skills/queue-dashboard.md @@ -0,0 +1,90 @@ +# Queue Dashboard — queue.projectbluefin.io + +The **Clanker Control Panel** — live view of everything waiting for a human decision +across the `projectbluefin` org. + +**Machine-readable reviewer briefing:** https://queue.projectbluefin.io/review-guide.md +**Live data snapshot (JSON):** https://queue.projectbluefin.io/data.json + +## What it shows + +https://queue.projectbluefin.io/ is a dashboard regenerated every 10 minutes by GitHub Actions +from `projectbluefin/queue`. It shows: + +- **Stats bar** — P0 · P1 · Triage · Issues · PRs · velocity counts at a glance +- **P0 / P1 column** — hive-tracked blockers and this-cycle items (right column) +- **PR tiers** — open PRs bucketed by review state, each card shows approval count +- **Dark / Light / System theme toggle** — persists via `localStorage` + +The browser auto-refreshes every 5 minutes without a page reload, comparing the +`generated` timestamp in `/data.json` to avoid unnecessary re-renders. + +## PR tiers (how your PR appears) + +The generator queries GitHub search with these filters: + +``` +is:pr is:open -is:draft status:success review:approved → ✅ Approved (ready to merge) +is:pr is:open -is:draft status:success review:required → ⏳ Needs reviews +is:pr is:open -is:draft status:success review:none → ○ No reviews yet +``` + +**Key:** `review:approved` only turns green when ALL required approvals are satisfied. +`review:required` means at least one review is still needed. + +Each PR card displays the **approval count** prominently (e.g. `1 / 2`) so reviewers +can see at a glance how close a PR is to merge. + +## Merge ruleset for projectbluefin/common + +Ruleset: `main-review-required-with-renovate-bypass` + +- **Required approvals: 2** — one review leaves a PR in `review:required`, not `review:approved` +- **Required status check: `Build and push image`** only +- Smoke tests (`E2E — */GNOME 50 — smoke`) are **not** required checks — stale failures + from prior runs don't block merge +- Renovate PRs bypass the review requirement (auto-merge eligible) + +## When a PR has one review + +`review:required` → appears in the yellow "Needs reviews" tier on the dashboard. +A second human approval moves it to the green "Approved" tier. + +## Data architecture + +``` +GitHub API (every 10 min, GHA cron) + → generate.js (25-min file TTL cache layer) + → data.json ← committed to repo root, served as static asset + → index.html ← bakes data.json contents as __DATA__ for instant first paint + +Browser (on load) + → renders immediately from embedded __DATA__ + → polls /data.json every 5 min, re-renders if generated timestamp changed +``` + +`data.json` contains: full PR lists per tier, hive issue lists per priority, +review counts per PR, velocity counts, and a `generated` ISO timestamp. + +## Refresh cadence + +- Regenerated every 10 minutes via GitHub Actions cron in `projectbluefin/queue` +- `hive-progress-sync.yml` in this repo posts Common-specific stats to the org project board + at :20 past the hour (staggered from bluefin :15, dakota :00, knuckle :30, lts :45) + +## Repos tracked + +`bluefin`, `bluefin-lts`, `common`, `dakota`, `actions`, `renovate-config`, `bonedigger`, `knuckle` + +## Full reviewer guide + +For everything needed to review a Bluefin PR (merge rules, what to check, human gates, +label taxonomy, hive labels, quick reference commands): + +**https://queue.projectbluefin.io/review-guide.md** + +Also see: https://docs.projectbluefin.io/agentic-contributing + +## Source + +Generator: https://github.com/projectbluefin/queue/blob/main/generate.js