docs(6206): code_shape model comments drop record and milestone citations

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-21 20:37:22 -04:00
co-authored by Claude Opus 5.5
parent edf725687a
commit a01f5492bc
+21 -22
View File
@@ -15,9 +15,9 @@ from sqlalchemy.orm import Mapped, mapped_column
from scribe.models import Base from scribe.models import Base
from scribe.models.base import TimestampMixin, iso from scribe.models.base import TimestampMixin, iso
# The classification vocabulary (note 2786). `unclassified` is the default and # The classification vocabulary. `unclassified` is the default and
# THE todo state; every other status is a judgment, stamped with who made it — # THE todo state; every other status is a judgment, stamped with who made it —
# except `scoped` (#2869): the coverage sync's mechanical stamp on shapes that # except `scoped`: the coverage sync's mechanical stamp on shapes that
# are one-offs BY CONSTRUCTION (a Vue component's scoped <style> rules and its # are one-offs BY CONSTRUCTION (a Vue component's scoped <style> rules and its
# <script setup> functions — unreachable from any other file). Scoped rows are # <script setup> functions — unreachable from any other file). Scoped rows are
# accounted for without a human judging them, so `exempt` keeps meaning "a # accounted for without a human judging them, so `exempt` keeps meaning "a
@@ -26,11 +26,11 @@ from scribe.models.base import TimestampMixin, iso
SHAPE_STATUSES = ("canonical", "instance", "variant", "exempt", "scoped", "unclassified") SHAPE_STATUSES = ("canonical", "instance", "variant", "exempt", "scoped", "unclassified")
SHAPE_CLASSIFIERS = ("agent", "audit", "hook", "mechanical", "import") SHAPE_CLASSIFIERS = ("agent", "audit", "hook", "mechanical", "import")
# The reason catalogue (#2874): an OPTIONAL code beside the prose reason on # The reason catalogue: an OPTIONAL code beside the prose reason on
# variant/exempt rows, so the ledger can be filtered and aggregated by kind # variant/exempt rows, so the ledger can be filtered and aggregated by kind
# of one-off. The prose remains the record; the code is the index. # of one-off. The prose remains the record; the code is the index.
REASON_CODES = ( REASON_CODES = (
"scoped-css", # a scoped rule styling one element (pre-#2869 rows) "scoped-css", # a scoped rule styling one element (rows judged before `scoped`)
"one-off-handler", # a view/component handler or loader, one per surface "one-off-handler", # a view/component handler or loader, one per surface
"test-helper", # a test module's stub, driver or fixture data "test-helper", # a test module's stub, driver or fixture data
"convention-plumbing", # registration, wiring, app factory — one of each "convention-plumbing", # registration, wiring, app factory — one of each
@@ -40,17 +40,16 @@ REASON_CODES = (
"typed-record", # a NamedTuple / dataclass / error class — one each "typed-record", # a NamedTuple / dataclass / error class — one each
) )
# How the mechanical proposer (#2792) arrived at a proposal, strongest first. # How the mechanical proposer arrived at a proposal, strongest first.
# `derive` is the odd one out: not "this is an instance of #N" but "this # `derive` is the odd one out: not "this is an instance of #N" but "this
# shape repeats with NO canon — derive one first" (note 2786's derive-first # shape repeats with NO canon — derive one first", so it carries a group key instead of a snippet.
# rule), so it carries a group key instead of a snippet.
PROPOSAL_BASES = ("symbol", "text", "reference", "signature", "semantic", "derive") PROPOSAL_BASES = ("symbol", "text", "reference", "signature", "semantic", "derive")
class CodeShape(Base, TimestampMixin): class CodeShape(Base, TimestampMixin):
"""One extracted code shape and its classification against canon (#2787). """One extracted code shape and its classification against canon.
The accounting half of the pattern system (governing note 2786): the The accounting half of the pattern system: the
snippet library records CANON (small); this ledger accounts for EVERY snippet library records CANON (small); this ledger accounts for EVERY
shape the coverage extractor finds in a bound repo (total). A row's shape the coverage extractor finds in a bound repo (total). A row's
status says how the shape relates to canon — it IS a snippet's reference status says how the shape relates to canon — it IS a snippet's reference
@@ -62,15 +61,15 @@ class CodeShape(Base, TimestampMixin):
Identity is (project, repo_key, path, symbol, kind) — kind is part of it Identity is (project, repo_key, path, symbol, kind) — kind is part of it
because one file can define `.foo` (css) and `foo` (sym) as distinct because one file can define `.foo` (css) and `foo` (sym) as distinct
shapes. A rename therefore reads as vanish + new row: accepted for v1, shapes. A rename therefore reads as vanish + new row: accepted,
because chasing renames needs content identity the extractor doesn't because chasing renames needs content identity the extractor doesn't
have. `vanished_at` keeps the history instead of deleting it. have. `vanished_at` keeps the history instead of deleting it.
snippet_id is SET NULL on snippet deletion: the classification's target snippet_id is SET NULL on snippet deletion: the classification's target
is gone but the judgment happened; the sync pass (step 2) re-files such is gone but the judgment happened; the sync pass re-files such
rows as unclassified so they rejoin the todo instead of dangling. rows as unclassified so they rejoin the todo instead of dangling.
`signature` / `body_sha` (#2792) are the shape's content fingerprint — `signature` / `body_sha` are the shape's content fingerprint —
its definition line and a whitespace/comment-insensitive hash of its its definition line and a whitespace/comment-insensitive hash of its
block — refreshed by every sync. They are what the mechanical proposer block — refreshed by every sync. They are what the mechanical proposer
matches on and what a later drift recheck compares against; the ledger matches on and what a later drift recheck compares against; the ledger
@@ -80,7 +79,7 @@ class CodeShape(Base, TimestampMixin):
when a later sync sees the body change under an instance/variant, the when a later sync sees the body change under an instance/variant, the
row is flagged `recheck_at` (the judgment stands, it just asks to be row is flagged `recheck_at` (the judgment stands, it just asks to be
confirmed again) and a `drifted` event is written. `diverges_from` confirmed again) and a `drifted` event is written. `diverges_from`
(#2793) is the button-B flag: a shape new since the previous refresh, in is the button-B flag: a shape new since the previous refresh, in
a directory+kind where one canon dominates the judged siblings, that the a directory+kind where one canon dominates the judged siblings, that the
proposer did not match to that canon — "button B appeared where button proposer did not match to that canon — "button B appeared where button
A is canon: divergence or variant? classify it." Both clear on judgment. A is canon: divergence or variant? classify it." Both clear on judgment.
@@ -119,7 +118,7 @@ class CodeShape(Base, TimestampMixin):
BigInteger, ForeignKey("notes.id", ondelete="SET NULL"), nullable=True BigInteger, ForeignKey("notes.id", ondelete="SET NULL"), nullable=True
) )
reason: Mapped[str | None] = mapped_column(Text, nullable=True) reason: Mapped[str | None] = mapped_column(Text, nullable=True)
reason_code: Mapped[str | None] = mapped_column(Text, nullable=True) # REASON_CODES (#2874) reason_code: Mapped[str | None] = mapped_column(Text, nullable=True) # REASON_CODES
classified_by: Mapped[str | None] = mapped_column(Text, nullable=True) classified_by: Mapped[str | None] = mapped_column(Text, nullable=True)
classified_at: Mapped[datetime | None] = mapped_column( classified_at: Mapped[datetime | None] = mapped_column(
DateTime(timezone=True), nullable=True DateTime(timezone=True), nullable=True
@@ -190,7 +189,7 @@ class CodeShape(Base, TimestampMixin):
} }
def to_compact(self) -> dict: def to_compact(self) -> dict:
"""The row as an audit reads it (#2868): identity, standing, the """The row as an audit reads it: identity, standing, the
definition line and the proposer's word — none of the bookkeeping definition line and the proposer's word — none of the bookkeeping
(commits, shas, timestamps). A 500-row page of these fits the tool (commits, shas, timestamps). A 500-row page of these fits the tool
budget; a page of to_dict() does not.""" budget; a page of to_dict() does not."""
@@ -217,16 +216,16 @@ class CodeShape(Base, TimestampMixin):
return out return out
# How a uses edge was established (#2870): who/what said "this shape calls # How a uses edge was established: who/what said "this shape calls
# that canon". `reference` is the proposer's mechanical by-name hit on the # that canon". `reference` is the proposer's mechanical by-name hit on the
# body (language-gated, #2871); `hook` is write-path evidence (pulled the # body (language-gated); `hook` is write-path evidence (pulled the
# snippet, then wrote code naming its symbol); agent/audit/import are # snippet, then wrote code naming its symbol); agent/audit/import are
# judgments carried on classify_shapes(..., uses=[...]). # judgments carried on classify_shapes(..., uses=[...]).
USE_BASES = ("reference", "hook", "agent", "audit", "import") USE_BASES = ("reference", "hook", "agent", "audit", "import")
class CodeShapeUse(Base): class CodeShapeUse(Base):
"""One consumption edge: shape → canonical snippet it calls/uses (#2870). """One consumption edge: shape → canonical snippet it calls/uses.
Conformance (CodeShape.status/snippet_id) answers "what shape is this"; Conformance (CodeShape.status/snippet_id) answers "what shape is this";
this table answers "what does it use" — many per shape. A service function this table answers "what does it use" — many per shape. A service function
@@ -265,7 +264,7 @@ class CodeShapeUse(Base):
} }
# How a consumer edge was established (milestone 302). `template` is the # How a consumer edge was established. `template` is the
# sync's mechanical read of a file's markup (class= / :class= / className=); # sync's mechanical read of a file's markup (class= / :class= / className=);
# the vocabulary is a list so a later basis (a stylesheet `@apply`, a script's # the vocabulary is a list so a later basis (a stylesheet `@apply`, a script's
# classList) has a name without a schema change. # classList) has a name without a schema change.
@@ -274,8 +273,8 @@ CONSUMER_BASES = ("template",)
class CodeShapeConsumer(Base): class CodeShapeConsumer(Base):
"""One consumer edge: CSS shape → the file whose markup names its class """One consumer edge: CSS shape → the file whose markup names its class
(milestone 302; note 2917 — CSS is watched by name, by recipe, by token (CSS is watched by name, by recipe, by token and by WHAT USES IT). The
and by WHAT USES IT). The analogue of CodeShapeUse for styling: `uses` analogue of CodeShapeUse for styling: `uses`
says what a shape calls, this says who renders a class. Rows, not prose, says what a shape calls, this says who renders a class. Rows, not prose,
so "is this recipe shared or scoped?" is a count, not a guess. so "is this recipe shared or scoped?" is a count, not a guess.
@@ -311,7 +310,7 @@ class CodeShapeConsumer(Base):
} }
# What a shape's history records (#2793). Not "appeared" — first_seen and # What a shape's history records. Not "appeared" — first_seen and
# created_at already say that on the row; history is for what CHANGED: # created_at already say that on the row; history is for what CHANGED:
SHAPE_EVENTS = ("classified", "vanished", "reappeared", "drifted") SHAPE_EVENTS = ("classified", "vanished", "reappeared", "drifted")