Skip to content

Upgrading to edikt v0.7.0

This is the real upgrade path. diktahq/edikt's public releases stop at v0.4.5 — v0.5.x was cut but never released, and v0.6.0 has a git tag but no published release. No public project has ever upgraded through those in isolation. If you have an installed project today, it's on v0.4.x, and /edikt:upgrade carries it to v0.7.0 in one run — the sentinel-to-sidecar migration (originally shipped as v0.6.0's headline change) followed by this page's schema and enforcement changes, back to back, in a single pass.

v0.7.0 also changes what happens the next time you write to a file .claude/rules/ governs — not because any of your rules changed, but because edikt now enforces them the way they were actually written. Read Before you upgrade below before running /edikt:upgrade; the mechanical migration step is smaller than the behavior change.

TL;DR

bash
/edikt:upgrade

The slash command runs the sentinel-to-sidecar migration (the real case for essentially every existing install, since none started past v0.4.x), the required sidecar schema v1→v2 upgrade, and recompiles. Read the warning below first — nothing about /edikt:upgrade itself asks you to confirm the enforcement change, because it isn't a migration step; it's the corpus you already have, graded correctly for the first time.

Before you upgrade

Two independent fixes land together, and their combined effect is the thing to plan for.

  1. Grade derivation now reads actual obligation strength, not a keyword list. Before this release, a directive only graded must if its text literally contained "MUST NOT", "NEVER", or "NO EXCEPTIONS". A bare, unconditional "MUST" — how most directives in a typical corpus are actually phrased — fell through to advisory regardless of intent. That's fixed: grading now classifies the real RFC-2119 modal force (MUST / SHALL / REQUIRED, either polarity). Measured directly against this project's own compiled directive-index.yaml before shipping: 404 of the 420 directives previously graded advisory move to must.
  2. The deny channel now actually denies. Independently of the grading fix, a must-grade write that should have been refused was instead allowed onto disk, with only the assistant's turn killed afterward — measured at 14 of 14 sampled denied writes still landing. That's fixed: a must-grade write is now refused before it happens, citing the specific rule.

Combined, on an unchanged corpus: roughly 400 rules that were previously informational-only become enforced, write-blocking rules. If your team writes ADRs and invariants with plain, unconditional MUST language — the common style, and arguably the correct one — expect edits that used to go through silently to start getting refused, correctly, the moment you upgrade.

This is not a regression to work around. A refusal after upgrading means a rule you already wrote, as must-strength language, is now doing what you wrote it to do. If a specific refusal looks wrong for what you actually meant:

  • Reword the directive to genuinely conditional language (SHOULD, MAY, or a qualified MUST with a stated exception) if the rule was never meant to be absolute.
  • Don't treat this as a bug to route around by disabling the gate — the fix is in the directive's wording, which is exactly the lever ADR-064 hands back to you: grade now follows what you actually wrote, so a directive that's too strict grades that way because it reads that way.

Do a quick pass over your own ADRs and invariants before upgrading if you want to anticipate which directives will flip, rather than discover it live: any bare "MUST"/"SHALL"/"REQUIRED" statement, not just ones containing "MUST NOT"/"NEVER", is a candidate.

What changed

Areav0.6.0v0.7.0
Grade derivationThree-word negative-marker match (MUST NOT/NEVER/NO EXCEPTIONS)Full RFC-2119 modal-force classification (MUST/SHALL/REQUIRED, either polarity)
Deny-channel effectcontinue:false — write already landed, turn killed after the factpermissionDecision: "deny" — write refused before it happens
Sidecar schemav1 — one source_excerpt anchor per directivev2 — source_excerpts[], one to many anchors per directive
Compile's Phase B gateRuns on any schema-valid sidecarRefuses outright — "Run bin/edikt migrate to-v2 first" — while any v1-shaped sidecar exists

What /edikt:upgrade does

In order:

  1. Runs the sentinel-to-sidecar migration if any legacy in-body sentinel remains — the real case for nearly every existing project, since v0.6.0 was never a standalone public step (see Sidecar Migration for the full per-artifact mechanics of this step).
  2. Runs the required schema upgradeedikt migrate to-v2 — converting every v1-shaped sidecar to the v2 multi-anchor shape. This step is not optional: /edikt:gov:compile's Phase B dispatch gate refuses to run at all while any v1-shaped sidecar exists in the corpus.
  3. Recompiles (/edikt:gov:compile), which re-derives every directive's grade under the fixed rule from step 1 above — this is where the 404-of-420 reclassification actually happens for your project.
  4. Reports the result. Run /edikt:gov:grade-compile afterward if you want a quality score on the freshly re-extracted corpus — not required, but the tool exists and a fresh migration is exactly when it's most useful.

If you're scripting the migration directly rather than going through the slash command, run both migration steps explicitly — edikt migrate sidecars --apply alone leaves any pre-existing sidecar in its old v1 shape:

bash
edikt migrate sidecars --apply   # only if migrating from pre-v0.6.0; skip if already on sidecars
edikt migrate to-v2              # required regardless of starting version
/edikt:gov:compile               # re-derives grades under the fixed rule

After the upgrade

  • [ ] /edikt:doctor — should report sidecars at schema v2 and no pending migration.
  • [ ] Skim directive-index.yaml (or /edikt:gov:score's output) for directives that moved from advisory to must and confirm each one is intentionally absolute.
  • [ ] If a write gets refused that shouldn't be, reword the underlying directive — don't bypass the gate.
  • [ ] Commit the recompiled .claude/rules/ and any sidecar schema changes as one commit.

Rollback

edikt rollback reverts the launcher payload only. Neither the schema-v2 migration nor the grade reclassification is reversed by rollback — both are structural/derived changes, the same category the sentinel-to-sidecar migration is documented as permanent (rollback mechanics). If you need to go back further than one payload generation, use edikt use <version> — but your sidecars stay v2-shaped and your directives stay correctly graded regardless of which payload version is active.

Released under the Elastic License 2.0. Free to use, not for resale.