Document the rule-pack authoring process - #6
Merged
Conversation
rulepacks/ and starters/ were the only directories without a README, while being the two the top-level README names as the largest external contribution surfaces. Four packs were added in one day by following the existing packs as templates, which worked for the auto-discovered wiring and failed for everything else — so the guide is organized around that split rather than around file formats. The load-bearing section is "Most wiring is automatic. Three things are not": demo verdict phrasing (fails a test, but in demo/, which pack authors do not expect to touch, and boolean decisions pass without it), golden-corpus coverage (expected.yaml catches breakage; only the corpus catches drift, so a pack without a generator template reports "0 of N decisions flip" forever), and extractor pinning for scripted confidences (no test warns at all — found by looking at the running demo). All three were missed by every track today. Also records the constraints that actually bit, verified against the kernel rather than recalled: one entity per entityType, the same-priority disjointness proof and the fact that _equality_guards matches only quoted string literals so boolean guards do not count, and the IR's absence of calendar arithmetic with tila-rescission's MODELING BOUNDARY as the worked example of documenting a limit instead of approximating past it. Plus the honesty conventions — real citations or TODO(verify), never invented statutory history, labelled scripted values, and fail-safe defaults whose asymmetry is argued in the pack. starters/README.md covers the starter layout and shared tooling and points here for the full path. Partially fulfils the v1.0 roadmap item "Rule-pack authoring guide and contribution pipeline". All referenced paths and commands verified to resolve. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Rule-change impact analysis0 of 251 decisions flip; 0 reasoning-only changes (251 golden cases analyzed) No decisions flip under this change. Reasoning-only changes: 0 (same decision, different rules fired or defeated sets) |
kjpatel
added a commit
that referenced
this pull request
Jul 30, 2026
The authoring guide (rulepacks/README.md, #6) shipped early because four packs were authored in one day and the process showed what to write down. The same exercise exposed two pipeline gaps, now filed under the v1.0 item so they don't evaporate: - Decision phrasing as pack data: non-boolean decisions require a _determination edit in demo/app.py before their verdicts render, which means a complete pack contribution currently touches a core file — the one thing the contribution model promises pack authors never do. Proposed fix is an optional per-decision phrasing block in pack.yaml, consumed generically: wording stays server-side, edges decouple fully. - A rule-id naming convention: the six packs mix pack-prefix-first, jurisdiction-first, and function-first ids, each inherited from a different aspect of the earliest packs' precedent. Rule ids are audit-facing (receipts, reports, defeat chains), so the convention belongs in the guide before pack seven exists. Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
kjpatel
added a commit
that referenced
this pull request
Jul 31, 2026
The changelog said twenty-one and the v0.4.0 release notes said twenty-three; the actual count between the tags is twenty-five, #6 through #30. Both numbers were guesses from PR numbers rather than counts of the commit range, and they disagreed with each other, which is how the error surfaced. `git log v0.3.0..v0.4.0 --oneline | grep -cE "\(#[0-9]+\)"` is the number. It is higher than a count of "M4 work" would suggest because v0.3.0 was tagged retroactively at #5, so the range legitimately includes the roadmap restructure, the authoring guide, and the corpus-coverage work that preceded the milestone proper. The published release notes are corrected to match. Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Documentation only. Adds
rulepacks/README.mdandstarters/README.md— the only two directories that had no README, while being the two the top-level README names as the largest external contribution surfaces.Why it's organized this way
Four rule packs were added in a single day, each by following the existing packs as templates. That experiment produced unusually clean evidence about what a guide needs to say: the auto-discovered wiring, every author got right. Everything requiring explicit registration, every author missed. So the guide is organized around that split rather than around file formats.
The load-bearing section is "Most wiring is automatic. Three things are not":
demo/, which pack authors have no reason to touch, and boolean decisions pass via the Yes/No fallback while code-, date-, and money-valued decisions leak a raw CURIE into the UI.expected.yamlcatches breakage; only the corpus catches drift. Impact analysis runs over the corpus, so a pack without a generator template reports "0 of N decisions flip" forever. This is a live gap for four of six packs (tracked as M4's first item in Roadmap: M3 complete; reorder M4, split out M5, defer commercial adapter to v1.1 #5).Constraints, verified rather than recalled
Each was checked against the kernel before writing it down. The one worth calling out:
_equality_guardsinkernel/duly_kernel/ir.pymatches onlyvar == "quoted string", so boolean guards do not satisfy the same-priority disjointness proof — two rules distinguished solely byx == true/x == falseneed an explicitoverrideseven though they look disjoint to a human. One of today's authors hit this and designed around it; nothing recorded why until now.Also documented: one entity per
entityTypeper case and its consequence for per-document decisions; the IR's absence of calendar arithmetic, withtila-rescission'sMODELING BOUNDARYheader as the worked example of documenting a limit instead of approximating past it; and that changing a pack moves receipts, so expect the impact comment.Honesty conventions
Written down because they are the value proposition, not style: real citations or an explicit
TODO(verify)naming what wasn't confirmed; scope comments; never invented statutory history (notarization-ron-us-statesis built entirely on real state authorization dates, and anything synthetic is markedDEMO-SYNTHETIC); labelled scripted values; and fail-safe defaults whose asymmetry is argued in the pack —esign-closing-packageon why unknown document types route to wet ink,notarization-ron-us-stateson why an unauthorized state is a decision rather than an abstention.Partially fulfils the v1.0 roadmap item "Rule-pack authoring guide and contribution pipeline." Every referenced path and command was verified to resolve.
🤖 Generated with Claude Code