Design the rulebook schema #40
Labels
No Label
P0
P1
P2
P3
afk-ready
hitl
next
ready-for-agent
review
semi
waiting
wayfinder:grilling
wayfinder:map
wayfinder:research
wayfinder:task
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: jared/cc-os#40
Loading…
Reference in New Issue
No description provided.
Delete Branch "%!s(<nil>)"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Map: #31
Question
Define the rulebook format: file location(s) in the plugin and per-project override; glob matching semantics and precedence (file over directory); fields per rule (lifetime, extract modifier, ignore-propagation flags, provenance/confirmed-by); how the scanner consumes it.
jared referenced this issue2026-07-14 17:28:17 +00:00
RESOLUTION: Rulebook schema locked.
Format & locations: JSON (stdlib both directions; per-rule
notefield substitutes for comments). Global rulebook atplugins/os-doc-hygiene/rulebook.json(resolved relative to plugin scripts, per #34). Per-project override at repo-root.dochygiene-rules.json— committed config, matching the.dochygiene-ignoreprecedent, deliberately NOT in gitignored.cc-os/. ⚠ ADR required for the repo-root-dotfile-vs-.cc-os/deviation (user-flagged; fold into #46's ADR set).Glob dialect: gitignore-style via stdlib
glob.translate(recursive=True, include_hidden=True)(Python ≥3.13), patterns repo-root-relative, real**; compiled once at load. Directory rules = patterns covering a subtree (#38 semantics).Precedence (two-axis, source first): project file-rule > project directory-rule > global file-rule > global directory-rule; ties broken by longest pattern, then last-defined. A project neutralizes a global rule by shadowing it with
lifetime: "keep"— no rule-removal mechanism; the merge is add-only.Per-rule fields:
max_age_daysvalues/defaults are #43's decision;propagate_ignoresemantics are #44's — the schema fixes only that the slots exist.Envelope:
{"schema_version": 1, "rules": [...]}for both files. Unmatched files get NO lifetime — they flow through existing signals unchanged and become :calibrate candidates (unmatched-means-unmanaged).Scanner consumption: new stdlib
rulebook.pyloader; a directory-rule match prunes the walk (files beneath never opened, one aggregate entry); a file-rule match attaches alifecyclesignal (rule ref + lifetime + served_when) consumed by the classifier as #37's new signal class.Validation: skip-and-warn per invalid/unconfirmed rule (a rule missing
confirmed_bynever acts, per #39, but doesn't take scanning down); hard-fail on unparseable JSON or unknownschema_version.RESOLUTION: Rulebook schema locked.
Format & locations: JSON (stdlib both directions; per-rule
notefield substitutes for comments). Global rulebook atplugins/os-doc-hygiene/rulebook.json(resolved relative to plugin scripts, per #34). Per-project override at repo-root.dochygiene-rules.json— committed config, matching the.dochygiene-ignoreprecedent, deliberately NOT in gitignored.cc-os/. ⚠ ADR required for the repo-root-dotfile-vs-.cc-os deviation (user-flagged; fold into #46's ADR set).Glob dialect: gitignore-style via stdlib
glob.translate(recursive=True, include_hidden=True)(Python ≥3.13), patterns repo-root-relative, real**; compiled once at load. Directory rules = patterns covering a subtree (#38 semantics).Precedence (two-axis, source first): project file-rule > project directory-rule > global file-rule > global directory-rule; ties broken by longest pattern, then last-defined. A project neutralizes a global rule by shadowing with
lifetime: "keep"— no rule-removal mechanism; merge is add-only.Per-rule fields:
max_age_daysvalues/defaults are #43's decision;propagate_ignoresemantics are #44's — schema fixes only that the slots exist.Envelope:
{"schema_version": 1, "rules": [...]}for both files. Unmatched files get NO lifetime — they flow through existing signals unchanged and become :calibrate candidates (unmatched-means-unmanaged).Scanner consumption: new stdlib
rulebook.pyloader; directory-rule match prunes the walk (files beneath never opened, one aggregate entry); file-rule match attaches alifecyclesignal (rule ref + lifetime + served_when) consumed by the classifier as #37's new signal class.Validation: skip-and-warn per invalid/unconfirmed rule (a rule missing
confirmed_bynever acts, per #39, but doesn't take scanning down); hard-fail on unparseable JSON or unknownschema_version.Schema amendment (from #44): the
propagate_ignorefield is dropped. #44 resolved that a lifecycle rule never writes into another tool's ignore surface (separation of concerns;.graphifyignoreownership stays with os-vault:onboard-project per ADR-017). The reserved slot is removed, not left empty. Everything else in this schema stands. #46 must assemble from schema-minus-propagate_ignore.