generated from coulomb/repo-seed
Finalized dependency aware scope prop
This commit is contained in:
@@ -47,6 +47,14 @@ The current implementation exposes this through `RegistryService`:
|
||||
The impact result includes changed fact keys, impacted items, reason chains,
|
||||
maximum propagation depth, breadth, and whether the root scope was affected.
|
||||
|
||||
## Review Workflow
|
||||
|
||||
The change-review UI shows dependency impact alongside ordinary run diffs. Each
|
||||
impacted item carries a freshness state, reason chain, propagation depth, and a
|
||||
recommended action. Curators can accept recalculated candidate text by approving
|
||||
the target run, keep prior approved claims by leaving the change unapproved, or
|
||||
edit approved characteristics through the existing manual registry forms.
|
||||
|
||||
## Interactive Visualization
|
||||
|
||||
The accepted implementation framework for the interactive graph view is
|
||||
|
||||
@@ -1619,6 +1619,11 @@ def analysis_run_diff_detail(
|
||||
base_analysis_run_id,
|
||||
target_analysis_run_id,
|
||||
)
|
||||
impact = service.analyze_dependency_impact(
|
||||
repository_id,
|
||||
base_analysis_run_id,
|
||||
target_analysis_run_id,
|
||||
)
|
||||
except NotFoundError as exc:
|
||||
raise HTTPException(status_code=404, detail=str(exc)) from exc
|
||||
display_name = repository_display_name(diff.repository)
|
||||
@@ -1639,6 +1644,13 @@ def analysis_run_diff_detail(
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
<section class="panel" style="margin-top:18px">
|
||||
<div class="actions">
|
||||
<h2 style="margin-right:auto">Dependency Impact</h2>
|
||||
<a class="button secondary" href="/ui/repos/{repository_id}/dependency-graph?base_analysis_run_id={base_analysis_run_id}&target_analysis_run_id={target_analysis_run_id}">Open Graph</a>
|
||||
</div>
|
||||
{render_dependency_impact_summary(asdict(impact))}
|
||||
</section>
|
||||
<div class="grid" style="margin-top:18px">
|
||||
<section class="panel">
|
||||
<h2>Approved Registry Impact</h2>
|
||||
@@ -2403,6 +2415,65 @@ def render_diff_section(section: dict) -> str:
|
||||
return rendered or '<p class="muted">No differences.</p>'
|
||||
|
||||
|
||||
def render_dependency_impact_summary(impact: dict) -> str:
|
||||
impacts = impact.get("impacts", [])
|
||||
metric_row = (
|
||||
f'<span class="pill">{escape(str(impact.get("propagation_breadth", 0)))} impacted</span>'
|
||||
f'<span class="pill">depth {escape(str(impact.get("max_depth", 0)))}</span>'
|
||||
+ (
|
||||
'<span class="pill">scope impacted</span>'
|
||||
if impact.get("scope_impacted")
|
||||
else '<span class="pill">scope current</span>'
|
||||
)
|
||||
)
|
||||
changed_facts = impact.get("changed_fact_keys", [])
|
||||
changed_fact_rows = "".join(
|
||||
f'<li class="source">{escape(str(fact_key))}</li>'
|
||||
for fact_key in changed_facts[:8]
|
||||
)
|
||||
changed_fact_note = (
|
||||
f"<ul>{changed_fact_rows}</ul>"
|
||||
if changed_fact_rows
|
||||
else '<p class="muted">No changed facts reached approved characteristics.</p>'
|
||||
)
|
||||
rows = "\n".join(
|
||||
f"""
|
||||
<tr>
|
||||
<td><span class="pill">{escape(str(item.get('item_kind', '')))}</span></td>
|
||||
<td>{escape(str(item.get('name', '')))}</td>
|
||||
<td><span class="pill">{escape(str(item.get('freshness_state', '')))}</span></td>
|
||||
<td>{escape(str(item.get('recommended_action', '')))}</td>
|
||||
<td>{escape(str(item.get('impact_depth', '')))}</td>
|
||||
<td>{render_impact_reasons(item.get('reasons', []))}</td>
|
||||
</tr>
|
||||
"""
|
||||
for item in impacts
|
||||
)
|
||||
table = (
|
||||
f"""
|
||||
<table>
|
||||
<thead><tr><th>Kind</th><th>Name</th><th>Freshness</th><th>Action</th><th>Depth</th><th>Why</th></tr></thead>
|
||||
<tbody>{rows}</tbody>
|
||||
</table>
|
||||
"""
|
||||
if rows
|
||||
else '<p class="muted">No approved downstream items were marked stale.</p>'
|
||||
)
|
||||
return f"""
|
||||
<div class="actions">{metric_row}</div>
|
||||
<h3>Changed Facts</h3>
|
||||
{changed_fact_note}
|
||||
<h3>Impacted Items</h3>
|
||||
{table}
|
||||
"""
|
||||
|
||||
|
||||
def render_impact_reasons(reasons: list[str]) -> str:
|
||||
if not reasons:
|
||||
return '<span class="muted">No reason recorded.</span>'
|
||||
return "<br>".join(escape(str(reason)) for reason in reasons[:3])
|
||||
|
||||
|
||||
def render_diff_group(items: list[dict], title: str) -> str:
|
||||
if not items:
|
||||
return ""
|
||||
|
||||
@@ -1691,6 +1691,8 @@ def test_ui_register_analyze_and_approve_loop(tmp_path):
|
||||
)
|
||||
assert diff_response.status_code == 200
|
||||
assert "Change Review" in diff_response.text
|
||||
assert "Dependency Impact" in diff_response.text
|
||||
assert "Open Graph" in diff_response.text
|
||||
assert "Approved Registry Impact" in diff_response.text
|
||||
assert "Candidate Claims" in diff_response.text
|
||||
assert "GET /ready" in diff_response.text
|
||||
|
||||
@@ -4,7 +4,7 @@ type: workplan
|
||||
title: "Dependency-Aware Scope Propagation"
|
||||
domain: capabilities
|
||||
repo: repo-scoping
|
||||
status: active
|
||||
status: done
|
||||
owner: codex
|
||||
topic_slug: foerster-capabilities
|
||||
created: "2026-05-01"
|
||||
@@ -80,7 +80,7 @@ Acceptance criteria:
|
||||
|
||||
```task
|
||||
id: RREG-WP-0008-T03
|
||||
status: in_progress
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "29a85e0a-7203-484c-aa5d-94096ab695a9"
|
||||
```
|
||||
@@ -115,7 +115,7 @@ Acceptance criteria:
|
||||
|
||||
```task
|
||||
id: RREG-WP-0008-T05
|
||||
status: in_progress
|
||||
status: done
|
||||
priority: medium
|
||||
state_hub_task_id: "02147d64-d339-40e2-b88d-406567bfa366"
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user