feat(ledger): reason codes, case-insensitive repo filter, next action on the coverage line (#2874, milestone 294)
CI & Build / Python lint (push) Successful in 4s
CI & Build / Plugin hooks (push) Successful in 9s
CI & Build / integration (push) Failing after 25s
CI & Build / TypeScript typecheck (push) Canceled after 32s
CI & Build / Python tests (push) Canceled after 31s
CI & Build / Build & push image (push) Canceled after 0s

- code_shapes.reason_code (migration 0083): an optional code from a fixed
  catalogue (scoped-css, one-off-handler, test-helper, convention-plumbing,
  pure-helper, generated, script, typed-record) beside the prose reason, so
  the ledger can be filtered/aggregated by kind of one-off; validated in
  classify_shapes and classify_shapes_by_rule; on to_dict/to_compact.
- Snippet location lookups match repo case-insensitively in both dialects
  (location_matches / location_jsonpath via like_regex flag "i") — "Scribe"
  vs "FabledScribe" vs "fabledscribe" recorded free-form hid half the canon
  from list_snippets(repo=, path=).
- coverage line names the next action: "top canon #N ×k" (biggest proposal
  queue) and "top copy <label> ×files" (widest body-identical group).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-21 15:14:34 -04:00
co-authored by Claude Fable 5
parent d01201539b
commit 1a8e5787e8
9 changed files with 123 additions and 11 deletions
+10
View File
@@ -16,6 +16,7 @@ endorsed, so a one-off direct share has to be searched for rather than arriving
in your ambient lists.
"""
import json
import re
import logging
from sqlalchemy import and_, func, or_, select
@@ -76,6 +77,10 @@ def location_matches(data: dict | None, parts: dict[str, str]) -> bool:
if all(
_path_matches((loc.get(key) or "").strip(), want)
if key == "path"
# Repo names are recorded free-form ("Scribe" / "FabledScribe" /
# "fabledscribe") — case is never the distinguishing thing (#2874).
else (loc.get(key) or "").strip().lower() == want.lower()
if key == "repo"
else (loc.get(key) or "").strip() == want
for key, want in parts.items()
):
@@ -99,6 +104,11 @@ def location_jsonpath(parts: dict[str, str]) -> str:
if key == "path":
prefix = json.dumps(want.rstrip("/") + "/")
filters.append(f"(@.path == {literal} || @.path starts with {prefix})")
elif key == "repo":
# Case-insensitive, anchored, regex-escaped (#2874) — mirrors the
# Python dialect's .lower() compare.
pattern = json.dumps("^" + re.escape(want) + "$")
filters.append(f'(@.repo like_regex {pattern} flag "i")')
else:
filters.append(f"@.{key} == {literal}")
return f"$.locations[*] ? ({' && '.join(filters)})"