/policykit
Reference for the Claude Code skill policykit ships: how it triggers, how to install it, the workflow it runs, and the rules file that binds every session.

The package ships a Claude Code skill that authors a policy revision end to end: it decides material-change-vs-erratum, creates the dated revision directory with one MDX file per locale, sets the notice tier and the effective date, and validates. It is the writing a revision checklist, executed.
/policykit [policy slug or description of the change - omit to be asked]
It is user-invokable, so you can call it by name. It also triggers on its own when you ask for the work in plain language: "add a policy revision", "update the terms", "publish the privacy policy change", "fix a typo in a policy", or "when does the new DPA take effect?".
Install it
You need the package installed first (see getting started) - the skill and the
rules file ship inside it. Symlink the skill out of node_modules rather than copying it, so it
tracks the version of policykit you actually have:
mkdir -p .claude/skills
ln -s ../../node_modules/@daanvandenbergh/policykit/skills/policykit .claude/skills/policykit
Then add this line to your CLAUDE.md so the editing rules load into every session, not only the
ones that invoke the skill:
@node_modules/@daanvandenbergh/policykit/rules/policies.md
What it does
Eight steps, in order.
- Locate the policy and its config. It finds your
new Policy({ slug, dir, locales, defaultLocale? })instances - conventionally one module such assrc/content/policies.ts- and reads the target policy'sdir,localesanddefaultLocale. If you did not name a policy, it lists the configured slugs and asks. - Material change or erratum? An erratum is edited in place and the run stops after validation. A material change continues as a new revision.
- Pick the revision date. Today, zero-padded
YYYY-MM-DD. - Create the revision directory and write the text.
<dir>/<date>/with one<locale>.mdxper configured locale, matching^[a-z]{2}(?:-[A-Z]{2})?\.mdx$, each with a non-empty body - drafted to the legal minimum, never above it. - Write the frontmatter on the default locale's file only:
effectiveFrom,noticeandchangeSummary, plus an optionaltitle. Other locale files get an optionaltitleand nothing else. - Set
effectiveFrom. A real calendar day on or after the revision date. - Validate. It runs your own test suite, which covers
assertValid()/assertValidAll(), and fixes what throws until it is green - a fullnext buildexercises the same loader. Every grammar or frontmatter breach throws aPolicyValidationErrornaming the file and field. See validation. - Show the diff. The git diff is the review artifact: one new dated directory, or one in-place erratum edit, and nothing else touched. It reminds you that committed means published on the next deploy, and that policy history is never rewritten.
The judgement calls it makes for you
- Material vs erratum. Material means the meaning moved - a right, a price, a limit, an obligation, a data practice. If it has to ask, it is material.
- The notice tier.
none,notifyorreconsent, chosen from what the change does to the user, and recorded in frontmatter as the legal decision. Unsure means the stricter tier. - How much to promise. It drafts to the legal floor - the statutory period, right or disclosure, and no better one - so you are not left keeping a promise the law never asked for. Where the governing law or the customer class is unsettled, it asks rather than defaulting to the generous reading.
- One revision per day. If today's directory exists but has not deployed, the change folds into it. If it has deployed, the new revision is dated tomorrow.
- Fresh translations. Every locale is translated from the new source text, never copied forward from the previous revision.
- Supersession. If the new revision supersedes one still inside its notice window, it checks that the surviving obligations, and the stricter tier, move to the new revision.
Each of these is spelled out in full on writing a revision, with the layout grammar on policy directories.
The rules file
rules/policies.md is the other half of the contract. The skill reads it first and treats it as
binding - the steps are the workflow, the rules are the law. The @-import extends the same rules
to every agent session, including the ones that edit a policy without ever reaching for the skill.
Most of what it states is judgement no test can catch:
- A material change is a new dated directory, never an edit to a published one.
- A typo, format or link fix in a published file is an erratum: edit in place. If the fix changed what a clause means, it was never an erratum - revert and cut a revision.
- One revision per day; never amend a shipped revision.
- Promise the legal minimum and never more: the statutory bound, not a better one; no volunteered guarantees; no unbounded absolutes like "never" or "immediately". Removing an over-promise you already published is itself a material change, not a quiet in-place edit.
- Every locale of a new revision is translated fresh; a new locale starts at the revision that introduces it and never back-fills history.
noticeis the legal decision, recorded per revision, and the tier drives the UI: anonerevision is never announced by the banner and never queued, so if users should see it coming, it was nevernone. See notices and consent.- A revision that supersedes a still-pending one carries the surviving obligations itself.
effectiveFromhonours the notice window your own terms promise; the package only checks>= revision.changeSummarysays what changed and why the tier is right - evidence, never user copy.- Drafts never sit in the content directory. Use
drafts/or a branch. - Never rewrite git history over policy content.
What it will not do
- It never cuts a revision for an erratum. A fake revision flips your consent gates and re-prompts every user over a comma.
- It never puts anything but
<locale>.mdxfiles in a revision directory - no images, no notes. Work in progress that must be committed goes indrafts/at the policy root, never inside a revision directory and never as a dated directory. - It does not decide your notice window. That comes from your own published change-notice clause. Where the window is unclear, it asks you.
- It does not write you a more generous policy than the law requires. Anything above the statutory floor is an obligation you then have to meet, so it stays at the floor unless you tell it otherwise.