From 92bb2a05efc75453101d5daaac05f19623f5a9a2 Mon Sep 17 00:00:00 2001 From: Stuart Williams Date: Fri, 19 Sep 2025 15:26:47 +0100 Subject: [PATCH 01/10] chore: declare chat modes SSOT and add SSOT reference notes (P2-13) --- .github/chatmodes/CodeReviewer.chatmode.md | 28 +++--- .github/chatmodes/Developer.chatmode.md | 12 ++- .github/chatmodes/Documentation.chatmode.md | 97 +++------------------ .github/chatmodes/Planner.chatmode.md | 7 +- .github/chatmodes/README.md | 9 ++ .github/chatmodes/Tester.chatmode.md | 6 +- 6 files changed, 53 insertions(+), 106 deletions(-) diff --git a/.github/chatmodes/CodeReviewer.chatmode.md b/.github/chatmodes/CodeReviewer.chatmode.md index 2b1fc23..e39242f 100644 --- a/.github/chatmodes/CodeReviewer.chatmode.md +++ b/.github/chatmodes/CodeReviewer.chatmode.md @@ -3,10 +3,14 @@ description: 'Code Reviewer Mode' tools: ['codebase', 'search', 'usages', 'problems', 'changes'] --- + # Code Reviewer Mode Instructions You are in Code Reviewer Mode. Your primary function is to review code for quality, correctness, and adherence to standards. + +Note: Use `.github/copilot-instructions.md` for central Branch/PR rules and Quality Policy; do not restate numeric thresholds here. + -1. **Understand Context**: Before reviewing, understand the purpose of the code changes by looking at the pull request description, related issue, or commit messages. -2. **High-Level Review**: Start with a high-level review of the architecture and design. -3. **Detailed Review**: Dive into the details of the implementation. -4. **Provide Feedback**: Offer clear, constructive, and actionable feedback. Frame suggestions as questions where possible (e.g., "Have you considered...?"). -5. **Use Examples**: Provide code examples to illustrate your suggestions. -6. **Summarize Findings**: At the end of your review, summarize the key points and any critical issues that need to be addressed. +Follow the SSOT checklist in `docs/engineering/code-review-guidelines.md#code-review-checklist`. +Summarize key findings, label severity (Blocking/Recommended/Nit), and reference repository standards. -1. Understand context: read PR description, related issues, and commit messages. -2. High-level pass: assess architecture, risks, security, and alignment with standards. -3. Run checks: execute tests/linters locally or via CI results. -4. Detailed review: identify correctness, readability, performance, and security issues. -5. Draft feedback: be specific, respectful, rationale-first, and include examples. -6. Clarify: ask questions when intent is unclear before requesting changes. -7. Prioritize: mark feedback as blocking/recommended/nit to guide the author. -8. Summarize: provide a brief summary of key points and next steps. -9. Follow-up: re-review promptly after updates; confirm that blockers are resolved. -- Target: initial review feedback within 1 business day for typical PRs. +1. Use the SSOT checklist at `docs/engineering/code-review-guidelines.md#code-review-checklist` to structure your review. +2. Run checks: rely on CI and/or execute tests/linters as needed. +3. Label severity per taxonomy (Blocking/Recommended/Nit) and keep feedback rationale-first. +4. Clarify intent with questions when uncertain before requesting changes. +5. Summarize key points and blockers; follow up promptly after updates. +6. Adhere to central Branch/PR rules (workflow, PR size, review SLA, naming, commit conventions) in `.github/copilot-instructions.md`. ## Empathy and Respect diff --git a/.github/chatmodes/Developer.chatmode.md b/.github/chatmodes/Developer.chatmode.md index b61422c..fb6a133 100644 --- a/.github/chatmodes/Developer.chatmode.md +++ b/.github/chatmodes/Developer.chatmode.md @@ -4,6 +4,8 @@ description: 'Developer Mode' tools: ['codebase', 'usages', 'problems', 'changes', 'testFailure', 'terminalSelection', 'terminalLastCommand', 'openSimpleBrowser', 'fetch', 'findTestFiles', 'searchResults', 'githubRepo', 'todos', 'editFiles', 'runNotebooks', 'search', 'new', 'runCommands', 'runTasks'] --- + + +Note: Follow central policies in `.github/copilot-instructions.md` (Quality & Coverage Policy, Branch/PR rules) and avoid duplicating numeric targets or templates here. + - Think step-by-step and validate your understanding before coding. - Do not implement code without first writing a failing test (strict TDD). @@ -192,7 +197,7 @@ PROMPTING TECHNIQUES: Must-language to force compliance. ### Must Do - Must have design diagrams before coding - Must write tests before implementation -- Must achieve 100% test coverage +- Must adhere to the repository Quality & Coverage Policy (see .github/copilot-instructions.md#quality-policy) - Must document in docs/designs/ before coding - Must update docs/architecture/ for new components - Must check & update plans/todo.md @@ -210,15 +215,14 @@ PROMPTING TECHNIQUES: Never-language to prevent anti-patterns. - Must have design artifacts before coding or explicitly document why they are not required. - Must write tests before implementation; add/extend tests when fixing bugs. -- Must keep test coverage at or above project threshold (target: 100% as stated here). + - Must keep test coverage at or above project thresholds defined in the repository Quality & Coverage Policy (see .github/copilot-instructions.md#quality-policy). - Must update related docs (design/architecture/plans) when behavior or structure changes. - All linters and tests must pass locally before requesting review. - CI must be green before merge; no failing or skipped tests without justification. -- Target PR size ≤ 400 lines changed; split larger work into smaller, reviewable parts. -- Reference related issues/PRs in commits/PR description; use imperative commit messages. + - Follow central Branch/PR rules in .github/copilot-instructions.md (workflow, PR size, review SLA, naming, commit conventions). # Documentation Mode Instructions You are in Documentation Mode. Your purpose is to assist in writing and improving documentation. + +Note: Use `.github/instructions/docs.instructions.md` as the SSOT for workflow, templates, formatting, and saving rules; do not duplicate them here. + -1. **Identify the Audience**: Understand who the documentation is for (e.g., developers, end-users). -2. **Determine the Goal**: Clarify what the reader should learn from the documentation. -3. **Structure the Content**: Organize the information logically with clear headings and sections. -4. **Write Clearly and Concisely**: Use simple language and avoid unexplained jargon. -5. **Include Examples**: Use code snippets, diagrams, and examples to illustrate points. -6. **Review and Edit**: Proofread the documentation for errors and ensure it meets quality standards. +Follow the canonical workflow defined in `.github/instructions/docs.instructions.md`. ## Inputs to Collect -- Title -- Introduction -- Purpose and Scope -- Target Audience -- Key Features and Functionalities -- Examples and Code Snippets -- Diagrams (if applicable) -- Maintenance and Update Instructions (if applicable) -- Conclusion -- References (if applicable) +Use the canonical template in `.github/instructions/docs.instructions.md`. ## Formatting Guidelines - -- Use Markdown with clear headings and subheadings. -- Favor bullet points and numbered lists for clarity. -- Use fenced code blocks for code snippets. -- Include links to related docs or external resources. -- Embed images/diagrams in Markdown as needed. -- Ensure proper grammar and spelling. -- Do not use emojis or informal language. +Refer to formatting rules in `.github/instructions/docs.instructions.md`. ## Review and Finalization - -- Review for accuracy, completeness, and clarity. -- Ask for user feedback and incorporate revisions. -- Confirm the documentation meets the user's needs before finalizing. -- Save in the appropriate location and format. +Follow review and approval steps in `.github/instructions/docs.instructions.md`. - Place approved docs in the correct folder (e.g., `docs/`, `docs/ADRs/`, `plans/`). @@ -95,19 +60,7 @@ How to interpret: Always perform this checklist before marking a doc complete. ## Specialization by Document Type - -- ADRs (Architecture Decision Records) - - Include Purpose, Context, Options Considered, Decision, and Consequences. - - Save under `docs/ADRs/` following the ADR naming convention. -- PRDs (Product Requirements Documents) - - Include Overview, Goals & Objectives, Stakeholders, Success Criteria. - - Save under `docs/PRDs/` using `prd-*.md` naming where applicable. -- Design Documents - - Include Architecture, Data Models, APIs, UI, and Security sections. - - Save under `docs/design/` with an appropriate filename. +Consult document-type specifics in `.github/instructions/docs.instructions.md`. ## Do's and Don'ts -- If inputs are missing, request them before drafting. -- If inputs are ambiguous, ask clarifying questions. -- If inputs conflict, ask the user to prioritize and clarify. -- If format/location/structure are unspecified, use the defaults in this chatmode. +Apply the input collection and validation rules in `.github/instructions/docs.instructions.md`. ## Saving and Location - -- Default format: Markdown (`.md`). -- Default location: `/docs/` with a relevant filename (e.g., `documentation-title.md`). -- For ADRs/PRDs/Design docs, use their respective directories and templates. +Use saving and location guidance in `.github/instructions/docs.instructions.md`. ## Documentation Process (Flow) -```mermaid -flowchart TD - A[Collect inputs: purpose, audience, features, existing docs] --> B[Outline structure] - B --> C[Draft content in clear, concise language] - C --> D[Add examples, code, and diagrams] - D --> E[Review for accuracy and clarity] - E --> F{Owner approval?} - F -- No --> C - F -- Yes --> G[Publish to docs/ and link] - G --> H[Plan maintenance/update cadence] -``` +- Reference: See `.github/instructions/docs.instructions.md#documentation-process-flow` for the canonical mermaid flow. diff --git a/.github/chatmodes/Planner.chatmode.md b/.github/chatmodes/Planner.chatmode.md index 9e5cf90..5a575ba 100644 --- a/.github/chatmodes/Planner.chatmode.md +++ b/.github/chatmodes/Planner.chatmode.md @@ -3,6 +3,8 @@ description: 'Planner Mode' tools: ['codebase', 'editFiles', 'fetch', 'get_file_contents', 'runCommands', 'search', 'usages'] --- + + +Note: Follow plan structure in `plans/plan-template.md` and central policies in `.github/copilot-instructions.md`. Do not restate numeric thresholds or global rules here. + +Note: Enforce coverage and critical-path rules per `.github/copilot-instructions.md#quality-policy`. For BDD, follow `.github/instructions/bdd-tests.instructions.md`. + ## Core Responsibilities +## Testing + +1. **SSOT References** + - Tester chat mode: `.github/chatmodes/Tester.chatmode.md` + - BDD tests instructions: `.github/instructions/bdd-tests.instructions.md` + +2. **Unit/UI Tests (default stack: Jest + Testing Library unless overridden)** + - Cover rendering, critical interactions (click, type, submit), and state transitions. + - Include accessibility assertions (roles/labels/name, focus management, keyboard nav). + - Assert async states: loading, success, and error paths; handle empty data gracefully. + +3. **E2E/UI Flows (optional, if project uses Playwright/Cypress)** + - Keep scenarios small and stable; tag appropriately (e.g., `@ui`, `@smoke`). + - Prefer testids sparingly; select by role/name first. + +4. **Coverage Policy** + - Follow central Quality & Coverage Policy in `.github/copilot-instructions.md#quality-policy`. + - Ensure hot paths and error paths are fully covered (100%). + ## Required Documentation Structure The documentation file must follow the template specified in `docs/ADRs/adr-template.md`, ensuring that all sections are filled out appropriately. The front matter for the Markdown must be structured correctly as per the template. + +## Save & Versioning Rules + +1. Discover existing ADRs in `docs/ADRs/` matching `adr-*.md`. +2. If one or more sequential files exist, compute next NNNN and propose `adr-NNNN-[slug].md`. +3. If no sequential files exist or computation fails, propose timestamped `adr-YYYYMMDD-[slug].md` (or `-HHMM-` variant). +4. Validate the save path is exactly `docs/ADRs/` (reject other directories). +5. Set front matter `date` to today in `YYYY-MM-DD` and ensure `status` is present. +6. After saving, confirm the file exists and report the final path. + +## Commit & Branching + +- If not already on a feature branch, create `adr/[brief-title-slug]` before saving. +- Commit message should follow Conventional Commits, e.g.: `docs: add ADR NNNN `. From a07eb6331957d9ca1639bfe525a875c42abc10c6 Mon Sep 17 00:00:00 2001 From: Stuart Williams Date: Fri, 19 Sep 2025 15:28:55 +0100 Subject: [PATCH 04/10] docs: require SMART success metrics via reusable snippet in PRD prompt (P2-16) --- .../snippets/prd-success-metrics.snippet.md | 39 +++++++++++++++++++ .github/prompts/write-prd.prompt.md | 4 +- 2 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 .github/prompts/snippets/prd-success-metrics.snippet.md diff --git a/.github/prompts/snippets/prd-success-metrics.snippet.md b/.github/prompts/snippets/prd-success-metrics.snippet.md new file mode 100644 index 0000000..ea41889 --- /dev/null +++ b/.github/prompts/snippets/prd-success-metrics.snippet.md @@ -0,0 +1,39 @@ +# Success Metrics (Snippet) + +Use this structure to define SMART metrics that tie directly to Goals and Acceptance Criteria. Provide at least 3 metrics. + +For each metric, fill these fields: + +- Metric: [Name/short description] +- Baseline: [Current value, with date/source] +- Target: [Numeric goal and direction] +- Timeframe: [By when; date or period] +- Datasource: [Where/how it’s measured] +- Owner: [Role/team accountable] +- Guardrails: [Boundaries to prevent regressions] + +Example metrics: + +1) Metric: Week 1 Activation Rate + - Baseline: 42% (as of 2025-08-31; Snowflake dashboard ABC) + - Target: 55% + - Timeframe: By end of Q4 2025 + - Datasource: Product analytics (Amplitude), event: user_activated + - Owner: Growth PM + - Guardrails: NPS does not drop below 45; Support volume +< 10% + +2) Metric: Onboarding Time (p50) + - Baseline: 11m 30s (2025-08; internal telemetry) + - Target: 7m 00s + - Timeframe: By 2026-01-31 + - Datasource: Backend logs (Grafana Loki), derived dashboard PRD-ONB-01 + - Owner: Onboarding team + - Guardrails: Error rate stays ≤ 0.5%; Accessibility score ≥ 95 + +3) Metric: Uptime (SLA) + - Baseline: 99.80% (rolling 30d) + - Target: ≥ 99.90% + - Timeframe: Continuous; measured monthly + - Datasource: Uptime monitoring (Pingdom) + - Owner: SRE + - Guardrails: Mean Time to Recovery ≤ 15m; No P0 incidents from this change diff --git a/.github/prompts/write-prd.prompt.md b/.github/prompts/write-prd.prompt.md index 4bf9f93..55e0c8a 100644 --- a/.github/prompts/write-prd.prompt.md +++ b/.github/prompts/write-prd.prompt.md @@ -43,7 +43,7 @@ If any required input (FeatureTitle, Problem, Goals, Stakeholders, Specification - Use clear, unambiguous language suitable for product, design, and engineering readers - Follow the `docs/PRDs/prd-template.md` structure and include the same sections -- Provide measurable objectives and success metrics where possible +- Provide measurable objectives and success metrics; include at least 3 SMART metrics using the snippet at `.github/prompts/snippets/prd-success-metrics.snippet.md` - Mark requirements with priority tags (Must/Should/Could) - Include a short rollout/implementation notes section and suggested acceptance tests - Call out dependencies, constraints, and open questions explicitly @@ -67,7 +67,7 @@ The generated PRD must follow the PRD template in `docs/PRDs/prd-template.md` an - Functional Requirements (with priorities) - Out of Scope - Non-Functional Requirements -- Success Metrics +- Success Metrics (populate using `.github/prompts/snippets/prd-success-metrics.snippet.md`) - Constraints & Assumptions - Timeline & Milestones - Risks & Mitigations From af1e9e835f52d3bd3ceffb69780b75d239086485 Mon Sep 17 00:00:00 2001 From: Stuart Williams Date: Fri, 19 Sep 2025 15:31:46 +0100 Subject: [PATCH 05/10] docs: reference docs SSOT and avoid embedding templates in docs prompt (P2-17) --- .github/prompts/write-docs.prompt.md | 55 ++++------------------------ 1 file changed, 7 insertions(+), 48 deletions(-) diff --git a/.github/prompts/write-docs.prompt.md b/.github/prompts/write-docs.prompt.md index ac9ad09..9b53d8c 100644 --- a/.github/prompts/write-docs.prompt.md +++ b/.github/prompts/write-docs.prompt.md @@ -4,16 +4,9 @@ tools: ['codebase', 'editFiles', 'fetch'] --- # Write Documentation -You are an AI assistant. Your task is to help the user write clear, concise, and comprehensive documentation for their codebase. Follow these steps: -1. Ask the user for the purpose and scope of the documentation. What specific aspects of the codebase should be covered? -2. Identify the target audience for the documentation (e.g., developers, end-users, stakeholders). -3. Gather relevant information about the codebase, including key features, functionalities, and any existing documentation. -4. Organize the information into a logical structure, using headings and subheadings as needed. -5. Write the documentation in clear, concise language, avoiding jargon and technical terms where possible. -6. Include examples, code snippets, and diagrams to illustrate key points and enhance understanding. -7. Review the documentation for accuracy, completeness, and clarity. Make revisions as necessary. -8. Save the documentation in the appropriate format (e.g., Markdown, HTML) and location within the codebase. -9. If applicable, provide instructions for maintaining and updating the documentation in the future. +You are an AI assistant. Your task is to help the user write clear, concise, and comprehensive documentation for their codebase. + +Follow the canonical workflow, templates, formatting, saving, and quality gates in `.github/instructions/docs.instructions.md` (see anchor `#documentation-process-flow`). Do not embed or restate templates in this prompt; reference the SSOT instead. Only include custom steps or templates if the user explicitly overrides the defaults. ## Do's and Don'ts @@ -37,53 +30,19 @@ If any of the required inputs are not provided or cannot be determined from the ## Documentation Structure -- Title -- Introduction -- Purpose and Scope -- Target Audience -- Key Features and Functionalities -- Examples and Code Snippets -- Diagrams (if applicable) -- Maintenance and Update Instructions (if applicable) -- Conclusion -- References (if applicable) +Use the canonical structure from `.github/instructions/docs.instructions.md`. If the user specifies a different structure, note it and proceed while still applying the SSOT’s quality gates and saving rules. ## Formatting Guidelines -- Use Markdown for formatting. -- Use headings and subheadings to organize content. -- Use bullet points and numbered lists for clarity. -- Use Markdown code blocks for code snippets, e.g.: - ```python - def example_function(): - pass - ``` -- Use links to reference related documentation or external resources. -- Use images or diagrams in Markdown format, e.g.: - ![Diagram](path/to/diagram.png) -- Ensure proper grammar and spelling throughout the document. -- Save the documentation file in the `/docs/` directory with a relevant filename, e.g., `documentation-title.md`. -- If the user does not specify a filename, suggest one based on the title or main topic of the documentation. -- If the user does not specify a location, suggest saving it in the `/docs/` directory. -- If the user does not specify a format, default to Markdown (`.md`). -- If the user does not specify a structure, use the provided Documentation Structure as a template. -- If the user does not specify formatting guidelines, use the provided Formatting Guidelines as a template. -- If the user provides additional requirements or preferences, incorporate them into the documentation as appropriate. +Follow the formatting and saving guidance in `.github/instructions/docs.instructions.md`. Default to `/docs/` and Markdown unless the user specifies otherwise. Do not duplicate formatting rules here. ## Review and Finalization -- After drafting the documentation, review it for accuracy, completeness, and clarity. -- Ask the user for feedback and make revisions as necessary. -- Confirm with the user that the documentation meets their needs and expectations before finalizing it. -- Once finalized, save the documentation in the specified format and location within the codebase. -- Notify the user that the documentation has been successfully created and saved. +Use the review and approval steps in `.github/instructions/docs.instructions.md` (process flow). Confirm with the user before finalizing and saving. ## Input Validation -If any of the required inputs are not provided or cannot be determined from the conversation history, ask the user to provide information for each missing item before proceeding with documentation generation. -If the user provides incomplete or ambiguous information, ask clarifying questions to ensure you have a clear understanding of their needs and expectations for the documentation. -If the user provides conflicting information, ask them to clarify their priorities and preferences for the documentation. -If the user does not specify certain aspects (e.g., format, location, structure), use the defaults provided in the Documentation Structure and Formatting Guidelines sections above. +If inputs are missing/ambiguous/conflicting, follow the input collection and validation rules in `.github/instructions/docs.instructions.md`. ## Special Instructions From afed59f8b378a2c321fbf4a44faf0ee364461822 Mon Sep 17 00:00:00 2001 From: Stuart Williams Date: Fri, 19 Sep 2025 15:33:12 +0100 Subject: [PATCH 06/10] docs: add status badges and usage example to ROADMAP (P2-18) --- plans/ROADMAP.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/plans/ROADMAP.md b/plans/ROADMAP.md index 707bca7..ac605b7 100644 --- a/plans/ROADMAP.md +++ b/plans/ROADMAP.md @@ -2,6 +2,15 @@ Use this roadmap to communicate upcoming milestones and recently completed work. Keep it lightweight and updated as plans evolve. +## Status Badges + +- Planned: ![Planned](https://img.shields.io/badge/status-Planned-lightgrey) +- In Progress: ![In Progress](https://img.shields.io/badge/status-In%20Progress-blue) +- Done: ![Done](https://img.shields.io/badge/status-Done-brightgreen) + +Usage: Add one badge per item to convey current status. Optionally include an owner badge. +Example: `Q4 2025 — Platform auth hardening` ![In Progress](https://img.shields.io/badge/status-In%20Progress-blue) ![Owner](https://img.shields.io/badge/owner-Platform%20Team-informational) + ## Milestones (Upcoming) - Qx YYYY — Milestone name - Goals From 2197d53198eb4d03888607019183d55ad4994309 Mon Sep 17 00:00:00 2001 From: Stuart Williams Date: Fri, 19 Sep 2025 15:37:24 +0100 Subject: [PATCH 07/10] chore: enrich PR description context in settings and add PR template (P2-19) --- .github/pull_request_template.md | 19 +++++++++++++++++++ settings.json | 6 ++++-- 2 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 .github/pull_request_template.md diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..fe53445 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,19 @@ +# Pull Request + +## Summary +- What is changing and why? + +## Links +- Plan/TODO item: (e.g., plans/TODO.md row or issue link) +- ADR/PRD/design doc: (link to docs/ADRs or docs/PRDs or docs/design) + +## Quality & Policy Checks +- [ ] Branch/PR rules followed (see `.github/copilot-instructions.md`) +- [ ] Tests added/updated; critical paths & errors at 100% (see Quality Policy) +- [ ] Docs updated (if applicable) +- [ ] Security and privacy considerations noted + +## Screenshots / Demos (optional) + +## Notes for Reviewers +- Risks, trade-offs, or areas needing extra attention diff --git a/settings.json b/settings.json index 8631901..657362e 100644 --- a/settings.json +++ b/settings.json @@ -1,8 +1,10 @@ { "github.copilot.chat.pullRequestDescriptionGeneration.instructions": [ - { "file": "docs/engineering/pull-request-guidelines.md" }, + { "file": "docs/engineering/pull-request-guidelines.md" }, + { "file": ".github/copilot-instructions.md" }, + { "file": "plans/TODO.md" } ], "github.copilot.chat.reviewSelection.instructions": [ - { "file": "docs/engineering/code-review-guidelines.md" }, + { "file": "docs/engineering/code-review-guidelines.md" } ] } \ No newline at end of file From fe1a7e4692684395305db32f0b3aeebc87e013f9 Mon Sep 17 00:00:00 2001 From: Stuart Williams Date: Fri, 19 Sep 2025 15:38:39 +0100 Subject: [PATCH 08/10] ci: add coverage enforcement script and workflow; document adaptation in README (P3-20) --- .github/workflows/coverage.yml | 39 ++++++++++++++ README.md | 41 +++++++++++++- scripts/enforce-coverage.js | 99 ++++++++++++++++++++++++++++++++++ 3 files changed, 178 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/coverage.yml create mode 100644 scripts/enforce-coverage.js diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml new file mode 100644 index 0000000..5330979 --- /dev/null +++ b/.github/workflows/coverage.yml @@ -0,0 +1,39 @@ +name: Coverage Enforcement + +on: + pull_request: + push: + branches: [ main ] + +jobs: + enforce-coverage: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + + - name: Install dependencies (if package.json exists) + run: | + if [ -f package.json ]; then npm ci; fi + + - name: Run tests with coverage (Node/Jest example if present) + run: | + if [ -f package.json ] && npx --yes --quiet jest --help > /dev/null 2>&1; then \ + npx jest --coverage --coverageReporters=json-summary || true; \ + fi + + - name: Fail if no coverage output found + run: | + if [ ! -f coverage/coverage-summary.json ]; then \ + echo "No coverage summary found; skipping enforcement (pass)."; \ + exit 0; \ + fi + + - name: Enforce unified coverage thresholds + run: | + node scripts/enforce-coverage.js --file coverage/coverage-summary.json diff --git a/README.md b/README.md index c467211..01587fb 100644 --- a/README.md +++ b/README.md @@ -270,4 +270,43 @@ flowchart LR - Templates (`adr-template.md`, `prd-template.md`) are referenced by both instructions and prompts - Directory structures are consistently referenced across multiple configuration files -This hierarchy shows how the repository maintains consistency through strategic cross-referencing, with clear patterns for documentation workflows, planning processes, and configuration management. \ No newline at end of file +This hierarchy shows how the repository maintains consistency through strategic cross-referencing, with clear patterns for documentation workflows, planning processes, and configuration management. + +## Appendix: SSOT Source Map + +Authoritative single sources of truth (SSOT) for key policies and templates. Prefer linking to these instead of duplicating content. + +- Core policies and workflow + - Copilot instructions (SSOT): `.github/copilot-instructions.md` + - Quality & Coverage Policy: `.github/copilot-instructions.md#quality-policy` + + ### CI Coverage Enforcement (template) + + This repo includes a minimal coverage enforcement workflow (`.github/workflows/coverage.yml`) and script (`scripts/enforce-coverage.js`) aligned with the Quality & Coverage Policy: + - Global ≥ 90%; core modules ≥ 95%; integrations ≥ 85%; critical/hot/error/security paths 100%. + - The sample job looks for a Jest `coverage/coverage-summary.json`. Adapt the test step for your stack (e.g., Python `coverage.json`, Java `jacoco.xml` converted to JSON) and point the script to the generated summary. + - Branching & Workflow: see "Project Methodologies" in the same file + - Naming & Commit Conventions: see corresponding sections in the same file +- Engineering guidelines + - Code review checklist (SSOT): `docs/engineering/code-review-guidelines.md#code-review-checklist` + - Pull request guidelines: `docs/engineering/pull-request-guidelines.md` +- Documentation + - Docs authoring rules (SSOT): `.github/instructions/docs.instructions.md` + - Documentation flow anchor: `.github/instructions/docs.instructions.md#documentation-process-flow` +- Testing + - BDD feature guidance (SSOT): `.github/instructions/bdd-tests.instructions.md` + - Tester chat mode (enforces policy): `.github/chatmodes/Tester.chatmode.md` +- Backend + - Backend instructions (SSOT): `.github/instructions/backend.instructions.md` + - Architecture: `.github/instructions/backend.instructions.md#backend-architecture` + - Error handling: `.github/instructions/backend.instructions.md#backend-error-handling` + - Observability: `.github/instructions/backend.instructions.md#backend-observability` + - Security: `.github/instructions/backend.instructions.md#backend-security` +- Planning + - Plan template (SSOT): `plans/plan-template.md` + - Small plan example: `plans/examples/plan-small.md` + - TODO (work queue): `plans/TODO.md` + +Notes: +- Chat modes and prompts should reference these SSOT files. Avoid duplicating numeric thresholds, templates, or process steps in multiple places. +- CI tasks (if added) should validate adherence to SSOT anchors where practical. \ No newline at end of file diff --git a/scripts/enforce-coverage.js b/scripts/enforce-coverage.js new file mode 100644 index 0000000..a87346a --- /dev/null +++ b/scripts/enforce-coverage.js @@ -0,0 +1,99 @@ +#!/usr/bin/env node +/* +Simple coverage enforcement script. +- Reads a JSON summary from stdin or a file (istanbul/nyc, jest --coverage, etc.) +- Enforces global >= 90% +- Enforces core modules >= 95% (by path includes /src/core or /core/) +- Enforces integrations/adapters >= 85% (by path includes /adapters or /integrations/) +- Enforces 100% for files matched as hot paths or error/security (by filename hints) +Exit non-zero on failure with a readable summary. +*/ + +const fs = require('fs'); + +function parseArgs() { + const args = process.argv.slice(2); + const params = { file: null }; + for (let i = 0; i < args.length; i++) { + if (args[i] === '--file' && args[i + 1]) { + params.file = args[i + 1]; + i++; + } + } + return params; +} + +function loadSummary(file) { + const input = file ? fs.readFileSync(file, 'utf8') : fs.readFileSync(0, 'utf8'); + return JSON.parse(input); +} + +function pct(n) { return Math.round(n * 10000) / 100; } + +function classifyFile(path) { + const p = path.toLowerCase(); + if (p.includes('/core/') || p.includes('/src/core/')) return 'core'; + if (p.includes('/adapters/') || p.includes('/integrations/')) return 'integration'; + return 'other'; +} + +function isCritical(path) { + const p = path.toLowerCase(); + return ( + p.includes('hot') || + p.includes('critical') || + p.includes('auth') || + p.includes('security') || + p.includes('error') || + p.includes('exception') + ); +} + +function check(summary) { + const metrics = summary.total || summary; + const globalLines = metrics.lines.pct || metrics.lines.covered / metrics.lines.total * 100; + const globalPass = globalLines >= 90; + + const failures = []; + if (!globalPass) failures.push(`Global lines coverage ${pct(globalLines)}% < 90%`); + + // Per-file checks if available + if (summary && typeof summary === 'object') { + for (const [file, m] of Object.entries(summary)) { + if (file === 'total' || !m || !m.lines) continue; + const filePct = m.lines.pct || (m.lines.covered / m.lines.total * 100); + const cls = classifyFile(file); + if (isCritical(file) && filePct < 100) { + failures.push(`Critical path not fully covered: ${file} ${pct(filePct)}% < 100%`); + continue; + } + if (cls === 'core' && filePct < 95) { + failures.push(`Core module below 95%: ${file} ${pct(filePct)}%`); + } else if (cls === 'integration' && filePct < 85) { + failures.push(`Integration below 85%: ${file} ${pct(filePct)}%`); + } + } + } + + return failures; +} + +function main() { + try { + const { file } = parseArgs(); + const summary = loadSummary(file); + const failures = check(summary); + if (failures.length) { + console.error('Coverage enforcement failed:\n- ' + failures.join('\n- ')); + process.exit(1); + } + console.log('Coverage enforcement passed.'); + } catch (e) { + console.error('Error running coverage enforcement:', e.message); + process.exit(2); + } +} + +if (require.main === module) { + main(); +} From 64287c160985e7235fdcb92d780193cad868ef7f Mon Sep 17 00:00:00 2001 From: Stuart Williams Date: Fri, 19 Sep 2025 15:38:58 +0100 Subject: [PATCH 09/10] ci: add markdown lint and link check workflows with configs (P3-21) --- .github/workflows/docs-lint.yml | 32 ++++++++++++++++++++++++++++++++ .lychee.toml | 22 ++++++++++++++++++++++ .markdownlint.jsonc | 21 +++++++++++++++++++++ 3 files changed, 75 insertions(+) create mode 100644 .github/workflows/docs-lint.yml create mode 100644 .lychee.toml create mode 100644 .markdownlint.jsonc diff --git a/.github/workflows/docs-lint.yml b/.github/workflows/docs-lint.yml new file mode 100644 index 0000000..98fa5a1 --- /dev/null +++ b/.github/workflows/docs-lint.yml @@ -0,0 +1,32 @@ +name: Docs Lint & Links + +on: + pull_request: + push: + branches: [ main ] + +jobs: + markdownlint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Run markdownlint-cli2 + uses: DavidAnson/markdownlint-cli2-action@v16 + with: + globs: | + **/*.md + config: .markdownlint.jsonc + + link-check: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Run lychee link checker + uses: lycheeverse/lychee-action@v1 + with: + args: | + --config .lychee.toml \ + --verbose \ + **/*.md + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.lychee.toml b/.lychee.toml new file mode 100644 index 0000000..ab130c6 --- /dev/null +++ b/.lychee.toml @@ -0,0 +1,22 @@ +# Lychee link checker configuration +# See https://github.com/lycheeverse/lychee + +# Exclude common transient or rate-limited hosts +exclude = [ + "https://img.shields.io/", + "https://badgen.net/", + "https://github.com/capgemini/template-github-copilot/actions", +] + +# Accept 429/403 as warnings instead of failures for rate-limited hosts +accept = [429, 403] + +# Request options +user_agent = "lychee-link-checker" +max_concurrency = 20 + +# Treat mailto and anchors as valid without network requests +accept_pattern = [ + "^mailto:", + "^#", +] diff --git a/.markdownlint.jsonc b/.markdownlint.jsonc new file mode 100644 index 0000000..bbdceeb --- /dev/null +++ b/.markdownlint.jsonc @@ -0,0 +1,21 @@ +{ + // General rules + "default": true, + + // Allow long lines in docs for readability tables/links (disable MD013) + "MD013": false, + + // Allow inline HTML for badges and diagrams (MD033) + "MD033": { + "allowed_elements": ["img", "br", "a", "details", "summary"] + }, + + // Require first heading to be a top-level H1 + "MD002": true, + + // Disallow trailing spaces except in code blocks + "MD009": { "br_spaces": 0 }, + + // Enforce consistent unordered list markers + "MD004": { "style": "dash" } +} From 652f54384021c1d6f8ce96af26d85cd9da1f1f7c Mon Sep 17 00:00:00 2001 From: Stuart Williams Date: Fri, 19 Sep 2025 15:39:18 +0100 Subject: [PATCH 10/10] ci: add policy linter for copilot-instructions SSOT tags and sections (P3-22) --- .github/workflows/policy-lint.yml | 22 ++++++++++++ scripts/validate-policy.js | 59 +++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+) create mode 100644 .github/workflows/policy-lint.yml create mode 100644 scripts/validate-policy.js diff --git a/.github/workflows/policy-lint.yml b/.github/workflows/policy-lint.yml new file mode 100644 index 0000000..7e3c4f3 --- /dev/null +++ b/.github/workflows/policy-lint.yml @@ -0,0 +1,22 @@ +name: Policy Lint + +on: + pull_request: + push: + branches: [ main ] + +jobs: + validate-policy: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + + - name: Run policy validator + run: | + node scripts/validate-policy.js diff --git a/scripts/validate-policy.js b/scripts/validate-policy.js new file mode 100644 index 0000000..be6d768 --- /dev/null +++ b/scripts/validate-policy.js @@ -0,0 +1,59 @@ +#!/usr/bin/env node +/* +Validates that `.github/copilot-instructions.md` contains required SSOT tags/sections. +Checks: +- Presence of XML-like tags: , , , , , +- Presence of anchor #quality-policy +- Presence of key headings: Project Methodologies, Coding Standards +Exit non-zero with a readable message if any check fails. +*/ + +const fs = require('fs'); +const path = require('path'); + +function fail(msg) { + console.error(msg); + process.exit(1); +} + +function main() { + const repoRoot = process.cwd(); + const filePath = path.join(repoRoot, '.github', 'copilot-instructions.md'); + if (!fs.existsSync(filePath)) fail(`File not found: ${filePath}`); + const content = fs.readFileSync(filePath, 'utf8'); + + const requiredTags = [ + ' !content.includes(t)); + if (missingTags.length) { + fail('Missing required tags: ' + missingTags.join(', ')); + } + + if (!content.includes('# Quality & Coverage Policy') && !content.includes('# Quality & Coverage Policy'.toLowerCase())) { + // Also allow anchor reference if heading case changes + if (!content.toLowerCase().includes('## quality & coverage policy') && !content.includes('#quality-policy')) { + fail('Missing Quality & Coverage Policy section or anchor (#quality-policy).'); + } + } + + const requiredHeadings = [ + '## Project Methodologies', + '## Coding Standards' + ]; + const missingHeadings = requiredHeadings.filter(h => !content.includes(h)); + if (missingHeadings.length) { + fail('Missing required headings: ' + missingHeadings.join(', ')); + } + + console.log('Policy validation passed.'); +} + +if (require.main === module) { + main(); +}