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"]
|
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
|
@contextmanager
|
||||||
def run_lock(name: str):
|
def run_lock(name: str):
|
||||||
"""Hold a nonblocking process lock for long-running consistency modes."""
|
"""Hold a nonblocking process lock for long-running consistency modes."""
|
||||||
@@ -1999,6 +2031,24 @@ def archive_closed_workplans(
|
|||||||
# Output / rendering
|
# 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:
|
def render_text(report: ConsistencyReport, show_info: bool = True) -> str:
|
||||||
SEP = "=" * 66
|
SEP = "=" * 66
|
||||||
lines = [
|
lines = [
|
||||||
@@ -2089,6 +2139,8 @@ def main() -> None:
|
|||||||
help="Run checks against all repos with a resolvable path on this host")
|
help="Run checks against all repos with a resolvable path on this host")
|
||||||
group.add_argument("--here", metavar="PATH", nargs="?", const="",
|
group.add_argument("--here", metavar="PATH", nargs="?", const="",
|
||||||
help="Infer repo slug from git remote URL at PATH (default: CWD)")
|
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",
|
parser.add_argument("--fix", action="store_true",
|
||||||
help="Apply auto-fixable issues (status drift, repo mismatch, etc.)")
|
help="Apply auto-fixable issues (status drift, repo mismatch, etc.)")
|
||||||
parser.add_argument("--remote", action="store_true",
|
parser.add_argument("--remote", action="store_true",
|
||||||
@@ -2115,6 +2167,25 @@ def main() -> None:
|
|||||||
help="Output JSON instead of human-readable text")
|
help="Output JSON instead of human-readable text")
|
||||||
args = parser.parse_args()
|
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
|
import os as _os
|
||||||
no_wb = getattr(args, "no_writeback", False)
|
no_wb = getattr(args, "no_writeback", False)
|
||||||
do_fix = args.fix or args.remote
|
do_fix = args.fix or args.remote
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ from consistency_check import (
|
|||||||
ConsistencyReport,
|
ConsistencyReport,
|
||||||
Issue,
|
Issue,
|
||||||
FILE_TO_DB_WORKSTREAM_STATUS,
|
FILE_TO_DB_WORKSTREAM_STATUS,
|
||||||
|
RENORMALIZATION_RULES,
|
||||||
STATUS_ORDER,
|
STATUS_ORDER,
|
||||||
_BACKGROUND_CHECKS,
|
_BACKGROUND_CHECKS,
|
||||||
_detect_behind_remote,
|
_detect_behind_remote,
|
||||||
@@ -41,6 +42,7 @@ from consistency_check import (
|
|||||||
parse_frontmatter,
|
parse_frontmatter,
|
||||||
parse_task_blocks,
|
parse_task_blocks,
|
||||||
render_text,
|
render_text,
|
||||||
|
render_renormalization_guide,
|
||||||
report_to_dict,
|
report_to_dict,
|
||||||
)
|
)
|
||||||
from api.workplan_status import ready_review_status
|
from api.workplan_status import ready_review_status
|
||||||
@@ -377,6 +379,20 @@ class TestRenderText:
|
|||||||
assert "C-08" not in text
|
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
|
# report_to_dict
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -154,7 +154,7 @@ existing consistency sync loop.
|
|||||||
|
|
||||||
```task
|
```task
|
||||||
id: STATE-WP-0047-T06
|
id: STATE-WP-0047-T06
|
||||||
status: todo
|
status: done
|
||||||
priority: medium
|
priority: medium
|
||||||
state_hub_task_id: "4b663fce-876c-4a52-955c-c754dbf44b0f"
|
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"
|
Done when renormalization scaffolding has an explicit "add the next guard here"
|
||||||
pattern instead of relying on ad hoc fixes.
|
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
|
## T07 - Regression Tests
|
||||||
|
|
||||||
```task
|
```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
|
renormalization detection and repair, including a guard that C-23 takes
|
||||||
precedence over generic C-04 status drift.
|
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
|
## Acceptance Criteria
|
||||||
|
|
||||||
- Starting task work deterministically activates the parent workstream.
|
- Starting task work deterministically activates the parent workstream.
|
||||||
|
|||||||
Reference in New Issue
Block a user