Skip to content

Commit 7f1dc34

Browse files
feat: Add GitHub Copilot instructions and coding agent PR gate workflow
1 parent 93cd413 commit 7f1dc34

4 files changed

Lines changed: 176 additions & 1 deletion

File tree

.github/CODEOWNERS

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# CODEOWNERS — see https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners
2+
#
3+
# Personal-project repository: @frasermolyneux owns everything by default.
4+
# Add path-specific overrides above the catch-all if a particular area needs
5+
# stricter review (e.g. workload-identity JSON, branch-protection-touched files).
6+
7+
* @frasermolyneux

.github/copilot-instructions.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
# Copilot Instructions
22

3-
> Shared conventions: see [`.github-copilot/.github/instructions/terraform.instructions.md`](../../.github-copilot/.github/instructions/terraform.instructions.md) for the standard Terraform layout, providers, remote-state pattern, validation commands, and CI/CD workflows.
3+
> Shared conventions: see [`.github-copilot/.github/instructions/terraform.instructions.md`](../.github-copilot/.github/instructions/terraform.instructions.md) for the standard Terraform layout, providers, remote-state pattern, validation commands, and CI/CD workflows.
4+
>
5+
> <!-- Links use `../.github-copilot/` which resolves in the cloud-runner checkout (copilot-setup-steps.yml clones `.github-copilot` to the repo root). In local VS Code with the multi-root workspace, browse `../../.github-copilot/` instead. -->
6+
>
7+
> **Cloud agents (GitHub Copilot coding agent etc.):** read [`AGENTS.md`](../AGENTS.md) at the repo root first — it is the canonical brief that survives outside the local VS Code multi-root workspace.
48
59
## Project Overview
610

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
name: Coding-Agent PR Gate
2+
3+
on:
4+
pull_request:
5+
types: [opened, edited, reopened, ready_for_review, synchronize, labeled, unlabeled]
6+
7+
permissions: {}
8+
9+
jobs:
10+
checklist-gate:
11+
name: PR body checklist gate
12+
if: github.event.pull_request.draft == false && contains(github.event.pull_request.labels.*.name, 'coding-agent')
13+
runs-on: ubuntu-latest
14+
permissions:
15+
pull-requests: read
16+
steps:
17+
- name: Verify every checkbox in PR body is ticked
18+
uses: actions/github-script@v7
19+
with:
20+
script: |
21+
const body = context.payload.pull_request.body || '';
22+
23+
// Strip HTML comments — guidance comments may contain unticked example boxes.
24+
// Then strip fenced code blocks — pasted command output must not trip the gate.
25+
const stripped = body
26+
.replace(/<!--[\s\S]*?-->/g, '')
27+
.replace(/```[\s\S]*?```/g, '');
28+
29+
const lines = stripped.split(/\r?\n/);
30+
const unchecked = [];
31+
for (let i = 0; i < lines.length; i++) {
32+
const m = lines[i].match(/^\s*[-*]\s+\[\s\]\s+(.*)$/);
33+
if (m) {
34+
unchecked.push(`L${i + 1}: ${m[1]}`);
35+
}
36+
}
37+
38+
if (unchecked.length > 0) {
39+
core.setFailed(
40+
`PR body has ${unchecked.length} unticked checkbox(es). ` +
41+
`The 'coding-agent' label requires every checkbox to be ticked before merge.\n\n` +
42+
unchecked.map(u => ` - ${u}`).join('\n') +
43+
`\n\nTick each box in the PR description, or remove the 'coding-agent' label if this PR was not produced by the agent.`
44+
);
45+
return;
46+
}
47+
48+
core.info('All checkboxes in the PR body are ticked. Gate passes.');

AGENTS.md

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
# AGENTS.md — portal-web
2+
3+
ASP.NET Core 9 web application — the XtremeIdiots Portal front-end. Razor views (runtime compile in Debug, build-time precompile in Release), SCSS via npm, Application Insights, Azure App Configuration, EF Core for identity / data-protection, and typed API clients for the Portal Repository, Servers Integration, and GeoLocation APIs.
4+
5+
This file is the brief for the **GitHub Copilot coding agent** (and any other agent that follows the [agents.md](https://agents.md) convention) when it runs in a cloud runner without the local VS Code multi-root workspace context.
6+
7+
> If you are a human reading this in VS Code, prefer `.github/copilot-instructions.md` for project orientation. `AGENTS.md` is the agent execution brief.
8+
9+
---
10+
11+
## Required reading (read these BEFORE doing any work)
12+
13+
The `copilot-setup-steps.yml` workflow checks out `frasermolyneux/.github-copilot` at `./.github-copilot/` in the runner, so the paths below resolve.
14+
15+
1. `.github/copilot-instructions.md` — repo-specific orientation, build commands, conventions
16+
2. `.github-copilot/.github/instructions/personal.working-preferences.instructions.md`
17+
3. `.github-copilot/.github/copilot-instructions.md` — org-wide catalog
18+
4. Stack-specific files — see **Stack guardrails** below
19+
5. `docs/ui-standards-guide.md`**mandatory for any Razor view change** (buttons, icons, forms, destructive operations, legacy patterns to avoid)
20+
6. `docs/authorization-model.md` — how roles, policies, and `PotentialAccessProbe` work
21+
7. `docs/css-architecture-guide.md` — SCSS structure, tokens, components
22+
8. `docs/DATATABLE-IMPLEMENTATION-GUIDE.md` — server-backed data table patterns
23+
24+
---
25+
26+
## Stack guardrails
27+
28+
### Tenant facts (always-on)
29+
- `tenant.subscriptions`, `tenant.regions`, `tenant.identity`, `tenant.dns`
30+
31+
### Enforceable standards
32+
- `standards.oidc-and-secrets`**no client secrets**
33+
- `standards.dotnet-project`
34+
- `standards.azure-naming`, `standards.azure-tagging`, `standards.terraform-style`
35+
- `standards.branching-and-prs`
36+
37+
### Patterns
38+
- `patterns.api-client` — consumes Portal Repository + Servers Integration + GeoLocation clients
39+
- `patterns.scss-build` — SCSS build pattern
40+
- `patterns.nbgv-versioning`
41+
- `patterns.terraform-remote-state`
42+
43+
### Platform consumption contracts
44+
- `platform.workloads`, `platform.monitoring`, `platform.hosting`, `platform.connectivity`
45+
46+
### Shared
47+
- `shared.api-client-abstractions`
48+
- `shared.observability-appinsights`
49+
- `shared.portal-core` — App Insights / ASP / SQL consumed from `portal-core`
50+
51+
---
52+
53+
## Build, test, format
54+
55+
```pwsh
56+
# .NET
57+
dotnet build src/XtremeIdiots.Portal.Web/XtremeIdiots.Portal.Web.csproj
58+
dotnet test src --filter "FullyQualifiedName!~IntegrationTests"
59+
dotnet format src/XtremeIdiots.Portal.Web.sln --verify-no-changes
60+
61+
# SCSS (npm install runs automatically on first build via MSBuild target)
62+
cd src/XtremeIdiots.Portal.Web
63+
npm install
64+
npm run build:css:dev
65+
cd ../..
66+
67+
# Terraform
68+
terraform -chdir=terraform fmt -check -recursive
69+
terraform -chdir=terraform init -backend-config=backends/dev.backend.hcl
70+
terraform -chdir=terraform validate
71+
terraform -chdir=terraform plan -var-file=tfvars/dev.tfvars
72+
```
73+
74+
Release builds treat warnings as errors and precompile Razor views — check `ValidateRazor=true` Razor compilation succeeds before declaring done.
75+
76+
---
77+
78+
## Do NOT
79+
80+
- ❌ Do not `git commit`, `git push`, force-push, rebase, or branch-mutate. Work on the assigned branch only.
81+
- ❌ Do not introduce client secrets. App Configuration + Key Vault + managed identity only.
82+
- ❌ Do not bypass `dotnet format`, `dotnet test`, `terraform fmt`, `terraform validate`, or the SCSS build.
83+
- ❌ Do not use legacy Razor / Bootstrap classes: `control-label`, `help-block`, `float-e-margins`, `btn-xs`, `dl-horizontal`, `admin-actions-filters`, `fa-save`, `fa-edit`, `type="button"` on `<a>` tags. See `docs/ui-standards-guide.md`.
84+
- ❌ Do not use inline `onclick` / `onsubmit` confirm handlers — use Tier 1 (confirmation page) or Tier 2 (`data-confirm` attribute) per the UI standards guide.
85+
- ❌ Do not use `ClaimedGamesAndItems` or direct claim checks as authorization gates — use `PotentialAccessProbe` instead. The handler is the single source of truth.
86+
- ❌ Do not bypass the `{Domain}.{Action}` policy convention — register new policies via `PolicyExtensions.AddXtremeIdiotsPolicies()`.
87+
- ❌ Do not modify `.github/workflows/`, `.github/dependabot.yml`, or `version.json` unless that is the explicit task.
88+
89+
---
90+
91+
## Validation before opening PR
92+
93+
- [ ] `dotnet build` succeeds (clean) — Release config catches warning-as-error and Razor precompile issues
94+
- [ ] `dotnet test --filter "FullyQualifiedName!~IntegrationTests"` passes
95+
- [ ] `dotnet format --verify-no-changes` passes
96+
- [ ] `npm run build:css:dev` succeeds
97+
- [ ] `terraform fmt -check -recursive` passes
98+
- [ ] `terraform validate` + `terraform plan -var-file=tfvars/dev.tfvars` succeed
99+
- [ ] All Razor view changes follow `docs/ui-standards-guide.md` (buttons, icons, forms, destructive gating)
100+
- [ ] New authorization checks use `PotentialAccessProbe` for "can user potentially..." gates
101+
- [ ] No new secrets / GUIDs / connection strings
102+
- [ ] PR body cites each acceptance criterion
103+
- [ ] Risk/rollout section filled in
104+
105+
---
106+
107+
## Escalation
108+
109+
If you hit any of the conditions below, **open the PR as draft** and **apply the `needs-decision` label** instead of pushing forward to ready-for-review. Post a comment on the originating issue summarising what's blocking you and what decision is needed.
110+
111+
Stop and escalate when:
112+
113+
- The change requires modifying `AdditionalPermission` constants in the `portal-repository` abstractions package (coordinate there first).
114+
- A new authorization policy crosses domain boundaries and would need cross-repo coordination.
115+
- A `code-review` finding is **High** and cannot be resolved in-scope.
116+
- The SCSS build fails and `npm install` + `npm run build:css:dev` does not resolve it.

0 commit comments

Comments
 (0)