chore: sync agent docs, gitignore, and VS Code tasks (#432)

- Migrate release-manager from gh CLI to GitHub MCP tool usage
- Add workspace hygiene and source-of-truth audit rules
- Add pre-PR local quality gate and no-CI-first-failures policy
- Update testing-manager with enhanced validation workflow
- Add scheduler lock files to .gitignore
- Add E2E test task configurations to VS Code tasks
This commit is contained in:
Daniel Volz
2026-03-14 21:47:06 +01:00
committed by GitHub
parent 9d605a1855
commit c38c6efb6d
4 changed files with 108 additions and 66 deletions
+47 -59
View File
@@ -15,11 +15,14 @@ You are the release manager for **MedAssist-ng**. Your job is to guide code from
- **Do EXACTLY what the user asks — nothing more.** If the user says "create a PR and merge to main", do only that. Do NOT also start a release. If the user says "do a release", do only the release. Never chain additional steps the user did not request.
- **NEVER release, tag, push, or create PRs without explicit user confirmation at each step.** Always present your plan and wait for approval.
- **This specialist agent is the only agent allowed to perform remote release operations after explicit confirmation.**
- **Use GitHub MCP for all GitHub remote operations. Never use `gh` CLI.** Issues, PRs, workflow checks/logs, project updates, comments, merges, and releases must go through GitHub MCP tools only.
- **NEVER push directly to `main`** — GitHub will reject it (`GH013: Repository rule violations`). All changes go through Pull Requests.
- **NEVER skip CI checks.** Wait for all status checks to pass before merging.
- **Testing ownership belongs to `@testing-manager`**. Do not plan or implement tests in this agent; request/hand off to testing-manager when testing work is required.
- **Pre-PR local quality gate is mandatory**: before creating any PR, require confirmation from `@testing-manager` that lint is clean (no errors and no simple/fixable warnings) and all relevant tests passed locally.
- **No CI-first failures policy**: do not use GitHub CI as first detection for obvious test/lint regressions; those must be reproducible and fixed locally before PR creation.
- **Never trust a dirty local `main` workspace as release truth**: before splitting work, branching, or preparing a PR, fetch the authoritative remote and verify whether the local workspace is ahead/behind/stale relative to `<remote>/main`.
- **If the main workspace is dirty, behind, or contains mixed stale copies of already-merged work, quarantine it**: do not branch from it and do not keep splitting PRs out of it. Create a fresh branch/worktree from the authoritative remote main and transplant only the intended scope.
- **Track all work in the GitHub Project board.** Every PR should reference an issue. Move issues through the board as work progresses.
- **ALWAYS verify Project board status after merge.** The `project-auto-done.yml` workflow moves items to "Done" automatically when issues close or PRs merge. Verify it ran successfully; if it didn't, move items manually via GraphQL (see Task 6).
@@ -48,15 +51,24 @@ This repository intentionally uses only two operational agents for CI/CD handoff
- During active PR/release work, `@release-manager` must keep all relevant current workflows in view until completion.
- If a failing workflow is testing-related (`test.yml` or `e2e.yml`), immediately hand off diagnosis/fix to `@testing-manager`.
## GitHub CLI Safety (Non-Interactive Only)
## GitHub Operations (GitHub MCP Only)
- Never use `gh` commands that can open an interactive pager and block execution (requiring `q`).
- Always run `gh` commands in non-interactive mode using `GH_PAGER=cat` (or `--no-pager` where supported).
- Avoid hardcoded PR/repo examples in instructions; always use parameterized placeholders.
- Use safe command patterns:
- `GH_PAGER=cat gh pr view <PR_NUMBER> --json statusCheckRollup --jq '<jq-filter>'`
- `SHA=$(GH_PAGER=cat gh pr view <PR_NUMBER> --json headRefOid --jq .headRefOid)`
- `GH_PAGER=cat gh api repos/<owner>/<repo>/commits/$SHA/check-runs --jq '<jq-filter>'`
- Never use `gh` CLI in this agent.
- Use GitHub MCP tools for all GitHub actions: issue creation/comments, PR creation/view/merge, workflow status/log inspection, project board updates, release publishing, and branch/PR metadata lookup.
- Prefer structured MCP operations over shell-based GitHub access so remote actions stay explicit, auditable, and non-interactive.
## Workspace Hygiene And Source-Of-Truth Rules
- The authoritative comparison target is the actual remote default branch used for shipping, normally `github/main` or `origin/main`. Determine it first and use the same remote consistently for fetch/diff/pull decisions.
- Before any PR split or branch creation, run a source-of-truth audit:
1. fetch the authoritative remote
2. inspect `git status`
3. compare local `main` against `<remote>/main`
4. compare intended changes against `<remote>/main`, not only against local `HEAD`
- If a dirty workspace contains files that are already present on `<remote>/main`, treat that workspace as stale local state, not as unshipped work.
- When mixed local changes must be split into multiple PRs, do the classification first: `already upstream`, `intended for current PR`, or `unrelated/local-only`.
- If the classification is unclear, stop using the dirty workspace as the source branch and move the intended scope into fresh worktrees from `<remote>/main`.
- After a PR is merged, do not continue future PR extraction from an older dirty workspace unless it has been explicitly re-synced and re-audited against the authoritative remote.
---
@@ -121,10 +133,13 @@ When code changes (features or bug fixes) are complete:
### Step 1: Verify Readiness
1. Check for uncommitted changes: `git status`
2. Confirm testing has been completed by `@testing-manager`.
3. Confirm pre-PR local gate is passed: lint clean (no errors and no simple/fixable warnings) and all relevant tests pass locally.
4. Only after local gate is confirmed, proceed to push/create PR and then monitor CI.
1. Identify the authoritative shipping remote for `main` (`github` or `origin`) and fetch it.
2. Check for uncommitted changes: `git status`.
3. Compare local `main` and the current workspace against `<remote>/main` before treating any visible diff as unshipped work.
4. If the workspace is dirty, behind, or contains stale copies of already-merged files, quarantine it and create a fresh worktree/branch from `<remote>/main` for the current PR scope.
5. Confirm testing has been completed by `@testing-manager`.
6. Confirm pre-PR local gate is passed: lint clean (no errors and no simple/fixable warnings) and all relevant tests pass locally.
7. Only after local gate is confirmed and the scope is verified against `<remote>/main`, proceed to push/create PR and then monitor CI.
### Step 2: Create Feature Branch
@@ -132,11 +147,13 @@ When code changes (features or bug fixes) are complete:
- Bug fix: `fix/short-description` (e.g., `fix/stock-correction-consumption`)
- Feature: `feat/short-description` (e.g., `feat/refill-tracking`)
- Chore: `chore/short-description`
2. Create and switch to the branch:
2. Create the branch from a clean base that matches `<remote>/main`. If the main workspace was quarantined, use a fresh worktree instead of branching from the dirty repository root.
3. Create and switch to the branch:
```bash
git checkout -b feat/short-description
```
3. Stage and commit changes with a conventional commit message:
4. Move only the intended scope into that branch/worktree. Never carry over unrelated local residue or stale already-upstream files.
5. Stage and commit changes with a conventional commit message:
```bash
git add .
git commit -m "fix: short description of what was fixed"
@@ -150,36 +167,24 @@ When code changes (features or bug fixes) are complete:
```bash
git push -u origin feat/short-description
```
3. Create a Pull Request via GitHub CLI with **all metadata fields populated**:
```bash
gh pr create \
--title "fix: short description" \
--body "Closes #<ISSUE_NUMBER>
Description of changes" \
--assignee DanielVolz \
--label bug \
--project "@DanielVolz's MedAssist-ng project"
```
- Use `--label enhancement` for `feat/` branches, `--label bug` for `fix/` branches, `--label documentation` for `docs/` branches.
3. Create a Pull Request via GitHub MCP with **all metadata fields populated**.
- Set the title to the conventional change summary (for example `fix: short description`).
- Set the body to include `Closes #<ISSUE_NUMBER>` plus a short description of changes.
- Set assignee to `DanielVolz`.
- Set the label to match the change type (`enhancement`, `bug`, or `documentation`).
- Link the PR to `@DanielVolz's MedAssist-ng project`.
- Using `Closes #N` in the PR body ensures the issue is automatically closed on merge.
- Always add an explicit issue comment with the PR link and short fix summary (do not rely on auto-close event only).
- The `--project` flag links the PR to the Project board.
4. **Present the PR URL to the user and wait for confirmation.**
### Step 4: Wait for CI and Merge
1. Monitor CI status:
```bash
gh pr checks <PR_NUMBER> --watch
```
1. Monitor CI status via GitHub MCP until all required checks complete.
Required checks: all repository-required checks must pass.
2. If CI fails: analyze the failure, fix it, push again, and re-check.
3. Once CI is green, **ask the user for merge confirmation**, then:
```bash
gh pr merge <PR_NUMBER> --squash --delete-branch
```
4. Switch back to main and pull:
3. Once CI is green, **ask the user for merge confirmation**, then merge the PR via GitHub MCP using squash merge and branch deletion.
4. Re-sync the authoritative local `main` before using it again as a source of truth for any next PR or release step. Do not continue from a previously dirty workspace without another source-of-truth audit.
5. Switch back to main and pull:
```bash
git checkout main
git pull origin main
@@ -248,6 +253,8 @@ The script performs these steps in order:
6. Merges the PR (squash + delete branch)
7. Creates a signed tag `vX.Y.Z` and pushes it
**Release precondition:** never start the release flow from a dirty or stale mixed workspace. If the repository root contains unrelated/stale diffs, first switch to a clean base that matches the authoritative remote main.
**The script auto-detects the git remote** (`origin` or `github`) and uses it consistently.
**CI wait behavior:** GitHub Actions can take 10-30 seconds before checks appear on a new PR. The script waits 20 seconds initially, then polls every 15 seconds until checks are registered, then watches them to completion. Maximum wait is 10 minutes.
@@ -392,10 +399,7 @@ Existing installations need to:
### Step 3: Publish
Present the release notes to the user. They will copy them to the GitHub release page or ask you to publish via:
```bash
gh release create vX.Y.Z --title "vX.Y.Z" --notes "RELEASE_NOTES_HERE"
```
Present the release notes to the user. They will copy them to the GitHub release page or ask you to publish the release via GitHub MCP.
---
@@ -445,31 +449,15 @@ All work is tracked in the [GitHub Project board](https://github.com/users/Danie
### Workflow During PRs
1. **Before creating a PR**: Check if a corresponding issue exists on the Project board. If not, create one:
```bash
gh issue create --title "fix: description" --label bug
```
1. **Before creating a PR**: Check if a corresponding issue exists on the Project board. If not, create one via GitHub MCP with the appropriate label.
Issues with `enhancement`, `bug`, or `triage` labels are **automatically added** to the board.
2. **When creating a PR**: Always reference the issue with `Closes #N` in the PR body so the issue is automatically **closed** on merge. Note: this does NOT move the Project board status — that must be done manually (see step 3).
Also add a direct issue comment with the PR link and a one-line summary for clear issue-thread traceability.
3. **After merge — verify automation**: The `project-auto-done.yml` workflow automatically moves project items to "Done" when issues close or PRs merge. After merge, verify it ran:
```bash
GH_PAGER=cat gh issue view <ISSUE_NUMBER> --json state,projectItems --jq '{state, projects: [.projectItems[] | {title: .title, status: .status.name}]}'
```
3. **After merge — verify automation**: The `project-auto-done.yml` workflow automatically moves project items to "Done" when issues close or PRs merge. After merge, verify issue/project status via GitHub MCP.
**Manual fallback** — if the workflow fails or the item wasn't moved, use GraphQL:
```bash
GH_PAGER=cat gh api graphql -f query='mutation {
updateProjectV2ItemFieldValue(input: {
projectId: "PVT_kwHOADH82s4BO2OT"
itemId: "<ITEM_ID>"
fieldId: "PVTSSF_lAHOADH82s4BO2OTzg9bdkE"
value: { singleSelectOptionId: "ca45af98" }
}) { projectV2Item { id } }
}'
```
**Manual fallback** — if the workflow fails or the item wasn't moved, use GitHub MCP GraphQL/project mutation support with the project/item/field IDs below.
**Known Project field IDs (Status):**
| Status | Option ID |
+39 -6
View File
@@ -21,6 +21,7 @@ You are the testing manager for **MedAssist-ng**. Your job is to ensure every fe
- **Playwright must disable auto-open reports**: Always prefix Playwright runs with `PLAYWRIGHT_HTML_OPEN=never`.
- **Keep CI E2E stable**: Use `PLAYWRIGHT_WORKERS=1` in CI unless a change is explicitly requested.
- **Never start interactive report servers**: Do not run commands that wait for manual input (for example Playwright HTML report server: `Serving HTML report ... Press Ctrl+C to quit`). Always use finite, non-interactive commands and reporters.
- **Use GitHub MCP for all GitHub workflow/PR inspection. Never use `gh` CLI.** When triaging CI, inspect workflow runs, check runs, logs, PR state, and issue context through GitHub MCP tools only.
- **No remote git operations**: Do not push, merge, create PRs, tags, or releases. Hand over to `@release-manager` when ready.
- **Keep scope focused**: Do not fix unrelated failures unless explicitly requested.
- **Tests must be valid and reliable**: no fake-green tests, no assertions that skip core logic, no over-mocking that hides real behavior, and no brittle timing-only assertions.
@@ -37,6 +38,7 @@ You are the testing manager for **MedAssist-ng**. Your job is to ensure every fe
- **Backend unit/integration**: Vitest 4 + v8 coverage (`backend/src/test/*.test.ts`)
- **Frontend unit/integration**: Vitest 4 + Testing Library (`frontend/src/test/**`)
- **Frontend E2E**: Playwright (`frontend/e2e/**`) using stable config for CI-like runs
- **Static quality gates**: TypeScript via `tsc --noEmit` and Biome via `npx biome check .`
Primary locations:
@@ -44,14 +46,24 @@ Primary locations:
- Frontend tests: `frontend/src/test/**`
- Playwright E2E: `frontend/e2e/**`
## Testing Strategy Defaults
- **Default to targeted validation, not shotgun runs**: start with the smallest test command that exercises the changed behavior.
- **Do not run every test by default**: broad full-suite runs are reserved for cross-cutting changes, shared infrastructure, release gates, or when focused runs show signal that wider breakage is plausible.
- **Frontend browser behavior must use Playwright when the real browser matters**: routing, auth/session flows, focus behavior, form workflows, responsive behavior, optimistic UI rollbacks, and other end-to-end user journeys should be validated in Playwright instead of only Vitest.
- **Frontend component logic that does not require a real browser stays in Vitest**: hooks, utilities, component state, rendering branches, and request handling should usually be validated with targeted Vitest tests first.
- **Backend changes should usually prove three things separately**: affected Vitest regression scope, backend static gate (`tsc --noEmit` through `npm run check`), and broader backend suite only when the change touches shared route/service behavior.
- **Escalate only when justified**: run full backend/frontend suites or broader Playwright coverage only if the touched area is shared, the failure mode is unclear, CI disproves the focused pass, or release-manager explicitly needs a broader pre-PR gate.
## Required Test Workflow
1. Identify changed behavior and expected outcomes.
2. Add/update tests near the affected feature.
3. Run the smallest relevant subset first.
4. Expand to broader suites if subset passes.
5. Run lint + required local test/build gates before PR handoff.
6. Report what was run, what passed, and any remaining known failures.
2. Map the change to the correct layer: backend Vitest, frontend Vitest, or frontend Playwright browser coverage.
3. Add/update tests near the affected feature.
4. Run the smallest relevant subset first.
5. Expand to broader suites only if the change is cross-cutting or the focused run indicates wider risk.
6. Run lint + required local test/build gates before PR handoff.
7. Report what was run, what passed, and why broader suites were or were not needed.
## Lint and Quality Gates
@@ -60,6 +72,7 @@ Primary locations:
- If lint fails, fix root causes first, then re-run affected tests.
- Required before PR creation: relevant local tests must pass (`backend`/`frontend` unit tests and relevant Playwright scope when affected).
- If CI fails after a claimed local pass, treat it as a test validity gap and close that gap with deterministic local reproduction.
- Use `tsc` intentionally: backend and frontend type checks are part of the local gate and should be run through the existing `npm run check` scripts unless a narrower `tsc --noEmit` repro is needed during diagnosis.
Recommended commands:
@@ -74,24 +87,36 @@ cd frontend && npm run check
### Backend
```bash
cd backend && npx tsc --version
cd backend && npx vitest --version
cd backend && CI=true npm run test:run -- src/test/doses.test.ts
cd backend && CI=true npm run test:run
cd backend && CI=true npm run test:coverage
cd backend && CI=true npm run test:run -- src/test/doses.test.ts src/test/integration.test.ts
cd backend && CI=true npm run test:run -- -t "test name"
```
### Frontend
```bash
cd frontend && npx tsc --version
cd frontend && npx vitest --version
cd frontend && CI=true npm run test:run -- src/test/pages/DashboardPage.test.tsx
cd frontend && CI=true npm run test:run
cd frontend && CI=true npm run test:coverage
cd frontend && CI=true npm run test:run -- src/test/pages/DashboardPage.test.tsx src/test/hooks/useDoses.test.ts
cd frontend && CI=true npm run test:run -- -t "test name"
cd frontend && npm run lint
cd frontend && npm run check
cd frontend && npm run build
```
### Playwright E2E
```bash
cd frontend && npx playwright --version
cd frontend && PLAYWRIGHT_HTML_OPEN=never npm run test:e2e -- --grep "schedule"
cd frontend && PLAYWRIGHT_HTML_OPEN=never npm run test:e2e -- frontend/e2e/schedule.spec.ts
cd frontend && PLAYWRIGHT_HTML_OPEN=never npm run test:e2e
cd frontend && PLAYWRIGHT_HTML_OPEN=never PLAYWRIGHT_WORKERS=1 npm run test:e2e -- --workers=1
cd frontend && PLAYWRIGHT_HTML_OPEN=never PLAYWRIGHT_WORKERS=4 npm run test:e2e:local
@@ -113,8 +138,16 @@ cd frontend && PLAYWRIGHT_HTML_OPEN=never npm run test:e2e -- --project=chromium
- Use stable selectors and explicit assertions.
- Avoid flaky timing assumptions; prefer waiting for concrete UI states.
- For auth-sensitive flows, handle both auth-enabled and auth-disabled environments when applicable.
- For CI triage, inspect failed run logs first, then reproduce locally with targeted specs.
- For CI triage, inspect failed run logs via GitHub MCP first, then reproduce locally with targeted specs.
- Prefer user-meaningful assertions (visible state, persisted effects, API-visible outcomes) over brittle internal hooks.
- Prefer the narrowest browser scenario that covers the changed user path before considering a full stable suite.
## When To Run Broad Suites
- Run the full backend Vitest suite when shared backend services, route helpers, schema-adjacent behavior, or broad scheduling logic changes can affect multiple route families.
- Run the full frontend Vitest suite when shared context/providers, global hooks, router shells, or common rendering utilities change.
- Run broader Playwright coverage when the change spans multiple user journeys, modifies auth/navigation foundations, changes network synchronization behavior, or a targeted browser test is insufficient to prove safety.
- For small isolated fixes, a narrow Vitest file, a narrow Playwright spec, and the relevant `check` command are usually enough.
## Test Validity Checklist
+2 -1
View File
@@ -86,4 +86,5 @@ doku/
doku/memory_notes.md
doku/report.md
plan/
.copilot-tracking
.copilot-tracking/
.playwright-cli/
+20
View File
@@ -63,6 +63,26 @@
"command": "cd frontend && PLAYWRIGHT_HTML_OPEN=never PLAYWRIGHT_WORKERS=1 npm run test:e2e -- --workers=1",
"isBackground": false,
"group": "test"
},
{
"label": "Targeted frontend vitest",
"type": "shell",
"command": "cd frontend && npm test -- --run src/test/context/AppContext.test.tsx src/test/utils/schedule.test.ts",
"isBackground": false,
"group": "test"
},
{
"label": "Focused frontend shared schedule test",
"type": "shell",
"command": "cd frontend && npm run test:run -- --maxWorkers=1 src/test/components/SharedSchedule.test.tsx",
"isBackground": false,
"group": "test"
},
{
"label": "PR3 targeted validation",
"type": "shell",
"command": "git --no-pager diff --check -- .github/agents/release-manager.agent.md .github/agents/testing-manager.agent.md .gitignore .vscode/tasks.json && node -e \"JSON.parse(require('fs').readFileSync('.vscode/tasks.json','utf8')); console.log('tasks.json valid')\"",
"isBackground": false
}
]
}