ci(plugins): validate manifests against JSON Schema on every PR#71
Conversation
ⓘ You are approaching your monthly quota for Qodo. Upgrade your plan Review Summary by QodoFix plugin manifest author field and add schema validation CI workflow
WalkthroughsDescription• Fixes six plugin manifests with invalid author field (bare string instead of object) • Adds JSON Schema validation for all plugin and marketplace manifests in CI • Implements local validation script using ajv-cli for contributor use • Updates documentation example to show correct author object format Diagramflowchart LR
A["Six broken plugin.json files<br/>author as string"] -->|"Fix to object form"| B["Valid manifests"]
C["New JSON Schemas<br/>plugin + marketplace"] -->|"Validate on PR"| D["CI workflow"]
E["Validation script<br/>ajv-cli"] -->|"Local + CI use"| D
F["CONTRIBUTING.md<br/>example"] -->|"Updated to object"| B
File Changes1. tests/validate-plugin-manifests.sh
|
Code Review by Qodo
1.
|
|
Thanks for the catch — fixed in 987c9ca.
Verified:
|
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (11)
✅ Files skipped from review due to trivial changes (9)
🚧 Files skipped from review as they are similar to previous changes (2)
📝 WalkthroughWalkthroughAdds JSON Schemas for plugin and marketplace manifests, updates several plugin manifests’ Changes
Sequence Diagram(s)sequenceDiagram
participant Dev as Developer
participant GH as GitHub Actions
participant Runner as Workflow Runner
participant Repo as Repository
participant Script as validate-plugin-manifests.sh
participant AJV as ajv-cli
Dev->>GH: push or open PR with manifest/schema changes
GH->>Runner: trigger workflow (concurrency by ref)
Runner->>Repo: checkout code
Runner->>Runner: setup Node.js 20 and install ajv-cli / ajv-formats
Runner->>Script: execute tests/validate-plugin-manifests.sh
Script->>Repo: read `schemas/*`, `.claude-plugin/marketplace.json`, `plugins/**/plugin.json`
Script->>AJV: validate each manifest
AJV-->>Script: validation results
Script-->>GH: emit logs and annotations for failures
Script-->>Runner: exit status (non-zero on any failure)
Runner-->>GH: report workflow result
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (1)
.github/workflows/validate-plugin-manifests.yml (1)
31-33: Pin GitHub Actions to immutable commit SHAs.Lines 31 and 33 use floating major tags (
@v4). Pin to commit SHAs instead to improve supply-chain safety and ensure deterministic runs. Current SHAs are:
actions/checkout@v4→34e114876b0b11c390a56381ad16ebd13914f8d5actions/setup-node@v4→49933ea5288caeca8642d1e84afbd3f7d6820020🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.github/workflows/validate-plugin-manifests.yml around lines 31 - 33, Replace the floating major tags for GitHub Actions with the provided immutable commit SHAs: update the uses entries that currently reference "actions/checkout@v4" and "actions/setup-node@v4" to use "34e114876b0b11c390a56381ad16ebd13914f8d5" and "49933ea5288caeca8642d1e84afbd3f7d6820020" respectively so the workflow (the lines containing the action identifiers "actions/checkout@v4" and "actions/setup-node@v4") is pinned to those exact commits for deterministic, supply-chain-safe runs.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@schemas/plugin.schema.json`:
- Around line 15-19: The "version" property currently allows any non-empty
string but claims to be "Semver-compatible"; update the schema so the behavior
matches the description by adding a semver validation (e.g., a "pattern" with a
semver regex such as
^\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z-.]+)?(?:\\+[0-9A-Za-z-.]+)?$) to the "version"
property, or alternatively change the "description" text to remove the semver
claim; modify the "version" object in plugin.schema.json (the "version"
property) accordingly so the schema and description stay consistent.
In `@tests/validate-plugin-manifests.sh`:
- Around line 19-20: The script sets repo_root and then runs cd "$repo_root"
without checking success; modify the validation script so the cd to repo_root is
guarded and fails fast (e.g., check the exit status of the cd command and exit
with a non‑zero code or print an error and exit) so subsequent validation always
runs from the intended directory; update the lines that define repo_root and
call cd (the repo_root variable and the cd "$repo_root" invocation) to include
this failure guard.
- Around line 97-99: The current -f guard lets deletion of
.claude-plugin/marketplace.json skip validation; replace it with a hard-fail
when the marketplace manifest is missing: check for the presence of
.claude-plugin/marketplace.json and if absent print a clear error and exit 1,
otherwise call validate_file with marketplace_schema and
.claude-plugin/marketplace.json so CI fails when the top-level marketplace
manifest is deleted.
---
Nitpick comments:
In @.github/workflows/validate-plugin-manifests.yml:
- Around line 31-33: Replace the floating major tags for GitHub Actions with the
provided immutable commit SHAs: update the uses entries that currently reference
"actions/checkout@v4" and "actions/setup-node@v4" to use
"34e114876b0b11c390a56381ad16ebd13914f8d5" and
"49933ea5288caeca8642d1e84afbd3f7d6820020" respectively so the workflow (the
lines containing the action identifiers "actions/checkout@v4" and
"actions/setup-node@v4") is pinned to those exact commits for deterministic,
supply-chain-safe runs.
🪄 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: 03c51fba-f5c6-4892-bc3a-d1a8d6460e0a
📒 Files selected for processing (11)
.github/workflows/validate-plugin-manifests.ymldocs/CONTRIBUTING.mdplugins/connectors/aws-inspector/.claude-plugin/plugin.jsonplugins/connectors/gcp-inspector/.claude-plugin/plugin.jsonplugins/connectors/github-inspector/.claude-plugin/plugin.jsonplugins/connectors/okta-inspector/.claude-plugin/plugin.jsonplugins/fedramp-ssp/.claude-plugin/plugin.jsonplugins/oscal/.claude-plugin/plugin.jsonschemas/marketplace.schema.jsonschemas/plugin.schema.jsontests/validate-plugin-manifests.sh
CodeRabbit posted 3 actionable comments on GRCEngClub#71. All addressed: 1. schemas/plugin.schema.json — `version` claimed semver-compatible but accepted any non-empty string. Add the semver 2.0.0 grammar as a `pattern` so the schema and description agree, and tighten the description to call out the semver enforcement explicitly. Also apply the same pattern to plugin entries inside schemas/marketplace.schema.json for consistency, so a marketplace that lists a plugin with a non-semver version is caught. 2. tests/validate-plugin-manifests.sh — `cd "$repo_root"` could silently fail and leave the script validating from the wrong working directory (Shellcheck SC2164). Guard it with an explicit `|| { echo "..."; exit 2; }`. 3. tests/validate-plugin-manifests.sh — a missing top-level `.claude-plugin/marketplace.json` previously passed silently (gated by `-f`). Since this repository is a Claude Code plugin marketplace, that file is required. Replace the silent skip with an explicit `emit_summary_error` and `exit 1`. Verified locally: - All 33 current manifests still pass. - A plugin.json with `version: "badversion"` is now rejected by schemas/plugin.schema.json. - A marketplace.json that lists a plugin with a non-semver version is now rejected by schemas/marketplace.schema.json. - Removing .claude-plugin/marketplace.json fails the validator with rc=1 and a clear error message.
|
Pushed 7ef8be3 addressing the three actionable CodeRabbit comments:
Verified locally:
Ready for re-review whenever a maintainer can trigger another bot pass. |
|
Only users with a collaborator, contributor, member, or owner role can interact with CodeRabbit. |
The Claude Code plugin loader rejects manifests where `author` is a
string with `Validation errors: author: Invalid input: expected
object, received string`, which means the affected plugins cannot be
installed via `claude plugin install`.
Six plugins shipped with `author` as a bare string while the rest of
the marketplace already uses the object form. Normalise them to
`{ "name": "..." }` to match the working plugins (e.g.
`grc-engineer`, `soc2`, `nist-800-53`) and unblock installation:
- plugins/connectors/aws-inspector
- plugins/connectors/gcp-inspector
- plugins/connectors/github-inspector
- plugins/connectors/okta-inspector
- plugins/fedramp-ssp
- plugins/oscal
Also update the `plugin.json` example in `docs/CONTRIBUTING.md` so
new connector contributors land on the working schema by default.
Verified locally: all six plugins install successfully after the
patch (`claude plugin install <name>@grc-engineering-suite`).
Adds a CI workflow that schema-validates every plugin.json plus the top-level marketplace.json on each PR. Catches the install-blocking manifest errors that `claude plugin install` rejects — most notably the `author` field type, which has already produced one round of broken plugins in this repo. Why two schemas instead of `claude plugin validate`: `claude plugin validate` rejects unknown keys in strict mode, which flags every framework plugin that uses `framework_metadata` (an intentional extension). The schemas here mirror what the CLI's *install-time* validator enforces — required fields and field types — while leaving extension keys via `additionalProperties: true`. Any manifest that passes here installs cleanly with `claude plugin install`; any that fails will not. Files: - schemas/plugin.schema.json: plugin.json contract (author must be an object, name + version required, extension keys allowed) - schemas/marketplace.schema.json: marketplace.json contract - tests/validate-plugin-manifests.sh: ajv-cli loop with GitHub-Actions-friendly error annotations - .github/workflows/validate-plugin-manifests.yml: triggers on manifest or schema changes; matches the existing contract-test workflow style (Node 20 + ajv-cli + ajv-formats) Verified locally: - All 33 current manifests pass - Reverting any one to the broken `author: <string>` form fails the job with an inline error annotation pointing at the file
Filenames in `tests/validate-plugin-manifests.sh` came from `find` over a PR-controlled tree and were interpolated unescaped into `::group::` and `::error file=…::…` workflow commands. A crafted filename containing `%`, CR, or LF could inject additional workflow commands into the CI log, mislead reviewers, or alter CI behavior. Add a `gha_escape` helper that applies the canonical escapes documented at https://docs.github.com/actions/reference/workflow-commands-for-github-actions (`%` → `%25`, CR → `%0D`, LF → `%0A`) and route every workflow command through it. Also gate workflow-command output on `$GITHUB_ACTIONS` so local runs print readable diagnostics instead of `::group::` markers. Verified locally: - All 33 current manifests still pass (CI and local mode) - A crafted path `plugins/connectors/evil%inj/.claude-plugin/plugin.json` is rendered as `evil%25inj` in `::group::` and `::error` lines - Reverting any manifest to the broken `author: <string>` form still fails the job (rc=1) with an inline error annotation
CodeRabbit posted 3 actionable comments on GRCEngClub#71. All addressed: 1. schemas/plugin.schema.json — `version` claimed semver-compatible but accepted any non-empty string. Add the semver 2.0.0 grammar as a `pattern` so the schema and description agree, and tighten the description to call out the semver enforcement explicitly. Also apply the same pattern to plugin entries inside schemas/marketplace.schema.json for consistency, so a marketplace that lists a plugin with a non-semver version is caught. 2. tests/validate-plugin-manifests.sh — `cd "$repo_root"` could silently fail and leave the script validating from the wrong working directory (Shellcheck SC2164). Guard it with an explicit `|| { echo "..."; exit 2; }`. 3. tests/validate-plugin-manifests.sh — a missing top-level `.claude-plugin/marketplace.json` previously passed silently (gated by `-f`). Since this repository is a Claude Code plugin marketplace, that file is required. Replace the silent skip with an explicit `emit_summary_error` and `exit 1`. Verified locally: - All 33 current manifests still pass. - A plugin.json with `version: "badversion"` is now rejected by schemas/plugin.schema.json. - A marketplace.json that lists a plugin with a non-semver version is now rejected by schemas/marketplace.schema.json. - Removing .claude-plugin/marketplace.json fails the validator with rc=1 and a clear error message.
7ef8be3 to
62e4f8b
Compare
Adds a Reference-depth plugin for India's Digital Personal Data Protection Act, 2023 (DPDPA) and the DPDP Rules, 2025. Built for CISOs, DPOs, GRC engineers, and platform teams operating in India or offering goods or services to Data Principals located in India. Plugin - Slug: ind-dpdpa - SCF framework ID: apac-ind-dpdpa-2023 (41 SCF → 96 framework controls) - Depth: reference - Regulator: Data Protection Board of India (DPB) under MeitY - Region: APAC, country IN Files (Reference-depth set per docs/FRAMEWORK-PLUGIN-GUIDE.md): - plugins/frameworks/ind-dpdpa/.claude-plugin/plugin.json - plugins/frameworks/ind-dpdpa/README.md - plugins/frameworks/ind-dpdpa/commands/assess.md - plugins/frameworks/ind-dpdpa/commands/scope.md - plugins/frameworks/ind-dpdpa/commands/evidence-checklist.md - plugins/frameworks/ind-dpdpa/commands/breach-process.md - plugins/frameworks/ind-dpdpa/skills/ind-dpdpa-expert/SKILL.md - .claude-plugin/marketplace.json (registration) Coverage - Act + Rules read together: substantive obligations from the Act, operational timelines and detail from the Rules notified November 2025. - Roles: Data Fiduciary, Processor, Principal, Consent Manager, SDF. - Section 3 territorial and material applicability decision tree. - Section 5–7 notice / consent / legitimate uses (no GDPR-style legitimate-interest framing — Section 7 is exhaustive). - Section 8 Fiduciary obligations including 8(5) security safeguards and 8(6) breach notification (penalty bands ₹250 cr / ₹50 cr). - Section 9 children's data (verifiable parental consent, no behavioural tracking, no targeted ads — penalty up to ₹200 cr). - Section 10 SDF additional obligations (DPO, DPIA, audit; up to ₹150 cr). - Sections 11–14 Data Principal rights (access, correction, erasure, grievance, nomination). - Section 16 cross-border (default-permissive with restricted- territory blocklist; sectoral localisation overlays preserved). - Section 17 exemptions. Reference-depth differentiators vs scaffolded stub - Substantive content in every SKILL section (no TODO markers). - /ind-dpdpa:scope — full applicability + role + SDF-trigger walk. - /ind-dpdpa:evidence-checklist — 14 obligation themes with collection guidance and "what good looks like" criteria. - /ind-dpdpa:breach-process — DPDPA 72-hour timeline plus the parallel sectoral clocks (CERT-In 6h, RBI 6h, SEBI 6h, IRDAI per current direction, DoT/TRAI per Telecom Cyber Security Rules 2024). Clock-collision is the most common DPDPA-era breach failure for regulated Fiduciaries; the playbook addresses it. Sectoral overlay Plugin flags overlap with RBI (Master Direction on IT Governance, Cyber Security Framework, payment-system data localisation), SEBI (CSCRF), IRDAI (Information & Cyber Security Guidelines), DoT/TRAI (Telecom Cyber Security Rules 2024), NHA (ABDM/Health Data Management Policy), NCIIPC (CII), and CERT-In (Direction 20(3)/2022). The plugin does not enforce sectoral rules — those remain separate plugins or org-internal playbooks. Constraints honoured - No verbatim Act or Rules text (paraphrase only; section / rule references by number). - No PII, no real org context, no credentials. - No legal-advice phrasing; "engineering and assessment guidance only" disclaimer in every file. - Cloud-agnostic implementation guidance. - No hand-maintained crosswalks; defers to SCF for control mapping. - No vendored copy of the Section 16 restricted-territories list (which is published by the Central Government and updates). Coordination with PR GRCEngClub#66 PR GRCEngClub#66 (@AnandSundar) proposes a Stub-depth plugin for the same framework. This PR is a Reference-depth contribution. Per docs/FRAMEWORK-PLUGIN-GUIDE.md ("Level-ups are separate PRs"), the intended sequence is: GRCEngClub#66 merges first, then this PR rebases as a Stub→Reference upgrade. Happy to defer or coordinate per maintainer preference. Validation - plugin.json passes the Reference manifest schema (PR GRCEngClub#71). - marketplace.json passes the Reference marketplace schema (PR GRCEngClub#71). - No matches in audit grep for: verbatim long quotes, real-org context, PII patterns, credentials, "legal advice" framing. - Disclaimer present in every user-facing file. Authored personally by Devam Shah.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@tests/validate-plugin-manifests.sh`:
- Around line 42-48: The gha_escape function only URL-encodes %, CR and LF, but
property values (e.g., the file= in the ::error file=%s::%s annotation) must
also escape ':' and ',' to avoid annotation parsing errors; add a separate
property-escaping variant (e.g., gha_escape_property) or extend gha_escape to
accept a mode and, when used for properties, additionally replace ':' with %3A
and ',' with %2C (while preserving existing %->%25, CR->%0D, LF->%0A behavior)
and use that new escape for the file/other property substitutions where
annotations are constructed.
🪄 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: 0d58868a-dc4b-47d6-9528-2d79afade7c8
📒 Files selected for processing (3)
schemas/marketplace.schema.jsonschemas/plugin.schema.jsontests/validate-plugin-manifests.sh
✅ Files skipped from review due to trivial changes (2)
- schemas/plugin.schema.json
- schemas/marketplace.schema.json
…e data CodeRabbit re-review on the previous fix flagged that `gha_escape` applied data-only escaping (`%`, CR, LF) to *property* values inside `::error file=...::...` annotations. Property values must additionally escape `:` and `,` — those are the property-delimiter characters and a crafted filename could otherwise inject fake `line=`/`title=` properties or break the `::` separator. This mirrors @actions/toolkit's split between escapeData and escapeProperty, documented in packages/core/src/command.ts of actions/toolkit. Changes: - Split `gha_escape` into `gha_escape_data` (message bodies) and `gha_escape_property` (key=value property values, additionally escaping `:` and `,`). - `emit_error` now uses `gha_escape_property` for the `file=` property and `gha_escape_data` for the message body (matching the toolkit's Command.toString contract). - `emit_group_start` and `emit_summary_error` continue to use `gha_escape_data` (their values aren't properties). Verified locally with a crafted filename containing `:` `,` `%`: - `::group::evil:inj,x%25` (data: only `%` escaped) - `::error file=evil%3Ainj%2Cx%25` (property: `:`,`,`,`%` all escaped) All 33 current manifests still pass.
|
Pushed f0cd40c addressing the post-rebase CodeRabbit finding on Issue: my Fix:
Verified locally with a crafted filename containing
All 33 current manifests still pass. |
Greptile SummaryThis PR introduces a CI workflow that schema-validates all Confidence Score: 5/5Safe to merge; the one open finding is a P2 schema inconsistency that doesn't affect any current manifest. All current manifests pass the new schemas, the workflow and script are well-constructed, and the only finding (author
Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[PR opened or push to main] --> B{Path filter matches?}
B -- No --> Z[Workflow skipped]
B -- Yes --> C[Checkout repo]
C --> D[Setup Node 20]
D --> E[Install ajv-cli and ajv-formats]
E --> F[Run validate-plugin-manifests.sh]
F --> G{marketplace.json exists?}
G -- No --> X[Exit 1 - missing marketplace manifest]
G -- Yes --> H[Validate marketplace.json against marketplace.schema.json]
H --> I[Find all plugin.json files]
I --> J[Validate each plugin.json against plugin.schema.json]
J --> K{Any failures?}
K -- Yes --> L[Emit error annotations and exit 1]
K -- No --> M[Exit 0 - all manifests valid]
Reviews (2): Last reviewed commit: "Merge branch 'main' into ci/validate-plu..." | Re-trigger Greptile |
| --errors=line; then | ||
| printf ' ✓ %s\n' "$file" | ||
| else | ||
| emit_error "$file" "Manifest failed schema validation against $schema" | ||
| fail=1 | ||
| fi | ||
| emit_group_end |
There was a problem hiding this comment.
ajv-formats installed but never activated
ajv-formats is installed alongside ajv-cli but no -c ajv-formats flag is passed to ajv validate. In ajv@8 (which ajv-cli@5 bundles), format validation is disabled by default — ajv-formats must be explicitly loaded via -c ajv-formats for "format": "email" / "format": "uri" constraints to fire. The current schemas don't use format keywords so this has no immediate impact, but if "format" validators are added to the schemas later, they will silently pass without being checked.
| --errors=line; then | |
| printf ' ✓ %s\n' "$file" | |
| else | |
| emit_error "$file" "Manifest failed schema validation against $schema" | |
| fail=1 | |
| fi | |
| emit_group_end | |
| if ajv validate \ | |
| --spec=draft2020 \ | |
| -c ajv-formats \ | |
| -s "$schema" \ | |
| -d "$file" \ | |
| --errors=line; then |
ethanolivertroy
left a comment
There was a problem hiding this comment.
Approving per pre-merge review pass: AI review feedback (qodo Bug+Security on GHA injection, CodeRabbit Major on deleted-marketplace.json, semver pattern, ajv-formats latent issue) addressed; schema validates current manifests; consistent with existing contract-test workflow style. Will close #70 as superseded after this lands.
Adds a Reference-depth plugin for India's Digital Personal Data Protection Act, 2023 (DPDPA) and the DPDP Rules, 2025. Built for CISOs, DPOs, GRC engineers, and platform teams operating in India or offering goods or services to Data Principals located in India. Plugin - Slug: ind-dpdpa - SCF framework ID: apac-ind-dpdpa-2023 (41 SCF → 96 framework controls) - Depth: reference - Regulator: Data Protection Board of India (DPB) under MeitY - Region: APAC, country IN Files (Reference-depth set per docs/FRAMEWORK-PLUGIN-GUIDE.md): - plugins/frameworks/ind-dpdpa/.claude-plugin/plugin.json - plugins/frameworks/ind-dpdpa/README.md - plugins/frameworks/ind-dpdpa/commands/assess.md - plugins/frameworks/ind-dpdpa/commands/scope.md - plugins/frameworks/ind-dpdpa/commands/evidence-checklist.md - plugins/frameworks/ind-dpdpa/commands/breach-process.md - plugins/frameworks/ind-dpdpa/skills/ind-dpdpa-expert/SKILL.md - .claude-plugin/marketplace.json (registration) Coverage - Act + Rules read together: substantive obligations from the Act, operational timelines and detail from the Rules notified November 2025. - Roles: Data Fiduciary, Processor, Principal, Consent Manager, SDF. - Section 3 territorial and material applicability decision tree. - Section 5–7 notice / consent / legitimate uses (no GDPR-style legitimate-interest framing — Section 7 is exhaustive). - Section 8 Fiduciary obligations including 8(5) security safeguards and 8(6) breach notification (penalty bands ₹250 cr / ₹50 cr). - Section 9 children's data (verifiable parental consent, no behavioural tracking, no targeted ads — penalty up to ₹200 cr). - Section 10 SDF additional obligations (DPO, DPIA, audit; up to ₹150 cr). - Sections 11–14 Data Principal rights (access, correction, erasure, grievance, nomination). - Section 16 cross-border (default-permissive with restricted- territory blocklist; sectoral localisation overlays preserved). - Section 17 exemptions. Reference-depth differentiators vs scaffolded stub - Substantive content in every SKILL section (no TODO markers). - /ind-dpdpa:scope — full applicability + role + SDF-trigger walk. - /ind-dpdpa:evidence-checklist — 14 obligation themes with collection guidance and "what good looks like" criteria. - /ind-dpdpa:breach-process — DPDPA 72-hour timeline plus the parallel sectoral clocks (CERT-In 6h, RBI 6h, SEBI 6h, IRDAI per current direction, DoT/TRAI per Telecom Cyber Security Rules 2024). Clock-collision is the most common DPDPA-era breach failure for regulated Fiduciaries; the playbook addresses it. Sectoral overlay Plugin flags overlap with RBI (Master Direction on IT Governance, Cyber Security Framework, payment-system data localisation), SEBI (CSCRF), IRDAI (Information & Cyber Security Guidelines), DoT/TRAI (Telecom Cyber Security Rules 2024), NHA (ABDM/Health Data Management Policy), NCIIPC (CII), and CERT-In (Direction 20(3)/2022). The plugin does not enforce sectoral rules — those remain separate plugins or org-internal playbooks. Constraints honoured - No verbatim Act or Rules text (paraphrase only; section / rule references by number). - No PII, no real org context, no credentials. - No legal-advice phrasing; "engineering and assessment guidance only" disclaimer in every file. - Cloud-agnostic implementation guidance. - No hand-maintained crosswalks; defers to SCF for control mapping. - No vendored copy of the Section 16 restricted-territories list (which is published by the Central Government and updates). Coordination with PR GRCEngClub#66 PR GRCEngClub#66 (@AnandSundar) proposes a Stub-depth plugin for the same framework. This PR is a Reference-depth contribution. Per docs/FRAMEWORK-PLUGIN-GUIDE.md ("Level-ups are separate PRs"), the intended sequence is: GRCEngClub#66 merges first, then this PR rebases as a Stub→Reference upgrade. Happy to defer or coordinate per maintainer preference. Validation - plugin.json passes the Reference manifest schema (PR GRCEngClub#71). - marketplace.json passes the Reference marketplace schema (PR GRCEngClub#71). - No matches in audit grep for: verbatim long quotes, real-org context, PII patterns, credentials, "legal advice" framing. - Disclaimer present in every user-facing file. Authored personally by Devam Shah.
* feat(frameworks): add Reference-depth India DPDPA plugin (ind-dpdpa) Adds a Reference-depth plugin for India's Digital Personal Data Protection Act, 2023 (DPDPA) and the DPDP Rules, 2025. Built for CISOs, DPOs, GRC engineers, and platform teams operating in India or offering goods or services to Data Principals located in India. Plugin - Slug: ind-dpdpa - SCF framework ID: apac-ind-dpdpa-2023 (41 SCF → 96 framework controls) - Depth: reference - Regulator: Data Protection Board of India (DPB) under MeitY - Region: APAC, country IN Files (Reference-depth set per docs/FRAMEWORK-PLUGIN-GUIDE.md): - plugins/frameworks/ind-dpdpa/.claude-plugin/plugin.json - plugins/frameworks/ind-dpdpa/README.md - plugins/frameworks/ind-dpdpa/commands/assess.md - plugins/frameworks/ind-dpdpa/commands/scope.md - plugins/frameworks/ind-dpdpa/commands/evidence-checklist.md - plugins/frameworks/ind-dpdpa/commands/breach-process.md - plugins/frameworks/ind-dpdpa/skills/ind-dpdpa-expert/SKILL.md - .claude-plugin/marketplace.json (registration) Coverage - Act + Rules read together: substantive obligations from the Act, operational timelines and detail from the Rules notified November 2025. - Roles: Data Fiduciary, Processor, Principal, Consent Manager, SDF. - Section 3 territorial and material applicability decision tree. - Section 5–7 notice / consent / legitimate uses (no GDPR-style legitimate-interest framing — Section 7 is exhaustive). - Section 8 Fiduciary obligations including 8(5) security safeguards and 8(6) breach notification (penalty bands ₹250 cr / ₹50 cr). - Section 9 children's data (verifiable parental consent, no behavioural tracking, no targeted ads — penalty up to ₹200 cr). - Section 10 SDF additional obligations (DPO, DPIA, audit; up to ₹150 cr). - Sections 11–14 Data Principal rights (access, correction, erasure, grievance, nomination). - Section 16 cross-border (default-permissive with restricted- territory blocklist; sectoral localisation overlays preserved). - Section 17 exemptions. Reference-depth differentiators vs scaffolded stub - Substantive content in every SKILL section (no TODO markers). - /ind-dpdpa:scope — full applicability + role + SDF-trigger walk. - /ind-dpdpa:evidence-checklist — 14 obligation themes with collection guidance and "what good looks like" criteria. - /ind-dpdpa:breach-process — DPDPA 72-hour timeline plus the parallel sectoral clocks (CERT-In 6h, RBI 6h, SEBI 6h, IRDAI per current direction, DoT/TRAI per Telecom Cyber Security Rules 2024). Clock-collision is the most common DPDPA-era breach failure for regulated Fiduciaries; the playbook addresses it. Sectoral overlay Plugin flags overlap with RBI (Master Direction on IT Governance, Cyber Security Framework, payment-system data localisation), SEBI (CSCRF), IRDAI (Information & Cyber Security Guidelines), DoT/TRAI (Telecom Cyber Security Rules 2024), NHA (ABDM/Health Data Management Policy), NCIIPC (CII), and CERT-In (Direction 20(3)/2022). The plugin does not enforce sectoral rules — those remain separate plugins or org-internal playbooks. Constraints honoured - No verbatim Act or Rules text (paraphrase only; section / rule references by number). - No PII, no real org context, no credentials. - No legal-advice phrasing; "engineering and assessment guidance only" disclaimer in every file. - Cloud-agnostic implementation guidance. - No hand-maintained crosswalks; defers to SCF for control mapping. - No vendored copy of the Section 16 restricted-territories list (which is published by the Central Government and updates). Coordination with PR #66 PR #66 (@AnandSundar) proposes a Stub-depth plugin for the same framework. This PR is a Reference-depth contribution. Per docs/FRAMEWORK-PLUGIN-GUIDE.md ("Level-ups are separate PRs"), the intended sequence is: #66 merges first, then this PR rebases as a Stub→Reference upgrade. Happy to defer or coordinate per maintainer preference. Validation - plugin.json passes the Reference manifest schema (PR #71). - marketplace.json passes the Reference marketplace schema (PR #71). - No matches in audit grep for: verbatim long quotes, real-org context, PII patterns, credentials, "legal advice" framing. - Disclaimer present in every user-facing file. Authored personally by Devam Shah. * docs(ind-dpdpa): address CodeRabbit review feedback CodeRabbit posted 3 actionable comments on #72: 1. Add `bash` language tag to fenced code blocks (markdownlint MD040). Applied to commands/assess.md (Usage and Delegation blocks), commands/scope.md, commands/evidence-checklist.md, commands/breach-process.md. 2. Reclassify DDoS row in commands/breach-process.md. The row previously said "No" for DPDPA-breach status, which contradicted Section 2's definition (which includes loss-of-access to personal data as a breach of availability). Updated to "Context-dependent — likely Yes if the unavailability blocks Data Principals from accessing their personal data" and added the "document the determination basis" reminder consistent with the rest of the document. 3. (Already covered by item 1.) * fix(ind-dpdpa): version baseline, Section 15 penalty, paraphrase Section 2(u) - plugin.json: version 0.2.0 → 0.1.0 to match repo baseline (every other plugin manifest is at 0.1.0) - SKILL.md (Penalty exposure): Section 15 Data Principal duty penalty is ₹10,000 per the Schedule, not ₹50 crore. Crore-scale penalties apply to Fiduciary failures; the Principal-side fine is the small one. - SKILL.md + breach-process.md: paraphrase the Section 2(u) personal-data- breach definition rather than reproducing the Act text verbatim, per ground rule #2 in docs/CONTRIBUTING.md - marketplace.json: register the ind-dpdpa plugin alongside the other framework plugins (resolves stale-base conflict against current main) Validates against tests/validate-plugin-manifests.sh (37 manifests, all valid). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Ethan Troy <63926014+ethanolivertroy@users.noreply.github.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Thanks for the merge @ethanolivertroy — happy this ships as a CI guardrail going forward. CodeRabbit's Glad the six manifest fixes folded in cleanly with the validator landing in the same merge — one PR, one set of artefacts, no half-fixed state on |
Both substantive PRs (GRCEngClub#71 validator, GRCEngClub#72 India DPDPA plugin) are merged into upstream main. PR GRCEngClub#70 closed-as-superseded (folded into GRCEngClub#71). README updated to: - Reflect the merged state of all three contributions, with explicit thanks for @ethanolivertroy's maintainer-edit pass that fixed the four blockers on GRCEngClub#72 before merge (version baseline, Section 15 ₹10,000 correction, Section 2(u) paraphrase). - Acknowledge @AnandSundar's original stub PR GRCEngClub#66 that locked in the SCF metadata baseline. - Recommend the upstream Club marketplace as the primary install path now that the work has landed there. - Preserve the upstream README verbatim as UPSTREAM-README.md.
Summary
plugin.jsonplus the top-level.claude-plugin/marketplace.jsonon each PR.authorfield as bare string instead of object) before it lands onmainand breaksclaude plugin installfor end users.schemas/plugin.schema.json,schemas/marketplace.schema.json) so the manifest contract is documented in the repo, and contributors can validate locally with one command.Why a custom schema, not
claude plugin validateclaude plugin validateworks locally but rejects unknown keys in strict mode — includingframework_metadata, which framework plugins (soc2,nist-800-53,cmmc, …) use intentionally. Running it across the repo would false-flag ~20 plugins.The schemas here mirror what
claude plugin installactually enforces at install time: required fields and field types, withadditionalProperties: truefor extension keys. Any manifest that passes here installs cleanly; any that fails won't.Files
schemas/plugin.schema.json— plugin.json contract. Requiresauthorto be an object, requiresnameandversion, allows extension keys.schemas/marketplace.schema.json— marketplace.json contract.tests/validate-plugin-manifests.sh— ajv-cli loop, emits GitHub Actions error annotations on failure..github/workflows/validate-plugin-manifests.yml— triggers on manifest or schema changes. Matches the existingcontract-test.ymlstyle: Node 20, ajv-cli@5, ajv-formats@3, concurrency cancellation.Test plan
bash tests/validate-plugin-manifests.sh)"author": "<string>"form fails the job with an inline::error file=...annotation pointing at the offending fileLocal usage
Same command CI runs.
🤖 Generated with Claude Code
Summary by CodeRabbit
Chores
Documentation