generated from coulomb/repo-seed
Add renormalization rule guide
This commit is contained in:
@@ -178,6 +178,38 @@ class ConsistencyReport:
|
||||
return [i for i in self.issues if i.severity == "INFO"]
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class RenormalizationRule:
|
||||
check_id: str
|
||||
invariant: str
|
||||
detection: str
|
||||
repair: str
|
||||
test_anchor: str
|
||||
|
||||
|
||||
RENORMALIZATION_RULES: tuple[RenormalizationRule, ...] = (
|
||||
RenormalizationRule(
|
||||
check_id="C-23",
|
||||
invariant="Planning-state workplans cannot contain active task work.",
|
||||
detection=(
|
||||
"Workplan status is proposed, ready, or backlog while a linked "
|
||||
"task is in_progress or blocked."
|
||||
),
|
||||
repair="Patch the DB workstream and workplan frontmatter to status=active.",
|
||||
test_anchor="tests/test_consistency_check.py::TestLifecycleRenormalization",
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
RENORMALIZATION_NEXT_GUARD_CHECKLIST: tuple[str, ...] = (
|
||||
"Name the invariant and assign the next C-id.",
|
||||
"Add rule metadata to RENORMALIZATION_RULES.",
|
||||
"Add detection in check_repo before generic drift rules that could fight it.",
|
||||
"Add the repair branch in fix_repo, using file writes only through helpers.",
|
||||
"Add detection and repair tests under TestLifecycleRenormalization.",
|
||||
)
|
||||
|
||||
|
||||
@contextmanager
|
||||
def run_lock(name: str):
|
||||
"""Hold a nonblocking process lock for long-running consistency modes."""
|
||||
@@ -1999,6 +2031,24 @@ def archive_closed_workplans(
|
||||
# Output / rendering
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def render_renormalization_guide() -> str:
|
||||
lines = ["Lifecycle Renormalization Rules", "=" * 33]
|
||||
for rule in RENORMALIZATION_RULES:
|
||||
lines.extend(
|
||||
[
|
||||
"",
|
||||
f"{rule.check_id}: {rule.invariant}",
|
||||
f" Detect: {rule.detection}",
|
||||
f" Repair: {rule.repair}",
|
||||
f" Tests: {rule.test_anchor}",
|
||||
]
|
||||
)
|
||||
lines.extend(["", "Add The Next Guard"])
|
||||
for idx, item in enumerate(RENORMALIZATION_NEXT_GUARD_CHECKLIST, 1):
|
||||
lines.append(f" {idx}. {item}")
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
def render_text(report: ConsistencyReport, show_info: bool = True) -> str:
|
||||
SEP = "=" * 66
|
||||
lines = [
|
||||
@@ -2089,6 +2139,8 @@ def main() -> None:
|
||||
help="Run checks against all repos with a resolvable path on this host")
|
||||
group.add_argument("--here", metavar="PATH", nargs="?", const="",
|
||||
help="Infer repo slug from git remote URL at PATH (default: CWD)")
|
||||
group.add_argument("--renormalization-guide", action="store_true",
|
||||
help="Print lifecycle renormalization rules and the add-next-guard checklist")
|
||||
parser.add_argument("--fix", action="store_true",
|
||||
help="Apply auto-fixable issues (status drift, repo mismatch, etc.)")
|
||||
parser.add_argument("--remote", action="store_true",
|
||||
@@ -2115,6 +2167,25 @@ def main() -> None:
|
||||
help="Output JSON instead of human-readable text")
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.renormalization_guide:
|
||||
if args.as_json:
|
||||
print(json.dumps({
|
||||
"rules": [
|
||||
{
|
||||
"check_id": rule.check_id,
|
||||
"invariant": rule.invariant,
|
||||
"detection": rule.detection,
|
||||
"repair": rule.repair,
|
||||
"test_anchor": rule.test_anchor,
|
||||
}
|
||||
for rule in RENORMALIZATION_RULES
|
||||
],
|
||||
"add_next_guard": list(RENORMALIZATION_NEXT_GUARD_CHECKLIST),
|
||||
}, indent=2))
|
||||
else:
|
||||
print(render_renormalization_guide())
|
||||
sys.exit(0)
|
||||
|
||||
import os as _os
|
||||
no_wb = getattr(args, "no_writeback", False)
|
||||
do_fix = args.fix or args.remote
|
||||
|
||||
@@ -24,6 +24,7 @@ from consistency_check import (
|
||||
ConsistencyReport,
|
||||
Issue,
|
||||
FILE_TO_DB_WORKSTREAM_STATUS,
|
||||
RENORMALIZATION_RULES,
|
||||
STATUS_ORDER,
|
||||
_BACKGROUND_CHECKS,
|
||||
_detect_behind_remote,
|
||||
@@ -41,6 +42,7 @@ from consistency_check import (
|
||||
parse_frontmatter,
|
||||
parse_task_blocks,
|
||||
render_text,
|
||||
render_renormalization_guide,
|
||||
report_to_dict,
|
||||
)
|
||||
from api.workplan_status import ready_review_status
|
||||
@@ -377,6 +379,20 @@ class TestRenderText:
|
||||
assert "C-08" not in text
|
||||
|
||||
|
||||
class TestRenormalizationGuide:
|
||||
def test_registry_contains_c23_rule(self):
|
||||
rule = next(rule for rule in RENORMALIZATION_RULES if rule.check_id == "C-23")
|
||||
assert "Planning-state" in rule.invariant
|
||||
assert "TestLifecycleRenormalization" in rule.test_anchor
|
||||
|
||||
def test_guide_points_to_next_guard_pattern(self):
|
||||
text = render_renormalization_guide()
|
||||
assert "C-23" in text
|
||||
assert "Add The Next Guard" in text
|
||||
assert "Add detection in check_repo" in text
|
||||
assert "Add the repair branch in fix_repo" in text
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# report_to_dict
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
@@ -154,7 +154,7 @@ existing consistency sync loop.
|
||||
|
||||
```task
|
||||
id: STATE-WP-0047-T06
|
||||
status: todo
|
||||
status: done
|
||||
priority: medium
|
||||
state_hub_task_id: "4b663fce-876c-4a52-955c-c754dbf44b0f"
|
||||
```
|
||||
@@ -165,6 +165,11 @@ turn that pattern into a new invariant, test, or consistency repair.
|
||||
Done when renormalization scaffolding has an explicit "add the next guard here"
|
||||
pattern instead of relying on ad hoc fixes.
|
||||
|
||||
Result 2026-05-23: added a renormalization rule registry and
|
||||
`scripts/consistency_check.py --renormalization-guide`. The guide lists active
|
||||
repair rules and the concise checklist for turning the next recognized drift
|
||||
pattern into metadata, detection, repair, and tests.
|
||||
|
||||
## T07 - Regression Tests
|
||||
|
||||
```task
|
||||
@@ -191,6 +196,9 @@ Progress 2026-05-23: added consistency checker coverage for lifecycle
|
||||
renormalization detection and repair, including a guard that C-23 takes
|
||||
precedence over generic C-04 status drift.
|
||||
|
||||
Progress 2026-05-23: added guide coverage so the drift-learning scaffold has a
|
||||
stable test anchor.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
- Starting task work deterministically activates the parent workstream.
|
||||
|
||||
Reference in New Issue
Block a user