From policystack
Audits a policystack.ts config by running validation, explaining each issue code, and proposing minimal fixes until clean. Use when PolicyStack config has validation errors or warnings.
How this skill is triggered — by the user, by Claude, or both
Slash command
/policystack:policystack-auditThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
<!-- Generated by @policystack/sdk renderSkillPack() — do not edit by hand. Run `vp run gen`. -->
Close the validate → explain → fix → re-validate loop on a PolicyStack config.
npx @policystack/cli@latest validate --json
--json writes exactly one object to stdout and nothing else:
type ValidateResult = {
ok: boolean; // false ⟺ exit code 1
config: string; // resolved config path
issues: { code: string; level: "error" | "warning"; message: string }[];
errorCount: number;
warningCount: number;
loadError: string | null; // set instead of issues when the file won't load
};
Branch on the exit code (or ok). loadError (missing file, TS syntax
error, no default export) is always ok: false and means fix the load
error first — there are no issues to triage yet. Pass a path or
--cwd if the config is not at the default location.
level is what validate() emits; the @policystack/vite plugin may
promote/suppress downstream, but errors block a valid config. Every code and
its durable meaning (the frozen 1.0 diagnostic surface — §6):
automated-decision-making — warning — Under GDPR/UK-GDPR automatedDecisionMaking is not declared (Art. 13(2)(f) / Art. 22) — set [] for none or list each activity.children-under-age-invalid — error — children.underAge must be a positive number.company-address-required — error — company.address is required.company-contact-phone-recommended — warning — With a California (us-ca) jurisdiction, company.contact.phone is absent — CCPA §1798.130(a)(1) expects a toll-free number unless you operate exclusively online.company-contact-required — error — company.contact.email is required.company-dpo-undeclared — warning — Under GDPR/UK-GDPR company.dpo is not declared (Art. 13(1)(b)) — set it, or { required: false } to declare none.company-legal-name-required — error — company.legalName is required.company-name-required — error — company.name is required.consent-banner-required — warning — A cookie category is consent-gated but consentMechanism.hasBanner is false — a banner is needed to collect affirmative consent.consent-mechanism-undeclared — warning — No enabled cookie category is consent-gated, so no consent mechanism is generated (correct for strictly-necessary cookies only).consent-preference-panel-required — warning — consentMechanism.canWithdraw is true but hasPreferencePanel is false — withdrawal has no preference panel in the wired runtime.consent-withdrawal-required — warning — Under GDPR/UK-GDPR users must be able to withdraw cookie consent — set consentMechanism.canWithdraw.cookie-lawful-basis-missing — error — An enabled cookie category is missing its Article 6 lawfulBasis in cookies.context.cookies-empty — error — No cookie category is enabled in cookies.used.data-collected-empty — warning — data.collected has no entries — the privacy policy will state that no personal data is collected.data-context-missing — error — A collected category has no matching data.context entry (purpose, lawful basis, retention, provision).data-context-orphan — error — A data.context entry has no matching category in data.collected.data-missing — error — data is required when a privacy policy is emitted — use an empty data.collected for a site that collects nothing.data-purpose-empty — error — A data.context purpose is present but blank.data-purpose-missing — error — A data.context entry is missing its processing purpose (GDPR Art. 13(1)(c)).effective-date-required — error — effectiveDate is required.jurisdiction-generic-policy-text — warning — A declared jurisdiction is supported only at the "equivalent" tier (posture-correct + parent text), not hand-authored "specific" text.jurisdiction-unknown — error — A declared jurisdiction code is not a recognised JurisdictionId.jurisdictions-required — error — jurisdictions must list at least one jurisdiction id.lawful-basis-incomplete — error — Under GDPR/UK-GDPR a collected category is missing its Article 6 lawfulBasis (Art. 13(1)(c)).locale-unknown — error — locale is not one of the supported LOCALES.policy-cookie-empty — error — policies includes "cookie" but no cookies block is set.policy-empty — error — The config produces no policy — add data-handling fields (data, children) or a cookies block.retention-incomplete — error — A collected category is missing a retention period.statutory-contractual-obligation — error — Under GDPR/UK-GDPR a category is missing the Art. 13(2)(e) provision (statutory / contractual / contract-prerequisite / voluntary) or its consequences.For each issue, change only what the code requires in policystack.ts — do
not restyle or expand the config. errors must be resolved; warnings
should be resolved or consciously accepted (e.g. data-collected-empty is
correct for a brochure site). Never invent compliance facts (a lawful basis, a
DPO) — surface the decision to the user. Many data/cookie issues are better
fixed at the source with policystack-instrument than hand-written.
Re-run step 1. Repeat until ok: true (exit 0). Report the remaining
accepted warnings, if any.
npx claudepluginhub jamiedavenport/policystack --plugin policystackDetects gaps between privacy policy and actual data practices. Sweeps saved PIAs and DPAs to find policy drift, or answers queries about proposed new practices.
Audits Next.js projects for RGPD compliance by scanning code, env vars, and dependencies to detect third-party data processors and compare with a privacy policy registry.
Scaffolds PolicyStack in a project: runs the @policystack/cli installer and wires the single <PolicyStack> provider for privacy policy and consent banner.