generated from coulomb/repo-seed
Explore after registration as default
This commit is contained in:
@@ -101,6 +101,15 @@ def page(title: str, body: str) -> HTMLResponse:
|
|||||||
font: inherit;
|
font: inherit;
|
||||||
}}
|
}}
|
||||||
label {{ display: grid; gap: 5px; color: var(--muted); font-size: 12px; font-weight: 600; }}
|
label {{ display: grid; gap: 5px; color: var(--muted); font-size: 12px; font-weight: 600; }}
|
||||||
|
label.checkbox {{
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
align-items: center;
|
||||||
|
color: var(--text);
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 500;
|
||||||
|
}}
|
||||||
|
label.checkbox input {{ width: auto; }}
|
||||||
button, .button {{
|
button, .button {{
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -203,6 +212,7 @@ def render_repository_index(
|
|||||||
<label>Branch <input name="branch" value="main"></label>
|
<label>Branch <input name="branch" value="main"></label>
|
||||||
<label>Username <input name="access_username" autocomplete="username" placeholder="Optional for private HTTP(S) repos"></label>
|
<label>Username <input name="access_username" autocomplete="username" placeholder="Optional for private HTTP(S) repos"></label>
|
||||||
<label>Password or access token <input name="access_password" type="password" autocomplete="current-password" placeholder="Used for this Git operation only"></label>
|
<label>Password or access token <input name="access_password" type="password" autocomplete="current-password" placeholder="Used for this Git operation only"></label>
|
||||||
|
<label class="checkbox"><input type="checkbox" name="explore_after_registration" value="1" checked> Explore after registration</label>
|
||||||
<div class="actions">
|
<div class="actions">
|
||||||
<button type="submit">Register</button>
|
<button type="submit">Register</button>
|
||||||
<span data-pending>Registering repository...</span>
|
<span data-pending>Registering repository...</span>
|
||||||
@@ -414,6 +424,7 @@ def create_repository_from_form(
|
|||||||
branch: str = Form("main"),
|
branch: str = Form("main"),
|
||||||
access_username: str = Form(""),
|
access_username: str = Form(""),
|
||||||
access_password: str = Form(""),
|
access_password: str = Form(""),
|
||||||
|
explore_after_registration: str | None = Form(None),
|
||||||
service: RegistryService = Depends(get_service),
|
service: RegistryService = Depends(get_service),
|
||||||
):
|
):
|
||||||
try:
|
try:
|
||||||
@@ -429,6 +440,16 @@ def create_repository_from_form(
|
|||||||
error_message=str(exc),
|
error_message=str(exc),
|
||||||
status_code=400,
|
status_code=400,
|
||||||
)
|
)
|
||||||
|
if explore_after_registration:
|
||||||
|
summary = service.analyze_repository(
|
||||||
|
repository.id,
|
||||||
|
access_username=access_username or None,
|
||||||
|
access_password=access_password or None,
|
||||||
|
)
|
||||||
|
return RedirectResponse(
|
||||||
|
f"/ui/repos/{repository.id}/analysis-runs/{summary.analysis_run.id}",
|
||||||
|
status_code=303,
|
||||||
|
)
|
||||||
return RedirectResponse(f"/ui/repos/{repository.id}", status_code=303)
|
return RedirectResponse(f"/ui/repos/{repository.id}", status_code=303)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1075,6 +1075,7 @@ def test_ui_register_analyze_and_approve_loop(tmp_path):
|
|||||||
assert "Register Repository" in index_response.text
|
assert "Register Repository" in index_response.text
|
||||||
assert "Registering repository..." in index_response.text
|
assert "Registering repository..." in index_response.text
|
||||||
assert "Password or access token" in index_response.text
|
assert "Password or access token" in index_response.text
|
||||||
|
assert "Explore after registration" in index_response.text
|
||||||
|
|
||||||
create_response = client.post(
|
create_response = client.post(
|
||||||
"/ui/repos",
|
"/ui/repos",
|
||||||
@@ -1083,6 +1084,7 @@ def test_ui_register_analyze_and_approve_loop(tmp_path):
|
|||||||
"branch": "main",
|
"branch": "main",
|
||||||
"access_username": "",
|
"access_username": "",
|
||||||
"access_password": "",
|
"access_password": "",
|
||||||
|
"explore_after_registration": "",
|
||||||
},
|
},
|
||||||
follow_redirects=False,
|
follow_redirects=False,
|
||||||
)
|
)
|
||||||
@@ -1210,6 +1212,47 @@ def test_ui_register_analyze_and_approve_loop(tmp_path):
|
|||||||
app.dependency_overrides.clear()
|
app.dependency_overrides.clear()
|
||||||
|
|
||||||
|
|
||||||
|
def test_ui_register_and_explore_lands_on_analysis_result(tmp_path):
|
||||||
|
source = tmp_path / "explore-repo"
|
||||||
|
source.mkdir()
|
||||||
|
(source / "README.md").write_text("# Explore Repo\n", encoding="utf-8")
|
||||||
|
(source / "pyproject.toml").write_text(
|
||||||
|
"[project]\nname = \"explore-repo\"\ndescription = \"Explorable repo.\"\n",
|
||||||
|
encoding="utf-8",
|
||||||
|
)
|
||||||
|
|
||||||
|
def override_settings():
|
||||||
|
return Settings(
|
||||||
|
database_path=str(tmp_path / "ui-explore.sqlite3"),
|
||||||
|
checkout_root=str(tmp_path / "ui-explore-checkouts"),
|
||||||
|
)
|
||||||
|
|
||||||
|
app.dependency_overrides[get_settings] = override_settings
|
||||||
|
client = TestClient(app)
|
||||||
|
try:
|
||||||
|
response = client.post(
|
||||||
|
"/ui/repos",
|
||||||
|
data={
|
||||||
|
"url": str(source),
|
||||||
|
"branch": "main",
|
||||||
|
"access_username": "",
|
||||||
|
"access_password": "",
|
||||||
|
"explore_after_registration": "1",
|
||||||
|
},
|
||||||
|
follow_redirects=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert response.status_code == 303
|
||||||
|
assert response.headers["location"].endswith("/analysis-runs/1")
|
||||||
|
|
||||||
|
result = client.get(response.headers["location"])
|
||||||
|
assert result.status_code == 200
|
||||||
|
assert "Candidate Graph" in result.text
|
||||||
|
assert "Observed Facts" in result.text
|
||||||
|
finally:
|
||||||
|
app.dependency_overrides.clear()
|
||||||
|
|
||||||
|
|
||||||
def test_ui_registration_failure_returns_feedback(tmp_path):
|
def test_ui_registration_failure_returns_feedback(tmp_path):
|
||||||
def override_settings():
|
def override_settings():
|
||||||
return Settings(
|
return Settings(
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ configured trusted automation mode.
|
|||||||
|
|
||||||
```task
|
```task
|
||||||
id: RREG-WP-0003-T01
|
id: RREG-WP-0003-T01
|
||||||
status: in_progress
|
status: done
|
||||||
priority: high
|
priority: high
|
||||||
state_hub_task_id: "ab718ce7-d38f-4080-9385-99be1bf80475"
|
state_hub_task_id: "ab718ce7-d38f-4080-9385-99be1bf80475"
|
||||||
```
|
```
|
||||||
@@ -58,7 +58,28 @@ coordination should be visible as source-linked claims.
|
|||||||
|
|
||||||
Acceptance: a self-analysis run produces non-trivial, source-linked candidate
|
Acceptance: a self-analysis run produces non-trivial, source-linked candidate
|
||||||
abilities and capabilities that a curator would recognize as the repo's real
|
abilities and capabilities that a curator would recognize as the repo's real
|
||||||
purpose.
|
purpose. A one-to-one correspondence of observed fact to generated feature is a
|
||||||
|
quality smell: features should describe user-visible or operational behavior, with
|
||||||
|
facts as drilldown evidence, not mirror individual scanner facts.
|
||||||
|
|
||||||
|
## P0: Abstraction Strategy And LLM Boundary
|
||||||
|
|
||||||
|
```task
|
||||||
|
id: RREG-WP-0003-T06
|
||||||
|
status: todo
|
||||||
|
priority: high
|
||||||
|
state_hub_task_id: "51890aff-511d-4635-85c4-fe4db0b7dd01"
|
||||||
|
```
|
||||||
|
|
||||||
|
Document and test how the registry should climb from deterministic observed facts
|
||||||
|
to useful ability/capability/feature abstractions. Explicitly compare what can be
|
||||||
|
done deterministically against what likely needs LLM assistance. Preserve the trust
|
||||||
|
boundary: deterministic scanners establish facts; abstraction may propose claims;
|
||||||
|
review or trusted automation decides approved registry truth.
|
||||||
|
|
||||||
|
Acceptance: `docs/` contains an abstraction strategy note with examples from the
|
||||||
|
three trial repos, and candidate generation has at least one regression guard
|
||||||
|
against feature granularity collapsing into one feature per observed fact.
|
||||||
|
|
||||||
## P1: Guided Review To Populated Registry
|
## P1: Guided Review To Populated Registry
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user