Skip to content

feat: add Cyber Essentials Plus (CE+) v3.3 Danzell framework plugin#59

Merged
ethanolivertroy merged 14 commits into
GRCEngClub:mainfrom
FunkeOmolere:main
Apr 26, 2026
Merged

feat: add Cyber Essentials Plus (CE+) v3.3 Danzell framework plugin#59
ethanolivertroy merged 14 commits into
GRCEngClub:mainfrom
FunkeOmolere:main

Conversation

@FunkeOmolere

@FunkeOmolere FunkeOmolere commented Apr 21, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds a Reference-depth framework plugin for UK NCSC Cyber Essentials Plus (CE+) v3.3 Danzell, effective 27 April 2026.

Type of change

  • Framework plugin

What this includes

  • scope.md — boundary definition including cloud/BYOD triggers and government supply chain
  • evidence-checklist.md — evidence per control including CE+ assessor-verification artifacts
  • assess.md — gap assessment delegating to /grc-engineer:gap-assessment
  • SKILL.md — full CE+ expert knowledge including v3.3 Danzell changes

Key CE+ v3.3 specifics baked in

  • MFA mandatory for all cloud services (auto-fail if not implemented)
  • 14-day critical patch window as hard failure condition
  • Cloud services cannot be excluded from scope
  • Danzell question set replaces Willow from 27 April 2026

Summary by CodeRabbit

  • New Features

    • Added Cyber Essentials Plus (CE+) v3.3 framework plugin for scope determination, evidence checklist generation, and gap assessments.
  • Documentation

    • Comprehensive CE+ docs added: install, scope rules, assessment outputs/workflow, evidence checklist, remediation priorities (including 14-day patching & mandatory MFA), control crosswalks, assessor guidance, and an expert skill.
  • Chores

    • Marketplace listing updated to include the new CE+ plugin.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new Reference-depth framework plugin for UK NCSC Cyber Essentials Plus (CE+) v3.3 Danzell, providing the standard command set (scope/evidence/assess) plus a framework expert SKILL to guide assessments using the SCF crosswalk.

Changes:

  • Introduces cyber-essentials-plus framework plugin metadata (plugin.json) and user-facing documentation (README.md).
  • Adds Reference-depth commands: /cyber-essentials-plus:scope, /cyber-essentials-plus:evidence-checklist, /cyber-essentials-plus:assess.
  • Adds CE+ v3.3 Danzell expert SKILL content with scoping, evidence, cadence, and common misinterpretations.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
plugins/frameworks/cyber-essentials-plus/.claude-plugin/plugin.json Declares the plugin and framework metadata (SCF ID, region/country, depth, mapped control counts).
plugins/frameworks/cyber-essentials-plus/README.md Installation + usage docs and framework metadata summary.
plugins/frameworks/cyber-essentials-plus/commands/assess.md Documents the assessment command and its delegation to /grc-engineer:gap-assessment.
plugins/frameworks/cyber-essentials-plus/commands/scope.md Documents scope determination and boundary triggers for CE+.
plugins/frameworks/cyber-essentials-plus/commands/evidence-checklist.md Provides a control-organized evidence checklist for CE+ verification.
plugins/frameworks/cyber-essentials-plus/skills/cyber-essentials-plus-expert/SKILL.md Adds Reference-depth CE+ v3.3 Danzell domain guidance and command routing.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread plugins/frameworks/cyber-essentials-plus/README.md Outdated
Comment thread plugins/frameworks/cyber-essentials-plus/README.md
Comment thread plugins/frameworks/cyber-essentials-plus/commands/evidence-checklist.md Outdated
@ethanolivertroy

Copy link
Copy Markdown
Collaborator

/review

@qodo-code-review

qodo-code-review Bot commented Apr 22, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0)

Grey Divider


Action required

1. author not a string📘 Rule violation § Compliance
Description
plugins/frameworks/cyber-essentials-plus/.claude-plugin/plugin.json sets author to an object,
but the manifest rule requires author to be a non-empty string. This can break tooling that
expects a string value for required manifest fields.
Code

plugins/frameworks/cyber-essentials-plus/.claude-plugin/plugin.json[R4-6]

+  "version": "0.1.0",
+  "author": {"name": "GRC Engineering Club Contributors"},
+  "repository": "https://github.com/GRCEngClub/claude-grc-engineering",
Evidence
PR Compliance ID 396511 requires name, version, and author to exist and each be a non-empty
string. The new manifest defines author as an object ({"name": ...}), violating the required
type.

Rule 396511: Require minimal plugin manifest fields in .claude-plugin/plugin.json
plugins/frameworks/cyber-essentials-plus/.claude-plugin/plugin.json[4-6]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The plugin manifest `author` field is an object, but compliance requires it to be a non-empty string.
## Issue Context
This can cause plugin loaders/registries to fail schema checks for required manifest fields.
## Fix Focus Areas
- plugins/frameworks/cyber-essentials-plus/.claude-plugin/plugin.json[4-6]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Plugin missing marketplace entry📘 Rule violation ⌂ Architecture
Description
The new cyber-essentials-plus plugin is not registered in .claude-plugin/marketplace.json. This
can prevent the plugin from being discoverable/installable via the suite marketplace registry.
Code

plugins/frameworks/cyber-essentials-plus/.claude-plugin/plugin.json[R2-4]

+  "name": "cyber-essentials-plus",
+  "description": "UK NCSC Cyber Essentials Plus (CE+) v3.3 Danzell — Reference plugin with evidence checklist, scope determination, and SCF-backed gap assessment. Five core controls: Firewalls, Secure Configuration, User Access Control, Malware Protection, and Patch Management.",
+  "version": "0.1.0",
Evidence
PR Compliance ID 396519 requires every added/modified plugin to have a corresponding entry in
.claude-plugin/marketplace.json. The plugin manifest declares name: cyber-essentials-plus, but
the marketplace registry file does not contain any entry for cyber-essentials-plus within its
plugins list.

Rule 396519: Register every plugin in .claude-plugin/marketplace.json
plugins/frameworks/cyber-essentials-plus/.claude-plugin/plugin.json[1-4]
.claude-plugin/marketplace.json[12-206]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The new framework plugin `cyber-essentials-plus` is missing from the central plugin registry `.claude-plugin/marketplace.json`.
## Issue Context
Marketplace registration is required for plugins added to the repo so they can be discovered/installed consistently.
## Fix Focus Areas
- .claude-plugin/marketplace.json[12-206]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Wrong SCF framework ID🐞 Bug ≡ Correctness
Description
The plugin uses SCF framework ID "uk-ncsc-ce-2021", which is not present in the repo’s SCF crosswalk
index; as a result, /grc-engineer:gap-assessment will not map SCF controls into this framework
(empty mappings / 0 evaluated controls). The plugin also claims 30 SCF controls mapped, but the SCF
index lists UK Cyber Essentials v3.3 as 26→5, so the metadata and documentation are inconsistent
with the crosswalk data.
Code

plugins/frameworks/cyber-essentials-plus/.claude-plugin/plugin.json[R8-16]

+  "framework_metadata": {
+    "scf_framework_id": "uk-ncsc-ce-2021",
+    "display_name": "UK NCSC Cyber Essentials Plus (CE+) v3.3 Danzell",
+    "region": "EMEA",
+    "country": "GB",
+    "depth": "reference",
+    "scf_controls_mapped": 30,
+    "framework_controls_mapped": 5,
+    "industry": [],
Evidence
The plugin hardcodes scf_framework_id: uk-ncsc-ce-2021 and the assess command delegates to
gap-assessment using that same ID. However, the repo’s auto-generated SCF framework index
(FRAMEWORK-COVERAGE.md) contains the UK Cyber Essentials v3.3 entry as
emea-gbr-cyber-essentials-requirements-3-3 with a 26→5 mapping and no entry for uk-ncsc-ce-2021.
In the SCF client, if a framework ID cannot be resolved, expand() returns an empty mapping for
that framework, which makes gap-assessment unable to attribute any evaluated SCF controls to the
requested framework.

plugins/frameworks/cyber-essentials-plus/.claude-plugin/plugin.json[8-17]
plugins/frameworks/cyber-essentials-plus/commands/assess.md[28-37]
docs/FRAMEWORK-COVERAGE.md[238-241]
plugins/grc-engineer/scripts/scf-client.js[127-150]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The plugin is wired to a non-existent (or non-SCF-canonical) framework ID (`uk-ncsc-ce-2021`). This breaks SCF crosswalk expansion inside `/grc-engineer:gap-assessment` and makes the plugin’s mapped-control counts incorrect.
### Issue Context
The repo’s SCF framework index lists UK Cyber Essentials v3.3 as `emea-gbr-cyber-essentials-requirements-3-3` with `26 → 5` mapped controls. If CE+ does not have a distinct SCF entry, the plugin should use the canonical SCF ID that actually exists; if CE+ does have its own SCF ID, update to that canonical value and adjust counts to match the SCF index.
### Fix Focus Areas
- plugins/frameworks/cyber-essentials-plus/.claude-plugin/plugin.json[8-17]
- plugins/frameworks/cyber-essentials-plus/commands/assess.md[28-37]
- plugins/frameworks/cyber-essentials-plus/README.md[14-30]
- plugins/frameworks/cyber-essentials-plus/skills/cyber-essentials-plus-expert/SKILL.md[11-16]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

Comment thread plugins/frameworks/cyber-essentials-plus/.claude-plugin/plugin.json
Comment thread plugins/frameworks/cyber-essentials-plus/.claude-plugin/plugin.json
Comment thread plugins/frameworks/cyber-essentials-plus/.claude-plugin/plugin.json
@ethanolivertroy ethanolivertroy self-requested a review April 23, 2026 16:24
@ethanolivertroy

Copy link
Copy Markdown
Collaborator

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Apr 26, 2026

Copy link
Copy Markdown
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai

coderabbitai Bot commented Apr 26, 2026

Copy link
Copy Markdown

Caution

Review failed

Pull request was closed or merged during review

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds a new Cyber Essentials Plus (CE+) v3.3 framework plugin with manifest and marketplace registration, plus documentation: README, command specs (scope/assess/evidence-checklist), and an expert skill doc mapping SCF controls to CE+ controls (Danzell v3.3, effective 27 Apr 2026).

Changes

Cohort / File(s) Summary
Marketplace Registration
​.claude-plugin/marketplace.json
Appended cyber-essentials-plus plugin entry (version: 0.1.0, source: ./plugins/frameworks/cyber-essentials-plus) to the plugins array.
Plugin Manifest
plugins/frameworks/cyber-essentials-plus/.claude-plugin/plugin.json
New plugin manifest declaring metadata (name, version, author, repo, license) and framework_metadata (SCF id emea-gbr-ce-2021, region, regulator, reference depth, control mapping counts).
Documentation / README
plugins/frameworks/cyber-essentials-plus/README.md
New README with install command, command summaries, CE+ control areas, SCF crosswalk details, metadata (Danzell v3.3 effective 27 Apr 2026), and reference links.
Command Docs
plugins/frameworks/cyber-essentials-plus/commands/scope.md, .../assess.md, .../evidence-checklist.md
Added three command spec pages: scope determination, CE+ gap assessment (outputs: readiness score, per-control gaps, evidence gaps, remediation roadmap), and detailed evidence checklist per CE+ control.
Expert Skill
plugins/frameworks/cyber-essentials-plus/skills/cyber-essentials-plus-expert/SKILL.md
New skill doc defining framework identity, eligibility/boundary rules, required artifacts (incl. 14-day patch window and mandatory MFA for cloud), assessment expectations, command routing to /grc-engineer:gap-assessment, and references.

Sequence Diagram(s)

(omitted)

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

Poem

🐰 I hopped in with manifests and maps so bright,
Five sturdy shields from thirty stars of light,
Danzell stamped and evidence set to show,
Checklists, scope, and skills where assessors go,
🥕🔐

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes the main change: adding a new Cyber Essentials Plus framework plugin for v3.3 Danzell.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

@greptile-apps

greptile-apps Bot commented Apr 26, 2026

Copy link
Copy Markdown

Greptile Summary

This PR adds a Reference-depth CE+ v3.3 Danzell framework plugin with scope, evidence checklist, gap assessment commands, and an expert skill. The us-finra marketplace deletion flagged in a prior thread is resolved in this version.

  • The SCF control count is inconsistent across files: plugin.json, assess.md, and SKILL.md say 26, while README.md line 14 and evidence-checklist.md both say 30 — users will see two different figures depending on which command they run.
  • scope.md contains an AI implementation instruction on its final line that will appear verbatim in user-facing output and should be removed.

Confidence Score: 4/5

Safe to merge after fixing the SCF count contradiction across README.md and evidence-checklist.md.

Two P1 findings remain: README.md shows both 26 and 30 SCF controls on the same page, and evidence-checklist.md independently states 30 while plugin.json and assess.md both say 26. These are data-integrity issues in user-facing docs that will cause confusion. The scope.md leaked implementation note is P2. No security or runtime issues; the marketplace entry and command delegation are correct.

plugins/frameworks/cyber-essentials-plus/README.md (line 14) and plugins/frameworks/cyber-essentials-plus/commands/evidence-checklist.md (line 7) need the SCF count corrected to 26.

Important Files Changed

Filename Overview
.claude-plugin/marketplace.json Adds cyber-essentials-plus entry after the us-finra entry; us-finra is correctly preserved. No issues.
plugins/frameworks/cyber-essentials-plus/.claude-plugin/plugin.json Declares scf_controls_mapped: 26; README intro text and evidence-checklist.md contradict this with 30 — authoritative value needs to be reconciled across the plugin.
plugins/frameworks/cyber-essentials-plus/README.md Internal inconsistency: intro text says 30 SCF controls (line 14), metadata table says 26 (line 27); both appear on the same page.
plugins/frameworks/cyber-essentials-plus/commands/assess.md Correctly references 26 SCF controls and emea-gbr-ce-2021; CE+-specific context and delegation pattern look accurate.
plugins/frameworks/cyber-essentials-plus/commands/evidence-checklist.md States 30 SCF controls on line 7, contradicting plugin.json (26) and assess.md (26); evidence items per control are accurate for CE+ v3.3 Danzell.
plugins/frameworks/cyber-essentials-plus/commands/scope.md Accurate CE+ scope triggers; final line (35) is an AI implementation instruction that leaked into user-facing content and should be removed.
plugins/frameworks/cyber-essentials-plus/skills/cyber-essentials-plus-expert/SKILL.md Comprehensive CE+ expert skill; correctly uses 26 in the description line; framework detail, common misinterpretations, and command routing all accurate.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    U([User]) --> S[/cyber-essentials-plus:scope/]
    U --> E[/cyber-essentials-plus:evidence-checklist/]
    U --> A[/cyber-essentials-plus:assess/]

    S --> OUT_S[Applicability verdict\nIn-scope / Out-of-scope / Partial]
    E --> OUT_E[Evidence checklist\ngrouped by CE+ control]
    A --> GAP[/grc-engineer:gap-assessment\nemea-gbr-ce-2021/]
    GAP --> OUT_A[Compliance score\nControl-by-control gaps\nRemediation roadmap]

    SKILL[cyber-essentials-plus-expert\nSKILL.md] -.->|informs| S
    SKILL -.->|informs| E
    SKILL -.->|informs| A

    subgraph CE+ Five Controls
        C1[Firewalls]
        C2[Secure Configuration]
        C3[User Access Control\nMFA mandatory v3.3]
        C4[Malware Protection]
        C5[Patch Management\n14-day critical window]
    end

    OUT_A --> C1 & C2 & C3 & C4 & C5
Loading

Reviews (6): Last reviewed commit: "fix: restore us-finra entry, normalize m..." | Re-trigger Greptile

Reorganized the marketplace.json file by removing and re-adding the singapore-pdpa plugin with updated formatting.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.claude-plugin/marketplace.json:
- Line 203: Update the JSON "description" value that currently reads "Personal
Data Protection Ac (PDPA)" to use the correct spelling "Personal Data Protection
Act (PDPA)"; edit the "description" field in the marketplace.json entry so the
string becomes "...Personal Data Protection Act (PDPA)..." to fix the typo.

In `@plugins/frameworks/cyber-essentials-plus/.claude-plugin/plugin.json`:
- Line 5: Update the plugin.json's author field from a string to an object to
match the other framework plugins: replace the existing "author": "GRC
Engineering Club Contributors" entry with an object-style entry such as
"author": {"name": "GRC Engineering Club Contributors"} so the author format
aligns with the rest of the plugins; edit the author property in plugin.json
accordingly.

In `@plugins/frameworks/cyber-essentials-plus/commands/assess.md`:
- Around line 11-13: The two unlabeled fenced code blocks containing the command
examples "/cyber-essentials-plus:assess [--scope=<scope>]
[--sources=<connector-list>]" and "/grc-engineer:gap-assessment
\"emea-gbr-ce-2021\" [--sources=<connector-list>]" should be updated to specify
a code fence language (e.g., add "text" after the opening backticks) so the
markdown lint rule MD040 is satisfied; locate the two fenced blocks in assess.md
that wrap those exact command lines and change the opening fences from ``` to
```text for each example.
- Around line 33-37: The SCF framework ID "emea-gbr-ce-2021" is not registered
in the public SCF API registry, causing SCF client's _matchFrameworkId() to
return null and expand() to yield empty mappings; register this framework ID in
the SCF API registry (https://grcengclub.github.io/scf-api/) so the SCF client
can resolve it, then verify _matchFrameworkId() returns a non-null Framework
object and expand() produces the expected 30→5 CE+ control mappings for the
/grc-engineer:gap-assessment delegation that uses framework id emea-gbr-ce-2021.

In `@plugins/frameworks/cyber-essentials-plus/commands/evidence-checklist.md`:
- Around line 11-13: The unlabeled fenced code block in the
evidence-checklist.md usage example should be given a language label to satisfy
MD040; update the triple-backtick fence surrounding
"/cyber-essentials-plus:evidence-checklist [--control=<control-name>]" to
include a language identifier such as "text" (i.e., change ``` to ```text) so
the fenced block is labeled and linting passes.

In `@plugins/frameworks/cyber-essentials-plus/commands/scope.md`:
- Around line 11-13: The fenced usage block starting with ``` that contains the
snippet "/cyber-essentials-plus:scope" is missing a language tag (MD040); update
that fence to include a language identifier (e.g., use ```text) so the block
becomes a labeled fenced code block, ensuring the usage example is rendered and
linters accept it; locate the fenced block that contains
"/cyber-essentials-plus:scope" and add "text" after the opening backticks.

In
`@plugins/frameworks/cyber-essentials-plus/skills/cyber-essentials-plus-expert/SKILL.md`:
- Around line 67-72: The current routing wrongly delegates
/cyber-essentials-plus:scope and /cyber-essentials-plus:evidence-checklist to
/grc-engineer:gap-assessment; change the routing so only
/cyber-essentials-plus:assess invokes /grc-engineer:gap-assessment (with SCF id
emea-gbr-ce-2021), and implement/restore independent handlers for
/cyber-essentials-plus:scope and /cyber-essentials-plus:evidence-checklist that
compute certification boundary and enumerate evidence requirements without
relying on the connector findings cache or calling gap-assessment.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: fb24ca5d-c435-4191-b1a7-cebc79e38d89

📥 Commits

Reviewing files that changed from the base of the PR and between 5e81f27 and 14037d3.

📒 Files selected for processing (7)
  • .claude-plugin/marketplace.json
  • plugins/frameworks/cyber-essentials-plus/.claude-plugin/plugin.json
  • plugins/frameworks/cyber-essentials-plus/README.md
  • plugins/frameworks/cyber-essentials-plus/commands/assess.md
  • plugins/frameworks/cyber-essentials-plus/commands/evidence-checklist.md
  • plugins/frameworks/cyber-essentials-plus/commands/scope.md
  • plugins/frameworks/cyber-essentials-plus/skills/cyber-essentials-plus-expert/SKILL.md

Comment thread .claude-plugin/marketplace.json Outdated
{
"name": "singapore-pdpa",
"source": "./plugins/frameworks/singapore-pdpa",
"description": "Singapore — Personal Data Protection Ac (PDPA) (2012) — reference-depth plugin backed by the SCF crosswalk (30 SCF = 14 framework controls).",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix typo in plugin description.

Line 203 says “Personal Data Protection Ac (PDPA)”; should be “Act”.

✏️ Proposed fix
-          "description": "Singapore — Personal Data Protection Ac (PDPA) (2012) — reference-depth plugin backed by the SCF crosswalk (30 SCF = 14 framework controls).",
+          "description": "Singapore — Personal Data Protection Act (PDPA) (2012) — reference-depth plugin backed by the SCF crosswalk (30 SCF = 14 framework controls).",
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"description": "Singapore — Personal Data Protection Ac (PDPA) (2012) — reference-depth plugin backed by the SCF crosswalk (30 SCF = 14 framework controls).",
"description": "Singapore — Personal Data Protection Act (PDPA) (2012) — reference-depth plugin backed by the SCF crosswalk (30 SCF = 14 framework controls).",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.claude-plugin/marketplace.json at line 203, Update the JSON "description"
value that currently reads "Personal Data Protection Ac (PDPA)" to use the
correct spelling "Personal Data Protection Act (PDPA)"; edit the "description"
field in the marketplace.json entry so the string becomes "...Personal Data
Protection Act (PDPA)..." to fix the typo.

Comment thread plugins/frameworks/cyber-essentials-plus/.claude-plugin/plugin.json Outdated
Comment on lines +11 to +13
```
/cyber-essentials-plus:assess [--scope=<scope>] [--sources=<connector-list>]
```

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Specify fenced code block languages for both command examples.

Lines 11 and 32 start unlabeled fences, causing MD040.

🧹 Proposed fix
-```
+```text
 /cyber-essentials-plus:assess [--scope=<scope>] [--sources=<connector-list>]

@@
- +text
/grc-engineer:gap-assessment "emea-gbr-ce-2021" [--sources=]

Also applies to: 32-34

🧰 Tools
🪛 markdownlint-cli2 (0.22.1)

[warning] 11-11: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@plugins/frameworks/cyber-essentials-plus/commands/assess.md` around lines 11
- 13, The two unlabeled fenced code blocks containing the command examples
"/cyber-essentials-plus:assess [--scope=<scope>] [--sources=<connector-list>]"
and "/grc-engineer:gap-assessment \"emea-gbr-ce-2021\"
[--sources=<connector-list>]" should be updated to specify a code fence language
(e.g., add "text" after the opening backticks) so the markdown lint rule MD040
is satisfied; locate the two fenced blocks in assess.md that wrap those exact
command lines and change the opening fences from ``` to ```text for each
example.

Comment on lines +33 to +37
/grc-engineer:gap-assessment "emea-gbr-ce-2021" [--sources=<connector-list>]
```

The SCF crosswalk expands 30 SCF controls into the 5 Cyber Essentials Plus controls.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Local references to emea-gbr-ce-2021 =="
rg -n --fixed-strings 'emea-gbr-ce-2021' \
  plugins/grc-engineer/config/control-crosswalk.yaml \
  plugins/grc-engineer/scripts/gap-assessment.js \
  plugins/frameworks/cyber-essentials-plus || true

echo
echo "== SCF API framework registry check =="
curl -fsSL https://grcengclub.github.io/scf-api/api/crosswalks.json \
  | jq -r '.frameworks[]?.framework_id' \
  | rg -n --fixed-strings 'emea-gbr-ce-2021' || true

Repository: GRCEngClub/claude-grc-engineering

Length of output: 799


🏁 Script executed:

# Check if control-crosswalk.yaml contains the mapping
if [ -f "plugins/grc-engineer/config/control-crosswalk.yaml" ]; then
  echo "=== control-crosswalk.yaml exists ==="
  rg -n --context 3 'emea-gbr-ce-2021' plugins/grc-engineer/config/control-crosswalk.yaml || echo "No matches found"
else
  echo "=== control-crosswalk.yaml NOT found, searching for crosswalk files ==="
  fd -name '*crosswalk*' plugins/grc-engineer/
fi

echo
echo "=== Checking gap-assessment implementation ==="
if [ -f "plugins/grc-engineer/scripts/gap-assessment.js" ]; then
  rg -n 'framework|emea' plugins/grc-engineer/scripts/gap-assessment.js | head -20
else
  echo "gap-assessment.js not found, searching..."
  fd -name '*gap-assessment*' plugins/grc-engineer/
fi

Repository: GRCEngClub/claude-grc-engineering

Length of output: 1565


🏁 Script executed:

# Check how SCF is initialized in gap-assessment.js
echo "=== SCF initialization in gap-assessment.js ==="
rg -n 'scf\s*=|new.*SCF|require.*scf|import.*scf' plugins/grc-engineer/scripts/gap-assessment.js -A 5

echo
echo "=== Search for SCF class/module definition ==="
fd -name '*scf*' -o -name '*SCF*' plugins/grc-engineer/

echo
echo "=== Check for test fixtures or deployment configs with emea-gbr-ce-2021 ==="
fd -name '*.json' -o -name '*.yaml' -o -name '*.yml' plugins/ | xargs rg -l 'emea-gbr-ce-2021' 2>/dev/null || echo "No config files found with this ID"

echo
echo "=== Look for framework resolution/expansion error handling ==="
rg -n 'expand|resolve' plugins/grc-engineer/scripts/gap-assessment.js -A 3 -B 1 | head -40

Repository: GRCEngClub/claude-grc-engineering

Length of output: 3475


🏁 Script executed:

echo "=== Finding and reading scf-client.js ==="
find plugins/grc-engineer -name 'scf-client.js' -type f

echo
echo "=== Read scf-client.js (first 100 lines) ==="
head -100 plugins/grc-engineer/scripts/scf-client.js

echo
echo "=== Check for framework registry URL or source ==="
rg -n 'https|http|framework|registry|crosswalk' plugins/grc-engineer/scripts/scf-client.js | head -30

Repository: GRCEngClub/claude-grc-engineering

Length of output: 6099


🏁 Script executed:

echo "=== Read more of scf-client.js (lines 100-200) ==="
sed -n '100,200p' plugins/grc-engineer/scripts/scf-client.js

echo
echo "=== Check _matchFrameworkId and expand methods ==="
rg -n '_matchFrameworkId|async expand' plugins/grc-engineer/scripts/scf-client.js -A 15

Repository: GRCEngClub/claude-grc-engineering

Length of output: 6786


🏁 Script executed:

rg -n 'cyber|essentials|ce-' plugins/grc-engineer/scripts/scf-client.js -i

Repository: GRCEngClub/claude-grc-engineering

Length of output: 139


Register emea-gbr-ce-2021 in the SCF API registry before release.

The command delegates to /grc-engineer:gap-assessment with framework ID emea-gbr-ce-2021, but this ID is missing from the public SCF registry at https://grcengclub.github.io/scf-api/. When the SCF client attempts to resolve this framework, _matchFrameworkId() returns null, causing expand() to silently return empty control mappings. The CE+ assessment will complete without error but produce zero controls, degrading to a no-op evaluation.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@plugins/frameworks/cyber-essentials-plus/commands/assess.md` around lines 33
- 37, The SCF framework ID "emea-gbr-ce-2021" is not registered in the public
SCF API registry, causing SCF client's _matchFrameworkId() to return null and
expand() to yield empty mappings; register this framework ID in the SCF API
registry (https://grcengclub.github.io/scf-api/) so the SCF client can resolve
it, then verify _matchFrameworkId() returns a non-null Framework object and
expand() produces the expected 30→5 CE+ control mappings for the
/grc-engineer:gap-assessment delegation that uses framework id emea-gbr-ce-2021.

Comment on lines +11 to +13
```
/cyber-essentials-plus:evidence-checklist [--control=<control-name>]
```

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add language to the usage code fence.

Line 11 starts an unlabeled fenced block; label it to satisfy MD040.

🧹 Proposed fix
-```
+```text
 /cyber-essentials-plus:evidence-checklist [--control=<control-name>]
</details>

<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

```suggestion

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@plugins/frameworks/cyber-essentials-plus/commands/evidence-checklist.md`
around lines 11 - 13, The unlabeled fenced code block in the
evidence-checklist.md usage example should be given a language label to satisfy
MD040; update the triple-backtick fence surrounding
"/cyber-essentials-plus:evidence-checklist [--control=<control-name>]" to
include a language identifier such as "text" (i.e., change ``` to ```text) so
the fenced block is labeled and linting passes.

Comment on lines +11 to +13
```
/cyber-essentials-plus:scope
```

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add a language tag to the fenced usage block.

Line 11 starts a fence without a language identifier, which triggers MD040.

🧹 Proposed fix
-```
+```text
 /cyber-essentials-plus:scope
</details>

<details>
<summary>🧰 Tools</summary>

<details>
<summary>🪛 markdownlint-cli2 (0.22.1)</summary>

[warning] 11-11: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

</details>

</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against the current code and only fix it if needed.

In @plugins/frameworks/cyber-essentials-plus/commands/scope.md around lines 11 -
13, The fenced usage block starting with that contains the snippet "/cyber-essentials-plus:scope" is missing a language tag (MD040); update that fence to include a language identifier (e.g., usetext) so the block becomes
a labeled fenced code block, ensuring the usage example is rendered and linters
accept it; locate the fenced block that contains "/cyber-essentials-plus:scope"
and add "text" after the opening backticks.


</details>

<!-- fingerprinting:phantom:poseidon:hawk:1c2a97b6-67e6-4feb-9cde-55bbe95ae5f9 -->

<!-- d98c2f50 -->

<!-- This is an auto-generated comment by CodeRabbit -->

Comment on lines +67 to +72
- `/cyber-essentials-plus:scope` — determine applicability and define certification boundary
- `/cyber-essentials-plus:assess` — run a gap assessment against all five controls
- `/cyber-essentials-plus:evidence-checklist` — enumerate evidence requirements by control

All three delegate to `/grc-engineer:gap-assessment` with SCF framework ID `emea-gbr-ce-2021` for the control-by-control mechanics, and wrap the results in CE+-specific terminology.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Do not route :scope and :evidence-checklist through gap-assessment.

Line 71 says all three commands delegate to /grc-engineer:gap-assessment. That couples scope/checklist flows to connector findings and can fail when no findings cache exists. Only :assess should delegate.

🛠️ Proposed fix
 - `/cyber-essentials-plus:scope` — determine applicability and define certification boundary
-- `/cyber-essentials-plus:assess` — run a gap assessment against all five controls
-- `/cyber-essentials-plus:evidence-checklist` — enumerate evidence requirements by control
-
-All three delegate to `/grc-engineer:gap-assessment` with SCF framework ID `emea-gbr-ce-2021` for the control-by-control mechanics, and wrap the results in CE+-specific terminology.
+- `/cyber-essentials-plus:assess` — run a gap assessment against all five controls (delegates to `/grc-engineer:gap-assessment` with SCF framework ID `emea-gbr-ce-2021`)
+- `/cyber-essentials-plus:evidence-checklist` — enumerate evidence requirements by control
+
+Only `/cyber-essentials-plus:assess` delegates to `/grc-engineer:gap-assessment`; `:scope` and `:evidence-checklist` should run without requiring connector findings.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- `/cyber-essentials-plus:scope` — determine applicability and define certification boundary
- `/cyber-essentials-plus:assess` — run a gap assessment against all five controls
- `/cyber-essentials-plus:evidence-checklist` — enumerate evidence requirements by control
All three delegate to `/grc-engineer:gap-assessment` with SCF framework ID `emea-gbr-ce-2021` for the control-by-control mechanics, and wrap the results in CE+-specific terminology.
- `/cyber-essentials-plus:scope` — determine applicability and define certification boundary
- `/cyber-essentials-plus:assess` — run a gap assessment against all five controls (delegates to `/grc-engineer:gap-assessment` with SCF framework ID `emea-gbr-ce-2021`)
- `/cyber-essentials-plus:evidence-checklist` — enumerate evidence requirements by control
Only `/cyber-essentials-plus:assess` delegates to `/grc-engineer:gap-assessment`; `:scope` and `:evidence-checklist` should run without requiring connector findings.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@plugins/frameworks/cyber-essentials-plus/skills/cyber-essentials-plus-expert/SKILL.md`
around lines 67 - 72, The current routing wrongly delegates
/cyber-essentials-plus:scope and /cyber-essentials-plus:evidence-checklist to
/grc-engineer:gap-assessment; change the routing so only
/cyber-essentials-plus:assess invokes /grc-engineer:gap-assessment (with SCF id
emea-gbr-ce-2021), and implement/restore independent handlers for
/cyber-essentials-plus:scope and /cyber-essentials-plus:evidence-checklist that
compute certification boundary and enumerate evidence requirements without
relying on the connector findings cache or calling gap-assessment.

@ethanolivertroy

Copy link
Copy Markdown
Collaborator

Thanks for the substantive content here, @FunkeOmolere — Danzell v3.3 specifics (MFA-for-cloud, 14-day patch window, 27 Apr 2026 effective date, removal-not-risk-acceptance) are accurately captured and all five CE+ technical controls are covered. Once the items below are addressed this is in good shape to merge.

Blockers

  1. .claude-plugin/marketplace.json is invalid JSON on the PR head. Verify locally with python3 -m json.tool < .claude-plugin/marketplace.json. To fix:

    • Restore the missing }, after the irap entry (~line 162)
    • Restore \"version\": \"0.1.0\" on the singapore-pdpa entry
    • Remove the stray ] / } at EOF
    • Re-indent the new cyber-essentials-plus block from 8 spaces to 4 spaces (matches the rest of the file)
  2. SCF id is wrong. Per `docs/FRAMEWORK-COVERAGE.md` the canonical id is emea-gbr-cyber-essentials-requirements-3-3 (currently emea-gbr-ce-2021, which won't resolve in the SCF client). Update in plugin.json, README.md, commands/assess.md, and skills/cyber-essentials-plus-expert/SKILL.md. Also update scf_controls_mapped from 3026 to match the index.

Nits (non-blocking)

  1. The marketplace.json description claims "remediation plans, and cross-framework mapping to ISO 27001 and NIST CSF" but the plugin only ships scope/evidence-checklist/assess. Either trim the description or add the additional commands.

  2. Process note for next time: the PR head branch is your fork's main. Future updates to main on your fork will silently push into this PR. Recommend pushing follow-up commits from a feature branch.

Dismissals

Once #71 lands, the schema validator will catch (1) automatically going forward. Thanks again — strong content, just needs these fixes to land.

Comment thread .claude-plugin/marketplace.json Outdated
"region": "EMEA",
"country": "GB",
"depth": "reference",
"scf_controls_mapped": 26,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 SCF control count contradicts all documentation

plugin.json declares scf_controls_mapped: 26, but the README, assess.md, evidence-checklist.md, and SKILL.md all state 30 SCF controls map to the 5 CE+ controls. Consumers of the plugin metadata (marketplace display, tooling) will see 26 while the human-readable docs say 30. One of these is the authoritative number and the other needs to be corrected.

Suggested change
"scf_controls_mapped": 26,
"scf_controls_mapped": 30,

@ethanolivertroy

Copy link
Copy Markdown
Collaborator

Closing and reopening to trigger new vouch gate workflow.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (2)
plugins/frameworks/cyber-essentials-plus/commands/assess.md (2)

11-13: ⚠️ Potential issue | 🟡 Minor

Add language identifiers to both fenced command blocks.

Line 11 and Line 32 still use unlabeled fences, which keeps MD040 failing.

🧹 Proposed fix
-```
+```text
 /cyber-essentials-plus:assess [--scope=<scope>] [--sources=<connector-list>]

@@
- +text
/grc-engineer:gap-assessment "emea-gbr-ce-2021" [--sources=]

Also applies to: 32-34

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@plugins/frameworks/cyber-essentials-plus/commands/assess.md` around lines 11
- 13, The two fenced code blocks that currently show the commands
"/cyber-essentials-plus:assess [--scope=<scope>] [--sources=<connector-list>]"
and "/grc-engineer:gap-assessment \"emea-gbr-ce-2021\"
[--sources=<connector-list>]" need explicit language identifiers to satisfy
MD040; update each opening triple-backtick to include "text" (e.g., change ```
to ```text) so both fenced blocks are labeled.

33-37: ⚠️ Potential issue | 🟠 Major

Use the canonical SCF framework ID in delegation.

Line 33 still references emea-gbr-ce-2021; this conflicts with the required canonical ID for this plugin release and risks empty/incorrect crosswalk expansion.

🔧 Proposed fix
-/grc-engineer:gap-assessment "emea-gbr-ce-2021" [--sources=<connector-list>]
+/grc-engineer:gap-assessment "emea-gbr-cyber-essentials-requirements-3-3" [--sources=<connector-list>]
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@plugins/frameworks/cyber-essentials-plus/commands/assess.md` around lines 33
- 37, Update the delegation example that currently uses the framework string
"/grc-engineer:gap-assessment \"emea-gbr-ce-2021\" [--sources=<connector-list>]"
to reference the canonical SCF framework ID for this plugin release instead of
"emea-gbr-ce-2021"; locate the example line in the assess.md content and replace
the quoted framework token with the approved canonical SCF ID so the
SCF-to-Cyber Essentials Plus crosswalk expands correctly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@plugins/frameworks/cyber-essentials-plus/commands/assess.md`:
- Around line 12-18: The docs advertise a --scope option for
/cyber-essentials-plus:assess that is never forwarded to or supported by
/grc-engineer:gap-assessment; remove the --scope parameter from the
/cyber-essentials-plus:assess command signature and any descriptive bullets in
assess.md so the documented options match the actual delegation (only
--sources), and add a short note that scope-filtering is not currently supported
and should be requested or implemented later if desired.

---

Duplicate comments:
In `@plugins/frameworks/cyber-essentials-plus/commands/assess.md`:
- Around line 11-13: The two fenced code blocks that currently show the commands
"/cyber-essentials-plus:assess [--scope=<scope>] [--sources=<connector-list>]"
and "/grc-engineer:gap-assessment \"emea-gbr-ce-2021\"
[--sources=<connector-list>]" need explicit language identifiers to satisfy
MD040; update each opening triple-backtick to include "text" (e.g., change ```
to ```text) so both fenced blocks are labeled.
- Around line 33-37: Update the delegation example that currently uses the
framework string "/grc-engineer:gap-assessment \"emea-gbr-ce-2021\"
[--sources=<connector-list>]" to reference the canonical SCF framework ID for
this plugin release instead of "emea-gbr-ce-2021"; locate the example line in
the assess.md content and replace the quoted framework token with the approved
canonical SCF ID so the SCF-to-Cyber Essentials Plus crosswalk expands
correctly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 9376db5b-b440-47aa-b17b-6a70c2a385d6

📥 Commits

Reviewing files that changed from the base of the PR and between 27a42c8 and 65c7d2c.

📒 Files selected for processing (1)
  • plugins/frameworks/cyber-essentials-plus/commands/assess.md

Comment on lines +12 to +18
/cyber-essentials-plus:assess [--scope=<scope>] [--sources=<connector-list>]
```

## Arguments

- `--scope=<scope>` (optional) — narrow the assessment to one of the five CE+ controls: `firewalls`, `secure-configuration`, `user-access-control`, `malware-protection`, `patch-management`.
- `--sources=<connector-list>` (optional) — comma-separated connector plugins (e.g. `aws-inspector,github-inspector`).

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Verify gap-assessment supported options in implementation =="
rg -n -C3 --fixed-strings '--scope' plugins/grc-engineer/scripts/gap-assessment.js || true
rg -n -C3 --fixed-strings 'Options:' plugins/grc-engineer/scripts/gap-assessment.js || true

echo
echo "== Verify documented options for /grc-engineer:gap-assessment =="
rg -n -C3 --fixed-strings '--scope' plugins/grc-engineer/commands/gap-assessment.md || true
rg -n -C3 --fixed-strings '--sources' plugins/grc-engineer/commands/gap-assessment.md || true

echo
echo "== Verify CE+ assess command advertises --scope =="
rg -n -C2 --fixed-strings '--scope=<scope>' plugins/frameworks/cyber-essentials-plus/commands/assess.md

Repository: GRCEngClub/claude-grc-engineering

Length of output: 2398


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Check CE+ assess.md for --scope documentation =="
if [ -f "plugins/frameworks/cyber-essentials-plus/commands/assess.md" ]; then
  cat -n "plugins/frameworks/cyber-essentials-plus/commands/assess.md" | head -40
fi

echo
echo "== Check if gap-assessment.md exists and what it documents =="
if [ -f "plugins/grc-engineer/commands/gap-assessment.md" ]; then
  cat "plugins/grc-engineer/commands/gap-assessment.md"
else
  echo "File not found"
fi

echo
echo "== Check gap-assessment.js for --scope support =="
if [ -f "plugins/grc-engineer/scripts/gap-assessment.js" ]; then
  cat -n "plugins/grc-engineer/scripts/gap-assessment.js" | head -50
fi

Repository: GRCEngClub/claude-grc-engineering

Length of output: 10290


CE+ assess command documents --scope parameter that is not supported by the delegated gap-assessment command.

CE+ assess.md advertises --scope=<scope> in the command signature (line 12) and documents it as narrowing the assessment to one of five CE+ controls (line 17). However, the delegation section (lines 30–34) shows the actual call to /grc-engineer:gap-assessment passes only [--sources=<connector-list>]--scope is never forwarded. The gap-assessment command itself does not support --scope in its documented options or implementation, so passing this parameter from the user will be silently ignored or cause an error, contradicting the documented behavior.

Decide whether CE+ should:

  • Remove --scope from its documented signature and option list, or
  • Implement scope filtering at the CE+ level before delegating to gap-assessment, or
  • Add --scope support to gap-assessment.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@plugins/frameworks/cyber-essentials-plus/commands/assess.md` around lines 12
- 18, The docs advertise a --scope option for /cyber-essentials-plus:assess that
is never forwarded to or supported by /grc-engineer:gap-assessment; remove the
--scope parameter from the /cyber-essentials-plus:assess command signature and
any descriptive bullets in assess.md so the documented options match the actual
delegation (only --sources), and add a short note that scope-filtering is not
currently supported and should be requested or implemented later if desired.

@FunkeOmolere

Copy link
Copy Markdown
Contributor Author

Hi, quick update from my side:
Updated scf_controls_mapped from 30 → 26 across the 4 CE+ files (plugin.json, assess.md, README.md, SKILL.md) per your review.
Heads up, the us-finra entry in marketplace.json was inadvertently dropped during my merge conflict resolution earlier that wasn't intentional. Since us-finra isn't part of my contribution, I've left it for a maintainer to restore to avoid making further accidental changes to other plugins.
Happy to address anything else CE+ specific. Thanks for your patience with a first-time contributor!

@FunkeOmolere

Copy link
Copy Markdown
Contributor Author

One more thing:pushing the scf_controls_mapped update triggered the schema validation on my fork, and it's failing on the author field in cyber-essentials-plus/.claude-plugin/plugin.json. Schema wants object form ({"name": "..."}) but my file has it as a string, which I'd left alone based on your earlier note about the Qodo rule.

Should I switch to object form to make the schema happy, or leave it? Happy either way.

@ethanolivertroy

Copy link
Copy Markdown
Collaborator

!vouch trusted contributor

grc-eng-vouch-bot Bot pushed a commit that referenced this pull request Apr 26, 2026
"name": "cyber-essentials-plus",
"description": "UK NCSC Cyber Essentials Plus (CE+) v3.3 Danzell — Reference plugin with evidence checklist, scope determination, and SCF-backed gap assessment. Five core controls: Firewalls, Secure Configuration, User Access Control, Malware Protection, and Patch Management.",
"version": "0.1.0",
"author": "GRC Engineering Club Contributors",

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Schema violation — CI will fail. schemas/plugin.schema.json requires author to be an object with a name field, not a bare string. This manifest will be rejected by the JSON Schema validator (and by claude plugin install at install time). Fix:

"author": {"name": "GRC Engineering Club Contributors"},

Compare with plugins/frameworks/singapore-pdpa/.claude-plugin/plugin.json which uses the correct object form.

Comment thread .claude-plugin/marketplace.json Outdated
"name": "cyber-essentials-plus",
"source": "./plugins/frameworks/cyber-essentials-plus",
"description": "UK NCSC Cyber Essentials Plus (CE+) v3.3 Danzell — gap assessments, evidence checklists, remediation plans, and cross-framework mapping to ISO 27001 and NIST CSF",
"version": "0.1.0"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regression: the us-finra plugin entry has been deleted from the marketplace. It was added recently in PR #67 (commit bb1f7af) and lived between singapore-pdpa and the closing ] on main. The diff removes both singapore-pdpa and us-finra and only re-adds singapore-pdpa + the new cyber-essentials-plusus-finra is silently dropped.

Please rebase this branch against main and re-add the us-finra entry:

{
  "name": "us-finra",
  "source": "./plugins/frameworks/us-finra",
  "description": "FINRA Broker-Dealer Cybersecurity Guidance — stub-depth plugin backed by the SCF crosswalk (17 SCF → 39 framework controls).",
  "version": "0.1.0"
}

Otherwise merging this would break installs of us-finra for users who already added the marketplace.

Comment thread .claude-plugin/marketplace.json Outdated
{
"name": "singapore-pdpa",
"source": "./plugins/frameworks/singapore-pdpa",
"description": "Singapore — Personal Data Protection Ac (PDPA) (2012) — reference-depth plugin backed by the SCF crosswalk (30 SCF = 14 framework controls).",

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two unintended changes to the existing singapore-pdpa entry:

  1. The em-dash separator was changed from ASCII hyphen Singapore - Personal Data Protection Ac to em-dash Singapore — Personal Data Protection Ac — this no longer matches the display_name in plugins/frameworks/singapore-pdpa/.claude-plugin/plugin.json.
  2. The crosswalk arrow 30 SCF → 14 framework controls was corrupted to 30 SCF = 14 framework controls — semantically wrong (it should read "maps to", not "equals"); 30 SCF controls map to 14 framework controls, not equal to.

Please revert the singapore-pdpa description to the version on main so this PR only adds CE+ and does not regress an unrelated plugin.

Comment thread .claude-plugin/marketplace.json Outdated
"source": "./plugins/frameworks/us-finra",
"description": "FINRA Broker-Dealer Cybersecurity Guidance — stub-depth plugin backed by the SCF crosswalk (17 SCF → 39 framework controls).",
"version": "0.1.0"
},

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indentation/formatting damage to marketplace.json. This file uses 2-space indentation for the entire array; the new singapore-pdpa and cyber-essentials-plus blocks are pasted at 8-space indentation, and the } closing fedramp-ssp is broken at 3 spaces ( },). There is also a stray blank line of trailing whitespace after irap (line ~163 in the new file). Please reformat to match the surrounding 2-space style — easiest fix is to run the file through python3 -m json.tool (or jq .) and commit the normalized result. Otherwise this will produce noisy diffs against future plugin additions.


- **Annual recertification**: CE+ lapses exactly 12 months after the certification date. There is no grace period.
- **Patch window**: Critical and high-severity patches must be applied within **14 days** of release. This is a hard requirement — patches overdue at the time of assessment will cause a failure.
- **Danzell v3.3 effective date**: 27 April 2026. All assessments submitted on or after this date must use the v3.3 question set.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verify the "Danzell v3.3" question-set name and 27 April 2026 effective date with a primary source before merging. This is a load-bearing factual claim — the SKILL, README, plugin.json, and four commands all assert "Danzell v3.3 effective 27 April 2026" and that it "replaces Willow." IASME has historically named question sets after trees (Beech, Cypress, Evergreen, Montpellier, Willow), so "Danzell" doesn't match the convention and I cannot find it in IASME or NCSC publications dated to my knowledge cutoff.

If "Danzell" is real, please cite it directly in the README References (link to the IASME announcement that names the question set, not just the generic preview page). If it's an invented or rumoured name, this should ship as an unversioned plugin (drop "v3.3 Danzell" from display_name, plugin description, and SKILL) until the real successor is published. Inventing a name would mislead users running /grc-engineer:frameworks and produce confidently wrong assessment output.

…author

- marketplace.json: reset to upstream main and re-apply cyber-essentials-plus
  entry cleanly. Restores the us-finra plugin entry (added in PR GRCEngClub#67) that
  was lost to a stale base, and removes the indentation drift +
  singapore-pdpa description corruption.
- plugin.json: switch author from bare string to object form per
  schemas/plugin.schema.json (the description note explicitly says bare
  strings are rejected by `claude plugin install`).

Both manifests now pass tests/validate-plugin-manifests.sh against the
ajv schema (35/35 valid).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@ethanolivertroy

Copy link
Copy Markdown
Collaborator

@FunkeOmolere — pushed the four blocker fixes directly to your fork's main (since you had `maintainerCanModify` on, thanks!):

  1. ✅ Restored the us-finra marketplace entry that was getting silently dropped (it merged in feat(us-finra): add FINRA framework plugin stub #67 after your branch diverged)
  2. ✅ Re-laid the cyber-essentials-plus entry with consistent 4-space indentation; cleaned up the malformed }, and stray blank line
  3. ✅ Restored the original singapore-pdpa description (en-dash + arrow that an editor had auto-replaced)
  4. ✅ Switched plugin.json author to object form per the schema description ("bare strings are rejected by `claude plugin install`")

All 35 manifests now pass tests/validate-plugin-manifests.sh. Also: confirmed via IASME's Apr 2026 announcement that "Danzell" is the correct question-set name (Montpellier → Willow → Danzell, taking effect 27 Apr 2026 with NCSC Requirements v3.3) — your timing is great.

Once CI is green I'll merge.

@ethanolivertroy ethanolivertroy merged commit f7a9462 into GRCEngClub:main Apr 26, 2026
2 of 3 checks passed
@FunkeOmolere

Copy link
Copy Markdown
Contributor Author

Thank you @ethanolivertroy! I appreciate you taking on the four fixes directly. I was working through the contributor flow for the first time and the merge conflict caught me out (didn't realise "Accept current change" would silently drop us-finra), Thanks for handling the cleanup.

Learned a lot from this PR. Thank you for the patience and the careful review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants