feat(family): the shape ledger judges against family ideas, across languages (milestone 463 step 5, #4991)
CI & Build / Python lint (push) Successful in 2s
CI & Build / Plugin hooks (push) Successful in 13s
CI & Build / TypeScript typecheck (push) Successful in 58s
CI & Build / integration (push) Successful in 1m26s
CI & Build / Python tests (push) Successful in 2m9s
CI & Build / Build & push image (push) Successful in 1m27s
CI & Build / Python lint (push) Successful in 2s
CI & Build / Plugin hooks (push) Successful in 13s
CI & Build / TypeScript typecheck (push) Successful in 58s
CI & Build / integration (push) Successful in 1m26s
CI & Build / Python tests (push) Successful in 2m9s
CI & Build / Build & push image (push) Successful in 1m27s
- classify_shapes takes idea_id: the shape is judged against the idea's reference in its language, or its first. - A shape classified against a canon idea's reference moves the project's adoption row (instance -> adopted, variant -> variant). Withdrawing the shapes that gave an answer returns it to unassessed. This runs on classify_shapes, the sweep, confirm_proposals and the coverage refresh. - assess and undo refuse an answer the shapes contradict. A conflict resolution re-judges the variant shapes on both sides. - The proposer's family arm offers a canon idea's reference on a shared platform, in any language. It proposes only when the reference is the top hit over every readable snippet and scores at least 0.70. The pairs this was measured on are recorded beside _FAMILY_FLOOR. The proposer is now v6. - The matrix cell shows the code that answers it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -280,6 +280,12 @@ async def assess_family_adoption(
|
||||
variant cancels it, owed again reopens it. The same answer given twice
|
||||
records nothing the second time.
|
||||
|
||||
When the project's code is in the shape ledger, prefer answering THERE:
|
||||
classify_shapes the shape against the idea (idea_id=…) as an instance or
|
||||
a variant, and this answer moves with it. An answer the shapes already
|
||||
give otherwise is refused — the two ledgers never disagree; reclassify
|
||||
the shapes if they are wrong.
|
||||
|
||||
Args:
|
||||
project_id: the project answering.
|
||||
idea_id: the canon idea.
|
||||
|
||||
@@ -37,10 +37,15 @@ async def classify_shapes(
|
||||
Args:
|
||||
project_id: The project whose ledger is being judged.
|
||||
classifications: Objects of {path, symbol, status, kind?, snippet_id?,
|
||||
reason?, reason_code?}. path+symbol name the shape exactly as
|
||||
idea_id?, reason?, reason_code?}. path+symbol name the shape exactly as
|
||||
list_shapes shows it; kind ("sym"/"css") narrows when one file
|
||||
defines both. snippet_id is required for canonical/instance/
|
||||
variant; reason is required for variant/exempt. reason_code is
|
||||
variant — or idea_id, a family idea: the shape is then judged
|
||||
against that idea's reference implementation in the shape's
|
||||
language, or its first reference when none is in that language
|
||||
(an idea is shared across languages: a Python shape can be an
|
||||
instance of an idea whose reference is Go). reason is required
|
||||
for variant/exempt. reason_code is
|
||||
an OPTIONAL index beside the prose (one of: scoped-css,
|
||||
one-off-handler, test-helper, convention-plumbing, pure-helper,
|
||||
generated, script, typed-record) so the ledger can be filtered
|
||||
@@ -60,11 +65,20 @@ async def classify_shapes(
|
||||
confirms it. Must be bound to the project. Omit it to judge only
|
||||
synced rows.
|
||||
|
||||
FAMILY CANON FOLLOWS. A shape judged against a canon family idea's
|
||||
reference IS the project's answer to that idea: an instance answers it
|
||||
`adopted`, a variant `variant` (with the shape's reason), and
|
||||
withdrawing the shapes that gave an answer returns it to `unassessed`.
|
||||
The adoption ledger is moved for you — `family` in the result lists the
|
||||
answers that moved — and assess_family_adoption refuses an answer the
|
||||
shapes contradict.
|
||||
|
||||
All-or-nothing: a structural error, a missing snippet target, an unbound
|
||||
repo, or no write access applies NOTHING. Returns {"classified": N,
|
||||
"unmatched": [...], "provisional": N?} — unmatched names shapes no live
|
||||
ledger row matches (the tree may have moved since you listed; pass `repo`
|
||||
for a shape you just wrote, or re-run the project's coverage refresh).
|
||||
"unmatched": [...], "provisional": N?, "family": [...]?} — unmatched names
|
||||
shapes no live ledger row matches (the tree may have moved since you
|
||||
listed; pass `repo` for a shape you just wrote, or re-run the project's
|
||||
coverage refresh).
|
||||
"""
|
||||
uid = current_user_id()
|
||||
return await shape_ledger_svc.classify_shapes(
|
||||
@@ -116,7 +130,10 @@ async def list_shapes(
|
||||
machine thinks are an instance of a snippet: `proposal` carries
|
||||
snippet_id, basis, score), "derive" (rows that repeat with NO
|
||||
canon: `proposal.group` names the family), or one basis
|
||||
(symbol/text/reference/signature/semantic).
|
||||
(symbol/text/reference/signature/semantic/family). "family" is
|
||||
a canon family idea's reference — another project's, often
|
||||
another language's — that the body means: the top match over
|
||||
every snippet you can read, on a platform the project shares.
|
||||
flag: the divergence readout (#2793) — "divergence": shapes new
|
||||
since the previous refresh in a directory where one canon
|
||||
dominates the judged siblings and NOT proposed as that canon
|
||||
@@ -145,7 +162,8 @@ async def list_shapes(
|
||||
THE FAST PATH through a big todo is the proposer's queue: every coverage
|
||||
refresh matches unclassified shapes against canon (strongest basis
|
||||
first: same symbol elsewhere → textual containment → body references
|
||||
the canon → signature resemblance → semantic) and attaches a
|
||||
the canon → signature resemblance → semantic, and a family idea's
|
||||
reference in any language) and attaches a
|
||||
`proposal` to each row it can speak for. Review `proposal="canon"` by
|
||||
snippet or directory, then confirm_shape_proposals the ones that hold —
|
||||
hundreds at a time — and classify_shapes the rest (variant/exempt, or
|
||||
@@ -214,9 +232,11 @@ async def classify_shapes_by_rule(
|
||||
revise a family you judged earlier).
|
||||
|
||||
One transaction: applies whole or not at all. Returns
|
||||
{"classified": N, "sample": ["path::symbol", ...]} (first 12, sorted)
|
||||
so you can see what the rule reached; N = 0 means the rule matched
|
||||
nothing live and unclassified — widen the pattern or refresh coverage.
|
||||
{"classified": N, "sample": ["path::symbol", ...], "family": [...]?}
|
||||
(sample: first 12, sorted) so you can see what the rule reached; N = 0
|
||||
means the rule matched nothing live and unclassified — widen the pattern
|
||||
or refresh coverage. As with classify_shapes, a family idea's reference
|
||||
judged here moves the project's answer to that idea (`family`).
|
||||
"""
|
||||
uid = current_user_id()
|
||||
try:
|
||||
@@ -317,12 +337,14 @@ async def confirm_shape_proposals(
|
||||
snippet_id (confirm one canon's whole queue after reading its
|
||||
`list_shapes(proposal="canon", ...)` page), path (a directory you
|
||||
audited), or basis (e.g. "symbol" and "reference" are near-certain;
|
||||
"semantic" deserves a look first) is required — a bare confirm-all is
|
||||
not a judgment. min_score trims a basis's tail.
|
||||
"semantic" and "family" deserve a look first) is required — a bare
|
||||
confirm-all is not a judgment. min_score trims a basis's tail.
|
||||
|
||||
Proposals you do NOT confirm are judged with classify_shapes (variant,
|
||||
exempt, or instance of a different snippet) — any judgment retires the
|
||||
proposal. Requires write access. Returns {"confirmed": N}.
|
||||
proposal. A confirmed family reference answers that idea `adopted` in
|
||||
the project (`family` lists the answers that moved). Requires write
|
||||
access. Returns {"confirmed": N, "family": [...]?}.
|
||||
"""
|
||||
uid = current_user_id()
|
||||
try:
|
||||
|
||||
Reference in New Issue
Block a user