Help us improve
Share bugs, ideas, or general feedback.
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.
npx claudepluginhub jamiedavenport/policystack --plugin policystackHow 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`. -->
Detects gaps between privacy policy and actual data practices. Sweeps saved PIAs and DPAs to find policy drift, or answers queries about proposed new practices.
Runs Maestro-style audits for GDPR/CCPA compliance, cookie consent, data handling practices, and licensing. Reports findings with severity levels and remediation options.
Scaffolds PolicyStack in a project: runs the @policystack/cli installer and wires the single <PolicyStack> provider for privacy policy and consent banner.
Share bugs, ideas, or general feedback.
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.