docs(6206): rulebook model comments state the design, not the history of the rulebook
The relation kinds say what each prevents without the rule-46 split story; the removed tier, subscriptions and suppressions are stated as what the model does not have, with the migration that dropped them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -92,15 +92,13 @@ class Rule(Base, TimestampMixin, SoftDeleteMixin):
|
||||
# WHEN this rule applies — the trigger, not the instruction. Required of
|
||||
# new rules at the service layer and nullable here, because rules written
|
||||
# before migration 0088 have none and a migration cannot invent one.
|
||||
# It carries three jobs at once (note 3026): it is the readable form of
|
||||
# the canon tag, the half of the document that makes a rule findable by
|
||||
# meaning, and — since milestone 394 removed the always-on tier — the ONLY
|
||||
# thing that decides whether a rule ever reaches a session at all. A rule
|
||||
# It carries three jobs at once: it is the readable form of the canon tag,
|
||||
# the half of the document that makes a rule findable by meaning, and —
|
||||
# with no always-on tier — the ONLY thing that decides whether a rule ever reaches a session at all. A rule
|
||||
# with no trigger is not a quiet rule, it is an unreachable one.
|
||||
when_to_apply: Mapped[str | None] = mapped_column(Text, nullable=True)
|
||||
# WHAT KIND of instruction this is. `tier` used to sit beside this and
|
||||
# carry delivery; milestone 394 removed it, so kind is now the only axis
|
||||
# on a rule and delivery belongs entirely to retrieval.
|
||||
# WHAT KIND of instruction this is — the only axis on a rule; delivery
|
||||
# belongs entirely to retrieval.
|
||||
# `rule` must be FOLLOWED: ignoring it breaks something or crosses a
|
||||
# boundary. `preference` is how this person wants work DONE: ignoring it
|
||||
# costs consistency, not correctness.
|
||||
@@ -116,7 +114,7 @@ class Rule(Base, TimestampMixin, SoftDeleteMixin):
|
||||
# trigger-dominated document, ownership-scoped search, the retrieval arms,
|
||||
# relations, and `rule_versions`, which is where its drift is recorded.
|
||||
# Defaults to `rule` so nothing changes force on upgrade.
|
||||
# CHECK ck_rules_kind (migration 0098, rule 36).
|
||||
# CHECK ck_rules_kind (migration 0098).
|
||||
kind: Mapped[str] = mapped_column(Text, default="rule", server_default="rule")
|
||||
why: Mapped[str | None] = mapped_column(Text, nullable=True)
|
||||
how_to_apply: Mapped[str | None] = mapped_column(Text, nullable=True)
|
||||
@@ -141,7 +139,7 @@ class Rule(Base, TimestampMixin, SoftDeleteMixin):
|
||||
DateTime(timezone=True), nullable=True
|
||||
)
|
||||
# The record that caused this rule — the edge notes and tasks already
|
||||
# have. Rule 46's `why` names note 2813 in prose; this is that link as a
|
||||
# have. A `why` can name its origin in prose; this is that link as a
|
||||
# field, so it survives a rewording of the paragraph.
|
||||
arose_from_id: Mapped[int | None] = mapped_column(
|
||||
BigInteger, ForeignKey("notes.id", ondelete="SET NULL"), nullable=True
|
||||
@@ -175,10 +173,9 @@ class Rule(Base, TimestampMixin, SoftDeleteMixin):
|
||||
}
|
||||
|
||||
|
||||
# Which global AREA a rule is about (milestone 307). Points at the canonical
|
||||
# catalog, NEVER at a project's `systems` row: a rule that spans projects
|
||||
# cannot be chained to one project's vocabulary. This is the edge three
|
||||
# projects were drawing by hand, as rule text copied into a System's charter.
|
||||
# Which global AREA a rule is about. Points at the canonical catalog, NEVER at
|
||||
# a project's `systems` row: a rule that spans projects cannot be chained to
|
||||
# one project's vocabulary.
|
||||
rule_systems = Table(
|
||||
"rule_systems",
|
||||
Base.metadata,
|
||||
@@ -188,7 +185,7 @@ rule_systems = Table(
|
||||
)
|
||||
|
||||
|
||||
# Which MOMENTS of work a rule arrives at (milestone 458). A rule mounted on a
|
||||
# Which MOMENTS of work a rule arrives at. A rule mounted on a
|
||||
# moment is delivered whenever that moment happens, by lookup and with no
|
||||
# score — the route for a rule that is about WHEN something is done rather
|
||||
# than what it is about, which semantic retrieval structurally misses. The
|
||||
@@ -204,17 +201,15 @@ rule_moments = Table(
|
||||
)
|
||||
|
||||
class RuleRelation(Base, CreatedAtMixin):
|
||||
"""A typed edge between two rules. Each kind exists because its ABSENCE
|
||||
forced a workaround somewhere in the operator's rulebook (note 3026).
|
||||
"""A typed edge between two rules. Each kind exists because without it a
|
||||
rulebook needs a workaround.
|
||||
|
||||
- ``co_surfaces`` — these fail together, so they must arrive together.
|
||||
Without it, the only way to guarantee that was to merge them into one
|
||||
row, which is what happened to rule 46: split into 144, folded back the
|
||||
same day because "either rule could surface without the other."
|
||||
Without it, the only way to guarantee that is to merge them into one
|
||||
row, because either rule could surface without the other.
|
||||
Symmetric in meaning; stored once and read both ways.
|
||||
- ``overrides`` — this rule supersedes that one for its scope. Only
|
||||
*suppression* existed, so an override had to be written as a parallel
|
||||
rule that then drifts from its parent.
|
||||
- ``overrides`` — this rule supersedes that one for its scope. Without
|
||||
it, an override is a parallel rule that drifts from its parent.
|
||||
- ``elaborates`` — this rule adds local specifics to that one; surfacing
|
||||
the parent brings the addendum with it.
|
||||
|
||||
@@ -232,7 +227,7 @@ class RuleRelation(Base, CreatedAtMixin):
|
||||
to_rule_id: Mapped[int] = mapped_column(
|
||||
BigInteger, ForeignKey("rules.id", ondelete="CASCADE"), index=True
|
||||
)
|
||||
# CHECK ck_rule_relations_kind (migration 0088, rule 36).
|
||||
# CHECK ck_rule_relations_kind (migration 0088).
|
||||
kind: Mapped[str] = mapped_column(Text)
|
||||
note: Mapped[str | None] = mapped_column(Text, nullable=True)
|
||||
|
||||
@@ -251,10 +246,8 @@ class RuleRelation(Base, CreatedAtMixin):
|
||||
}
|
||||
|
||||
|
||||
# `project_rulebook_subscriptions`, `project_rule_suppressions` and
|
||||
# `project_topic_suppressions` lived here until milestone 414 (migration 0101).
|
||||
# A rule's home is its scope now: a rule in a rulebook topic is global, a rule
|
||||
# on a project applies to that project, and retrieval reads that directly. A
|
||||
# subscription had stopped changing anything a session received, and a
|
||||
# suppression muted rules from a subscription. A project that departs from a
|
||||
# global rule writes a project rule with an `overrides` relation instead.
|
||||
# A rule's home is its scope: a rule in a rulebook topic is global, a rule on
|
||||
# a project applies to that project, and retrieval reads that directly. There
|
||||
# are no per-project subscriptions or suppressions (migration 0101 dropped
|
||||
# those tables); a project that departs from a global rule writes a project
|
||||
# rule with an `overrides` relation.
|
||||
|
||||
Reference in New Issue
Block a user